]> git.sur5r.net Git - openldap/blob - servers/slapd/config.c
Fix cargv leak in recursive read_config()
[openldap] / servers / slapd / config.c
1 /* config.c - configuration file handling routines */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/string.h>
13 #include <ac/ctype.h>
14 #include <ac/signal.h>
15 #include <ac/socket.h>
16 #include <ac/errno.h>
17
18 #include "lutil.h"
19 #include "ldap_pvt.h"
20 #include "slap.h"
21
22 #define ARGS_STEP       512
23
24 /*
25  * defaults for various global variables
26  */
27 struct slap_limits_set deflimit = {
28         SLAPD_DEFAULT_TIMELIMIT,        /* backward compatible limits */
29         0,
30
31         SLAPD_DEFAULT_SIZELIMIT,        /* backward compatible limits */
32         0,
33         -1                              /* no limit on unchecked size */
34 };
35
36 AccessControl   *global_acl = NULL;
37 slap_access_t           global_default_access = ACL_READ;
38 slap_mask_t             global_restrictops = 0;
39 slap_mask_t             global_allows = 0;
40 slap_mask_t             global_disallows = 0;
41 slap_mask_t             global_requires = 0;
42 slap_ssf_set_t  global_ssf_set;
43 char            *replogfile;
44 int             global_gentlehup = 0;
45 int             global_idletimeout = 0;
46 char    *global_host = NULL;
47 char    *global_realm = NULL;
48 char            *ldap_srvtab = "";
49 char            *default_passwd_hash = NULL;
50 int             cargc = 0, cargv_size = 0;
51 char    **cargv;
52 struct berval default_search_base = { 0, NULL };
53 struct berval default_search_nbase = { 0, NULL };
54 unsigned                num_subordinates = 0;
55
56 ber_len_t sockbuf_max_incoming = SLAP_SB_MAX_INCOMING_DEFAULT;
57 ber_len_t sockbuf_max_incoming_auth= SLAP_SB_MAX_INCOMING_AUTH;
58
59 char   *slapd_pid_file  = NULL;
60 char   *slapd_args_file = NULL;
61
62 char   *strtok_quote_ptr;
63
64 #ifdef SLAPD_RLOOKUPS
65 int use_reverse_lookup = 1;
66 #else /* !SLAPD_RLOOKUPS */
67 int use_reverse_lookup = 0;
68 #endif /* !SLAPD_RLOOKUPS */
69
70 static char     *fp_getline(FILE *fp, int *lineno);
71 static void     fp_getline_init(int *lineno);
72 static int      fp_parse_line(int lineno, char *line);
73
74 static char     *strtok_quote(char *line, char *sep);
75 static int      load_ucdata(char *path);
76
77 int
78 read_config( const char *fname, int depth )
79 {
80         FILE    *fp;
81         char    *line, *savefname, *saveline;
82         int savelineno;
83         int     lineno, i;
84         int rc;
85         struct berval vals[2];
86
87         static int lastmod = 1;
88         static BackendInfo *bi = NULL;
89         static BackendDB        *be = NULL;
90
91         vals[1].bv_val = NULL;
92
93         if ( depth == 0 ) {
94                 cargv = ch_calloc( ARGS_STEP + 1, sizeof(*cargv) );
95                 cargv_size = ARGS_STEP + 1;
96         }
97
98         if ( (fp = fopen( fname, "r" )) == NULL ) {
99                 ldap_syslog = 1;
100 #ifdef NEW_LOGGING
101                 LDAP_LOG( CONFIG, ENTRY, 
102                         "read_config: " "could not open config file \"%s\": %s (%d)\n",
103                     fname, strerror(errno), errno );
104 #else
105                 Debug( LDAP_DEBUG_ANY,
106                     "could not open config file \"%s\": %s (%d)\n",
107                     fname, strerror(errno), errno );
108 #endif
109                 return 1;
110         }
111
112 #ifdef NEW_LOGGING
113         LDAP_LOG( CONFIG, ENTRY, 
114                 "read_config: reading config file %s\n", fname, 0, 0 );
115 #else
116         Debug( LDAP_DEBUG_CONFIG, "reading config file %s\n", fname, 0, 0 );
117 #endif
118
119
120         fp_getline_init( &lineno );
121
122         while ( (line = fp_getline( fp, &lineno )) != NULL ) {
123                 /* skip comments and blank lines */
124                 if ( line[0] == '#' || line[0] == '\0' ) {
125                         continue;
126                 }
127
128                 /* fp_parse_line is destructive, we save a copy */
129                 saveline = ch_strdup( line );
130
131                 if ( fp_parse_line( lineno, line ) != 0 ) {
132                         return( 1 );
133                 }
134
135                 if ( cargc < 1 ) {
136 #ifdef NEW_LOGGING
137                         LDAP_LOG( CONFIG, INFO, 
138                                 "%s: line %d: bad config line (ignored)\n", fname, lineno, 0 );
139 #else
140                         Debug( LDAP_DEBUG_ANY,
141                             "%s: line %d: bad config line (ignored)\n",
142                             fname, lineno, 0 );
143 #endif
144
145                         continue;
146                 }
147
148                 if ( strcasecmp( cargv[0], "backend" ) == 0 ) {
149                         if ( cargc < 2 ) {
150 #ifdef NEW_LOGGING
151                                 LDAP_LOG( CONFIG, CRIT, 
152                                            "%s : line %d: missing type in \"backend\" line.\n",
153                                            fname, lineno, 0 );
154 #else
155                                 Debug( LDAP_DEBUG_ANY,
156                 "%s: line %d: missing type in \"backend <type>\" line\n",
157                                     fname, lineno, 0 );
158 #endif
159
160                                 return( 1 );
161                         }
162
163                         if( be != NULL ) {
164 #ifdef NEW_LOGGING
165                                 LDAP_LOG( CONFIG, CRIT, 
166                                            "%s: line %d: backend line must appear before any "
167                                            "database definition.\n", fname, lineno , 0 );
168 #else
169                                 Debug( LDAP_DEBUG_ANY,
170 "%s: line %d: backend line must appear before any database definition\n",
171                                     fname, lineno, 0 );
172 #endif
173
174                                 return( 1 );
175                         }
176
177                         bi = backend_info( cargv[1] );
178
179                         if( bi == NULL ) {
180 #ifdef NEW_LOGGING
181                                 LDAP_LOG( CONFIG, CRIT, 
182                                            "read_config: backend %s initialization failed.\n",
183                                            cargv[1], 0, 0 );
184 #else
185                                 Debug( LDAP_DEBUG_ANY,
186                                         "backend %s initialization failed.\n",
187                                     cargv[1], 0, 0 );
188 #endif
189
190                                 return( 1 );
191                         }
192                 } else if ( strcasecmp( cargv[0], "database" ) == 0 ) {
193                         if ( cargc < 2 ) {
194 #ifdef NEW_LOGGING
195                                 LDAP_LOG( CONFIG, CRIT, 
196                                         "%s: line %d: missing type in \"database <type>\" line\n",
197                                         fname, lineno, 0 );
198 #else
199                                 Debug( LDAP_DEBUG_ANY,
200                 "%s: line %d: missing type in \"database <type>\" line\n",
201                                     fname, lineno, 0 );
202 #endif
203
204                                 return( 1 );
205                         }
206
207                         bi = NULL;
208                         be = backend_db_init( cargv[1] );
209
210                         if( be == NULL ) {
211 #ifdef NEW_LOGGING
212                                 LDAP_LOG( CONFIG, CRIT, 
213                                         "database %s initialization failed.\n", cargv[1], 0, 0 );
214 #else
215                                 Debug( LDAP_DEBUG_ANY,
216                                         "database %s initialization failed.\n",
217                                     cargv[1], 0, 0 );
218 #endif
219
220                                 return( 1 );
221                         }
222
223                 /* set thread concurrency */
224                 } else if ( strcasecmp( cargv[0], "concurrency" ) == 0 ) {
225                         int c;
226                         if ( cargc < 2 ) {
227 #ifdef NEW_LOGGING
228                                 LDAP_LOG( CONFIG, CRIT, 
229                                         "%s: line %d: missing level in \"concurrency <level\" "
230                                         " line\n", fname, lineno, 0 );
231 #else
232                                 Debug( LDAP_DEBUG_ANY,
233             "%s: line %d: missing level in \"concurrency <level>\" line\n",
234                                     fname, lineno, 0 );
235 #endif
236
237                                 return( 1 );
238                         }
239
240                         c = atoi( cargv[1] );
241
242                         if( c < 1 ) {
243 #ifdef NEW_LOGGING
244                                 LDAP_LOG( CONFIG, CRIT, 
245                                         "%s: line %d: invalid level (%d) in "
246                                         "\"concurrency <level>\" line.\n", fname, lineno, c );
247 #else
248                                 Debug( LDAP_DEBUG_ANY,
249             "%s: line %d: invalid level (%d) in \"concurrency <level>\" line\n",
250                                     fname, lineno, c );
251 #endif
252
253                                 return( 1 );
254                         }
255
256                         ldap_pvt_thread_set_concurrency( c );
257
258                 /* set sockbuf max */
259                 } else if ( strcasecmp( cargv[0], "sockbuf_max_incoming" ) == 0 ) {
260                         long max;
261                         if ( cargc < 2 ) {
262 #ifdef NEW_LOGGING
263                                 LDAP_LOG( CONFIG, CRIT, 
264                                    "%s: line %d: missing max in \"sockbuf_max_incoming "
265                                    "<bytes>\" line\n", fname, lineno, 0 );
266 #else
267                                 Debug( LDAP_DEBUG_ANY,
268                                            "%s: line %d: missing max in \"sockbuf_max_incoming <bytes>\" line\n",
269                                     fname, lineno, 0 );
270 #endif
271
272                                 return( 1 );
273                         }
274
275                         max = atol( cargv[1] );
276
277                         if( max < 0 ) {
278 #ifdef NEW_LOGGING
279                                 LDAP_LOG( CONFIG, CRIT, 
280                                            "%s: line %d: invalid max value (%ld) in "
281                                            "\"sockbuf_max_incoming <bytes>\" line.\n",
282                                            fname, lineno, max );
283 #else
284                                 Debug( LDAP_DEBUG_ANY,
285                                         "%s: line %d: invalid max value (%ld) in "
286                                         "\"sockbuf_max_incoming <bytes>\" line.\n",
287                                     fname, lineno, max );
288 #endif
289
290                                 return( 1 );
291                         }
292
293                         sockbuf_max_incoming = max;
294
295                 /* set sockbuf max authenticated */
296                 } else if ( strcasecmp( cargv[0], "sockbuf_max_incoming_auth" ) == 0 ) {
297                         long max;
298                         if ( cargc < 2 ) {
299 #ifdef NEW_LOGGING
300                                 LDAP_LOG( CONFIG, CRIT, 
301                                    "%s: line %d: missing max in \"sockbuf_max_incoming_auth "
302                                    "<bytes>\" line\n", fname, lineno, 0 );
303 #else
304                                 Debug( LDAP_DEBUG_ANY,
305                                            "%s: line %d: missing max in \"sockbuf_max_incoming_auth <bytes>\" line\n",
306                                     fname, lineno, 0 );
307 #endif
308
309                                 return( 1 );
310                         }
311
312                         max = atol( cargv[1] );
313
314                         if( max < 0 ) {
315 #ifdef NEW_LOGGING
316                                 LDAP_LOG( CONFIG, CRIT, 
317                                            "%s: line %d: invalid max value (%ld) in "
318                                            "\"sockbuf_max_incoming_auth <bytes>\" line.\n",
319                                            fname, lineno, max );
320 #else
321                                 Debug( LDAP_DEBUG_ANY,
322                                         "%s: line %d: invalid max value (%ld) in "
323                                         "\"sockbuf_max_incoming_auth <bytes>\" line.\n",
324                                     fname, lineno, max );
325 #endif
326
327                                 return( 1 );
328                         }
329
330                         sockbuf_max_incoming_auth = max;
331
332                 /* default search base */
333                 } else if ( strcasecmp( cargv[0], "defaultSearchBase" ) == 0 ) {
334                         if ( cargc < 2 ) {
335 #ifdef NEW_LOGGING
336                                 LDAP_LOG( CONFIG, CRIT, 
337                                         "%s: line %d: missing dn in \"defaultSearchBase <dn\" "
338                                         "line\n", fname, lineno, 0 );
339 #else
340                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
341                                         "missing dn in \"defaultSearchBase <dn>\" line\n",
342                                         fname, lineno, 0 );
343 #endif
344
345                                 return 1;
346
347                         } else if ( cargc > 2 ) {
348 #ifdef NEW_LOGGING
349                                 LDAP_LOG( CONFIG, INFO, 
350                                         "%s: line %d: extra cruft after <dn> in "
351                                         "\"defaultSearchBase %s\" line (ignored)\n",
352                                         fname, lineno, cargv[1] );
353 #else
354                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
355                                         "extra cruft after <dn> in \"defaultSearchBase %s\", "
356                                         "line (ignored)\n",
357                                         fname, lineno, cargv[1] );
358 #endif
359                         }
360
361                         if ( bi != NULL || be != NULL ) {
362 #ifdef NEW_LOGGING
363                                 LDAP_LOG( CONFIG, CRIT, 
364                                         "%s: line %d: defaultSearchBase line must appear "
365                                         "prior to any backend or database definitions\n",
366                                         fname, lineno, 0 );
367 #else
368                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
369                                         "defaultSearchBaase line must appear prior to "
370                                         "any backend or database definition\n",
371                                     fname, lineno, 0 );
372 #endif
373
374                                 return 1;
375                         }
376
377                         if ( default_search_nbase.bv_len ) {
378 #ifdef NEW_LOGGING
379                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
380                                         "default search base \"%s\" already defined "
381                                         "(discarding old)\n", fname, lineno,
382                                         default_search_base.bv_val );
383 #else
384                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
385                                         "default search base \"%s\" already defined "
386                                         "(discarding old)\n",
387                                         fname, lineno, default_search_base.bv_val );
388 #endif
389
390                                 free( default_search_base.bv_val );
391                                 free( default_search_nbase.bv_val );
392                         }
393
394                         if ( load_ucdata( NULL ) < 0 ) return 1;
395
396                         {
397                                 struct berval dn;
398
399                                 dn.bv_val = cargv[1];
400                                 dn.bv_len = strlen( dn.bv_val );
401
402                                 rc = dnPrettyNormal( NULL, &dn,
403                                         &default_search_base,
404                                         &default_search_nbase );
405
406                                 if( rc != LDAP_SUCCESS ) {
407 #ifdef NEW_LOGGING
408                                         LDAP_LOG( CONFIG, CRIT, 
409                                                 "%s: line %d: defaultSearchBase DN is invalid.\n",
410                                                 fname, lineno, 0 );
411 #else
412                                         Debug( LDAP_DEBUG_ANY,
413                                                 "%s: line %d: defaultSearchBase DN is invalid\n",
414                                            fname, lineno, 0 );
415 #endif
416                                         return( 1 );
417                                 }
418                         }
419
420                 /* set maximum threads in thread pool */
421                 } else if ( strcasecmp( cargv[0], "threads" ) == 0 ) {
422                         int c;
423                         if ( cargc < 2 ) {
424 #ifdef NEW_LOGGING
425                                 LDAP_LOG( CONFIG, CRIT, 
426                                         "%s: line %d: missing count in \"threads <count>\" line\n",
427                                         fname, lineno, 0 );
428 #else
429                                 Debug( LDAP_DEBUG_ANY,
430             "%s: line %d: missing count in \"threads <count>\" line\n",
431                                     fname, lineno, 0 );
432 #endif
433
434                                 return( 1 );
435                         }
436
437                         c = atoi( cargv[1] );
438
439                         if( c < 0 ) {
440 #ifdef NEW_LOGGING
441                                 LDAP_LOG( CONFIG, CRIT, 
442                                            "%s: line %d: invalid level (%d) in \"threads <count>\""
443                                            "line\n", fname, lineno, c );
444 #else
445                                 Debug( LDAP_DEBUG_ANY,
446             "%s: line %d: invalid level (%d) in \"threads <count>\" line\n",
447                                     fname, lineno, c );
448 #endif
449
450                                 return( 1 );
451                         }
452
453                         ldap_pvt_thread_pool_maxthreads( &connection_pool, c );
454
455                         /* save for later use */
456                         connection_pool_max = c;
457
458                 /* get pid file name */
459                 } else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) {
460                         if ( cargc < 2 ) {
461 #ifdef NEW_LOGGING
462                                 LDAP_LOG( CONFIG, CRIT, 
463                                         "%s: line %d missing file name in \"pidfile <file>\" "
464                                         "line.\n", fname, lineno, 0 );
465 #else
466                                 Debug( LDAP_DEBUG_ANY,
467             "%s: line %d: missing file name in \"pidfile <file>\" line\n",
468                                     fname, lineno, 0 );
469 #endif
470
471                                 return( 1 );
472                         }
473
474                         slapd_pid_file = ch_strdup( cargv[1] );
475
476                 /* get args file name */
477                 } else if ( strcasecmp( cargv[0], "argsfile" ) == 0 ) {
478                         if ( cargc < 2 ) {
479 #ifdef NEW_LOGGING
480                                 LDAP_LOG( CONFIG, CRIT, 
481                                            "%s: %d: missing file name in "
482                                            "\"argsfile <file>\" line.\n",
483                                            fname, lineno, 0 );
484 #else
485                                 Debug( LDAP_DEBUG_ANY,
486             "%s: line %d: missing file name in \"argsfile <file>\" line\n",
487                                     fname, lineno, 0 );
488 #endif
489
490                                 return( 1 );
491                         }
492
493                         slapd_args_file = ch_strdup( cargv[1] );
494
495                 /* default password hash */
496                 } else if ( strcasecmp( cargv[0], "password-hash" ) == 0 ) {
497                         if ( cargc < 2 ) {
498 #ifdef NEW_LOGGING
499                                 LDAP_LOG( CONFIG, CRIT, 
500                                            "%s: line %d: missing hash in "
501                                            "\"password-hash <hash>\" line.\n",
502                                            fname, lineno, 0 );
503 #else
504                                 Debug( LDAP_DEBUG_ANY,
505             "%s: line %d: missing hash in \"password-hash <hash>\" line\n",
506                                     fname, lineno, 0 );
507 #endif
508
509                                 return( 1 );
510                         }
511                         if ( default_passwd_hash != NULL ) {
512 #ifdef NEW_LOGGING
513                                 LDAP_LOG( CONFIG, CRIT, 
514                                            "%s: line %d: already set default password_hash!\n",
515                                            fname, lineno, 0 );
516 #else
517                                 Debug( LDAP_DEBUG_ANY,
518                                         "%s: line %d: already set default password_hash!\n",
519                                         fname, lineno, 0 );
520 #endif
521
522                                 return 1;
523
524                         }
525
526                         if ( lutil_passwd_scheme( cargv[1] ) == 0 ) {
527 #ifdef NEW_LOGGING
528                                 LDAP_LOG( CONFIG, CRIT, 
529                                            "%s: line %d: password scheme \"%s\" not available\n",
530                                            fname, lineno, cargv[1] );
531 #else
532                                 Debug( LDAP_DEBUG_ANY,
533                                         "%s: line %d: password scheme \"%s\" not available\n",
534                                         fname, lineno, cargv[1] );
535 #endif
536                                 return 1;
537                         }
538
539                         default_passwd_hash = ch_strdup( cargv[1] );
540
541                 } else if ( strcasecmp( cargv[0], "password-crypt-salt-format" ) == 0 ) 
542                 {
543                         if ( cargc < 2 ) {
544 #ifdef NEW_LOGGING
545                                 LDAP_LOG( CONFIG, CRIT, 
546                                         "%s: line %d: missing format in "
547                                         "\"password-crypt-salt-format <format>\" line\n",
548                                         fname, lineno, 0 );
549 #else
550                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: missing format in "
551                                         "\"password-crypt-salt-format <format>\" line\n",
552                                     fname, lineno, 0 );
553 #endif
554
555                                 return 1;
556                         }
557
558                         lutil_salt_format( cargv[1] );
559
560 #ifdef HAVE_CYRUS_SASL
561                 /* SASL config options */
562                 } else if ( strncasecmp( cargv[0], "sasl", 4 ) == 0 ) {
563                         if ( slap_sasl_config( cargc, cargv, line, fname, lineno ) )
564                                 return 1;
565 #endif /* HAVE_CYRUS_SASL */
566
567                 /* set UCDATA path */
568                 } else if ( strcasecmp( cargv[0], "ucdata-path" ) == 0 ) {
569                         int err;
570                         if ( cargc < 2 ) {
571 #ifdef NEW_LOGGING
572                                 LDAP_LOG( CONFIG, CRIT, 
573                                            "%s: line %d: missing path in "
574                                            "\"ucdata-path <path>\" line.\n", fname, lineno, 0  );
575 #else
576                                 Debug( LDAP_DEBUG_ANY,
577             "%s: line %d: missing path in \"ucdata-path <path>\" line\n",
578                                     fname, lineno, 0 );
579 #endif
580
581                                 return( 1 );
582                         }
583
584                         err = load_ucdata( cargv[1] );
585                         if ( err <= 0 ) {
586                                 if ( err == 0 ) {
587 #ifdef NEW_LOGGING
588                                         LDAP_LOG( CONFIG, CRIT, 
589                                                    "%s: line %d: ucdata already loaded, ucdata-path "
590                                                    "must be set earlier in the file and/or be "
591                                                    "specified only once!\n", fname, lineno, 0 );
592 #else
593                                         Debug( LDAP_DEBUG_ANY,
594                                                "%s: line %d: ucdata already loaded, ucdata-path must be set earlier in the file and/or be specified only once!\n",
595                                                fname, lineno, 0 );
596 #endif
597
598                                 }
599                                 return( 1 );
600                         }
601
602                 /* set size limit */
603                 } else if ( strcasecmp( cargv[0], "sizelimit" ) == 0 ) {
604                         int rc = 0, i;
605                         struct slap_limits_set *lim;
606                         
607                         if ( cargc < 2 ) {
608 #ifdef NEW_LOGGING
609                                 LDAP_LOG( CONFIG, CRIT, 
610                                    "%s: line %d: missing limit in \"sizelimit <limit>\" "
611                                    "line.\n", fname, lineno, 0 );
612 #else
613                                 Debug( LDAP_DEBUG_ANY,
614             "%s: line %d: missing limit in \"sizelimit <limit>\" line\n",
615                                     fname, lineno, 0 );
616 #endif
617
618                                 return( 1 );
619                         }
620
621                         if ( be == NULL ) {
622                                 lim = &deflimit;
623                         } else {
624                                 lim = &be->be_def_limit;
625                         }
626
627                         for ( i = 1; i < cargc; i++ ) {
628                                 if ( strncasecmp( cargv[i], "size", 4 ) == 0 ) {
629                                         rc = parse_limit( cargv[i], lim );
630                                 } else {
631                                         lim->lms_s_soft = atoi( cargv[i] );
632                                         lim->lms_s_hard = 0;
633                                 }
634
635                                 if ( rc ) {
636 #ifdef NEW_LOGGING
637                                         LDAP_LOG( CONFIG, CRIT, 
638                                                 "%s: line %d: unable "
639                                                    "to parse value \"%s\" in \"sizelimit "
640                                                    "<limit>\" line.\n", fname, lineno, cargv[i] );
641 #else
642                                         Debug( LDAP_DEBUG_ANY,
643                                                 "%s: line %d: unable "
644                                                 "to parse value \"%s\" "
645                                                 "in \"sizelimit "
646                                                 "<limit>\" line\n",
647                                                 fname, lineno, cargv[i] );
648 #endif
649                                 }
650                         }
651
652                 /* set time limit */
653                 } else if ( strcasecmp( cargv[0], "timelimit" ) == 0 ) {
654                         int rc = 0, i;
655                         struct slap_limits_set *lim;
656                         
657                         if ( cargc < 2 ) {
658 #ifdef NEW_LOGGING
659                                 LDAP_LOG( CONFIG, CRIT, 
660                                         "%s: line %d missing limit in \"timelimit <limit>\" "
661                                         "line.\n", fname, lineno, 0 );
662 #else
663                                 Debug( LDAP_DEBUG_ANY,
664             "%s: line %d: missing limit in \"timelimit <limit>\" line\n",
665                                     fname, lineno, 0 );
666 #endif
667
668                                 return( 1 );
669                         }
670                         
671                         if ( be == NULL ) {
672                                 lim = &deflimit;
673                         } else {
674                                 lim = &be->be_def_limit;
675                         }
676
677                         for ( i = 1; i < cargc; i++ ) {
678                                 if ( strncasecmp( cargv[i], "time", 4 ) == 0 ) {
679                                         rc = parse_limit( cargv[i], lim );
680                                 } else {
681                                         lim->lms_t_soft = atoi( cargv[i] );
682                                         lim->lms_t_hard = 0;
683                                 }
684
685                                 if ( rc ) {
686 #ifdef NEW_LOGGING
687                                         LDAP_LOG( CONFIG, CRIT, 
688                                                     "%s: line %d: unable to parse value \"%s\" "
689                                                    "in \"timelimit <limit>\" line.\n",
690                                                    fname, lineno, cargv[i] );
691 #else
692                                         Debug( LDAP_DEBUG_ANY,
693                                                 "%s: line %d: unable "
694                                                 "to parse value \"%s\" "
695                                                 "in \"timelimit "
696                                                 "<limit>\" line\n",
697                                                 fname, lineno, cargv[i] );
698 #endif
699                                 }
700                         }
701
702                 /* set regex-based limits */
703                 } else if ( strcasecmp( cargv[0], "limits" ) == 0 ) {
704                         if ( be == NULL ) {
705 #ifdef NEW_LOGGING
706                                 LDAP_LOG( CONFIG, WARNING, 
707                                            "%s: line %d \"limits\" allowed only in database "
708                                            "environment.\n", fname, lineno, 0 );
709 #else
710                                 Debug( LDAP_DEBUG_ANY,
711         "%s: line %d \"limits\" allowed only in database environment.\n%s",
712                                         fname, lineno, "" );
713 #endif
714                                 return( 1 );
715                         }
716
717                         if ( parse_limits( be, fname, lineno, cargc, cargv ) ) {
718                                 return( 1 );
719                         }
720
721                 /* mark this as a subordinate database */
722                 } else if ( strcasecmp( cargv[0], "subordinate" ) == 0 ) {
723                         if ( be == NULL ) {
724 #ifdef NEW_LOGGING
725                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
726                                         "subordinate keyword must appear inside a database "
727                                         "definition.\n", fname, lineno, 0 );
728 #else
729                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix line "
730                                         "must appear inside a database definition.\n",
731                                     fname, lineno, 0 );
732 #endif
733                                 return 1;
734
735                         } else {
736                                 be->be_flags |= SLAP_BFLAG_GLUE_SUBORDINATE;
737                                 num_subordinates++;
738                         }
739
740                 /* set database suffix */
741                 } else if ( strcasecmp( cargv[0], "suffix" ) == 0 ) {
742                         Backend *tmp_be;
743                         struct berval dn, pdn, ndn;
744
745                         if ( cargc < 2 ) {
746 #ifdef NEW_LOGGING
747                                 LDAP_LOG( CONFIG, CRIT, 
748                                         "%s: line %d: missing dn in \"suffix <dn>\" line.\n",
749                                         fname, lineno, 0 );
750 #else
751                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
752                                         "missing dn in \"suffix <dn>\" line\n",
753                                     fname, lineno, 0 );
754 #endif
755
756                                 return( 1 );
757
758                         } else if ( cargc > 2 ) {
759 #ifdef NEW_LOGGING
760                                 LDAP_LOG( CONFIG, INFO, 
761                                         "%s: line %d: extra cruft after <dn> in \"suffix %s\""
762                                         " line (ignored).\n", fname, lineno, cargv[1] );
763 #else
764                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: extra cruft "
765                                         "after <dn> in \"suffix %s\" line (ignored)\n",
766                                     fname, lineno, cargv[1] );
767 #endif
768                         }
769
770                         if ( be == NULL ) {
771 #ifdef NEW_LOGGING
772                                 LDAP_LOG( CONFIG, INFO, 
773                                         "%s: line %d: suffix line must appear inside a database "
774                                         "definition.\n", fname, lineno, 0 );
775 #else
776                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix line "
777                                         "must appear inside a database definition\n",
778                                     fname, lineno, 0 );
779 #endif
780                                 return( 1 );
781
782 #if defined(SLAPD_MONITOR_DN)
783                         /* "cn=Monitor" is reserved for monitoring slap */
784                         } else if ( strcasecmp( cargv[1], SLAPD_MONITOR_DN ) == 0 ) {
785 #ifdef NEW_LOGGING
786                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: \""
787                                         SLAPD_MONITOR_DN "\" is reserved for monitoring slapd\n", 
788                                         fname, lineno, 0 );
789 #else
790                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: \""
791                                         SLAPD_MONITOR_DN "\" is reserved for monitoring slapd\n", 
792                                         fname, lineno, 0 );
793 #endif
794                                 return( 1 );
795 #endif /* SLAPD_MONITOR_DN */
796                         }
797
798                         if ( load_ucdata( NULL ) < 0 ) return 1;
799
800                         dn.bv_val = cargv[1];
801                         dn.bv_len = strlen( cargv[1] );
802
803                         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
804                         if( rc != LDAP_SUCCESS ) {
805 #ifdef NEW_LOGGING
806                                 LDAP_LOG( CONFIG, CRIT, 
807                                         "%s: line %d: suffix DN is invalid.\n",
808                                         fname, lineno, 0 );
809 #else
810                                 Debug( LDAP_DEBUG_ANY,
811                                         "%s: line %d: suffix DN is invalid\n",
812                                    fname, lineno, 0 );
813 #endif
814                                 return( 1 );
815                         }
816
817                         tmp_be = select_backend( &ndn, 0, 0 );
818                         if ( tmp_be == be ) {
819 #ifdef NEW_LOGGING
820                                 LDAP_LOG( CONFIG, INFO, 
821                                         "%s: line %d: suffix already served by this backend "
822                                         "(ignored)\n", fname, lineno, 0 );
823 #else
824                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
825                                         "already served by this backend (ignored)\n",
826                                     fname, lineno, 0 );
827 #endif
828                                 free( pdn.bv_val );
829                                 free( ndn.bv_val );
830
831                         } else if ( tmp_be  != NULL ) {
832 #ifdef NEW_LOGGING
833                                 LDAP_LOG( CONFIG, INFO, 
834                                         "%s: line %d: suffix already served by a preceding "
835                                         "backend \"%s\"\n", fname, lineno,
836                                         tmp_be->be_suffix[0].bv_val );
837 #else
838                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
839                                         "already served by a preceeding backend \"%s\"\n",
840                                     fname, lineno, tmp_be->be_suffix[0].bv_val );
841 #endif
842                                 free( pdn.bv_val );
843                                 free( ndn.bv_val );
844                                 return( 1 );
845
846                         } else if( pdn.bv_len == 0 && default_search_nbase.bv_len ) {
847 #ifdef NEW_LOGGING
848                                         LDAP_LOG( CONFIG, INFO, 
849                                                 "%s: line %d: suffix DN empty and default search "
850                                                 "base provided \"%s\" (assuming okay).\n",
851                                                 fname, lineno, default_search_base.bv_val );
852 #else
853                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
854                                                 "suffix DN empty and default "
855                                                 "search base provided \"%s\" (assuming okay)\n",
856                                         fname, lineno, default_search_base.bv_val );
857 #endif
858                         }
859
860                         ber_bvarray_add( &be->be_suffix, &pdn );
861                         ber_bvarray_add( &be->be_nsuffix, &ndn );
862
863                 /* set database suffixAlias */
864                 } else if ( strcasecmp( cargv[0], "suffixAlias" ) == 0 ) {
865                         Backend *tmp_be;
866                         struct berval alias, palias, nalias;
867                         struct berval aliased, paliased, naliased;
868
869                         if ( cargc < 2 ) {
870 #ifdef NEW_LOGGING
871                                 LDAP_LOG( CONFIG, CRIT, 
872                                         "%s: line %d: missing alias and aliased_dn in "
873                                         "\"suffixAlias <alias> <aliased_dn>\" line.\n",
874                                         fname, lineno, 0 );
875 #else
876                                 Debug( LDAP_DEBUG_ANY,
877                                         "%s: line %d: missing alias and aliased_dn in "
878                                         "\"suffixAlias <alias> <aliased_dn>\" line.\n",
879                                         fname, lineno, 0 );
880 #endif
881
882                                 return( 1 );
883                         } else if ( cargc < 3 ) {
884 #ifdef NEW_LOGGING
885                                 LDAP_LOG( CONFIG, CRIT, 
886                                         "%s: line %d: missing aliased_dn in "
887                                         "\"suffixAlias <alias> <aliased_dn>\" line\n",
888                                         fname, lineno, 0 );
889 #else
890                                 Debug( LDAP_DEBUG_ANY,
891                                         "%s: line %d: missing aliased_dn in "
892                                         "\"suffixAlias <alias> <aliased_dn>\" line\n",
893                                         fname, lineno, 0 );
894 #endif
895                                 return( 1 );
896
897                         } else if ( cargc > 3 ) {
898 #ifdef NEW_LOGGING
899                                 LDAP_LOG( CONFIG, CRIT, 
900                                         "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
901                                         fname, lineno, 0 );
902 #else
903                                 Debug( LDAP_DEBUG_ANY,
904                                         "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
905                                         fname, lineno, 0 );
906 #endif
907                         }
908
909                         if ( be == NULL ) {
910 #ifdef NEW_LOGGING
911                                 LDAP_LOG( CONFIG, INFO, 
912                                         "%s: line %d: suffix line must appear inside a database "
913                                         "definition.\n", fname, lineno, 0 );
914 #else
915                                 Debug( LDAP_DEBUG_ANY,
916                                         "%s: line %d: suffixAlias line"
917                                         " must appear inside a database definition.\n",
918                                         fname, lineno, 0 );
919 #endif
920                                 return 1;
921                         }
922
923                         if ( load_ucdata( NULL ) < 0 ) return 1;
924                         
925                         alias.bv_val = cargv[1];
926                         alias.bv_len = strlen( cargv[1] );
927
928                         rc = dnPrettyNormal( NULL, &alias, &palias, &nalias );
929                         if( rc != LDAP_SUCCESS ) {
930 #ifdef NEW_LOGGING
931                                 LDAP_LOG( CONFIG, CRIT, 
932                                         "%s: line %d: alias DN is invalid.\n", fname, lineno, 0 );
933 #else
934                                 Debug( LDAP_DEBUG_ANY,
935                                         "%s: line %d: alias DN is invalid\n",
936                                    fname, lineno, 0 );
937 #endif
938                                 return( 1 );
939                         }
940
941                         tmp_be = select_backend( &nalias, 0, 0 );
942                         free( nalias.bv_val );
943                         if ( tmp_be && tmp_be != be ) {
944 #ifdef NEW_LOGGING
945                                 LDAP_LOG( CONFIG, INFO, 
946                                         "%s: line %d: suffixAlias served by a preceeding "
947                                         "backend \"%s\"\n", fname, lineno, 
948                                         tmp_be->be_suffix[0].bv_val );
949 #else
950                                 Debug( LDAP_DEBUG_ANY,
951                                         "%s: line %d: suffixAlias served by"
952                                         "  a preceeding backend \"%s\"\n",
953                                         fname, lineno, tmp_be->be_suffix[0].bv_val );
954 #endif
955                                 free( palias.bv_val );
956                                 return -1;
957                         }
958
959                         aliased.bv_val = cargv[2];
960                         aliased.bv_len = strlen( cargv[2] );
961
962                         rc = dnPrettyNormal( NULL, &aliased, &paliased, &naliased );
963                         if( rc != LDAP_SUCCESS ) {
964 #ifdef NEW_LOGGING
965                                 LDAP_LOG( CONFIG, CRIT, 
966                                         "%s: line %d: aliased DN is invalid.\n", fname, lineno,0 );
967 #else
968                                 Debug( LDAP_DEBUG_ANY,
969                                         "%s: line %d: aliased DN is invalid\n",
970                                    fname, lineno, 0 );
971 #endif
972                                 free( palias.bv_val );
973                                 return( 1 );
974                         }
975
976                         tmp_be = select_backend( &naliased, 0, 0 );
977                         free( naliased.bv_val );
978                         if ( tmp_be && tmp_be != be ) {
979 #ifdef NEW_LOGGING
980                                 LDAP_LOG( CONFIG, INFO, 
981                                         "%s: line %d: suffixAlias derefs to a different backend "
982                                         "a preceeding backend \"%s\"\n",
983                                         fname, lineno, tmp_be->be_suffix[0].bv_val );
984 #else
985                                 Debug( LDAP_DEBUG_ANY,
986                                         "%s: line %d: suffixAlias derefs to differnet backend"
987                                         "  a preceeding backend \"%s\"\n",
988                                         fname, lineno, tmp_be->be_suffix[0].bv_val );
989 #endif
990                                 free( palias.bv_val );
991                                 free( paliased.bv_val );
992                                 return -1;
993                         }
994
995                         ber_bvarray_add( &be->be_suffixAlias, &palias ); 
996                         ber_bvarray_add( &be->be_suffixAlias, &paliased );
997
998                /* set max deref depth */
999                } else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
1000                                         int i;
1001                        if ( cargc < 2 ) {
1002 #ifdef NEW_LOGGING
1003                                LDAP_LOG( CONFIG, CRIT, 
1004                                           "%s: line %d: missing depth in \"maxDerefDepth <depth>\""
1005                                           " line\n", fname, lineno, 0 );
1006 #else
1007                                Debug( LDAP_DEBUG_ANY,
1008                    "%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
1009                                    fname, lineno, 0 );
1010 #endif
1011
1012                                return( 1 );
1013                        }
1014                        if ( be == NULL ) {
1015 #ifdef NEW_LOGGING
1016                                LDAP_LOG( CONFIG, INFO, 
1017                                           "%s: line %d: depth line must appear inside a database "
1018                                           "definition.\n", fname, lineno ,0 );
1019 #else
1020                                Debug( LDAP_DEBUG_ANY,
1021 "%s: line %d: depth line must appear inside a database definition.\n",
1022                                    fname, lineno, 0 );
1023 #endif
1024                                                         return 1;
1025
1026                        } else if ((i = atoi(cargv[1])) < 0) {
1027 #ifdef NEW_LOGGING
1028                                LDAP_LOG( CONFIG, INFO, 
1029                                           "%s: line %d: depth must be positive.\n",
1030                                           fname, lineno ,0 );
1031 #else
1032                                Debug( LDAP_DEBUG_ANY,
1033 "%s: line %d: depth must be positive.\n",
1034                                    fname, lineno, 0 );
1035 #endif
1036                                                         return 1;
1037
1038
1039                        } else {
1040                            be->be_max_deref_depth = i;
1041                                            }
1042
1043
1044                 /* set magic "root" dn for this database */
1045                 } else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
1046                         if ( cargc < 2 ) {
1047 #ifdef NEW_LOGGING
1048                                 LDAP_LOG( CONFIG, INFO, 
1049                                            "%s: line %d: missing dn in \"rootdn <dn>\" line.\n",
1050                                            fname, lineno ,0 );
1051 #else
1052                                 Debug( LDAP_DEBUG_ANY,
1053                     "%s: line %d: missing dn in \"rootdn <dn>\" line\n",
1054                                     fname, lineno, 0 );
1055 #endif
1056
1057                                 return( 1 );
1058                         }
1059
1060                         if ( be == NULL ) {
1061 #ifdef NEW_LOGGING
1062                                 LDAP_LOG( CONFIG, INFO, 
1063                                            "%s: line %d: rootdn line must appear inside a database "
1064                                            "definition.\n", fname, lineno ,0 );
1065 #else
1066                                 Debug( LDAP_DEBUG_ANY,
1067 "%s: line %d: rootdn line must appear inside a database definition.\n",
1068                                     fname, lineno, 0 );
1069 #endif
1070                                 return 1;
1071
1072                         } else {
1073                                 struct berval dn;
1074                                 
1075                                 if ( load_ucdata( NULL ) < 0 ) return 1;
1076
1077                                 dn.bv_val = cargv[1];
1078                                 dn.bv_len = strlen( cargv[1] );
1079
1080                                 rc = dnPrettyNormal( NULL, &dn,
1081                                         &be->be_rootdn,
1082                                         &be->be_rootndn );
1083
1084                                 if( rc != LDAP_SUCCESS ) {
1085 #ifdef NEW_LOGGING
1086                                         LDAP_LOG( CONFIG, CRIT, 
1087                                                 "%s: line %d: rootdn DN is invalid.\n", 
1088                                                 fname, lineno ,0 );
1089 #else
1090                                         Debug( LDAP_DEBUG_ANY,
1091                                                 "%s: line %d: rootdn DN is invalid\n",
1092                                            fname, lineno, 0 );
1093 #endif
1094                                         return( 1 );
1095                                 }
1096                         }
1097
1098                 /* set super-secret magic database password */
1099                 } else if ( strcasecmp( cargv[0], "rootpw" ) == 0 ) {
1100                         if ( cargc < 2 ) {
1101 #ifdef NEW_LOGGING
1102                                 LDAP_LOG( CONFIG, CRIT, 
1103                                         "%s: line %d: missing passwd in \"rootpw <passwd>\""
1104                                         " line\n", fname, lineno ,0 );
1105 #else
1106                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1107                                         "missing passwd in \"rootpw <passwd>\" line\n",
1108                                     fname, lineno, 0 );
1109 #endif
1110
1111                                 return( 1 );
1112                         }
1113
1114                         if ( be == NULL ) {
1115 #ifdef NEW_LOGGING
1116                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
1117                                         "rootpw line must appear inside a database "
1118                                         "definition.\n", fname, lineno ,0 );
1119 #else
1120                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1121                                         "rootpw line must appear inside a database "
1122                                         "definition.\n",
1123                                     fname, lineno, 0 );
1124 #endif
1125                                 return 1;
1126
1127                         } else {
1128                                 Backend *tmp_be = select_backend( &be->be_rootndn, 0, 0 );
1129
1130                                 if( tmp_be != be ) {
1131 #ifdef NEW_LOGGING
1132                                         LDAP_LOG( CONFIG, INFO,
1133                                                 "%s: line %d: "
1134                                                 "rootpw can only be set when rootdn is under suffix\n",
1135                                                 fname, lineno, "" );
1136 #else
1137                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1138                                                 "rootpw can only be set when rootdn is under suffix\n",
1139                                         fname, lineno, 0 );
1140 #endif
1141                                         return 1;
1142                                 }
1143
1144                                 be->be_rootpw.bv_val = ch_strdup( cargv[1] );
1145                                 be->be_rootpw.bv_len = strlen( be->be_rootpw.bv_val );
1146                         }
1147
1148                 /* make this database read-only */
1149                 } else if ( strcasecmp( cargv[0], "readonly" ) == 0 ) {
1150                         if ( cargc < 2 ) {
1151 #ifdef NEW_LOGGING
1152                                 LDAP_LOG( CONFIG, CRIT, 
1153                                         "%s: line %d: missing on|off in \"readonly <on|off>\" "
1154                                         "line.\n", fname, lineno ,0 );
1155 #else
1156                                 Debug( LDAP_DEBUG_ANY,
1157             "%s: line %d: missing on|off in \"readonly <on|off>\" line\n",
1158                                     fname, lineno, 0 );
1159 #endif
1160
1161                                 return( 1 );
1162                         }
1163                         if ( be == NULL ) {
1164                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1165                                         global_restrictops |= SLAP_RESTRICT_OP_WRITES;
1166                                 } else {
1167                                         global_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
1168                                 }
1169                         } else {
1170                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1171                                         be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
1172                                 } else {
1173                                         be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
1174                                 }
1175                         }
1176
1177
1178                 /* allow these features */
1179                 } else if ( strcasecmp( cargv[0], "allows" ) == 0 ||
1180                         strcasecmp( cargv[0], "allow" ) == 0 )
1181                 {
1182                         slap_mask_t     allows;
1183
1184                         if ( be != NULL ) {
1185 #ifdef NEW_LOGGING
1186                                 LDAP_LOG( CONFIG, INFO, 
1187                                            "%s: line %d: allow line must appear prior to "
1188                                            "database definitions.\n", fname, lineno ,0 );
1189 #else
1190                                 Debug( LDAP_DEBUG_ANY,
1191 "%s: line %d: allow line must appear prior to database definitions\n",
1192                                     fname, lineno, 0 );
1193 #endif
1194
1195                         }
1196
1197                         if ( cargc < 2 ) {
1198 #ifdef NEW_LOGGING
1199                                 LDAP_LOG( CONFIG, CRIT, 
1200                                            "%s: line %d: missing feature(s) in \"allow <features>\""
1201                                            " line\n", fname, lineno ,0 );
1202 #else
1203                                 Debug( LDAP_DEBUG_ANY,
1204             "%s: line %d: missing feature(s) in \"allow <features>\" line\n",
1205                                     fname, lineno, 0 );
1206 #endif
1207
1208                                 return( 1 );
1209                         }
1210
1211                         allows = 0;
1212
1213                         for( i=1; i < cargc; i++ ) {
1214                                 if( strcasecmp( cargv[i], "bind_v2" ) == 0 ) {
1215                                         allows |= SLAP_ALLOW_BIND_V2;
1216
1217                                 } else if( strcasecmp( cargv[i], "bind_anon_cred" ) == 0 ) {
1218                                         allows |= SLAP_ALLOW_BIND_ANON_CRED;
1219
1220                                 } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) {
1221                                         allows |= SLAP_ALLOW_BIND_ANON_DN;
1222
1223                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1224 #ifdef NEW_LOGGING
1225                                         LDAP_LOG( CONFIG, CRIT, 
1226                                                    "%s: line %d: unknown feature %s in "
1227                                                    "\"allow <features>\" line.\n",
1228                                                    fname, lineno, cargv[1] );
1229 #else
1230                                         Debug( LDAP_DEBUG_ANY,
1231                     "%s: line %d: unknown feature %s in \"allow <features>\" line\n",
1232                                             fname, lineno, cargv[i] );
1233 #endif
1234
1235                                         return( 1 );
1236                                 }
1237                         }
1238
1239                         global_allows = allows;
1240
1241                 /* disallow these features */
1242                 } else if ( strcasecmp( cargv[0], "disallows" ) == 0 ||
1243                         strcasecmp( cargv[0], "disallow" ) == 0 )
1244                 {
1245                         slap_mask_t     disallows;
1246
1247                         if ( be != NULL ) {
1248 #ifdef NEW_LOGGING
1249                                 LDAP_LOG( CONFIG, INFO, 
1250                                            "%s: line %d: disallow line must appear prior to "
1251                                            "database definitions.\n", fname, lineno ,0 );
1252 #else
1253                                 Debug( LDAP_DEBUG_ANY,
1254 "%s: line %d: disallow line must appear prior to database definitions\n",
1255                                     fname, lineno, 0 );
1256 #endif
1257
1258                         }
1259
1260                         if ( cargc < 2 ) {
1261 #ifdef NEW_LOGGING
1262                                 LDAP_LOG( CONFIG, CRIT, 
1263                                         "%s: line %d: missing feature(s) in \"disallow <features>\""
1264                                         " line.\n", fname, lineno ,0 );
1265 #else
1266                                 Debug( LDAP_DEBUG_ANY,
1267             "%s: line %d: missing feature(s) in \"disallow <features>\" line\n",
1268                                     fname, lineno, 0 );
1269 #endif
1270
1271                                 return( 1 );
1272                         }
1273
1274                         disallows = 0;
1275
1276                         for( i=1; i < cargc; i++ ) {
1277                                 if( strcasecmp( cargv[i], "bind_anon" ) == 0 ) {
1278                                         disallows |= SLAP_DISALLOW_BIND_ANON;
1279
1280                                 } else if( strcasecmp( cargv[i], "bind_simple" ) == 0 ) {
1281                                         disallows |= SLAP_DISALLOW_BIND_SIMPLE;
1282
1283                                 } else if( strcasecmp( cargv[i], "bind_simple_unprotected" ) == 0 ) {
1284                                         disallows |= SLAP_DISALLOW_BIND_SIMPLE_UNPROTECTED;
1285
1286                                 } else if( strcasecmp( cargv[i], "bind_krbv4" ) == 0 ) {
1287                                         disallows |= SLAP_DISALLOW_BIND_KRBV4;
1288
1289                                 } else if( strcasecmp( cargv[i], "tls_2_anon" ) == 0 ) {
1290                                         disallows |= SLAP_DISALLOW_TLS_2_ANON;
1291
1292                                 } else if( strcasecmp( cargv[i], "tls_authc" ) == 0 ) {
1293                                         disallows |= SLAP_DISALLOW_TLS_AUTHC;
1294
1295                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1296 #ifdef NEW_LOGGING
1297                                         LDAP_LOG( CONFIG, CRIT, 
1298                                                 "%s: line %d: unknown feature %s in "
1299                                                 "\"disallow <features>\" line.\n",
1300                                                 fname, lineno, cargv[i] );
1301 #else
1302                                         Debug( LDAP_DEBUG_ANY,
1303                     "%s: line %d: unknown feature %s in \"disallow <features>\" line\n",
1304                                             fname, lineno, cargv[i] );
1305 #endif
1306
1307                                         return( 1 );
1308                                 }
1309                         }
1310
1311                         global_disallows = disallows;
1312
1313                 /* require these features */
1314                 } else if ( strcasecmp( cargv[0], "requires" ) == 0 ||
1315                         strcasecmp( cargv[0], "require" ) == 0 )
1316                 {
1317                         slap_mask_t     requires;
1318
1319                         if ( cargc < 2 ) {
1320 #ifdef NEW_LOGGING
1321                                 LDAP_LOG( CONFIG, CRIT, 
1322                                            "%s: line %d: missing feature(s) in "
1323                                            "\"require <features>\" line.\n", fname, lineno ,0 );
1324 #else
1325                                 Debug( LDAP_DEBUG_ANY,
1326             "%s: line %d: missing feature(s) in \"require <features>\" line\n",
1327                                     fname, lineno, 0 );
1328 #endif
1329
1330                                 return( 1 );
1331                         }
1332
1333                         requires = 0;
1334
1335                         for( i=1; i < cargc; i++ ) {
1336                                 if( strcasecmp( cargv[i], "bind" ) == 0 ) {
1337                                         requires |= SLAP_REQUIRE_BIND;
1338
1339                                 } else if( strcasecmp( cargv[i], "LDAPv3" ) == 0 ) {
1340                                         requires |= SLAP_REQUIRE_LDAP_V3;
1341
1342                                 } else if( strcasecmp( cargv[i], "authc" ) == 0 ) {
1343                                         requires |= SLAP_REQUIRE_AUTHC;
1344
1345                                 } else if( strcasecmp( cargv[i], "SASL" ) == 0 ) {
1346                                         requires |= SLAP_REQUIRE_SASL;
1347
1348                                 } else if( strcasecmp( cargv[i], "strong" ) == 0 ) {
1349                                         requires |= SLAP_REQUIRE_STRONG;
1350
1351                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1352 #ifdef NEW_LOGGING
1353                                         LDAP_LOG( CONFIG, CRIT, 
1354                                                    "%s: line %d: unknown feature %s in "
1355                                                    "\"require <features>\" line.\n", 
1356                                                    fname, lineno , cargv[i] );
1357 #else
1358                                         Debug( LDAP_DEBUG_ANY,
1359                     "%s: line %d: unknown feature %s in \"require <features>\" line\n",
1360                                             fname, lineno, cargv[i] );
1361 #endif
1362
1363                                         return( 1 );
1364                                 }
1365                         }
1366
1367                         if ( be == NULL ) {
1368                                 global_requires = requires;
1369                         } else {
1370                                 be->be_requires = requires;
1371                         }
1372
1373                 /* required security factors */
1374                 } else if ( strcasecmp( cargv[0], "security" ) == 0 ) {
1375                         slap_ssf_set_t *set;
1376
1377                         if ( cargc < 2 ) {
1378 #ifdef NEW_LOGGING
1379                                 LDAP_LOG( CONFIG, CRIT, 
1380                                         "%s: line %d: missing factor(s) in \"security <factors>\""
1381                                         " line.\n", fname, lineno ,0 );
1382 #else
1383                                 Debug( LDAP_DEBUG_ANY,
1384             "%s: line %d: missing factor(s) in \"security <factors>\" line\n",
1385                                     fname, lineno, 0 );
1386 #endif
1387
1388                                 return( 1 );
1389                         }
1390
1391                         if ( be == NULL ) {
1392                                 set = &global_ssf_set;
1393                         } else {
1394                                 set = &be->be_ssf_set;
1395                         }
1396
1397                         for( i=1; i < cargc; i++ ) {
1398                                 if( strncasecmp( cargv[i], "ssf=",
1399                                         sizeof("ssf") ) == 0 )
1400                                 {
1401                                         set->sss_ssf =
1402                                                 atoi( &cargv[i][sizeof("ssf")] );
1403
1404                                 } else if( strncasecmp( cargv[i], "transport=",
1405                                         sizeof("transport") ) == 0 )
1406                                 {
1407                                         set->sss_transport =
1408                                                 atoi( &cargv[i][sizeof("transport")] );
1409
1410                                 } else if( strncasecmp( cargv[i], "tls=",
1411                                         sizeof("tls") ) == 0 )
1412                                 {
1413                                         set->sss_tls =
1414                                                 atoi( &cargv[i][sizeof("tls")] );
1415
1416                                 } else if( strncasecmp( cargv[i], "sasl=",
1417                                         sizeof("sasl") ) == 0 )
1418                                 {
1419                                         set->sss_sasl =
1420                                                 atoi( &cargv[i][sizeof("sasl")] );
1421
1422                                 } else if( strncasecmp( cargv[i], "update_ssf=",
1423                                         sizeof("update_ssf") ) == 0 )
1424                                 {
1425                                         set->sss_update_ssf =
1426                                                 atoi( &cargv[i][sizeof("update_ssf")] );
1427
1428                                 } else if( strncasecmp( cargv[i], "update_transport=",
1429                                         sizeof("update_transport") ) == 0 )
1430                                 {
1431                                         set->sss_update_transport =
1432                                                 atoi( &cargv[i][sizeof("update_transport")] );
1433
1434                                 } else if( strncasecmp( cargv[i], "update_tls=",
1435                                         sizeof("update_tls") ) == 0 )
1436                                 {
1437                                         set->sss_update_tls =
1438                                                 atoi( &cargv[i][sizeof("update_tls")] );
1439
1440                                 } else if( strncasecmp( cargv[i], "update_sasl=",
1441                                         sizeof("update_sasl") ) == 0 )
1442                                 {
1443                                         set->sss_update_sasl =
1444                                                 atoi( &cargv[i][sizeof("update_sasl")] );
1445
1446                                 } else {
1447 #ifdef NEW_LOGGING
1448                                         LDAP_LOG( CONFIG, CRIT, 
1449                                                    "%s: line %d: unknown factor %S in "
1450                                                    "\"security <factors>\" line.\n",
1451                                                    fname, lineno, cargv[1] );
1452 #else
1453                                         Debug( LDAP_DEBUG_ANY,
1454                     "%s: line %d: unknown factor %s in \"security <factors>\" line\n",
1455                                             fname, lineno, cargv[i] );
1456 #endif
1457
1458                                         return( 1 );
1459                                 }
1460                         }
1461                 /* where to send clients when we don't hold it */
1462                 } else if ( strcasecmp( cargv[0], "referral" ) == 0 ) {
1463                         if ( cargc < 2 ) {
1464 #ifdef NEW_LOGGING
1465                                 LDAP_LOG( CONFIG, CRIT, 
1466                                         "%s: line %d: missing URL in \"referral <URL>\""
1467                                         " line.\n", fname, lineno , 0 );
1468 #else
1469                                 Debug( LDAP_DEBUG_ANY,
1470                     "%s: line %d: missing URL in \"referral <URL>\" line\n",
1471                                     fname, lineno, 0 );
1472 #endif
1473
1474                                 return( 1 );
1475                         }
1476
1477                         if( validate_global_referral( cargv[1] ) ) {
1478 #ifdef NEW_LOGGING
1479                                 LDAP_LOG( CONFIG, CRIT, 
1480                                         "%s: line %d: invalid URL (%s) in \"referral\" line.\n",
1481                                         fname, lineno, cargv[1]  );
1482 #else
1483                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1484                                         "invalid URL (%s) in \"referral\" line.\n",
1485                                     fname, lineno, cargv[1] );
1486 #endif
1487                                 return 1;
1488                         }
1489
1490                         vals[0].bv_val = cargv[1];
1491                         vals[0].bv_len = strlen( vals[0].bv_val );
1492                         value_add( &default_referral, vals );
1493
1494 #ifdef NEW_LOGGING
1495                 } else if ( strcasecmp( cargv[0], "logfile" ) == 0 ) {
1496                         FILE *logfile;
1497                         if ( cargc < 2 ) {
1498 #ifdef NEW_LOGGING
1499                                 LDAP_LOG( CONFIG, CRIT, 
1500                                         "%s: line %d: Error in logfile directive, "
1501                                         "\"logfile <filename>\"\n", fname, lineno , 0 );
1502 #else
1503                                 Debug( LDAP_DEBUG_ANY,
1504                                        "%s: line %d: Error in logfile directive, \"logfile filename\"\n",
1505                                        fname, lineno, 0 );
1506 #endif
1507
1508                                 return( 1 );
1509                         }
1510                         logfile = fopen( cargv[1], "w" );
1511                         if ( logfile != NULL ) lutil_debug_file( logfile  );
1512
1513 #endif
1514                 /* start of a new database definition */
1515                 } else if ( strcasecmp( cargv[0], "debug" ) == 0 ) {
1516                         int level;
1517                         if ( cargc < 3 ) {
1518 #ifdef NEW_LOGGING
1519                                 LDAP_LOG( CONFIG, CRIT, 
1520                                            "%s: line %d: Error in debug directive, "
1521                                            "\"debug <subsys> <level>\"\n", fname, lineno , 0 );
1522 #else
1523                                 Debug( LDAP_DEBUG_ANY,
1524                                         "%s: line %d: Error in debug directive, \"debug subsys level\"\n",
1525                                         fname, lineno, 0 );
1526 #endif
1527
1528                                 return( 1 );
1529                         }
1530                         level = atoi( cargv[2] );
1531                         if ( level <= 0 ) level = lutil_mnem2level( cargv[2] );
1532                         lutil_set_debug_level( cargv[1], level );
1533                 /* specify an Object Identifier macro */
1534                 } else if ( strcasecmp( cargv[0], "objectidentifier" ) == 0 ) {
1535                         rc = parse_oidm( fname, lineno, cargc, cargv );
1536                         if( rc ) return rc;
1537
1538                 /* specify an objectclass */
1539                 } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
1540                         if ( *cargv[1] == '(' ) {
1541                                 char * p;
1542                                 p = strchr(saveline,'(');
1543                                 rc = parse_oc( fname, lineno, p, cargv );
1544                                 if( rc ) return rc;
1545
1546                         } else {
1547 #ifdef NEW_LOGGING
1548                                 LDAP_LOG( CONFIG, INFO, 
1549                                         "%s: line %d: old objectclass format not supported\n",
1550                                         fname, lineno , 0 );
1551 #else
1552                                 Debug( LDAP_DEBUG_ANY,
1553                                        "%s: line %d: old objectclass format not supported.\n",
1554                                        fname, lineno, 0 );
1555 #endif
1556                         }
1557
1558                 /* specify an attribute type */
1559                 } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
1560                         || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
1561                 {
1562                         if ( *cargv[1] == '(' ) {
1563                                 char * p;
1564                                 p = strchr(saveline,'(');
1565                                 rc = parse_at( fname, lineno, p, cargv );
1566                                 if( rc ) return rc;
1567
1568                         } else {
1569 #ifdef NEW_LOGGING
1570                                 LDAP_LOG( CONFIG, INFO, 
1571                                         "%s: line %d: old attribute type format not supported.\n",
1572                                         fname, lineno , 0 );
1573 #else
1574                                 Debug( LDAP_DEBUG_ANY,
1575     "%s: line %d: old attribute type format not supported.\n",
1576                                     fname, lineno, 0 );
1577 #endif
1578
1579                         }
1580
1581                 /* turn on/off schema checking */
1582                 } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
1583                         if ( cargc < 2 ) {
1584 #ifdef NEW_LOGGING
1585                                 LDAP_LOG( CONFIG, CRIT, 
1586                                         "%s: line %d: missing on|off in \"schemacheck <on|off>\""
1587                                         " line.\n", fname, lineno , 0 );
1588 #else
1589                                 Debug( LDAP_DEBUG_ANY,
1590     "%s: line %d: missing on|off in \"schemacheck <on|off>\" line\n",
1591                                     fname, lineno, 0 );
1592 #endif
1593
1594                                 return( 1 );
1595                         }
1596                         if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1597 #ifdef NEW_LOGGING
1598                                 LDAP_LOG( CONFIG, CRIT, 
1599                                         "%s: line %d: schema checking disabled! your mileage may "
1600                                         "vary!\n", fname, lineno , 0 );
1601 #else
1602                                 Debug( LDAP_DEBUG_ANY,
1603                                         "%s: line %d: schema checking disabled! your mileage may vary!\n",
1604                                     fname, lineno, 0 );
1605 #endif
1606                                 global_schemacheck = 0;
1607                         } else {
1608                                 global_schemacheck = 1;
1609                         }
1610
1611                 /* specify access control info */
1612                 } else if ( strcasecmp( cargv[0], "access" ) == 0 ) {
1613                         parse_acl( be, fname, lineno, cargc, cargv );
1614
1615                 /* debug level to log things to syslog */
1616                 } else if ( strcasecmp( cargv[0], "loglevel" ) == 0 ) {
1617                         if ( cargc < 2 ) {
1618 #ifdef NEW_LOGGING
1619                                 LDAP_LOG( CONFIG, CRIT, 
1620                                         "%s: line %d: missing level in \"loglevel <level>\""
1621                                         " line.\n", fname, lineno , 0 );
1622 #else
1623                                 Debug( LDAP_DEBUG_ANY,
1624                     "%s: line %d: missing level in \"loglevel <level>\" line\n",
1625                                     fname, lineno, 0 );
1626 #endif
1627
1628                                 return( 1 );
1629                         }
1630
1631                         ldap_syslog = 0;
1632
1633                         for( i=1; i < cargc; i++ ) {
1634                                 ldap_syslog += atoi( cargv[1] );
1635                         }
1636
1637                 /* list of replicas of the data in this backend (master only) */
1638                 } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
1639                         if ( cargc < 2 ) {
1640 #ifdef NEW_LOGGING
1641                                 LDAP_LOG( CONFIG, CRIT, 
1642                                         "%s: line %d: missing host in \"replica "
1643                                         " <host[:port]\" line\n", fname, lineno , 0 );
1644 #else
1645                                 Debug( LDAP_DEBUG_ANY,
1646             "%s: line %d: missing host in \"replica <host[:port]>\" line\n",
1647                                     fname, lineno, 0 );
1648 #endif
1649
1650                                 return( 1 );
1651                         }
1652                         if ( be == NULL ) {
1653 #ifdef NEW_LOGGING
1654                                 LDAP_LOG( CONFIG, INFO, 
1655                                             "%s: line %d: replica line must appear inside "
1656                                             "a database definition.\n", fname, lineno, 0);
1657 #else
1658                                 Debug( LDAP_DEBUG_ANY,
1659 "%s: line %d: replica line must appear inside a database definition\n",
1660                                     fname, lineno, 0 );
1661 #endif
1662                                 return 1;
1663
1664                         } else {
1665                                 int nr = -1;
1666
1667                                 for ( i = 1; i < cargc; i++ ) {
1668                                         if ( strncasecmp( cargv[i], "host=", 5 )
1669                                             == 0 ) {
1670                                                 nr = add_replica_info( be, 
1671                                                         cargv[i] + 5 );
1672                                                 break;
1673                                         }
1674                                 }
1675                                 if ( i == cargc ) {
1676 #ifdef NEW_LOGGING
1677                                         LDAP_LOG( CONFIG, INFO, 
1678                                                 "%s: line %d: missing host in \"replica\" line\n", 
1679                                                 fname, lineno , 0 );
1680 #else
1681                                         Debug( LDAP_DEBUG_ANY,
1682                     "%s: line %d: missing host in \"replica\" line\n",
1683                                             fname, lineno, 0 );
1684 #endif
1685                                         return 1;
1686
1687                                 } else if ( nr == -1 ) {
1688 #ifdef NEW_LOGGING
1689                                         LDAP_LOG( CONFIG, INFO, 
1690                                                    "%s: line %d: unable to add"
1691                                                    " replica \"%s\"\n",
1692                                                    fname, lineno, 
1693                                                    cargv[i] + 5 );
1694 #else
1695                                         Debug( LDAP_DEBUG_ANY,
1696                 "%s: line %d: unable to add replica \"%s\"\n",
1697                                                 fname, lineno, cargv[i] + 5 );
1698 #endif
1699                                         return 1;
1700                                 } else {
1701                                         for ( i = 1; i < cargc; i++ ) {
1702                                                 if ( strncasecmp( cargv[i], "suffix=", 7 ) == 0 ) {
1703
1704                                                         switch ( add_replica_suffix( be, nr, cargv[i] + 7 ) ) {
1705                                                         case 1:
1706 #ifdef NEW_LOGGING
1707                                                                 LDAP_LOG( CONFIG, INFO, 
1708                                                                         "%s: line %d: suffix \"%s\" in \"replica\""
1709                                                                         " line is not valid for backend(ignored)\n",
1710                                                                         fname, lineno, cargv[i] + 7 );
1711 #else
1712                                                                 Debug( LDAP_DEBUG_ANY,
1713                                                                                 "%s: line %d: suffix \"%s\" in \"replica\" line is not valid for backend (ignored)\n",
1714                                                                                 fname, lineno, cargv[i] + 7 );
1715 #endif
1716                                                                 break;
1717
1718                                                         case 2:
1719 #ifdef NEW_LOGGING
1720                                                                 LDAP_LOG( CONFIG, INFO, 
1721                                                                         "%s: line %d: unable to normalize suffix"
1722                                                                         " in \"replica\" line (ignored)\n",
1723                                                                         fname, lineno , 0 );
1724 #else
1725                                                                 Debug( LDAP_DEBUG_ANY,
1726                                                                                  "%s: line %d: unable to normalize suffix in \"replica\" line (ignored)\n",
1727                                                                                  fname, lineno, 0 );
1728 #endif
1729                                                                 break;
1730                                                         }
1731
1732                                                 } else if ( strncasecmp( cargv[i], "attr", 4 ) == 0 ) {
1733                                                         int exclude = 0;
1734                                                         char *arg = cargv[i] + 4;
1735
1736                                                         if ( arg[0] == '!' ) {
1737                                                                 arg++;
1738                                                                 exclude = 1;
1739                                                         }
1740
1741                                                         if ( arg[0] != '=' ) {
1742                                                                 continue;
1743                                                         }
1744
1745                                                         if ( add_replica_attrs( be, nr, arg + 1, exclude ) ) {
1746 #ifdef NEW_LOGGING
1747                                                                 LDAP_LOG( CONFIG, INFO, 
1748                                                                         "%s: line %d: attribute \"%s\" in "
1749                                                                         "\"replica\" line is unknown\n",
1750                                                                         fname, lineno, arg + 1 ); 
1751 #else
1752                                                                 Debug( LDAP_DEBUG_ANY,
1753                                                                                 "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
1754                                                                                 fname, lineno, arg + 1 );
1755 #endif
1756                                                                 return( 1 );
1757                                                         }
1758                                                 }
1759                                         }
1760                                 }
1761                         }
1762
1763                 /* dn of master entity allowed to write to replica */
1764                 } else if ( strcasecmp( cargv[0], "updatedn" ) == 0 ) {
1765                         if ( cargc < 2 ) {
1766 #ifdef NEW_LOGGING
1767                                 LDAP_LOG( CONFIG, CRIT, 
1768                                         "%s: line %d: missing dn in \"updatedn <dn>\""
1769                                         " line.\n", fname, lineno , 0 );
1770 #else
1771                                 Debug( LDAP_DEBUG_ANY,
1772                     "%s: line %d: missing dn in \"updatedn <dn>\" line\n",
1773                                     fname, lineno, 0 );
1774 #endif
1775
1776                                 return( 1 );
1777                         }
1778                         if ( be == NULL ) {
1779 #ifdef NEW_LOGGING
1780                                 LDAP_LOG( CONFIG, INFO, 
1781                                         "%s: line %d: updatedn line must appear inside "
1782                                         "a database definition\n", 
1783                                         fname, lineno , 0 );
1784 #else
1785                                 Debug( LDAP_DEBUG_ANY,
1786 "%s: line %d: updatedn line must appear inside a database definition\n",
1787                                     fname, lineno, 0 );
1788 #endif
1789                                 return 1;
1790
1791                         } else {
1792                                 struct berval dn;
1793
1794                                 if ( load_ucdata( NULL ) < 0 ) return 1;
1795
1796                                 dn.bv_val = cargv[1];
1797                                 dn.bv_len = strlen( cargv[1] );
1798
1799                                 rc = dnNormalize2( NULL, &dn, &be->be_update_ndn );
1800                                 if( rc != LDAP_SUCCESS ) {
1801 #ifdef NEW_LOGGING
1802                                         LDAP_LOG( CONFIG, CRIT, 
1803                                                 "%s: line %d: updatedn DN is invalid.\n",
1804                                                 fname, lineno , 0 );
1805 #else
1806                                         Debug( LDAP_DEBUG_ANY,
1807                                                 "%s: line %d: updatedn DN is invalid\n",
1808                                             fname, lineno, 0 );
1809 #endif
1810                                         return 1;
1811                                 }
1812                         }
1813
1814                 } else if ( strcasecmp( cargv[0], "updateref" ) == 0 ) {
1815                         if ( cargc < 2 ) {
1816 #ifdef NEW_LOGGING
1817                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1818                                         "missing url in \"updateref <ldapurl>\" line.\n",
1819                                         fname, lineno , 0 );
1820 #else
1821                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1822                                         "missing url in \"updateref <ldapurl>\" line\n",
1823                                     fname, lineno, 0 );
1824 #endif
1825
1826                                 return( 1 );
1827                         }
1828                         if ( be == NULL ) {
1829 #ifdef NEW_LOGGING
1830                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: updateref"
1831                                         " line must appear inside a database definition\n",
1832                                         fname, lineno , 0 );
1833 #else
1834                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: updateref"
1835                                         " line must appear inside a database definition\n",
1836                                         fname, lineno, 0 );
1837 #endif
1838                                 return 1;
1839
1840                         } else if ( !be->be_update_ndn.bv_len ) {
1841 #ifdef NEW_LOGGING
1842                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
1843                                         "updateref line must come after updatedn.\n",
1844                                         fname, lineno , 0 );
1845 #else
1846                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1847                                         "updateref line must after updatedn.\n",
1848                                     fname, lineno, 0 );
1849 #endif
1850                                 return 1;
1851                         }
1852
1853                         if( validate_global_referral( cargv[1] ) ) {
1854 #ifdef NEW_LOGGING
1855                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1856                                         "invalid URL (%s) in \"updateref\" line.\n",
1857                                         fname, lineno, cargv[1] );
1858 #else
1859                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1860                                         "invalid URL (%s) in \"updateref\" line.\n",
1861                                     fname, lineno, cargv[1] );
1862 #endif
1863                                 return 1;
1864                         }
1865
1866                         vals[0].bv_val = cargv[1];
1867                         vals[0].bv_len = strlen( vals[0].bv_val );
1868                         value_add( &be->be_update_refs, vals );
1869
1870                 /* replication log file to which changes are appended */
1871                 } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
1872                         if ( cargc < 2 ) {
1873 #ifdef NEW_LOGGING
1874                                 LDAP_LOG( CONFIG, CRIT, 
1875                                         "%s: line %d: missing filename in \"replogfile <filename>\""
1876                                         " line.\n", fname, lineno , 0 );
1877 #else
1878                                 Debug( LDAP_DEBUG_ANY,
1879             "%s: line %d: missing filename in \"replogfile <filename>\" line\n",
1880                                     fname, lineno, 0 );
1881 #endif
1882
1883                                 return( 1 );
1884                         }
1885                         if ( be ) {
1886                                 be->be_replogfile = ch_strdup( cargv[1] );
1887                         } else {
1888                                 replogfile = ch_strdup( cargv[1] );
1889                         }
1890
1891                 /* file from which to read additional rootdse attrs */
1892                 } else if ( strcasecmp( cargv[0], "rootDSE" ) == 0) {
1893                         if ( cargc < 2 ) {
1894 #ifdef NEW_LOGGING
1895                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1896                                         "missing filename in \"rootDSE <filename>\" line.\n",
1897                                         fname, lineno , 0 );
1898 #else
1899                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1900                                         "missing filename in \"rootDSE <filename>\" line.\n",
1901                                     fname, lineno, 0 );
1902 #endif
1903                                 return 1;
1904                         }
1905
1906                         if( read_root_dse_file( cargv[1] ) ) {
1907 #ifdef NEW_LOGGING
1908                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1909                                         "could not read \"rootDSE <filename>\" line.\n",
1910                                         fname, lineno , 0 );
1911 #else
1912                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1913                                         "could not read \"rootDSE <filename>\" line\n",
1914                                     fname, lineno, 0 );
1915 #endif
1916                                 return 1;
1917                         }
1918
1919                 /* maintain lastmodified{by,time} attributes */
1920                 } else if ( strcasecmp( cargv[0], "lastmod" ) == 0 ) {
1921                         if ( cargc < 2 ) {
1922 #ifdef NEW_LOGGING
1923                                 LDAP_LOG( CONFIG, CRIT, 
1924                                            "%s: line %d: missing on|off in \"lastmod <on|off>\""
1925                                            " line.\n", fname, lineno , 0 );
1926 #else
1927                                 Debug( LDAP_DEBUG_ANY,
1928             "%s: line %d: missing on|off in \"lastmod <on|off>\" line\n",
1929                                     fname, lineno, 0 );
1930 #endif
1931
1932                                 return( 1 );
1933                         }
1934                         if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1935                                 if ( be ) {
1936                                         be->be_flags &= ~SLAP_BFLAG_NOLASTMOD;
1937                                 } else {
1938                                         lastmod = 1;
1939                                 }
1940                         } else {
1941                                 if ( be ) {
1942                                         be->be_flags |= SLAP_BFLAG_NOLASTMOD;
1943                                 } else {
1944                                         lastmod = 0;
1945                                 }
1946                         }
1947
1948 #ifdef SIGHUP
1949                 /* turn on/off gentle SIGHUP handling */
1950                 } else if ( strcasecmp( cargv[0], "gentlehup" ) == 0 ) {
1951                         if ( cargc < 2 ) {
1952                                 Debug( LDAP_DEBUG_ANY,
1953     "%s: line %d: missing on|off in \"gentlehup <on|off>\" line\n",
1954                                     fname, lineno, 0 );
1955                                 return( 1 );
1956                         }
1957                         if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1958                                 global_gentlehup = 0;
1959                         } else {
1960                                 global_gentlehup = 1;
1961                         }
1962 #endif
1963
1964                 /* set idle timeout value */
1965                 } else if ( strcasecmp( cargv[0], "idletimeout" ) == 0 ) {
1966                         int i;
1967                         if ( cargc < 2 ) {
1968 #ifdef NEW_LOGGING
1969                                 LDAP_LOG( CONFIG, CRIT, 
1970                                         "%s: line %d: missing timeout value in "
1971                                         "\"idletimeout <seconds>\" line.\n", fname, lineno , 0 );
1972 #else
1973                                 Debug( LDAP_DEBUG_ANY,
1974             "%s: line %d: missing timeout value in \"idletimeout <seconds>\" line\n",
1975                                     fname, lineno, 0 );
1976 #endif
1977
1978                                 return( 1 );
1979                         }
1980
1981                         i = atoi( cargv[1] );
1982
1983                         if( i < 0 ) {
1984 #ifdef NEW_LOGGING
1985                                 LDAP_LOG( CONFIG, CRIT, 
1986                                         "%s: line %d: timeout value (%d) invalid "
1987                                         "\"idletimeout <seconds>\" line.\n", fname, lineno, i );
1988 #else
1989                                 Debug( LDAP_DEBUG_ANY,
1990             "%s: line %d: timeout value (%d) invalid \"idletimeout <seconds>\" line\n",
1991                                     fname, lineno, i );
1992 #endif
1993
1994                                 return( 1 );
1995                         }
1996
1997                         global_idletimeout = i;
1998
1999                 /* include another config file */
2000                 } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
2001                         if ( cargc < 2 ) {
2002 #ifdef NEW_LOGGING
2003                                 LDAP_LOG( CONFIG, CRIT, 
2004                                         "%s: line %d: missing filename in \"include "
2005                                         "<filename>\" line.\n", fname, lineno , 0 );
2006 #else
2007                                 Debug( LDAP_DEBUG_ANY,
2008     "%s: line %d: missing filename in \"include <filename>\" line\n",
2009                                     fname, lineno, 0 );
2010 #endif
2011
2012                                 return( 1 );
2013                         }
2014                         savefname = ch_strdup( cargv[1] );
2015                         savelineno = lineno;
2016
2017                         if ( read_config( savefname, depth+1 ) != 0 ) {
2018                                 return( 1 );
2019                         }
2020
2021                         free( savefname );
2022                         lineno = savelineno - 1;
2023
2024                 /* location of kerberos srvtab file */
2025                 } else if ( strcasecmp( cargv[0], "srvtab" ) == 0 ) {
2026                         if ( cargc < 2 ) {
2027 #ifdef NEW_LOGGING
2028                                 LDAP_LOG( CONFIG, CRIT, 
2029                                         "%s: line %d: missing filename in \"srvtab "
2030                                         "<filename>\" line.\n", fname, lineno , 0 );
2031 #else
2032                                 Debug( LDAP_DEBUG_ANY,
2033             "%s: line %d: missing filename in \"srvtab <filename>\" line\n",
2034                                     fname, lineno, 0 );
2035 #endif
2036
2037                                 return( 1 );
2038                         }
2039                         ldap_srvtab = ch_strdup( cargv[1] );
2040
2041 #ifdef SLAPD_MODULES
2042                 } else if (strcasecmp( cargv[0], "moduleload") == 0 ) {
2043                    if ( cargc < 2 ) {
2044 #ifdef NEW_LOGGING
2045                            LDAP_LOG( CONFIG, INFO, 
2046                                    "%s: line %d: missing filename in \"moduleload "
2047                                    "<filename>\" line.\n", fname, lineno , 0 );
2048 #else
2049                       Debug( LDAP_DEBUG_ANY,
2050                              "%s: line %d: missing filename in \"moduleload <filename>\" line\n",
2051                              fname, lineno, 0 );
2052 #endif
2053
2054                       exit( EXIT_FAILURE );
2055                    }
2056                    if (module_load(cargv[1], cargc - 2, (cargc > 2) ? cargv + 2 : NULL)) {
2057 #ifdef NEW_LOGGING
2058                            LDAP_LOG( CONFIG, CRIT, 
2059                                    "%s: line %d: failed to load or initialize module %s\n",
2060                                    fname, lineno, cargv[1] );
2061 #else
2062                       Debug( LDAP_DEBUG_ANY,
2063                              "%s: line %d: failed to load or initialize module %s\n",
2064                              fname, lineno, cargv[1]);
2065 #endif
2066
2067                       exit( EXIT_FAILURE );
2068                    }
2069                 } else if (strcasecmp( cargv[0], "modulepath") == 0 ) {
2070                    if ( cargc != 2 ) {
2071 #ifdef NEW_LOGGING
2072                            LDAP_LOG( CONFIG, INFO, 
2073                                   "%s: line %d: missing path in \"modulepath <path>\""
2074                                   " line\n", fname, lineno , 0 );
2075 #else
2076                       Debug( LDAP_DEBUG_ANY,
2077                              "%s: line %d: missing path in \"modulepath <path>\" line\n",
2078                              fname, lineno, 0 );
2079 #endif
2080
2081                       exit( EXIT_FAILURE );
2082                    }
2083                    if (module_path( cargv[1] )) {
2084 #ifdef NEW_LOGGING
2085                            LDAP_LOG( CONFIG, CRIT, 
2086                                   "%s: line %d: failed to set module search path to %s.\n",
2087                                   fname, lineno, cargv[1] );
2088 #else
2089                            Debug( LDAP_DEBUG_ANY,
2090                                   "%s: line %d: failed to set module search path to %s\n",
2091                                   fname, lineno, cargv[1]);
2092 #endif
2093
2094                       exit( EXIT_FAILURE );
2095                    }
2096                    
2097 #endif /*SLAPD_MODULES*/
2098
2099 #ifdef HAVE_TLS
2100                 } else if ( !strcasecmp( cargv[0], "TLSRandFile" ) ) {
2101                         rc = ldap_pvt_tls_set_option( NULL,
2102                                                       LDAP_OPT_X_TLS_RANDOM_FILE,
2103                                                       cargv[1] );
2104                         if ( rc )
2105                                 return rc;
2106
2107                 } else if ( !strcasecmp( cargv[0], "TLSCipherSuite" ) ) {
2108                         rc = ldap_pvt_tls_set_option( NULL,
2109                                                       LDAP_OPT_X_TLS_CIPHER_SUITE,
2110                                                       cargv[1] );
2111                         if ( rc )
2112                                 return rc;
2113
2114                 } else if ( !strcasecmp( cargv[0], "TLSCertificateFile" ) ) {
2115                         rc = ldap_pvt_tls_set_option( NULL,
2116                                                       LDAP_OPT_X_TLS_CERTFILE,
2117                                                       cargv[1] );
2118                         if ( rc )
2119                                 return rc;
2120
2121                 } else if ( !strcasecmp( cargv[0], "TLSCertificateKeyFile" ) ) {
2122                         rc = ldap_pvt_tls_set_option( NULL,
2123                                                       LDAP_OPT_X_TLS_KEYFILE,
2124                                                       cargv[1] );
2125                         if ( rc )
2126                                 return rc;
2127
2128                 } else if ( !strcasecmp( cargv[0], "TLSCACertificatePath" ) ) {
2129                         rc = ldap_pvt_tls_set_option( NULL,
2130                                                       LDAP_OPT_X_TLS_CACERTDIR,
2131                                                       cargv[1] );
2132                         if ( rc )
2133                                 return rc;
2134
2135                 } else if ( !strcasecmp( cargv[0], "TLSCACertificateFile" ) ) {
2136                         rc = ldap_pvt_tls_set_option( NULL,
2137                                                       LDAP_OPT_X_TLS_CACERTFILE,
2138                                                       cargv[1] );
2139                         if ( rc )
2140                                 return rc;
2141                 } else if ( !strcasecmp( cargv[0], "TLSVerifyClient" ) ) {
2142                         if ( isdigit( (unsigned char) cargv[1][0] ) ) {
2143                                 i = atoi(cargv[1]);
2144                                 rc = ldap_pvt_tls_set_option( NULL,
2145                                                       LDAP_OPT_X_TLS_REQUIRE_CERT,
2146                                                       &i );
2147                         } else {
2148                                 rc = ldap_int_tls_config( NULL,
2149                                                       LDAP_OPT_X_TLS_REQUIRE_CERT,
2150                                                       cargv[1] );
2151                         }
2152
2153                         if ( rc )
2154                                 return rc;
2155
2156 #endif
2157
2158                 } else if ( !strcasecmp( cargv[0], "reverse-lookup" ) ) {
2159 #ifdef SLAPD_RLOOKUPS
2160                         if ( cargc < 2 ) {
2161 #ifdef NEW_LOGGING
2162                                 LDAP_LOG( CONFIG, INFO, 
2163                                         "%s: line %d: reverse-lookup: missing \"on\" or \"off\"\n",
2164                                         fname, lineno , 0 );
2165 #else
2166                                 Debug( LDAP_DEBUG_ANY,
2167 "%s: line %d: reverse-lookup: missing \"on\" or \"off\"\n",
2168                                         fname, lineno, 0 );
2169 #endif
2170                                 return( 1 );
2171                         }
2172
2173                         if ( !strcasecmp( cargv[1], "on" ) ) {
2174                                 use_reverse_lookup = 1;
2175                         } else if ( !strcasecmp( cargv[1], "off" ) ) {
2176                                 use_reverse_lookup = 0;
2177                         } else {
2178 #ifdef NEW_LOGGING
2179                                 LDAP_LOG( CONFIG, INFO, 
2180                                         "%s: line %d: reverse-lookup: "
2181                                         "must be \"on\" (default) or \"off\"\n", fname, lineno, 0 );
2182 #else
2183                                 Debug( LDAP_DEBUG_ANY,
2184 "%s: line %d: reverse-lookup: must be \"on\" (default) or \"off\"\n",
2185                                         fname, lineno, 0 );
2186 #endif
2187                                 return( 1 );
2188                         }
2189
2190 #else /* !SLAPD_RLOOKUPS */
2191 #ifdef NEW_LOGGING
2192                         LDAP_LOG( CONFIG, INFO, 
2193                                 "%s: line %d: reverse lookups "
2194                                 "are not configured (ignored).\n", fname, lineno , 0 );
2195 #else
2196                         Debug( LDAP_DEBUG_ANY,
2197 "%s: line %d: reverse lookups are not configured (ignored).\n",
2198                                 fname, lineno, 0 );
2199 #endif
2200 #endif /* !SLAPD_RLOOKUPS */
2201
2202                 /* pass anything else to the current backend info/db config routine */
2203                 } else {
2204                         if ( bi != NULL ) {
2205                                 if ( bi->bi_config == 0 ) {
2206 #ifdef NEW_LOGGING
2207                                         LDAP_LOG( CONFIG, INFO, 
2208                                                 "%s: line %d: unknown directive \"%s\" inside "
2209                                                 "backend info definition (ignored).\n",
2210                                                 fname, lineno, cargv[0] );
2211 #else
2212                                         Debug( LDAP_DEBUG_ANY,
2213 "%s: line %d: unknown directive \"%s\" inside backend info definition (ignored)\n",
2214                                                 fname, lineno, cargv[0] );
2215 #endif
2216
2217                                 } else {
2218                                         if ( (*bi->bi_config)( bi, fname, lineno, cargc, cargv )
2219                                                 != 0 )
2220                                         {
2221                                                 return( 1 );
2222                                         }
2223                                 }
2224                         } else if ( be != NULL ) {
2225                                 if ( be->be_config == 0 ) {
2226 #ifdef NEW_LOGGING
2227                                         LDAP_LOG( CONFIG, INFO, 
2228                                                 "%s: line %d: uknown directive \"%s\" inside "
2229                                                 "backend database definition (ignored).\n",
2230                                                 fname, lineno, cargv[0] );
2231 #else
2232                                         Debug( LDAP_DEBUG_ANY,
2233 "%s: line %d: unknown directive \"%s\" inside backend database definition (ignored)\n",
2234                                         fname, lineno, cargv[0] );
2235 #endif
2236
2237                                 } else {
2238                                         if ( (*be->be_config)( be, fname, lineno, cargc, cargv )
2239                                                 != 0 )
2240                                         {
2241                                                 return( 1 );
2242                                         }
2243                                 }
2244                         } else {
2245 #ifdef NEW_LOGGING
2246                                 LDAP_LOG( CONFIG, INFO, 
2247                                         "%s: line %d: unknown directive \"%s\" outside backend "
2248                                         "info and database definitions (ignored).\n",
2249                                         fname, lineno, cargv[0] );
2250 #else
2251                                 Debug( LDAP_DEBUG_ANY,
2252 "%s: line %d: unknown directive \"%s\" outside backend info and database definitions (ignored)\n",
2253                                     fname, lineno, cargv[0] );
2254 #endif
2255
2256                         }
2257                 }
2258                 free( saveline );
2259         }
2260         fclose( fp );
2261
2262         if ( depth == 0 ) ch_free( cargv );
2263
2264         if ( load_ucdata( NULL ) < 0 ) return 1;
2265         return( 0 );
2266 }
2267
2268 static int
2269 fp_parse_line(
2270     int         lineno,
2271     char        *line
2272 )
2273 {
2274         char *  token;
2275         char *  logline;
2276         char    logbuf[sizeof("pseudorootpw ***")];
2277
2278         cargc = 0;
2279         token = strtok_quote( line, " \t" );
2280
2281         logline = line;
2282
2283         if ( token && ( strcasecmp( token, "rootpw" ) == 0 ||
2284                 strcasecmp( token, "replica" ) == 0 ||          /* contains "credentials" */
2285                 strcasecmp( token, "bindpw" ) == 0 ||           /* used in back-ldap */
2286                 strcasecmp( token, "pseudorootpw" ) == 0 ||     /* used in back-meta */
2287                 strcasecmp( token, "dbpasswd" ) == 0 ) )        /* used in back-sql */
2288         {
2289                 snprintf( logline = logbuf, sizeof logbuf, "%s ***", token );
2290         }
2291
2292         if ( strtok_quote_ptr ) {
2293                 *strtok_quote_ptr = ' ';
2294         }
2295
2296 #ifdef NEW_LOGGING
2297         LDAP_LOG( CONFIG, DETAIL1, "line %d (%s)\n", lineno, logline , 0 );
2298 #else
2299         Debug( LDAP_DEBUG_CONFIG, "line %d (%s)\n", lineno, logline, 0 );
2300 #endif
2301
2302         if ( strtok_quote_ptr ) {
2303                 *strtok_quote_ptr = '\0';
2304         }
2305
2306         for ( ; token != NULL; token = strtok_quote( NULL, " \t" ) ) {
2307                 if ( cargc == cargv_size - 1 ) {
2308                         char **tmp;
2309                         tmp = ch_realloc( cargv, (cargv_size + ARGS_STEP) *
2310                                             sizeof(*cargv) );
2311                         if ( tmp == NULL ) {
2312 #ifdef NEW_LOGGING
2313                                 LDAP_LOG( CONFIG, ERR, "line %d: out of memory\n", lineno, 0,0 );
2314 #else
2315                                 Debug( LDAP_DEBUG_ANY, 
2316                                                 "line %d: out of memory\n", 
2317                                                 lineno, 0, 0 );
2318 #endif
2319                                 return -1;
2320                         }
2321                         cargv = tmp;
2322                         cargv_size += ARGS_STEP;
2323                 }
2324                 cargv[cargc++] = token;
2325         }
2326         cargv[cargc] = NULL;
2327         return 0;
2328 }
2329
2330 static char *
2331 strtok_quote( char *line, char *sep )
2332 {
2333         int             inquote;
2334         char            *tmp;
2335         static char     *next;
2336
2337         strtok_quote_ptr = NULL;
2338         if ( line != NULL ) {
2339                 next = line;
2340         }
2341         while ( *next && strchr( sep, *next ) ) {
2342                 next++;
2343         }
2344
2345         if ( *next == '\0' ) {
2346                 next = NULL;
2347                 return( NULL );
2348         }
2349         tmp = next;
2350
2351         for ( inquote = 0; *next; ) {
2352                 switch ( *next ) {
2353                 case '"':
2354                         if ( inquote ) {
2355                                 inquote = 0;
2356                         } else {
2357                                 inquote = 1;
2358                         }
2359                         AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
2360                         break;
2361
2362                 case '\\':
2363                         if ( next[1] )
2364                                 AC_MEMCPY( next,
2365                                             next + 1, strlen( next + 1 ) + 1 );
2366                         next++;         /* dont parse the escaped character */
2367                         break;
2368
2369                 default:
2370                         if ( ! inquote ) {
2371                                 if ( strchr( sep, *next ) != NULL ) {
2372                                         strtok_quote_ptr = next;
2373                                         *next++ = '\0';
2374                                         return( tmp );
2375                                 }
2376                         }
2377                         next++;
2378                         break;
2379                 }
2380         }
2381
2382         return( tmp );
2383 }
2384
2385 static char     buf[BUFSIZ];
2386 static char     *line;
2387 static size_t lmax, lcur;
2388
2389 #define CATLINE( buf ) \
2390         do { \
2391                 size_t len = strlen( buf ); \
2392                 while ( lcur + len + 1 > lmax ) { \
2393                         lmax += BUFSIZ; \
2394                         line = (char *) ch_realloc( line, lmax ); \
2395                 } \
2396                 strcpy( line + lcur, buf ); \
2397                 lcur += len; \
2398         } while( 0 )
2399
2400 static char *
2401 fp_getline( FILE *fp, int *lineno )
2402 {
2403         char            *p;
2404
2405         lcur = 0;
2406         CATLINE( buf );
2407         (*lineno)++;
2408
2409         /* hack attack - keeps us from having to keep a stack of bufs... */
2410         if ( strncasecmp( line, "include", 7 ) == 0 ) {
2411                 buf[0] = '\0';
2412                 return( line );
2413         }
2414
2415         while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
2416                 /* trim off \r\n or \n */
2417                 if ( (p = strchr( buf, '\n' )) != NULL ) {
2418                         if( p > buf && p[-1] == '\r' ) --p;
2419                         *p = '\0';
2420                 }
2421                 
2422                 /* trim off trailing \ and append the next line */
2423                 if ( line[ 0 ] != '\0' 
2424                                 && (p = line + strlen( line ) - 1)[ 0 ] == '\\'
2425                                 && p[ -1 ] != '\\' ) {
2426                         p[ 0 ] = '\0';
2427                         lcur--;
2428
2429                 } else {
2430                         if ( ! isspace( (unsigned char) buf[0] ) ) {
2431                                 return( line );
2432                         }
2433
2434                         /* change leading whitespace to a space */
2435                         buf[0] = ' ';
2436                 }
2437
2438                 CATLINE( buf );
2439                 (*lineno)++;
2440         }
2441         buf[0] = '\0';
2442
2443         return( line[0] ? line : NULL );
2444 }
2445
2446 static void
2447 fp_getline_init( int *lineno )
2448 {
2449         *lineno = -1;
2450         buf[0] = '\0';
2451 }
2452
2453 /* Loads ucdata, returns 1 if loading, 0 if already loaded, -1 on error */
2454 static int
2455 load_ucdata( char *path )
2456 {
2457         static int loaded = 0;
2458         int err;
2459         
2460         if ( loaded ) {
2461                 return( 0 );
2462         }
2463         err = ucdata_load( path ? path : SLAPD_DEFAULT_UCDATA, UCDATA_ALL );
2464         if ( err ) {
2465 #ifdef NEW_LOGGING
2466                 LDAP_LOG( CONFIG, CRIT, 
2467                         "load_ucdata: Error %d loading ucdata.\n", err, 0,0 );
2468 #else
2469                 Debug( LDAP_DEBUG_ANY, "error loading ucdata (error %d)\n",
2470                        err, 0, 0 );
2471 #endif
2472
2473                 return( -1 );
2474         }
2475         loaded = 1;
2476         return( 1 );
2477 }
2478
2479 void
2480 config_destroy( )
2481 {
2482         ucdata_unload( UCDATA_ALL );
2483         free( line );
2484         if ( slapd_args_file )
2485                 free ( slapd_args_file );
2486         if ( slapd_pid_file )
2487                 free ( slapd_pid_file );
2488         acl_destroy( global_acl, NULL );
2489 }