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