]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/init.c
Fix for attr_merge
[openldap] / servers / slapd / back-monitor / init.c
1 /* init.c - initialize monitor backend */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  * Copyright 2001 The OpenLDAP Foundation, All Rights Reserved.
8  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
9  * 
10  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
11  * 
12  * This work has beed deveolped for the OpenLDAP Foundation 
13  * in the hope that it may be useful to the Open Source community, 
14  * but WITHOUT ANY WARRANTY.
15  * 
16  * Permission is granted to anyone to use this software for any purpose
17  * on any computer system, and to alter it and redistribute it, subject
18  * to the following restrictions:
19  * 
20  * 1. The author and SysNet s.n.c. are not responsible for the consequences
21  *    of use of this software, no matter how awful, even if they arise from
22  *    flaws in it.
23  * 
24  * 2. The origin of this software must not be misrepresented, either by
25  *    explicit claim or by omission.  Since few users ever read sources,
26  *    credits should appear in the documentation.
27  * 
28  * 3. Altered versions must be plainly marked as such, and must not be
29  *    misrepresented as being the original software.  Since few users
30  *    ever read sources, credits should appear in the documentation.
31  *    SysNet s.n.c. cannot be responsible for the consequences of the
32  *    alterations.
33  * 
34  * 4. This notice may not be removed or altered.
35  */
36
37 #include "portable.h"
38
39 #include <stdio.h>
40 #include <ac/string.h>
41
42 #include "slap.h"
43 #include "back-monitor.h"
44
45 /*
46  * used by many functions to add description to entries
47  */
48 AttributeDescription *monitor_ad_desc = NULL;
49
50 /*
51  * subsystem data
52  */
53 struct monitorsubsys monitor_subsys[] = {
54         { 
55                 SLAPD_MONITOR_LISTENER, SLAPD_MONITOR_LISTENER_NAME,    
56                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
57                 MONITOR_F_NONE,
58                 NULL,   /* init */
59                 NULL,   /* update */
60                 NULL,   /* create */
61                 NULL    /* modify */
62         }, { 
63                 SLAPD_MONITOR_DATABASE, SLAPD_MONITOR_DATABASE_NAME,    
64                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
65                 MONITOR_F_PERSISTENT_CH,
66                 monitor_subsys_database_init,
67                 NULL,   /* update */
68                 NULL,   /* create */
69                 NULL    /* modify */
70         }, { 
71                 SLAPD_MONITOR_BACKEND, SLAPD_MONITOR_BACKEND_NAME, 
72                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
73                 MONITOR_F_PERSISTENT_CH,
74                 monitor_subsys_backend_init,
75                 NULL,   /* update */
76                 NULL,   /* create */
77                 NULL    /* modify */
78         }, { 
79                 SLAPD_MONITOR_THREAD, SLAPD_MONITOR_THREAD_NAME,        
80                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
81                 MONITOR_F_NONE,
82                 monitor_subsys_thread_init,
83                 monitor_subsys_thread_update,
84                 NULL,   /* create */
85                 NULL    /* modify */
86         }, { 
87                 SLAPD_MONITOR_SASL, SLAPD_MONITOR_SASL_NAME,    
88                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
89                 MONITOR_F_NONE,
90                 NULL,   /* init */
91                 NULL,   /* update */
92                 NULL,   /* create */
93                 NULL    /* modify */
94         }, { 
95                 SLAPD_MONITOR_TLS, SLAPD_MONITOR_TLS_NAME,
96                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
97                 MONITOR_F_NONE,
98                 NULL,   /* init */
99                 NULL,   /* update */
100                 NULL,   /* create */
101                 NULL    /* modify */
102         }, { 
103                 SLAPD_MONITOR_CONN, SLAPD_MONITOR_CONN_NAME,
104                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
105                 MONITOR_F_VOLATILE_CH,
106                 monitor_subsys_conn_init,
107                 monitor_subsys_conn_update,
108                 monitor_subsys_conn_create,
109                 NULL    /* modify */
110         }, { 
111                 SLAPD_MONITOR_READW, SLAPD_MONITOR_READW_NAME,
112                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
113                 MONITOR_F_NONE,
114                 NULL,   /* init */
115                 monitor_subsys_readw_update,
116                 NULL,   /* create */
117                 NULL    /* modify */
118         }, { 
119                 SLAPD_MONITOR_WRITEW, SLAPD_MONITOR_WRITEW_NAME,
120                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
121                 MONITOR_F_NONE,
122                 NULL,   /* init */
123                 monitor_subsys_writew_update,
124                 NULL,   /* create */
125                 NULL    /* modify */
126         }, { 
127                 SLAPD_MONITOR_LOG, SLAPD_MONITOR_LOG_NAME,
128                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
129                 MONITOR_F_NONE,
130                 monitor_subsys_log_init,
131                 NULL,   /* update */
132                 NULL,   /* create */
133                 monitor_subsys_log_modify
134         }, { 
135                 SLAPD_MONITOR_OPS, SLAPD_MONITOR_OPS_NAME,
136                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
137                 MONITOR_F_NONE,
138                 monitor_subsys_ops_init,
139                 monitor_subsys_ops_update,
140                 NULL,   /* create */
141                 NULL,   /* modify */
142         }, { 
143                 SLAPD_MONITOR_SENT, SLAPD_MONITOR_SENT_NAME,
144                 { 0L, NULL }, { 0L, NULL }, { 0L, NULL },
145                 MONITOR_F_NONE,
146                 monitor_subsys_sent_init,
147                 monitor_subsys_sent_update,
148                 NULL,   /* create */
149                 NULL,   /* modify */
150         }, { -1, NULL }
151 };
152
153 int
154 monitor_back_initialize(
155         BackendInfo     *bi
156 )
157 {
158         static char *controls[] = {
159                 LDAP_CONTROL_MANAGEDSAIT,
160                 NULL
161         };
162
163         bi->bi_controls = controls;
164
165         bi->bi_init = 0;
166         bi->bi_open = monitor_back_open;
167         bi->bi_config = monitor_back_config;
168         bi->bi_close = 0;
169         bi->bi_destroy = 0;
170
171         bi->bi_db_init = monitor_back_db_init;
172         bi->bi_db_config = monitor_back_db_config;
173         bi->bi_db_open = 0;
174         bi->bi_db_close = 0;
175         bi->bi_db_destroy = monitor_back_db_destroy;
176
177         bi->bi_op_bind = monitor_back_bind;
178         bi->bi_op_unbind = 0;
179         bi->bi_op_search = monitor_back_search;
180         bi->bi_op_compare = monitor_back_compare;
181         bi->bi_op_modify = monitor_back_modify;
182         bi->bi_op_modrdn = 0;
183         bi->bi_op_add = 0;
184         bi->bi_op_delete = 0;
185         bi->bi_op_abandon = 0;
186
187         bi->bi_extended = 0;
188
189         bi->bi_entry_release_rw = 0;
190         bi->bi_acl_group = 0;
191         bi->bi_acl_attribute = 0;
192         bi->bi_chk_referrals = 0;
193         bi->bi_operational = monitor_back_operational;
194
195         /*
196          * hooks for slap tools
197          */
198         bi->bi_tool_entry_open = 0;
199         bi->bi_tool_entry_close = 0;
200         bi->bi_tool_entry_first = 0;
201         bi->bi_tool_entry_next = 0;
202         bi->bi_tool_entry_get = 0;
203         bi->bi_tool_entry_put = 0;
204         bi->bi_tool_entry_reindex = 0;
205         bi->bi_tool_sync = 0;
206
207         bi->bi_connection_init = 0;
208         bi->bi_connection_destroy = 0;
209
210         return 0;
211 }
212
213 int
214 monitor_back_db_init(
215         BackendDB       *be
216 )
217 {
218         struct monitorinfo      *mi;
219         Entry                   *e, *e_tmp;
220         struct monitorentrypriv *mp;
221         int                     i, rc;
222         char                    buf[1024], *end_of_line;
223         struct berval           dn, *ndn;
224         const char              *text;
225         struct berval           bv[2];
226
227         /*
228          * database monitor can be defined once only
229          */
230         static int              monitor_defined = 0;
231
232         if ( monitor_defined ) {
233 #ifdef NEW_LOGGING
234                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
235                         "only one monitor backend is allowed\n" ));
236 #else
237                 Debug( LDAP_DEBUG_ANY,
238                         "only one monitor backend is allowed\n%s%s%s",
239                         "", "", "" );
240 #endif
241                 return( -1 );
242         }
243         monitor_defined++;
244
245         ndn = NULL;
246         dn.bv_val = SLAPD_MONITOR_DN;
247         dn.bv_len = sizeof( SLAPD_MONITOR_DN ) - 1;
248
249         rc = dnNormalize( NULL, &dn, &ndn );
250         if( rc != LDAP_SUCCESS ) {
251 #ifdef NEW_LOGGING
252                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
253                         "monitor DN \"" SLAPD_MONITOR_DN "\" backend is allowed\n" ));
254 #else
255                 Debug( LDAP_DEBUG_ANY,
256                         "monitor DN \"" SLAPD_MONITOR_DN "\" backend is allowed\n",
257                         0, 0, 0 );
258 #endif
259                 return -1;
260         }
261
262         ber_bvecadd( &be->be_suffix, ber_bvdup( &dn ) );
263         ber_bvecadd( &be->be_nsuffix, ndn );
264
265         mi = ( struct monitorinfo * )ch_calloc( sizeof( struct monitorinfo ), 1 );
266         ldap_pvt_thread_mutex_init( &mi->mi_cache_mutex );
267
268         if ( slap_str2ad( "description", &monitor_ad_desc, &text ) ) {
269 #ifdef NEW_LOGGING
270                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
271                         "monitor_back_db_init: %s\n", text ));
272 #else
273                 Debug( LDAP_DEBUG_ANY,
274                         "monitor_subsys_backend_init: %s\n%s%s", 
275                         text, "", "" );
276 #endif
277                 return( -1 );
278         }
279
280         /*      
281          * Create all the subsystem specific entries
282          */
283         e_tmp = NULL;
284         for ( i = 0; monitor_subsys[ i ].mss_name != NULL; i++ ) {
285                 int             len = strlen( monitor_subsys[ i ].mss_name );
286                 struct berval   dn;
287                 int             rc;
288
289                 dn.bv_len = len + sizeof( "cn=" ) - 1;
290                 dn.bv_val = ch_calloc( sizeof( char ), dn.bv_len + 1 );
291                 strcpy( dn.bv_val, "cn=" );
292                 strcat( dn.bv_val, monitor_subsys[ i ].mss_name );
293                 rc = dnPretty2( NULL, &dn, &monitor_subsys[ i ].mss_rdn );
294                 free( dn.bv_val );
295                 if ( rc != LDAP_SUCCESS ) {
296 #ifdef NEW_LOGGING
297                         LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
298                                 "monitor RDN \"%s\" is invalid\n", 
299                                 dn.bv_val ));
300 #else
301                         Debug( LDAP_DEBUG_ANY,
302                                 "monitor RDN \"%s\" is invalid\n", 
303                                 dn.bv_val, 0, 0 );
304 #endif
305                         return( -1 );
306                 }
307
308                 dn.bv_len += sizeof( SLAPD_MONITOR_DN ); /* 1 for the , */
309                 dn.bv_val = ch_malloc( dn.bv_len + 1 );
310                 strcpy( dn.bv_val , monitor_subsys[ i ].mss_rdn.bv_val );
311                 strcat( dn.bv_val, "," SLAPD_MONITOR_DN );
312                 rc = dnPrettyNormal( NULL, &dn, &monitor_subsys[ i ].mss_dn,
313                         &monitor_subsys[ i ].mss_ndn );
314                 free( dn.bv_val );
315                 if ( rc != LDAP_SUCCESS ) {
316 #ifdef NEW_LOGGING
317                         LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
318                                 "monitor DN \"%s\" is invalid\n", 
319                                 dn.bv_val ));
320 #else
321                         Debug( LDAP_DEBUG_ANY,
322                                 "monitor DN \"%s\" is invalid\n", 
323                                 dn.bv_val, 0, 0 );
324 #endif
325                         return( -1 );
326                 }
327
328                 snprintf( buf, sizeof( buf ),
329                                 "dn: %s\n"
330                                 "objectClass: top\n"
331                                 "objectClass: LDAPsubEntry\n"
332 #ifdef SLAPD_MONITORSUBENTRY
333                                 "objectClass: monitorSubEntry\n"
334 #else /* !SLAPD_MONITORSUBENTRY */
335                                 "objectClass: extensibleObject\n"
336 #endif /* !SLAPD_MONITORSUBENTRY */
337                                 "cn: %s\n",
338                                 monitor_subsys[ i ].mss_dn.bv_val,
339                                 monitor_subsys[ i ].mss_name );
340                 
341                 e = str2entry( buf );
342                 
343                 if ( e == NULL) {
344 #ifdef NEW_LOGGING
345                         LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
346                                 "unable to create '%s' entry\n", 
347                                 monitor_subsys[ i ].mss_dn.bv_val ));
348 #else
349                         Debug( LDAP_DEBUG_ANY,
350                                 "unable to create '%s' entry\n", 
351                                 monitor_subsys[ i ].mss_dn.bv_val, 0, 0 );
352 #endif
353                         return( -1 );
354                 }
355
356                 mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
357                 e->e_private = ( void * )mp;
358                 mp->mp_info = &monitor_subsys[ i ];
359                 mp->mp_children = NULL;
360                 mp->mp_next = e_tmp;
361                 mp->mp_flags = monitor_subsys[ i ].mss_flags;
362
363                 if ( monitor_cache_add( mi, e ) ) {
364 #ifdef NEW_LOGGING
365                         LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
366                                 "unable to add entry '%s' to cache\n",
367                                 monitor_subsys[ i ].mss_dn.bv_val ));
368 #else
369                         Debug( LDAP_DEBUG_ANY,
370                                 "unable to add entry '%s' to cache\n",
371                                 monitor_subsys[ i ].mss_dn.bv_val, 0, 0 );
372 #endif
373                         return -1;
374                 }
375
376                 e_tmp = e;
377         }
378
379         /*
380          * creates the "cn=Monitor" entry 
381          */
382         snprintf( buf, sizeof( buf ), 
383                         "dn: " SLAPD_MONITOR_DN "\n"
384                         "objectClass: top\n"
385                         "objectClass: LDAPsubEntry\n"
386 #ifdef SLAPD_MONITORSUBENTRY
387                         "objectClass: monitorSubEntry\n"
388 #else /* !SLAPD_MONITORSUBENTRY */
389                         "objectClass: extensibleObject\n"
390 #endif /* !SLAPD_MONITORSUBENTRY */
391                         "cn: Monitor" );
392
393         e = str2entry( buf );
394         if ( e == NULL) {
395 #ifdef NEW_LOGGING
396                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
397                         "unable to create '%s' entry\n",
398                         SLAPD_MONITOR_DN ));
399 #else
400                 Debug( LDAP_DEBUG_ANY,
401                         "unable to create '%s' entry\n%s%s",
402                         SLAPD_MONITOR_DN, "", "" );
403 #endif
404                 return( -1 );
405         }
406         bv[1].bv_val = NULL;
407         bv[0].bv_val = (char *) Versionstr;
408         end_of_line = strchr( Versionstr, '\n' );
409         if ( end_of_line ) {
410                 bv[0].bv_len = end_of_line - Versionstr;
411         } else {
412                 bv[0].bv_len = strlen( Versionstr );
413         }
414         if ( attr_merge( e, monitor_ad_desc, bv ) ) {
415 #ifdef NEW_LOGGING
416                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
417                         "unable to add description to '%s' entry\n",
418                         SLAPD_MONITOR_DN ));
419 #else
420                 Debug( LDAP_DEBUG_ANY,
421                         "unable to add description to '%s' entry\n%s%s",
422                         SLAPD_MONITOR_DN, "", "" );
423 #endif
424                 return( -1 );
425         }
426
427         mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 );
428         e->e_private = ( void * )mp;
429
430         mp->mp_info = NULL;
431         mp->mp_children = e_tmp;
432         mp->mp_next = NULL;
433
434         if ( monitor_cache_add( mi, e ) ) {
435 #ifdef NEW_LOGGING
436                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
437                         "unable to add entry '%s' to cache\n",
438                         SLAPD_MONITOR_DN ));
439 #else
440                 Debug( LDAP_DEBUG_ANY,
441                         "unable to add entry '%s' to cache\n%s%s",
442                         SLAPD_MONITOR_DN, "", "" );
443 #endif
444                 return -1;
445         }
446
447         be->be_private = mi;
448         
449         return 0;
450 }
451
452 int
453 monitor_back_open(
454         BackendInfo     *bi
455 )
456 {
457         BackendDB               *be;
458         struct monitorsubsys    *ms;
459         struct berval dn = { sizeof(SLAPD_MONITOR_DN)-1, SLAPD_MONITOR_DN };
460         struct berval ndn;
461         int rc;
462
463         /*
464          * adds the monitor backend
465          */
466         rc = dnNormalize2( NULL, &dn, &ndn );
467         if( rc != LDAP_SUCCESS ) {
468 #ifdef NEW_LOGGING
469                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
470                         "monitor DN \"" SLAPD_MONITOR_DN "\" is invalid\n" ));
471 #else
472                 Debug( LDAP_DEBUG_ANY,
473                         "monitor DN \"" SLAPD_MONITOR_DN "\" is invalid\n",
474                         0, 0, 0 );
475 #endif
476                 return( -1 );
477         }
478
479         be = select_backend( &ndn , 0, 0 );
480         free( ndn.bv_val );
481
482         if ( be == NULL ) {
483 #ifdef NEW_LOGGING
484                 LDAP_LOG(( "operation", LDAP_LEVEL_CRIT,
485                         "unable to get monitor backend\n" ));
486 #else
487                 Debug( LDAP_DEBUG_ANY,
488                         "unable to get monitor backend\n", 0, 0, 0 );
489 #endif
490                 return( -1 );
491         }
492
493         for ( ms = monitor_subsys; ms->mss_name != NULL; ms++ ) {
494                 if ( ms->mss_init && ( *ms->mss_init )( be ) ) {
495                         return( -1 );
496                 }
497         }
498
499         return( 0 );
500 }
501
502 int
503 monitor_back_config(
504         BackendInfo     *bi,
505         const char      *fname,
506         int             lineno,
507         int             argc,
508         char            **argv
509 )
510 {
511         /*
512          * eventually, will hold backend specific configuration parameters
513          */
514         return 0;
515 }
516
517 int
518 monitor_back_db_config(
519         Backend     *be,
520         const char  *fname,
521         int         lineno,
522         int         argc,
523         char        **argv
524 )
525 {
526 #ifdef NEW_LOGGING
527         LDAP_LOG(( "config", LDAP_DEBUG_NOTICE,
528                 "line %d of file '%s' will be ignored\n", lineno, fname ));
529 #else
530         Debug( LDAP_DEBUG_CONFIG, 
531                 "line %d of file '%s' will be ignored\n%s", lineno, fname, "" );
532 #endif
533         return( 0 );
534 }
535
536 int
537 monitor_back_db_destroy(
538         BackendDB       *be
539 )
540 {
541         /*
542          * FIXME: destroys all the data
543          */
544         return 0;
545 }
546