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