]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/conn.c
add {creators|modifiers}Name to all entries
[openldap] / servers / slapd / back-monitor / conn.c
1 /* conn.c - deal with connection subsystem */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2001-2004 The OpenLDAP Foundation.
6  * Portions Copyright 2001-2003 Pierangelo Masarati.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* ACKNOWLEDGEMENTS:
18  * This work was initially developed by Pierangelo Masarati for inclusion
19  * in OpenLDAP Software.
20  */
21
22 #include "portable.h"
23
24 #include <stdio.h>
25 #include <ac/string.h>
26
27 #include "slap.h"
28 #include "lutil.h"
29 #include "back-monitor.h"
30
31 #define CONN_CN_PREFIX  "Connection"
32
33 int
34 monitor_subsys_conn_init(
35         BackendDB               *be
36 )
37 {
38         struct monitorinfo      *mi;
39         
40         Entry                   *e, *e_tmp, *e_conn;
41         struct monitorentrypriv *mp;
42         char                    buf[ BACKMONITOR_BUFSIZE ];
43         struct berval           bv;
44
45         assert( be != NULL );
46
47         mi = ( struct monitorinfo * )be->be_private;
48
49         if ( monitor_cache_get( mi,
50                         &monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn, &e_conn ) ) {
51 #ifdef NEW_LOGGING
52                 LDAP_LOG( OPERATION, CRIT,
53                         "monitor_subsys_conn_init: "
54                         "unable to get entry '%s'\n",
55                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
56 #else
57                 Debug( LDAP_DEBUG_ANY,
58                         "monitor_subsys_conn_init: "
59                         "unable to get entry '%s'\n%s%s",
60                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 
61                         "", "" );
62 #endif
63                 return( -1 );
64         }
65
66         e_tmp = NULL;
67
68         /*
69          * Total conns
70          */
71         snprintf( buf, sizeof( buf ),
72                 "dn: cn=Total,%s\n"
73                 "objectClass: %s\n"
74                 "structuralObjectClass: %s\n"
75                 "cn: Total\n"
76                 "creatorsName: %s\n"
77                 "modifiersName: %s\n"
78                 "createTimestamp: %s\n"
79                 "modifyTimestamp: %s\n",
80                 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val,
81                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
82                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
83                 mi->mi_creatorsName.bv_val,
84                 mi->mi_creatorsName.bv_val,
85                 mi->mi_startTime.bv_val,
86                 mi->mi_startTime.bv_val );
87         
88         e = str2entry( buf );
89         if ( e == NULL ) {
90 #ifdef NEW_LOGGING
91                 LDAP_LOG( OPERATION, CRIT,
92                         "monitor_subsys_conn_init: "
93                         "unable to create entry 'cn=Total,%s'\n",
94                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
95 #else
96                 Debug( LDAP_DEBUG_ANY,
97                         "monitor_subsys_conn_init: "
98                         "unable to create entry 'cn=Total,%s'\n%s%s",
99                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
100                         "", "" );
101 #endif
102                 return( -1 );
103         }
104         
105         bv.bv_val = "0";
106         bv.bv_len = 1;
107         attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
108         
109         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
110         e->e_private = ( void * )mp;
111         mp->mp_next = e_tmp;
112         mp->mp_children = NULL;
113         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
114         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
115                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
116         mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
117
118         if ( monitor_cache_add( mi, e ) ) {
119 #ifdef NEW_LOGGING
120                 LDAP_LOG( OPERATION, CRIT,
121                         "monitor_subsys_conn_init: "
122                         "unable to add entry 'cn=Total,%s'\n",
123                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
124 #else
125                 Debug( LDAP_DEBUG_ANY,
126                         "monitor_subsys_conn_init: "
127                         "unable to add entry 'cn=Total,%s'\n%s%s",
128                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
129                         "", "" );
130 #endif
131                 return( -1 );
132         }
133         
134         e_tmp = e;
135
136         /*
137          * Current conns
138          */
139         snprintf( buf, sizeof( buf ),
140                 "dn: cn=Current,%s\n"
141                 "objectClass: %s\n"
142                 "structuralObjectClass: %s\n"
143                 "cn: Current\n"
144                 "creatorsName: %s\n"
145                 "modifiersName: %s\n"
146                 "createTimestamp: %s\n"
147                 "modifyTimestamp: %s\n",
148                 monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val,
149                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
150                 mi->mi_oc_monitorCounterObject->soc_cname.bv_val,
151                 mi->mi_creatorsName.bv_val,
152                 mi->mi_creatorsName.bv_val,
153                 mi->mi_startTime.bv_val,
154                 mi->mi_startTime.bv_val );
155         
156         e = str2entry( buf );
157         if ( e == NULL ) {
158 #ifdef NEW_LOGGING
159                 LDAP_LOG( OPERATION, CRIT,
160                         "monitor_subsys_conn_init: "
161                         "unable to create entry 'cn=Current,%s'\n",
162                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
163 #else
164                 Debug( LDAP_DEBUG_ANY,
165                         "monitor_subsys_conn_init: "
166                         "unable to create entry 'cn=Current,%s'\n%s%s",
167                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
168                         "", "" );
169 #endif
170                 return( -1 );
171         }
172         
173         bv.bv_val = "0";
174         bv.bv_len = 1;
175         attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
176         
177         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
178         e->e_private = ( void * )mp;
179         mp->mp_next = e_tmp;
180         mp->mp_children = NULL;
181         mp->mp_info = &monitor_subsys[SLAPD_MONITOR_CONN];
182         mp->mp_flags = monitor_subsys[SLAPD_MONITOR_CONN].mss_flags \
183                 | MONITOR_F_SUB | MONITOR_F_PERSISTENT;
184         mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;
185
186         if ( monitor_cache_add( mi, e ) ) {
187 #ifdef NEW_LOGGING
188                 LDAP_LOG( OPERATION, CRIT,
189                         "monitor_subsys_conn_init: "
190                         "unable to add entry 'cn=Current,%s'\n",
191                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val, 0, 0 );
192 #else
193                 Debug( LDAP_DEBUG_ANY,
194                         "monitor_subsys_conn_init: "
195                         "unable to add entry 'cn=Current,%s'\n%s%s",
196                         monitor_subsys[SLAPD_MONITOR_CONN].mss_ndn.bv_val,
197                         "", "" );
198 #endif
199                 return( -1 );
200         }
201         
202         e_tmp = e;
203
204         mp = ( struct monitorentrypriv * )e_conn->e_private;
205         mp->mp_children = e_tmp;
206
207         monitor_cache_release( mi, e_conn );
208
209         return( 0 );
210 }
211
212 int
213 monitor_subsys_conn_update(
214         Operation               *op,
215         Entry                   *e
216 )
217 {
218         struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
219         long            n = -1;
220
221         assert( mi );
222         assert( e );
223         
224         if ( strncasecmp( e->e_ndn, "cn=total", 
225                                 sizeof("cn=total")-1 ) == 0 ) {
226                 n = connections_nextid();
227
228         } else if ( strncasecmp( e->e_ndn, "cn=current", 
229                                 sizeof("cn=current")-1 ) == 0 ) {
230                 Connection      *c;
231                 int             connindex;
232
233                 for ( n = 0, c = connection_first( &connindex );
234                                 c != NULL;
235                                 n++, c = connection_next( c, &connindex ) ) {
236                         /* No Op */ ;
237                 }
238                 connection_done(c);
239         }
240
241         if ( n != -1 ) {
242                 Attribute       *a;
243                 char            buf[] = "+9223372036854775807L";
244
245                 a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
246                 if ( a == NULL ) {
247                         return( -1 );
248                 }
249
250                 snprintf( buf, sizeof( buf ), "%ld", n );
251                 free( a->a_vals[ 0 ].bv_val );
252                 ber_str2bv( buf, 0, 1, a->a_vals );
253         }
254
255         return( 0 );
256 }
257
258 static int
259 conn_create(
260         struct monitorinfo      *mi,
261         Connection              *c,
262         Entry                   **ep
263 )
264 {
265         struct monitorentrypriv *mp;
266         struct tm               *ltm;
267         char                    buf[ BACKMONITOR_BUFSIZE ];
268         char                    buf2[ LDAP_LUTIL_GENTIME_BUFSIZE ];
269         char                    buf3[ LDAP_LUTIL_GENTIME_BUFSIZE ];
270
271         struct berval           bv;
272
273         Entry                   *e;
274
275         struct tm       *ctm;
276         char            ctmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
277         struct tm       *mtm;
278         char            mtmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
279 #ifdef HAVE_GMTIME_R
280         struct tm       tm_buf;
281 #endif /* HAVE_GMTIME_R */
282
283         assert( c != NULL );
284         assert( ep != NULL );
285
286 #ifndef HAVE_GMTIME_R
287         ldap_pvt_thread_mutex_lock( &gmtime_mutex );
288 #endif
289 #ifdef HACK_LOCAL_TIME
290 # ifdef HAVE_LOCALTIME_R
291         ctm = localtime_r( &c->c_starttime, &tm_buf );
292         lutil_localtime( ctmbuf, sizeof( ctmbuf ), ctm, -timezone );
293         mtm = localtime_r( &c->c_activitytime, &tm_buf );
294         lutil_localtime( mtmbuf, sizeof( mtmbuf ), mtm, -timezone );
295 # else
296         ctm = localtime( &c->c_starttime );
297         lutil_localtime( ctmbuf, sizeof( ctmbuf ), ctm, -timezone );
298         mtm = localtime( &c->c_activitytime );
299         lutil_localtime( mtmbuf, sizeof( mtmbuf ), mtm, -timezone );
300 # endif /* HAVE_LOCALTIME_R */
301 #else /* !HACK_LOCAL_TIME */
302 # ifdef HAVE_GMTIME_R
303         ctm = gmtime_r( &c->c_starttime, &tm_buf );
304         lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
305         mtm = gmtime_r( &c->c_activitytime, &tm_buf );
306         lutil_gentime( mtmbuf, sizeof( mtmbuf ), mtm );
307 # else
308         ctm = gmtime( &c->c_starttime );
309         lutil_gentime( ctmbuf, sizeof( ctmbuf ), ctm );
310         mtm = gmtime( &c->c_activitytime );
311         lutil_gentime( mtmbuf, sizeof( mtmbuf ), mtm );
312 # endif /* HAVE_GMTIME_R */
313 #endif /* !HACK_LOCAL_TIME */
314 #ifndef HAVE_GMTIME_R
315         ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
316 #endif
317
318         snprintf( buf, sizeof( buf ),
319                 "dn: cn=" CONN_CN_PREFIX " %ld,%s\n"
320                 "objectClass: %s\n"
321                 "structuralObjectClass: %s\n"
322                 "cn: " CONN_CN_PREFIX " %ld\n"
323                 "creatorsName: %s\n"
324                 "modifiersName: %s\n"
325                 "createTimestamp: %s\n"
326                 "modifyTimestamp: %s\n",
327                 c->c_connid, monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val,
328                 mi->mi_oc_monitorConnection->soc_cname.bv_val,
329                 mi->mi_oc_monitorConnection->soc_cname.bv_val,
330                 c->c_connid,
331                 mi->mi_creatorsName.bv_val,
332                 mi->mi_creatorsName.bv_val,
333                 ctmbuf,
334                 mtmbuf );
335                 
336         e = str2entry( buf );
337
338         if ( e == NULL) {
339 #ifdef NEW_LOGGING
340                 LDAP_LOG( OPERATION, CRIT,
341                         "monitor_subsys_conn_create: "
342                         "unable to create entry "
343                         "'cn=" CONN_CN_PREFIX " %ld,%s' entry\n",
344                         c->c_connid, monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val, 0 );
345 #else
346                 Debug( LDAP_DEBUG_ANY,
347                         "monitor_subsys_conn_create: "
348                         "unable to create entry "
349                         "'cn=" CONN_CN_PREFIX " %ld,%s' entry\n",
350                         c->c_connid, 
351                         monitor_subsys[SLAPD_MONITOR_CONN].mss_dn.bv_val, 0 );
352 #endif
353                 return( -1 );
354         }
355
356 #ifndef HAVE_GMTIME_R
357         ldap_pvt_thread_mutex_lock( &gmtime_mutex );
358 #endif
359
360 #ifdef HAVE_GMTIME_R
361         ltm = gmtime_r( &c->c_starttime, &tm_buf );
362 #else
363         ltm = gmtime( &c->c_starttime );
364 #endif
365         lutil_gentime( buf2, sizeof( buf2 ), ltm );
366
367 #ifdef HAVE_GMTIME_R
368         ltm = gmtime_r( &c->c_activitytime, &tm_buf );
369 #else
370         ltm = gmtime( &c->c_activitytime );
371 #endif
372         lutil_gentime( buf3, sizeof( buf3 ), ltm );
373
374 #ifndef HAVE_GMTIME_R
375         ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
376 #endif /* HAVE_GMTIME_R */
377
378         /* monitored info */
379         sprintf( buf,
380                 "%ld : %ld "
381                 ": %ld/%ld/%ld/%ld "
382                 ": %ld/%ld/%ld "
383                 ": %s%s%s%s%s%s "
384                 ": %s : %s : %s "
385                 ": %s : %s : %s : %s",
386                 c->c_connid,
387                 (long) c->c_protocol,
388                 c->c_n_ops_received, c->c_n_ops_executing,
389                 c->c_n_ops_pending, c->c_n_ops_completed,
390                 
391                 /* add low-level counters here */
392                 c->c_n_get, c->c_n_read, c->c_n_write,
393                 
394                 c->c_currentber ? "r" : "",
395                 c->c_writewaiter ? "w" : "",
396                 LDAP_STAILQ_EMPTY( &c->c_ops ) ? "" : "x",
397                 LDAP_STAILQ_EMPTY( &c->c_pending_ops ) ? "" : "p",
398                 connection_state2str( c->c_conn_state ),
399                 c->c_sasl_bind_in_progress ? "S" : "",
400                 
401                 c->c_dn.bv_len ? c->c_dn.bv_val : SLAPD_ANONYMOUS,
402                 
403                 c->c_listener_url.bv_val,
404                 c->c_peer_domain.bv_val,
405                 c->c_peer_name.bv_val,
406                 c->c_sock_name.bv_val,
407                 
408                 buf2,
409                 buf3
410                 );
411
412         bv.bv_val = buf;
413         bv.bv_len = strlen( buf );
414         attr_merge_one( e, mi->mi_ad_monitoredInfo, &bv, NULL );
415
416         /* connection number */
417         snprintf( buf, sizeof( buf ), "%ld", c->c_connid );
418         bv.bv_val = buf;
419         bv.bv_len = strlen( buf );
420         attr_merge_one( e, mi->mi_ad_monitorConnectionNumber, &bv, NULL );
421
422         /* authz DN */
423         attr_merge_one( e, mi->mi_ad_monitorConnectionAuthzDN,
424                         &c->c_dn, &c->c_ndn );
425
426         /* local address */
427         attr_merge_one( e, mi->mi_ad_monitorConnectionLocalAddress,
428                         &c->c_sock_name, NULL );
429
430         /* peer address */
431         attr_merge_one( e, mi->mi_ad_monitorConnectionPeerAddress,
432                         &c->c_peer_name, NULL );
433
434         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
435         e->e_private = ( void * )mp;
436         mp->mp_info = &monitor_subsys[ SLAPD_MONITOR_CONN ];
437         mp->mp_children = NULL;
438         mp->mp_flags = MONITOR_F_SUB | MONITOR_F_VOLATILE;
439
440         *ep = e;
441
442         return( 0 );
443 }
444
445 int 
446 monitor_subsys_conn_create( 
447         Operation               *op,
448         struct berval           *ndn,
449         Entry                   *e_parent,
450         Entry                   **ep
451 )
452 {
453         struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
454         Connection              *c;
455         int                     connindex;
456         struct monitorentrypriv *mp;
457
458         assert( mi != NULL );
459         assert( e_parent != NULL );
460         assert( ep != NULL );
461
462         *ep = NULL;
463
464         if ( ndn == NULL ) {
465                 Entry *e, *e_tmp = NULL;
466
467                 /* create all the children of e_parent */
468                 for ( c = connection_first( &connindex );
469                                 c != NULL;
470                                 c = connection_next( c, &connindex )) {
471                         if ( conn_create( mi, c, &e ) || e == NULL ) {
472                                 connection_done(c);
473                                 for ( ; e_tmp != NULL; ) {
474                                         mp = ( struct monitorentrypriv * )e_tmp->e_private;
475                                         e = mp->mp_next;
476
477                                         ch_free( mp );
478                                         e_tmp->e_private = NULL;
479                                         entry_free( e_tmp );
480
481                                         e_tmp = e;
482                                 }
483                                 return( -1 );
484                         }
485                         mp = ( struct monitorentrypriv * )e->e_private;
486                         mp->mp_next = e_tmp;
487                         e_tmp = e;
488                 }
489                 connection_done(c);
490
491                 *ep = e;
492
493         } else {
494                 LDAPRDN         values = NULL;
495                 const char      *text = NULL;
496                 unsigned long   connid;
497                
498                 /* create exactly the required entry */
499
500                 if ( ldap_bv2rdn( ndn, &values, (char **)&text,
501                         LDAP_DN_FORMAT_LDAP ) )
502                 {
503                         return( -1 );
504                 }
505                 
506                 assert( values );
507                 assert( values[ 0 ] );
508
509                 connid = atol( values[ 0 ]->la_value.bv_val
510                                 + sizeof( CONN_CN_PREFIX ) );
511
512                 ldap_rdnfree( values );
513
514                 for ( c = connection_first( &connindex );
515                                 c != NULL;
516                                 c = connection_next( c, &connindex )) {
517                         if ( c->c_connid == connid ) {
518                                 if ( conn_create( mi, c, ep ) || *ep == NULL ) {
519                                         connection_done( c );
520                                         return( -1 );
521                                 }
522
523                                 break;
524                         }
525                 }
526                 
527                 connection_done(c);
528         
529         }
530
531         return( 0 );
532 }
533