]> git.sur5r.net Git - openldap/blob - servers/slapd/config.c
numSubordinates and lcup (behind #ifdefs)
[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                                 } else {
668                                         lim->lms_s_soft = atoi( cargv[i] );
669                                         lim->lms_s_hard = 0;
670                                 }
671
672                                 if ( rc ) {
673 #ifdef NEW_LOGGING
674                                         LDAP_LOG( CONFIG, CRIT, 
675                                                 "%s: line %d: unable "
676                                                    "to parse value \"%s\" in \"sizelimit "
677                                                    "<limit>\" line.\n", fname, lineno, cargv[i] );
678 #else
679                                         Debug( LDAP_DEBUG_ANY,
680                                                 "%s: line %d: unable "
681                                                 "to parse value \"%s\" "
682                                                 "in \"sizelimit "
683                                                 "<limit>\" line\n",
684                                                 fname, lineno, cargv[i] );
685 #endif
686                                 }
687                         }
688
689                 /* set time limit */
690                 } else if ( strcasecmp( cargv[0], "timelimit" ) == 0 ) {
691                         int rc = 0, i;
692                         struct slap_limits_set *lim;
693                         
694                         if ( cargc < 2 ) {
695 #ifdef NEW_LOGGING
696                                 LDAP_LOG( CONFIG, CRIT, 
697                                         "%s: line %d missing limit in \"timelimit <limit>\" "
698                                         "line.\n", fname, lineno, 0 );
699 #else
700                                 Debug( LDAP_DEBUG_ANY,
701             "%s: line %d: missing limit in \"timelimit <limit>\" line\n",
702                                     fname, lineno, 0 );
703 #endif
704
705                                 return( 1 );
706                         }
707                         
708                         if ( be == NULL ) {
709                                 lim = &deflimit;
710                         } else {
711                                 lim = &be->be_def_limit;
712                         }
713
714                         for ( i = 1; i < cargc; i++ ) {
715                                 if ( strncasecmp( cargv[i], "time", 4 ) == 0 ) {
716                                         rc = parse_limit( cargv[i], lim );
717                                 } else {
718                                         lim->lms_t_soft = atoi( cargv[i] );
719                                         lim->lms_t_hard = 0;
720                                 }
721
722                                 if ( rc ) {
723 #ifdef NEW_LOGGING
724                                         LDAP_LOG( CONFIG, CRIT, 
725                                                     "%s: line %d: unable to parse value \"%s\" "
726                                                    "in \"timelimit <limit>\" line.\n",
727                                                    fname, lineno, cargv[i] );
728 #else
729                                         Debug( LDAP_DEBUG_ANY,
730                                                 "%s: line %d: unable "
731                                                 "to parse value \"%s\" "
732                                                 "in \"timelimit "
733                                                 "<limit>\" line\n",
734                                                 fname, lineno, cargv[i] );
735 #endif
736                                 }
737                         }
738
739                 /* set regex-based limits */
740                 } else if ( strcasecmp( cargv[0], "limits" ) == 0 ) {
741                         if ( be == NULL ) {
742 #ifdef NEW_LOGGING
743                                 LDAP_LOG( CONFIG, WARNING, 
744                                            "%s: line %d \"limits\" allowed only in database "
745                                            "environment.\n", fname, lineno, 0 );
746 #else
747                                 Debug( LDAP_DEBUG_ANY,
748         "%s: line %d \"limits\" allowed only in database environment.\n%s",
749                                         fname, lineno, "" );
750 #endif
751                                 return( 1 );
752                         }
753
754                         if ( parse_limits( be, fname, lineno, cargc, cargv ) ) {
755                                 return( 1 );
756                         }
757
758                 /* mark this as a subordinate database */
759                 } else if ( strcasecmp( cargv[0], "subordinate" ) == 0 ) {
760                         if ( be == NULL ) {
761 #ifdef NEW_LOGGING
762                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
763                                         "subordinate keyword must appear inside a database "
764                                         "definition.\n", fname, lineno, 0 );
765 #else
766                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix line "
767                                         "must appear inside a database definition.\n",
768                                     fname, lineno, 0 );
769 #endif
770                                 return 1;
771
772                         } else {
773                                 be->be_flags |= SLAP_BFLAG_GLUE_SUBORDINATE;
774                                 num_subordinates++;
775                         }
776
777                 /* set database suffix */
778                 } else if ( strcasecmp( cargv[0], "suffix" ) == 0 ) {
779                         Backend *tmp_be;
780                         struct berval dn, pdn, ndn;
781
782                         if ( cargc < 2 ) {
783 #ifdef NEW_LOGGING
784                                 LDAP_LOG( CONFIG, CRIT, 
785                                         "%s: line %d: missing dn in \"suffix <dn>\" line.\n",
786                                         fname, lineno, 0 );
787 #else
788                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
789                                         "missing dn in \"suffix <dn>\" line\n",
790                                     fname, lineno, 0 );
791 #endif
792
793                                 return( 1 );
794
795                         } else if ( cargc > 2 ) {
796 #ifdef NEW_LOGGING
797                                 LDAP_LOG( CONFIG, INFO, 
798                                         "%s: line %d: extra cruft after <dn> in \"suffix %s\""
799                                         " line (ignored).\n", fname, lineno, cargv[1] );
800 #else
801                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: extra cruft "
802                                         "after <dn> in \"suffix %s\" line (ignored)\n",
803                                     fname, lineno, cargv[1] );
804 #endif
805                         }
806
807                         if ( be == NULL ) {
808 #ifdef NEW_LOGGING
809                                 LDAP_LOG( CONFIG, INFO, 
810                                         "%s: line %d: suffix line must appear inside a database "
811                                         "definition.\n", fname, lineno, 0 );
812 #else
813                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix line "
814                                         "must appear inside a database definition\n",
815                                     fname, lineno, 0 );
816 #endif
817                                 return( 1 );
818
819 #if defined(SLAPD_MONITOR_DN)
820                         /* "cn=Monitor" is reserved for monitoring slap */
821                         } else if ( strcasecmp( cargv[1], SLAPD_MONITOR_DN ) == 0 ) {
822 #ifdef NEW_LOGGING
823                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: \""
824                                         SLAPD_MONITOR_DN "\" is reserved for monitoring slapd\n", 
825                                         fname, lineno, 0 );
826 #else
827                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: \""
828                                         SLAPD_MONITOR_DN "\" is reserved for monitoring slapd\n", 
829                                         fname, lineno, 0 );
830 #endif
831                                 return( 1 );
832 #endif /* SLAPD_MONITOR_DN */
833                         }
834
835                         if ( load_ucdata( NULL ) < 0 ) return 1;
836
837                         dn.bv_val = cargv[1];
838                         dn.bv_len = strlen( cargv[1] );
839
840                         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
841                         if( rc != LDAP_SUCCESS ) {
842 #ifdef NEW_LOGGING
843                                 LDAP_LOG( CONFIG, CRIT, 
844                                         "%s: line %d: suffix DN is invalid.\n",
845                                         fname, lineno, 0 );
846 #else
847                                 Debug( LDAP_DEBUG_ANY,
848                                         "%s: line %d: suffix DN is invalid\n",
849                                    fname, lineno, 0 );
850 #endif
851                                 return( 1 );
852                         }
853
854                         tmp_be = select_backend( &ndn, 0, 0 );
855                         if ( tmp_be == be ) {
856 #ifdef NEW_LOGGING
857                                 LDAP_LOG( CONFIG, INFO, 
858                                         "%s: line %d: suffix already served by this backend "
859                                         "(ignored)\n", fname, lineno, 0 );
860 #else
861                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
862                                         "already served by this backend (ignored)\n",
863                                     fname, lineno, 0 );
864 #endif
865                                 free( pdn.bv_val );
866                                 free( ndn.bv_val );
867
868                         } else if ( tmp_be  != NULL ) {
869 #ifdef NEW_LOGGING
870                                 LDAP_LOG( CONFIG, INFO, 
871                                         "%s: line %d: suffix already served by a preceding "
872                                         "backend \"%s\"\n", fname, lineno,
873                                         tmp_be->be_suffix[0].bv_val );
874 #else
875                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
876                                         "already served by a preceeding backend \"%s\"\n",
877                                     fname, lineno, tmp_be->be_suffix[0].bv_val );
878 #endif
879                                 free( pdn.bv_val );
880                                 free( ndn.bv_val );
881                                 return( 1 );
882
883                         } else if( pdn.bv_len == 0 && default_search_nbase.bv_len ) {
884 #ifdef NEW_LOGGING
885                                         LDAP_LOG( CONFIG, INFO, 
886                                                 "%s: line %d: suffix DN empty and default search "
887                                                 "base provided \"%s\" (assuming okay).\n",
888                                                 fname, lineno, default_search_base.bv_val );
889 #else
890                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
891                                                 "suffix DN empty and default "
892                                                 "search base provided \"%s\" (assuming okay)\n",
893                                         fname, lineno, default_search_base.bv_val );
894 #endif
895                         }
896
897                         ber_bvarray_add( &be->be_suffix, &pdn );
898                         ber_bvarray_add( &be->be_nsuffix, &ndn );
899
900                 /* set database suffixAlias */
901                 } else if ( strcasecmp( cargv[0], "suffixAlias" ) == 0 ) {
902                         Backend *tmp_be;
903                         struct berval alias, palias, nalias;
904                         struct berval aliased, paliased, naliased;
905
906                         if( 1 ) {
907 #ifdef NEW_LOGGING
908                                 LDAP_LOG( CONFIG, CRIT, 
909                                         "%s: line %d: suffixAlias is no longer supported.\n",
910                                         fname, lineno, 0 );
911 #else
912                                 Debug( LDAP_DEBUG_ANY,
913                                         "%s: line %d: suffixAlias is no longer supported.\n",
914                                         fname, lineno, 0 );
915 #endif
916
917                                 return( 1 );
918                         }
919
920                         if ( cargc < 2 ) {
921 #ifdef NEW_LOGGING
922                                 LDAP_LOG( CONFIG, CRIT, 
923                                         "%s: line %d: missing alias and aliased_dn in "
924                                         "\"suffixAlias <alias> <aliased_dn>\" line.\n",
925                                         fname, lineno, 0 );
926 #else
927                                 Debug( LDAP_DEBUG_ANY,
928                                         "%s: line %d: missing alias and aliased_dn in "
929                                         "\"suffixAlias <alias> <aliased_dn>\" line.\n",
930                                         fname, lineno, 0 );
931 #endif
932
933                                 return( 1 );
934                         } else if ( cargc < 3 ) {
935 #ifdef NEW_LOGGING
936                                 LDAP_LOG( CONFIG, CRIT, 
937                                         "%s: line %d: missing aliased_dn in "
938                                         "\"suffixAlias <alias> <aliased_dn>\" line\n",
939                                         fname, lineno, 0 );
940 #else
941                                 Debug( LDAP_DEBUG_ANY,
942                                         "%s: line %d: missing aliased_dn in "
943                                         "\"suffixAlias <alias> <aliased_dn>\" line\n",
944                                         fname, lineno, 0 );
945 #endif
946                                 return( 1 );
947
948                         } else if ( cargc > 3 ) {
949 #ifdef NEW_LOGGING
950                                 LDAP_LOG( CONFIG, CRIT, 
951                                         "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
952                                         fname, lineno, 0 );
953 #else
954                                 Debug( LDAP_DEBUG_ANY,
955                                         "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
956                                         fname, lineno, 0 );
957 #endif
958                         }
959
960                         if ( be == NULL ) {
961 #ifdef NEW_LOGGING
962                                 LDAP_LOG( CONFIG, INFO, 
963                                         "%s: line %d: suffix line must appear inside a database "
964                                         "definition.\n", fname, lineno, 0 );
965 #else
966                                 Debug( LDAP_DEBUG_ANY,
967                                         "%s: line %d: suffixAlias line"
968                                         " must appear inside a database definition.\n",
969                                         fname, lineno, 0 );
970 #endif
971                                 return 1;
972                         }
973
974                         if ( load_ucdata( NULL ) < 0 ) return 1;
975                         
976                         alias.bv_val = cargv[1];
977                         alias.bv_len = strlen( cargv[1] );
978
979                         rc = dnPrettyNormal( NULL, &alias, &palias, &nalias );
980                         if( rc != LDAP_SUCCESS ) {
981 #ifdef NEW_LOGGING
982                                 LDAP_LOG( CONFIG, CRIT, 
983                                         "%s: line %d: alias DN is invalid.\n", fname, lineno, 0 );
984 #else
985                                 Debug( LDAP_DEBUG_ANY,
986                                         "%s: line %d: alias DN is invalid\n",
987                                    fname, lineno, 0 );
988 #endif
989                                 return( 1 );
990                         }
991
992                         tmp_be = select_backend( &nalias, 0, 0 );
993                         free( nalias.bv_val );
994                         if ( tmp_be && tmp_be != be ) {
995 #ifdef NEW_LOGGING
996                                 LDAP_LOG( CONFIG, INFO, 
997                                         "%s: line %d: suffixAlias served by a preceeding "
998                                         "backend \"%s\"\n", fname, lineno, 
999                                         tmp_be->be_suffix[0].bv_val );
1000 #else
1001                                 Debug( LDAP_DEBUG_ANY,
1002                                         "%s: line %d: suffixAlias served by"
1003                                         "  a preceeding backend \"%s\"\n",
1004                                         fname, lineno, tmp_be->be_suffix[0].bv_val );
1005 #endif
1006                                 free( palias.bv_val );
1007                                 return -1;
1008                         }
1009
1010                         aliased.bv_val = cargv[2];
1011                         aliased.bv_len = strlen( cargv[2] );
1012
1013                         rc = dnPrettyNormal( NULL, &aliased, &paliased, &naliased );
1014                         if( rc != LDAP_SUCCESS ) {
1015 #ifdef NEW_LOGGING
1016                                 LDAP_LOG( CONFIG, CRIT, 
1017                                         "%s: line %d: aliased DN is invalid.\n", fname, lineno,0 );
1018 #else
1019                                 Debug( LDAP_DEBUG_ANY,
1020                                         "%s: line %d: aliased DN is invalid\n",
1021                                    fname, lineno, 0 );
1022 #endif
1023                                 free( palias.bv_val );
1024                                 return( 1 );
1025                         }
1026
1027                         tmp_be = select_backend( &naliased, 0, 0 );
1028                         free( naliased.bv_val );
1029                         if ( tmp_be && tmp_be != be ) {
1030 #ifdef NEW_LOGGING
1031                                 LDAP_LOG( CONFIG, INFO, 
1032                                         "%s: line %d: suffixAlias derefs to a different backend "
1033                                         "a preceeding backend \"%s\"\n",
1034                                         fname, lineno, tmp_be->be_suffix[0].bv_val );
1035 #else
1036                                 Debug( LDAP_DEBUG_ANY,
1037                                         "%s: line %d: suffixAlias derefs to differnet backend"
1038                                         "  a preceeding backend \"%s\"\n",
1039                                         fname, lineno, tmp_be->be_suffix[0].bv_val );
1040 #endif
1041                                 free( palias.bv_val );
1042                                 free( paliased.bv_val );
1043                                 return -1;
1044                         }
1045
1046                         ber_bvarray_add( &be->be_suffixAlias, &palias ); 
1047                         ber_bvarray_add( &be->be_suffixAlias, &paliased );
1048
1049                /* set max deref depth */
1050                } else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
1051                                         int i;
1052                        if ( cargc < 2 ) {
1053 #ifdef NEW_LOGGING
1054                                LDAP_LOG( CONFIG, CRIT, 
1055                                           "%s: line %d: missing depth in \"maxDerefDepth <depth>\""
1056                                           " line\n", fname, lineno, 0 );
1057 #else
1058                                Debug( LDAP_DEBUG_ANY,
1059                    "%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
1060                                    fname, lineno, 0 );
1061 #endif
1062
1063                                return( 1 );
1064                        }
1065                        if ( be == NULL ) {
1066 #ifdef NEW_LOGGING
1067                                LDAP_LOG( CONFIG, INFO, 
1068                                           "%s: line %d: depth line must appear inside a database "
1069                                           "definition.\n", fname, lineno ,0 );
1070 #else
1071                                Debug( LDAP_DEBUG_ANY,
1072 "%s: line %d: depth line must appear inside a database definition.\n",
1073                                    fname, lineno, 0 );
1074 #endif
1075                                                         return 1;
1076
1077                        } else if ((i = atoi(cargv[1])) < 0) {
1078 #ifdef NEW_LOGGING
1079                                LDAP_LOG( CONFIG, INFO, 
1080                                           "%s: line %d: depth must be positive.\n",
1081                                           fname, lineno ,0 );
1082 #else
1083                                Debug( LDAP_DEBUG_ANY,
1084 "%s: line %d: depth must be positive.\n",
1085                                    fname, lineno, 0 );
1086 #endif
1087                                                         return 1;
1088
1089
1090                        } else {
1091                            be->be_max_deref_depth = i;
1092                                            }
1093
1094
1095                 /* set magic "root" dn for this database */
1096                 } else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
1097                         if ( cargc < 2 ) {
1098 #ifdef NEW_LOGGING
1099                                 LDAP_LOG( CONFIG, INFO, 
1100                                            "%s: line %d: missing dn in \"rootdn <dn>\" line.\n",
1101                                            fname, lineno ,0 );
1102 #else
1103                                 Debug( LDAP_DEBUG_ANY,
1104                     "%s: line %d: missing dn in \"rootdn <dn>\" line\n",
1105                                     fname, lineno, 0 );
1106 #endif
1107
1108                                 return( 1 );
1109                         }
1110
1111                         if ( be == NULL ) {
1112 #ifdef NEW_LOGGING
1113                                 LDAP_LOG( CONFIG, INFO, 
1114                                            "%s: line %d: rootdn line must appear inside a database "
1115                                            "definition.\n", fname, lineno ,0 );
1116 #else
1117                                 Debug( LDAP_DEBUG_ANY,
1118 "%s: line %d: rootdn line must appear inside a database definition.\n",
1119                                     fname, lineno, 0 );
1120 #endif
1121                                 return 1;
1122
1123                         } else {
1124                                 struct berval dn;
1125                                 
1126                                 if ( load_ucdata( NULL ) < 0 ) return 1;
1127
1128                                 dn.bv_val = cargv[1];
1129                                 dn.bv_len = strlen( cargv[1] );
1130
1131                                 rc = dnPrettyNormal( NULL, &dn,
1132                                         &be->be_rootdn,
1133                                         &be->be_rootndn );
1134
1135                                 if( rc != LDAP_SUCCESS ) {
1136 #ifdef NEW_LOGGING
1137                                         LDAP_LOG( CONFIG, CRIT, 
1138                                                 "%s: line %d: rootdn DN is invalid.\n", 
1139                                                 fname, lineno ,0 );
1140 #else
1141                                         Debug( LDAP_DEBUG_ANY,
1142                                                 "%s: line %d: rootdn DN is invalid\n",
1143                                            fname, lineno, 0 );
1144 #endif
1145                                         return( 1 );
1146                                 }
1147                         }
1148
1149                 /* set super-secret magic database password */
1150                 } else if ( strcasecmp( cargv[0], "rootpw" ) == 0 ) {
1151                         if ( cargc < 2 ) {
1152 #ifdef NEW_LOGGING
1153                                 LDAP_LOG( CONFIG, CRIT, 
1154                                         "%s: line %d: missing passwd in \"rootpw <passwd>\""
1155                                         " line\n", fname, lineno ,0 );
1156 #else
1157                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1158                                         "missing passwd in \"rootpw <passwd>\" line\n",
1159                                     fname, lineno, 0 );
1160 #endif
1161
1162                                 return( 1 );
1163                         }
1164
1165                         if ( be == NULL ) {
1166 #ifdef NEW_LOGGING
1167                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
1168                                         "rootpw line must appear inside a database "
1169                                         "definition.\n", fname, lineno ,0 );
1170 #else
1171                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1172                                         "rootpw line must appear inside a database "
1173                                         "definition.\n",
1174                                     fname, lineno, 0 );
1175 #endif
1176                                 return 1;
1177
1178                         } else {
1179                                 Backend *tmp_be = select_backend( &be->be_rootndn, 0, 0 );
1180
1181                                 if( tmp_be != be ) {
1182 #ifdef NEW_LOGGING
1183                                         LDAP_LOG( CONFIG, INFO,
1184                                                 "%s: line %d: "
1185                                                 "rootpw can only be set when rootdn is under suffix\n",
1186                                                 fname, lineno, "" );
1187 #else
1188                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1189                                                 "rootpw can only be set when rootdn is under suffix\n",
1190                                         fname, lineno, 0 );
1191 #endif
1192                                         return 1;
1193                                 }
1194
1195                                 be->be_rootpw.bv_val = ch_strdup( cargv[1] );
1196                                 be->be_rootpw.bv_len = strlen( be->be_rootpw.bv_val );
1197                         }
1198
1199                 /* make this database read-only */
1200                 } else if ( strcasecmp( cargv[0], "readonly" ) == 0 ) {
1201                         if ( cargc < 2 ) {
1202 #ifdef NEW_LOGGING
1203                                 LDAP_LOG( CONFIG, CRIT, 
1204                                         "%s: line %d: missing on|off in \"readonly <on|off>\" "
1205                                         "line.\n", fname, lineno ,0 );
1206 #else
1207                                 Debug( LDAP_DEBUG_ANY,
1208             "%s: line %d: missing on|off in \"readonly <on|off>\" line\n",
1209                                     fname, lineno, 0 );
1210 #endif
1211
1212                                 return( 1 );
1213                         }
1214                         if ( be == NULL ) {
1215                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1216                                         global_restrictops |= SLAP_RESTRICT_OP_WRITES;
1217                                 } else {
1218                                         global_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
1219                                 }
1220                         } else {
1221                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1222                                         be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
1223                                 } else {
1224                                         be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
1225                                 }
1226                         }
1227
1228
1229                 /* allow these features */
1230                 } else if ( strcasecmp( cargv[0], "allows" ) == 0 ||
1231                         strcasecmp( cargv[0], "allow" ) == 0 )
1232                 {
1233                         slap_mask_t     allows;
1234
1235                         if ( be != NULL ) {
1236 #ifdef NEW_LOGGING
1237                                 LDAP_LOG( CONFIG, INFO, 
1238                                            "%s: line %d: allow line must appear prior to "
1239                                            "database definitions.\n", fname, lineno ,0 );
1240 #else
1241                                 Debug( LDAP_DEBUG_ANY,
1242 "%s: line %d: allow line must appear prior to database definitions\n",
1243                                     fname, lineno, 0 );
1244 #endif
1245
1246                         }
1247
1248                         if ( cargc < 2 ) {
1249 #ifdef NEW_LOGGING
1250                                 LDAP_LOG( CONFIG, CRIT, 
1251                                            "%s: line %d: missing feature(s) in \"allow <features>\""
1252                                            " line\n", fname, lineno ,0 );
1253 #else
1254                                 Debug( LDAP_DEBUG_ANY,
1255             "%s: line %d: missing feature(s) in \"allow <features>\" line\n",
1256                                     fname, lineno, 0 );
1257 #endif
1258
1259                                 return( 1 );
1260                         }
1261
1262                         allows = 0;
1263
1264                         for( i=1; i < cargc; i++ ) {
1265                                 if( strcasecmp( cargv[i], "bind_v2" ) == 0 ) {
1266                                         allows |= SLAP_ALLOW_BIND_V2;
1267
1268                                 } else if( strcasecmp( cargv[i], "bind_anon_cred" ) == 0 ) {
1269                                         allows |= SLAP_ALLOW_BIND_ANON_CRED;
1270
1271                                 } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) {
1272                                         allows |= SLAP_ALLOW_BIND_ANON_DN;
1273
1274                                 } else if( strcasecmp( cargv[i], "update_anon" ) == 0 ) {
1275                                         allows |= SLAP_ALLOW_UPDATE_ANON;
1276
1277                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1278 #ifdef NEW_LOGGING
1279                                         LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1280                                                 "unknown feature %s in \"allow <features>\" line.\n",
1281                                                 fname, lineno, cargv[1] );
1282 #else
1283                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1284                                                 "unknown feature %s in \"allow <features>\" line\n",
1285                                                 fname, lineno, cargv[i] );
1286 #endif
1287
1288                                         return( 1 );
1289                                 }
1290                         }
1291
1292                         global_allows = allows;
1293
1294                 /* disallow these features */
1295                 } else if ( strcasecmp( cargv[0], "disallows" ) == 0 ||
1296                         strcasecmp( cargv[0], "disallow" ) == 0 )
1297                 {
1298                         slap_mask_t     disallows;
1299
1300                         if ( be != NULL ) {
1301 #ifdef NEW_LOGGING
1302                                 LDAP_LOG( CONFIG, INFO, 
1303                                            "%s: line %d: disallow line must appear prior to "
1304                                            "database definitions.\n", fname, lineno ,0 );
1305 #else
1306                                 Debug( LDAP_DEBUG_ANY,
1307 "%s: line %d: disallow line must appear prior to database definitions\n",
1308                                     fname, lineno, 0 );
1309 #endif
1310
1311                         }
1312
1313                         if ( cargc < 2 ) {
1314 #ifdef NEW_LOGGING
1315                                 LDAP_LOG( CONFIG, CRIT, 
1316                                         "%s: line %d: missing feature(s) in \"disallow <features>\""
1317                                         " line.\n", fname, lineno ,0 );
1318 #else
1319                                 Debug( LDAP_DEBUG_ANY,
1320             "%s: line %d: missing feature(s) in \"disallow <features>\" line\n",
1321                                     fname, lineno, 0 );
1322 #endif
1323
1324                                 return( 1 );
1325                         }
1326
1327                         disallows = 0;
1328
1329                         for( i=1; i < cargc; i++ ) {
1330                                 if( strcasecmp( cargv[i], "bind_anon" ) == 0 ) {
1331                                         disallows |= SLAP_DISALLOW_BIND_ANON;
1332
1333                                 } else if( strcasecmp( cargv[i], "bind_simple" ) == 0 ) {
1334                                         disallows |= SLAP_DISALLOW_BIND_SIMPLE;
1335
1336                                 } else if( strcasecmp( cargv[i], "bind_krbv4" ) == 0 ) {
1337                                         disallows |= SLAP_DISALLOW_BIND_KRBV4;
1338
1339                                 } else if( strcasecmp( cargv[i], "tls_2_anon" ) == 0 ) {
1340                                         disallows |= SLAP_DISALLOW_TLS_2_ANON;
1341
1342                                 } else if( strcasecmp( cargv[i], "tls_authc" ) == 0 ) {
1343                                         disallows |= SLAP_DISALLOW_TLS_AUTHC;
1344
1345                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1346 #ifdef NEW_LOGGING
1347                                         LDAP_LOG( CONFIG, CRIT, 
1348                                                 "%s: line %d: unknown feature %s in "
1349                                                 "\"disallow <features>\" line.\n",
1350                                                 fname, lineno, cargv[i] );
1351 #else
1352                                         Debug( LDAP_DEBUG_ANY,
1353                     "%s: line %d: unknown feature %s in \"disallow <features>\" line\n",
1354                                             fname, lineno, cargv[i] );
1355 #endif
1356
1357                                         return( 1 );
1358                                 }
1359                         }
1360
1361                         global_disallows = disallows;
1362
1363                 /* require these features */
1364                 } else if ( strcasecmp( cargv[0], "requires" ) == 0 ||
1365                         strcasecmp( cargv[0], "require" ) == 0 )
1366                 {
1367                         slap_mask_t     requires;
1368
1369                         if ( cargc < 2 ) {
1370 #ifdef NEW_LOGGING
1371                                 LDAP_LOG( CONFIG, CRIT, 
1372                                            "%s: line %d: missing feature(s) in "
1373                                            "\"require <features>\" line.\n", fname, lineno ,0 );
1374 #else
1375                                 Debug( LDAP_DEBUG_ANY,
1376             "%s: line %d: missing feature(s) in \"require <features>\" line\n",
1377                                     fname, lineno, 0 );
1378 #endif
1379
1380                                 return( 1 );
1381                         }
1382
1383                         requires = 0;
1384
1385                         for( i=1; i < cargc; i++ ) {
1386                                 if( strcasecmp( cargv[i], "bind" ) == 0 ) {
1387                                         requires |= SLAP_REQUIRE_BIND;
1388
1389                                 } else if( strcasecmp( cargv[i], "LDAPv3" ) == 0 ) {
1390                                         requires |= SLAP_REQUIRE_LDAP_V3;
1391
1392                                 } else if( strcasecmp( cargv[i], "authc" ) == 0 ) {
1393                                         requires |= SLAP_REQUIRE_AUTHC;
1394
1395                                 } else if( strcasecmp( cargv[i], "SASL" ) == 0 ) {
1396                                         requires |= SLAP_REQUIRE_SASL;
1397
1398                                 } else if( strcasecmp( cargv[i], "strong" ) == 0 ) {
1399                                         requires |= SLAP_REQUIRE_STRONG;
1400
1401                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1402 #ifdef NEW_LOGGING
1403                                         LDAP_LOG( CONFIG, CRIT, 
1404                                                    "%s: line %d: unknown feature %s in "
1405                                                    "\"require <features>\" line.\n", 
1406                                                    fname, lineno , cargv[i] );
1407 #else
1408                                         Debug( LDAP_DEBUG_ANY,
1409                     "%s: line %d: unknown feature %s in \"require <features>\" line\n",
1410                                             fname, lineno, cargv[i] );
1411 #endif
1412
1413                                         return( 1 );
1414                                 }
1415                         }
1416
1417                         if ( be == NULL ) {
1418                                 global_requires = requires;
1419                         } else {
1420                                 be->be_requires = requires;
1421                         }
1422
1423                 /* required security factors */
1424                 } else if ( strcasecmp( cargv[0], "security" ) == 0 ) {
1425                         slap_ssf_set_t *set;
1426
1427                         if ( cargc < 2 ) {
1428 #ifdef NEW_LOGGING
1429                                 LDAP_LOG( CONFIG, CRIT, 
1430                                         "%s: line %d: missing factor(s) in \"security <factors>\""
1431                                         " line.\n", fname, lineno ,0 );
1432 #else
1433                                 Debug( LDAP_DEBUG_ANY,
1434             "%s: line %d: missing factor(s) in \"security <factors>\" line\n",
1435                                     fname, lineno, 0 );
1436 #endif
1437
1438                                 return( 1 );
1439                         }
1440
1441                         if ( be == NULL ) {
1442                                 set = &global_ssf_set;
1443                         } else {
1444                                 set = &be->be_ssf_set;
1445                         }
1446
1447                         for( i=1; i < cargc; i++ ) {
1448                                 if( strncasecmp( cargv[i], "ssf=",
1449                                         sizeof("ssf") ) == 0 )
1450                                 {
1451                                         set->sss_ssf =
1452                                                 atoi( &cargv[i][sizeof("ssf")] );
1453
1454                                 } else if( strncasecmp( cargv[i], "transport=",
1455                                         sizeof("transport") ) == 0 )
1456                                 {
1457                                         set->sss_transport =
1458                                                 atoi( &cargv[i][sizeof("transport")] );
1459
1460                                 } else if( strncasecmp( cargv[i], "tls=",
1461                                         sizeof("tls") ) == 0 )
1462                                 {
1463                                         set->sss_tls =
1464                                                 atoi( &cargv[i][sizeof("tls")] );
1465
1466                                 } else if( strncasecmp( cargv[i], "sasl=",
1467                                         sizeof("sasl") ) == 0 )
1468                                 {
1469                                         set->sss_sasl =
1470                                                 atoi( &cargv[i][sizeof("sasl")] );
1471
1472                                 } else if( strncasecmp( cargv[i], "update_ssf=",
1473                                         sizeof("update_ssf") ) == 0 )
1474                                 {
1475                                         set->sss_update_ssf =
1476                                                 atoi( &cargv[i][sizeof("update_ssf")] );
1477
1478                                 } else if( strncasecmp( cargv[i], "update_transport=",
1479                                         sizeof("update_transport") ) == 0 )
1480                                 {
1481                                         set->sss_update_transport =
1482                                                 atoi( &cargv[i][sizeof("update_transport")] );
1483
1484                                 } else if( strncasecmp( cargv[i], "update_tls=",
1485                                         sizeof("update_tls") ) == 0 )
1486                                 {
1487                                         set->sss_update_tls =
1488                                                 atoi( &cargv[i][sizeof("update_tls")] );
1489
1490                                 } else if( strncasecmp( cargv[i], "update_sasl=",
1491                                         sizeof("update_sasl") ) == 0 )
1492                                 {
1493                                         set->sss_update_sasl =
1494                                                 atoi( &cargv[i][sizeof("update_sasl")] );
1495
1496                                 } else if( strncasecmp( cargv[i], "simple_bind=",
1497                                         sizeof("simple_bind") ) == 0 )
1498                                 {
1499                                         set->sss_simple_bind =
1500                                                 atoi( &cargv[i][sizeof("simple_bind")] );
1501
1502                                 } else {
1503 #ifdef NEW_LOGGING
1504                                         LDAP_LOG( CONFIG, CRIT, 
1505                                                    "%s: line %d: unknown factor %S in "
1506                                                    "\"security <factors>\" line.\n",
1507                                                    fname, lineno, cargv[1] );
1508 #else
1509                                         Debug( LDAP_DEBUG_ANY,
1510                     "%s: line %d: unknown factor %s in \"security <factors>\" line\n",
1511                                             fname, lineno, cargv[i] );
1512 #endif
1513
1514                                         return( 1 );
1515                                 }
1516                         }
1517                 /* where to send clients when we don't hold it */
1518                 } else if ( strcasecmp( cargv[0], "referral" ) == 0 ) {
1519                         if ( cargc < 2 ) {
1520 #ifdef NEW_LOGGING
1521                                 LDAP_LOG( CONFIG, CRIT, 
1522                                         "%s: line %d: missing URL in \"referral <URL>\""
1523                                         " line.\n", fname, lineno , 0 );
1524 #else
1525                                 Debug( LDAP_DEBUG_ANY,
1526                     "%s: line %d: missing URL in \"referral <URL>\" line\n",
1527                                     fname, lineno, 0 );
1528 #endif
1529
1530                                 return( 1 );
1531                         }
1532
1533                         if( validate_global_referral( cargv[1] ) ) {
1534 #ifdef NEW_LOGGING
1535                                 LDAP_LOG( CONFIG, CRIT, 
1536                                         "%s: line %d: invalid URL (%s) in \"referral\" line.\n",
1537                                         fname, lineno, cargv[1]  );
1538 #else
1539                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1540                                         "invalid URL (%s) in \"referral\" line.\n",
1541                                     fname, lineno, cargv[1] );
1542 #endif
1543                                 return 1;
1544                         }
1545
1546                         vals[0].bv_val = cargv[1];
1547                         vals[0].bv_len = strlen( vals[0].bv_val );
1548                         value_add( &default_referral, vals );
1549
1550 #ifdef NEW_LOGGING
1551                 } else if ( strcasecmp( cargv[0], "logfile" ) == 0 ) {
1552                         FILE *logfile;
1553                         if ( cargc < 2 ) {
1554 #ifdef NEW_LOGGING
1555                                 LDAP_LOG( CONFIG, CRIT, 
1556                                         "%s: line %d: Error in logfile directive, "
1557                                         "\"logfile <filename>\"\n", fname, lineno , 0 );
1558 #else
1559                                 Debug( LDAP_DEBUG_ANY,
1560                                        "%s: line %d: Error in logfile directive, \"logfile filename\"\n",
1561                                        fname, lineno, 0 );
1562 #endif
1563
1564                                 return( 1 );
1565                         }
1566                         logfile = fopen( cargv[1], "w" );
1567                         if ( logfile != NULL ) lutil_debug_file( logfile  );
1568
1569 #endif
1570                 /* start of a new database definition */
1571                 } else if ( strcasecmp( cargv[0], "debug" ) == 0 ) {
1572                         int level;
1573                         if ( cargc < 3 ) {
1574 #ifdef NEW_LOGGING
1575                                 LDAP_LOG( CONFIG, CRIT, 
1576                                            "%s: line %d: Error in debug directive, "
1577                                            "\"debug <subsys> <level>\"\n", fname, lineno , 0 );
1578 #else
1579                                 Debug( LDAP_DEBUG_ANY,
1580                                         "%s: line %d: Error in debug directive, \"debug subsys level\"\n",
1581                                         fname, lineno, 0 );
1582 #endif
1583
1584                                 return( 1 );
1585                         }
1586                         level = atoi( cargv[2] );
1587                         if ( level <= 0 ) level = lutil_mnem2level( cargv[2] );
1588                         lutil_set_debug_level( cargv[1], level );
1589                 /* specify an Object Identifier macro */
1590                 } else if ( strcasecmp( cargv[0], "objectidentifier" ) == 0 ) {
1591                         rc = parse_oidm( fname, lineno, cargc, cargv );
1592                         if( rc ) return rc;
1593
1594                 /* specify an objectclass */
1595                 } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
1596                         if ( *cargv[1] == '('  /*')'*/) {
1597                                 char * p;
1598                                 p = strchr(saveline,'(' /*')'*/);
1599                                 rc = parse_oc( fname, lineno, p, cargv );
1600                                 if( rc ) return rc;
1601
1602                         } else {
1603 #ifdef NEW_LOGGING
1604                                 LDAP_LOG( CONFIG, INFO, 
1605                                         "%s: line %d: old objectclass format not supported\n",
1606                                         fname, lineno , 0 );
1607 #else
1608                                 Debug( LDAP_DEBUG_ANY,
1609                                        "%s: line %d: old objectclass format not supported.\n",
1610                                        fname, lineno, 0 );
1611 #endif
1612                         }
1613
1614 #ifdef SLAP_EXTENDED_SCHEMA
1615                 } else if ( strcasecmp( cargv[0], "ditcontentrule" ) == 0 ) {
1616                         char * p;
1617                         p = strchr(saveline,'(' /*')'*/);
1618                         rc = parse_cr( fname, lineno, p, cargv );
1619                         if( rc ) return rc;
1620 #endif
1621
1622                 /* specify an attribute type */
1623                 } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
1624                         || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
1625                 {
1626                         if ( *cargv[1] == '(' /*')'*/) {
1627                                 char * p;
1628                                 p = strchr(saveline,'(' /*')'*/);
1629                                 rc = parse_at( fname, lineno, p, cargv );
1630                                 if( rc ) return rc;
1631
1632                         } else {
1633 #ifdef NEW_LOGGING
1634                                 LDAP_LOG( CONFIG, INFO, 
1635                                         "%s: line %d: old attribute type format not supported.\n",
1636                                         fname, lineno , 0 );
1637 #else
1638                                 Debug( LDAP_DEBUG_ANY,
1639     "%s: line %d: old attribute type format not supported.\n",
1640                                     fname, lineno, 0 );
1641 #endif
1642
1643                         }
1644
1645                 /* turn on/off schema checking */
1646                 } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
1647                         if ( cargc < 2 ) {
1648 #ifdef NEW_LOGGING
1649                                 LDAP_LOG( CONFIG, CRIT, 
1650                                         "%s: line %d: missing on|off in \"schemacheck <on|off>\""
1651                                         " line.\n", fname, lineno , 0 );
1652 #else
1653                                 Debug( LDAP_DEBUG_ANY,
1654     "%s: line %d: missing on|off in \"schemacheck <on|off>\" line\n",
1655                                     fname, lineno, 0 );
1656 #endif
1657
1658                                 return( 1 );
1659                         }
1660                         if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1661 #ifdef NEW_LOGGING
1662                                 LDAP_LOG( CONFIG, CRIT, 
1663                                         "%s: line %d: schema checking disabled! your mileage may "
1664                                         "vary!\n", fname, lineno , 0 );
1665 #else
1666                                 Debug( LDAP_DEBUG_ANY,
1667                                         "%s: line %d: schema checking disabled! your mileage may vary!\n",
1668                                     fname, lineno, 0 );
1669 #endif
1670                                 global_schemacheck = 0;
1671                         } else {
1672                                 global_schemacheck = 1;
1673                         }
1674
1675                 /* specify access control info */
1676                 } else if ( strcasecmp( cargv[0], "access" ) == 0 ) {
1677                         parse_acl( be, fname, lineno, cargc, cargv );
1678
1679                 /* debug level to log things to syslog */
1680                 } else if ( strcasecmp( cargv[0], "loglevel" ) == 0 ) {
1681                         if ( cargc < 2 ) {
1682 #ifdef NEW_LOGGING
1683                                 LDAP_LOG( CONFIG, CRIT, 
1684                                         "%s: line %d: missing level in \"loglevel <level>\""
1685                                         " line.\n", fname, lineno , 0 );
1686 #else
1687                                 Debug( LDAP_DEBUG_ANY,
1688                     "%s: line %d: missing level in \"loglevel <level>\" line\n",
1689                                     fname, lineno, 0 );
1690 #endif
1691
1692                                 return( 1 );
1693                         }
1694
1695                         ldap_syslog = 0;
1696
1697                         for( i=1; i < cargc; i++ ) {
1698                                 ldap_syslog += atoi( cargv[1] );
1699                         }
1700
1701                 /* list of replicas of the data in this backend (master only) */
1702                 } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
1703                         if ( cargc < 2 ) {
1704 #ifdef NEW_LOGGING
1705                                 LDAP_LOG( CONFIG, CRIT, 
1706                                         "%s: line %d: missing host in \"replica "
1707                                         " <host[:port]\" line\n", fname, lineno , 0 );
1708 #else
1709                                 Debug( LDAP_DEBUG_ANY,
1710             "%s: line %d: missing host in \"replica <host[:port]>\" line\n",
1711                                     fname, lineno, 0 );
1712 #endif
1713
1714                                 return( 1 );
1715                         }
1716                         if ( be == NULL ) {
1717 #ifdef NEW_LOGGING
1718                                 LDAP_LOG( CONFIG, INFO, 
1719                                             "%s: line %d: replica line must appear inside "
1720                                             "a database definition.\n", fname, lineno, 0);
1721 #else
1722                                 Debug( LDAP_DEBUG_ANY,
1723 "%s: line %d: replica line must appear inside a database definition\n",
1724                                     fname, lineno, 0 );
1725 #endif
1726                                 return 1;
1727
1728                         } else {
1729                                 int nr = -1;
1730
1731                                 for ( i = 1; i < cargc; i++ ) {
1732                                         if ( strncasecmp( cargv[i], "host=", 5 )
1733                                             == 0 ) {
1734                                                 nr = add_replica_info( be, 
1735                                                         cargv[i] + 5 );
1736                                                 break;
1737                                         }
1738                                 }
1739                                 if ( i == cargc ) {
1740 #ifdef NEW_LOGGING
1741                                         LDAP_LOG( CONFIG, INFO, 
1742                                                 "%s: line %d: missing host in \"replica\" line\n", 
1743                                                 fname, lineno , 0 );
1744 #else
1745                                         Debug( LDAP_DEBUG_ANY,
1746                     "%s: line %d: missing host in \"replica\" line\n",
1747                                             fname, lineno, 0 );
1748 #endif
1749                                         return 1;
1750
1751                                 } else if ( nr == -1 ) {
1752 #ifdef NEW_LOGGING
1753                                         LDAP_LOG( CONFIG, INFO, 
1754                                                    "%s: line %d: unable to add"
1755                                                    " replica \"%s\"\n",
1756                                                    fname, lineno, 
1757                                                    cargv[i] + 5 );
1758 #else
1759                                         Debug( LDAP_DEBUG_ANY,
1760                 "%s: line %d: unable to add replica \"%s\"\n",
1761                                                 fname, lineno, cargv[i] + 5 );
1762 #endif
1763                                         return 1;
1764                                 } else {
1765                                         for ( i = 1; i < cargc; i++ ) {
1766                                                 if ( strncasecmp( cargv[i], "suffix=", 7 ) == 0 ) {
1767
1768                                                         switch ( add_replica_suffix( be, nr, cargv[i] + 7 ) ) {
1769                                                         case 1:
1770 #ifdef NEW_LOGGING
1771                                                                 LDAP_LOG( CONFIG, INFO, 
1772                                                                         "%s: line %d: suffix \"%s\" in \"replica\""
1773                                                                         " line is not valid for backend(ignored)\n",
1774                                                                         fname, lineno, cargv[i] + 7 );
1775 #else
1776                                                                 Debug( LDAP_DEBUG_ANY,
1777                                                                                 "%s: line %d: suffix \"%s\" in \"replica\" line is not valid for backend (ignored)\n",
1778                                                                                 fname, lineno, cargv[i] + 7 );
1779 #endif
1780                                                                 break;
1781
1782                                                         case 2:
1783 #ifdef NEW_LOGGING
1784                                                                 LDAP_LOG( CONFIG, INFO, 
1785                                                                         "%s: line %d: unable to normalize suffix"
1786                                                                         " in \"replica\" line (ignored)\n",
1787                                                                         fname, lineno , 0 );
1788 #else
1789                                                                 Debug( LDAP_DEBUG_ANY,
1790                                                                                  "%s: line %d: unable to normalize suffix in \"replica\" line (ignored)\n",
1791                                                                                  fname, lineno, 0 );
1792 #endif
1793                                                                 break;
1794                                                         }
1795
1796                                                 } else if ( strncasecmp( cargv[i], "attr", 4 ) == 0 ) {
1797                                                         int exclude = 0;
1798                                                         char *arg = cargv[i] + 4;
1799
1800                                                         if ( arg[0] == '!' ) {
1801                                                                 arg++;
1802                                                                 exclude = 1;
1803                                                         }
1804
1805                                                         if ( arg[0] != '=' ) {
1806                                                                 continue;
1807                                                         }
1808
1809                                                         if ( add_replica_attrs( be, nr, arg + 1, exclude ) ) {
1810 #ifdef NEW_LOGGING
1811                                                                 LDAP_LOG( CONFIG, INFO, 
1812                                                                         "%s: line %d: attribute \"%s\" in "
1813                                                                         "\"replica\" line is unknown\n",
1814                                                                         fname, lineno, arg + 1 ); 
1815 #else
1816                                                                 Debug( LDAP_DEBUG_ANY,
1817                                                                                 "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
1818                                                                                 fname, lineno, arg + 1 );
1819 #endif
1820                                                                 return( 1 );
1821                                                         }
1822                                                 }
1823                                         }
1824                                 }
1825                         }
1826
1827                 /* dn of master entity allowed to write to replica */
1828                 } else if ( strcasecmp( cargv[0], "updatedn" ) == 0 ) {
1829                         if ( cargc < 2 ) {
1830 #ifdef NEW_LOGGING
1831                                 LDAP_LOG( CONFIG, CRIT, 
1832                                         "%s: line %d: missing dn in \"updatedn <dn>\""
1833                                         " line.\n", fname, lineno , 0 );
1834 #else
1835                                 Debug( LDAP_DEBUG_ANY,
1836                     "%s: line %d: missing dn in \"updatedn <dn>\" line\n",
1837                                     fname, lineno, 0 );
1838 #endif
1839
1840                                 return( 1 );
1841                         }
1842                         if ( be == NULL ) {
1843 #ifdef NEW_LOGGING
1844                                 LDAP_LOG( CONFIG, INFO, 
1845                                         "%s: line %d: updatedn line must appear inside "
1846                                         "a database definition\n", 
1847                                         fname, lineno , 0 );
1848 #else
1849                                 Debug( LDAP_DEBUG_ANY,
1850 "%s: line %d: updatedn line must appear inside a database definition\n",
1851                                     fname, lineno, 0 );
1852 #endif
1853                                 return 1;
1854
1855                         } else {
1856                                 struct berval dn;
1857
1858                                 if ( load_ucdata( NULL ) < 0 ) return 1;
1859
1860                                 dn.bv_val = cargv[1];
1861                                 dn.bv_len = strlen( cargv[1] );
1862
1863                                 rc = dnNormalize2( NULL, &dn, &be->be_update_ndn );
1864                                 if( rc != LDAP_SUCCESS ) {
1865 #ifdef NEW_LOGGING
1866                                         LDAP_LOG( CONFIG, CRIT, 
1867                                                 "%s: line %d: updatedn DN is invalid.\n",
1868                                                 fname, lineno , 0 );
1869 #else
1870                                         Debug( LDAP_DEBUG_ANY,
1871                                                 "%s: line %d: updatedn DN is invalid\n",
1872                                             fname, lineno, 0 );
1873 #endif
1874                                         return 1;
1875                                 }
1876                         }
1877
1878                 } else if ( strcasecmp( cargv[0], "updateref" ) == 0 ) {
1879                         if ( cargc < 2 ) {
1880 #ifdef NEW_LOGGING
1881                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1882                                         "missing url in \"updateref <ldapurl>\" line.\n",
1883                                         fname, lineno , 0 );
1884 #else
1885                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1886                                         "missing url in \"updateref <ldapurl>\" line\n",
1887                                     fname, lineno, 0 );
1888 #endif
1889
1890                                 return( 1 );
1891                         }
1892                         if ( be == NULL ) {
1893 #ifdef NEW_LOGGING
1894                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: updateref"
1895                                         " line must appear inside a database definition\n",
1896                                         fname, lineno , 0 );
1897 #else
1898                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: updateref"
1899                                         " line must appear inside a database definition\n",
1900                                         fname, lineno, 0 );
1901 #endif
1902                                 return 1;
1903
1904                         } else if ( !be->be_update_ndn.bv_len ) {
1905 #ifdef NEW_LOGGING
1906                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
1907                                         "updateref line must come after updatedn.\n",
1908                                         fname, lineno , 0 );
1909 #else
1910                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1911                                         "updateref line must after updatedn.\n",
1912                                     fname, lineno, 0 );
1913 #endif
1914                                 return 1;
1915                         }
1916
1917                         if( validate_global_referral( cargv[1] ) ) {
1918 #ifdef NEW_LOGGING
1919                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1920                                         "invalid URL (%s) in \"updateref\" line.\n",
1921                                         fname, lineno, cargv[1] );
1922 #else
1923                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1924                                         "invalid URL (%s) in \"updateref\" line.\n",
1925                                     fname, lineno, cargv[1] );
1926 #endif
1927                                 return 1;
1928                         }
1929
1930                         vals[0].bv_val = cargv[1];
1931                         vals[0].bv_len = strlen( vals[0].bv_val );
1932                         value_add( &be->be_update_refs, vals );
1933
1934                 /* replication log file to which changes are appended */
1935                 } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
1936                         if ( cargc < 2 ) {
1937 #ifdef NEW_LOGGING
1938                                 LDAP_LOG( CONFIG, CRIT, 
1939                                         "%s: line %d: missing filename in \"replogfile <filename>\""
1940                                         " line.\n", fname, lineno , 0 );
1941 #else
1942                                 Debug( LDAP_DEBUG_ANY,
1943             "%s: line %d: missing filename in \"replogfile <filename>\" line\n",
1944                                     fname, lineno, 0 );
1945 #endif
1946
1947                                 return( 1 );
1948                         }
1949                         if ( be ) {
1950                                 be->be_replogfile = ch_strdup( cargv[1] );
1951                         } else {
1952                                 replogfile = ch_strdup( cargv[1] );
1953                         }
1954
1955                 /* file from which to read additional rootdse attrs */
1956                 } else if ( strcasecmp( cargv[0], "rootDSE" ) == 0) {
1957                         if ( cargc < 2 ) {
1958 #ifdef NEW_LOGGING
1959                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1960                                         "missing filename in \"rootDSE <filename>\" line.\n",
1961                                         fname, lineno , 0 );
1962 #else
1963                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1964                                         "missing filename in \"rootDSE <filename>\" line.\n",
1965                                     fname, lineno, 0 );
1966 #endif
1967                                 return 1;
1968                         }
1969
1970                         if( read_root_dse_file( cargv[1] ) ) {
1971 #ifdef NEW_LOGGING
1972                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1973                                         "could not read \"rootDSE <filename>\" line.\n",
1974                                         fname, lineno , 0 );
1975 #else
1976                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1977                                         "could not read \"rootDSE <filename>\" line\n",
1978                                     fname, lineno, 0 );
1979 #endif
1980                                 return 1;
1981                         }
1982
1983                 /* maintain lastmodified{by,time} attributes */
1984                 } else if ( strcasecmp( cargv[0], "lastmod" ) == 0 ) {
1985                         if ( cargc < 2 ) {
1986 #ifdef NEW_LOGGING
1987                                 LDAP_LOG( CONFIG, CRIT, 
1988                                            "%s: line %d: missing on|off in \"lastmod <on|off>\""
1989                                            " line.\n", fname, lineno , 0 );
1990 #else
1991                                 Debug( LDAP_DEBUG_ANY,
1992             "%s: line %d: missing on|off in \"lastmod <on|off>\" line\n",
1993                                     fname, lineno, 0 );
1994 #endif
1995
1996                                 return( 1 );
1997                         }
1998                         if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1999                                 if ( be ) {
2000                                         be->be_flags &= ~SLAP_BFLAG_NOLASTMOD;
2001                                 } else {
2002                                         lastmod = 1;
2003                                 }
2004                         } else {
2005                                 if ( be ) {
2006                                         be->be_flags |= SLAP_BFLAG_NOLASTMOD;
2007                                 } else {
2008                                         lastmod = 0;
2009                                 }
2010                         }
2011
2012 #ifdef SIGHUP
2013                 /* turn on/off gentle SIGHUP handling */
2014                 } else if ( strcasecmp( cargv[0], "gentlehup" ) == 0 ) {
2015                         if ( cargc < 2 ) {
2016                                 Debug( LDAP_DEBUG_ANY,
2017     "%s: line %d: missing on|off in \"gentlehup <on|off>\" line\n",
2018                                     fname, lineno, 0 );
2019                                 return( 1 );
2020                         }
2021                         if ( strcasecmp( cargv[1], "off" ) == 0 ) {
2022                                 global_gentlehup = 0;
2023                         } else {
2024                                 global_gentlehup = 1;
2025                         }
2026 #endif
2027
2028                 /* set idle timeout value */
2029                 } else if ( strcasecmp( cargv[0], "idletimeout" ) == 0 ) {
2030                         int i;
2031                         if ( cargc < 2 ) {
2032 #ifdef NEW_LOGGING
2033                                 LDAP_LOG( CONFIG, CRIT, 
2034                                         "%s: line %d: missing timeout value in "
2035                                         "\"idletimeout <seconds>\" line.\n", fname, lineno , 0 );
2036 #else
2037                                 Debug( LDAP_DEBUG_ANY,
2038             "%s: line %d: missing timeout value in \"idletimeout <seconds>\" line\n",
2039                                     fname, lineno, 0 );
2040 #endif
2041
2042                                 return( 1 );
2043                         }
2044
2045                         i = atoi( cargv[1] );
2046
2047                         if( i < 0 ) {
2048 #ifdef NEW_LOGGING
2049                                 LDAP_LOG( CONFIG, CRIT, 
2050                                         "%s: line %d: timeout value (%d) invalid "
2051                                         "\"idletimeout <seconds>\" line.\n", fname, lineno, i );
2052 #else
2053                                 Debug( LDAP_DEBUG_ANY,
2054             "%s: line %d: timeout value (%d) invalid \"idletimeout <seconds>\" line\n",
2055                                     fname, lineno, i );
2056 #endif
2057
2058                                 return( 1 );
2059                         }
2060
2061                         global_idletimeout = i;
2062
2063                 /* include another config file */
2064                 } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
2065                         if ( cargc < 2 ) {
2066 #ifdef NEW_LOGGING
2067                                 LDAP_LOG( CONFIG, CRIT, 
2068                                         "%s: line %d: missing filename in \"include "
2069                                         "<filename>\" line.\n", fname, lineno , 0 );
2070 #else
2071                                 Debug( LDAP_DEBUG_ANY,
2072     "%s: line %d: missing filename in \"include <filename>\" line\n",
2073                                     fname, lineno, 0 );
2074 #endif
2075
2076                                 return( 1 );
2077                         }
2078                         savefname = ch_strdup( cargv[1] );
2079                         savelineno = lineno;
2080
2081                         if ( read_config( savefname, depth+1 ) != 0 ) {
2082                                 return( 1 );
2083                         }
2084
2085                         free( savefname );
2086                         lineno = savelineno - 1;
2087
2088                 /* location of kerberos srvtab file */
2089                 } else if ( strcasecmp( cargv[0], "srvtab" ) == 0 ) {
2090                         if ( cargc < 2 ) {
2091 #ifdef NEW_LOGGING
2092                                 LDAP_LOG( CONFIG, CRIT, 
2093                                         "%s: line %d: missing filename in \"srvtab "
2094                                         "<filename>\" line.\n", fname, lineno , 0 );
2095 #else
2096                                 Debug( LDAP_DEBUG_ANY,
2097             "%s: line %d: missing filename in \"srvtab <filename>\" line\n",
2098                                     fname, lineno, 0 );
2099 #endif
2100
2101                                 return( 1 );
2102                         }
2103                         ldap_srvtab = ch_strdup( cargv[1] );
2104
2105 #ifdef SLAPD_MODULES
2106                 } else if (strcasecmp( cargv[0], "moduleload") == 0 ) {
2107                    if ( cargc < 2 ) {
2108 #ifdef NEW_LOGGING
2109                            LDAP_LOG( CONFIG, INFO, 
2110                                    "%s: line %d: missing filename in \"moduleload "
2111                                    "<filename>\" line.\n", fname, lineno , 0 );
2112 #else
2113                       Debug( LDAP_DEBUG_ANY,
2114                              "%s: line %d: missing filename in \"moduleload <filename>\" line\n",
2115                              fname, lineno, 0 );
2116 #endif
2117
2118                       exit( EXIT_FAILURE );
2119                    }
2120                    if (module_load(cargv[1], cargc - 2, (cargc > 2) ? cargv + 2 : NULL)) {
2121 #ifdef NEW_LOGGING
2122                            LDAP_LOG( CONFIG, CRIT, 
2123                                    "%s: line %d: failed to load or initialize module %s\n",
2124                                    fname, lineno, cargv[1] );
2125 #else
2126                       Debug( LDAP_DEBUG_ANY,
2127                              "%s: line %d: failed to load or initialize module %s\n",
2128                              fname, lineno, cargv[1]);
2129 #endif
2130
2131                       exit( EXIT_FAILURE );
2132                    }
2133                 } else if (strcasecmp( cargv[0], "modulepath") == 0 ) {
2134                    if ( cargc != 2 ) {
2135 #ifdef NEW_LOGGING
2136                            LDAP_LOG( CONFIG, INFO, 
2137                                   "%s: line %d: missing path in \"modulepath <path>\""
2138                                   " line\n", fname, lineno , 0 );
2139 #else
2140                       Debug( LDAP_DEBUG_ANY,
2141                              "%s: line %d: missing path in \"modulepath <path>\" line\n",
2142                              fname, lineno, 0 );
2143 #endif
2144
2145                       exit( EXIT_FAILURE );
2146                    }
2147                    if (module_path( cargv[1] )) {
2148 #ifdef NEW_LOGGING
2149                            LDAP_LOG( CONFIG, CRIT, 
2150                                   "%s: line %d: failed to set module search path to %s.\n",
2151                                   fname, lineno, cargv[1] );
2152 #else
2153                            Debug( LDAP_DEBUG_ANY,
2154                                   "%s: line %d: failed to set module search path to %s\n",
2155                                   fname, lineno, cargv[1]);
2156 #endif
2157
2158                       exit( EXIT_FAILURE );
2159                    }
2160                    
2161 #endif /*SLAPD_MODULES*/
2162
2163 #ifdef HAVE_TLS
2164                 } else if ( !strcasecmp( cargv[0], "TLSRandFile" ) ) {
2165                         rc = ldap_pvt_tls_set_option( NULL,
2166                                                       LDAP_OPT_X_TLS_RANDOM_FILE,
2167                                                       cargv[1] );
2168                         if ( rc )
2169                                 return rc;
2170
2171                 } else if ( !strcasecmp( cargv[0], "TLSCipherSuite" ) ) {
2172                         rc = ldap_pvt_tls_set_option( NULL,
2173                                                       LDAP_OPT_X_TLS_CIPHER_SUITE,
2174                                                       cargv[1] );
2175                         if ( rc )
2176                                 return rc;
2177
2178                 } else if ( !strcasecmp( cargv[0], "TLSCertificateFile" ) ) {
2179                         rc = ldap_pvt_tls_set_option( NULL,
2180                                                       LDAP_OPT_X_TLS_CERTFILE,
2181                                                       cargv[1] );
2182                         if ( rc )
2183                                 return rc;
2184
2185                 } else if ( !strcasecmp( cargv[0], "TLSCertificateKeyFile" ) ) {
2186                         rc = ldap_pvt_tls_set_option( NULL,
2187                                                       LDAP_OPT_X_TLS_KEYFILE,
2188                                                       cargv[1] );
2189                         if ( rc )
2190                                 return rc;
2191
2192                 } else if ( !strcasecmp( cargv[0], "TLSCACertificatePath" ) ) {
2193                         rc = ldap_pvt_tls_set_option( NULL,
2194                                                       LDAP_OPT_X_TLS_CACERTDIR,
2195                                                       cargv[1] );
2196                         if ( rc )
2197                                 return rc;
2198
2199                 } else if ( !strcasecmp( cargv[0], "TLSCACertificateFile" ) ) {
2200                         rc = ldap_pvt_tls_set_option( NULL,
2201                                                       LDAP_OPT_X_TLS_CACERTFILE,
2202                                                       cargv[1] );
2203                         if ( rc )
2204                                 return rc;
2205                 } else if ( !strcasecmp( cargv[0], "TLSVerifyClient" ) ) {
2206                         if ( isdigit( (unsigned char) cargv[1][0] ) ) {
2207                                 i = atoi(cargv[1]);
2208                                 rc = ldap_pvt_tls_set_option( NULL,
2209                                                       LDAP_OPT_X_TLS_REQUIRE_CERT,
2210                                                       &i );
2211                         } else {
2212                                 rc = ldap_int_tls_config( NULL,
2213                                                       LDAP_OPT_X_TLS_REQUIRE_CERT,
2214                                                       cargv[1] );
2215                         }
2216
2217                         if ( rc )
2218                                 return rc;
2219
2220 #endif
2221
2222                 } else if ( !strcasecmp( cargv[0], "reverse-lookup" ) ) {
2223 #ifdef SLAPD_RLOOKUPS
2224                         if ( cargc < 2 ) {
2225 #ifdef NEW_LOGGING
2226                                 LDAP_LOG( CONFIG, INFO, 
2227                                         "%s: line %d: reverse-lookup: missing \"on\" or \"off\"\n",
2228                                         fname, lineno , 0 );
2229 #else
2230                                 Debug( LDAP_DEBUG_ANY,
2231 "%s: line %d: reverse-lookup: missing \"on\" or \"off\"\n",
2232                                         fname, lineno, 0 );
2233 #endif
2234                                 return( 1 );
2235                         }
2236
2237                         if ( !strcasecmp( cargv[1], "on" ) ) {
2238                                 use_reverse_lookup = 1;
2239                         } else if ( !strcasecmp( cargv[1], "off" ) ) {
2240                                 use_reverse_lookup = 0;
2241                         } else {
2242 #ifdef NEW_LOGGING
2243                                 LDAP_LOG( CONFIG, INFO, 
2244                                         "%s: line %d: reverse-lookup: "
2245                                         "must be \"on\" (default) or \"off\"\n", fname, lineno, 0 );
2246 #else
2247                                 Debug( LDAP_DEBUG_ANY,
2248 "%s: line %d: reverse-lookup: must be \"on\" (default) or \"off\"\n",
2249                                         fname, lineno, 0 );
2250 #endif
2251                                 return( 1 );
2252                         }
2253
2254 #else /* !SLAPD_RLOOKUPS */
2255 #ifdef NEW_LOGGING
2256                         LDAP_LOG( CONFIG, INFO, 
2257                                 "%s: line %d: reverse lookups "
2258                                 "are not configured (ignored).\n", fname, lineno , 0 );
2259 #else
2260                         Debug( LDAP_DEBUG_ANY,
2261 "%s: line %d: reverse lookups are not configured (ignored).\n",
2262                                 fname, lineno, 0 );
2263 #endif
2264 #endif /* !SLAPD_RLOOKUPS */
2265
2266                 /* pass anything else to the current backend info/db config routine */
2267                 } else {
2268                         if ( bi != NULL ) {
2269                                 if ( bi->bi_config == 0 ) {
2270 #ifdef NEW_LOGGING
2271                                         LDAP_LOG( CONFIG, INFO, 
2272                                                 "%s: line %d: unknown directive \"%s\" inside "
2273                                                 "backend info definition (ignored).\n",
2274                                                 fname, lineno, cargv[0] );
2275 #else
2276                                         Debug( LDAP_DEBUG_ANY,
2277 "%s: line %d: unknown directive \"%s\" inside backend info definition (ignored)\n",
2278                                                 fname, lineno, cargv[0] );
2279 #endif
2280
2281                                 } else {
2282                                         if ( (*bi->bi_config)( bi, fname, lineno, cargc, cargv )
2283                                                 != 0 )
2284                                         {
2285                                                 return( 1 );
2286                                         }
2287                                 }
2288                         } else if ( be != NULL ) {
2289                                 if ( be->be_config == 0 ) {
2290 #ifdef NEW_LOGGING
2291                                         LDAP_LOG( CONFIG, INFO, 
2292                                                 "%s: line %d: uknown directive \"%s\" inside "
2293                                                 "backend database definition (ignored).\n",
2294                                                 fname, lineno, cargv[0] );
2295 #else
2296                                         Debug( LDAP_DEBUG_ANY,
2297 "%s: line %d: unknown directive \"%s\" inside backend database definition (ignored)\n",
2298                                         fname, lineno, cargv[0] );
2299 #endif
2300
2301                                 } else {
2302                                         if ( (*be->be_config)( be, fname, lineno, cargc, cargv )
2303                                                 != 0 )
2304                                         {
2305                                                 return( 1 );
2306                                         }
2307                                 }
2308                         } else {
2309 #ifdef NEW_LOGGING
2310                                 LDAP_LOG( CONFIG, INFO, 
2311                                         "%s: line %d: unknown directive \"%s\" outside backend "
2312                                         "info and database definitions (ignored).\n",
2313                                         fname, lineno, cargv[0] );
2314 #else
2315                                 Debug( LDAP_DEBUG_ANY,
2316 "%s: line %d: unknown directive \"%s\" outside backend info and database definitions (ignored)\n",
2317                                     fname, lineno, cargv[0] );
2318 #endif
2319
2320                         }
2321                 }
2322                 free( saveline );
2323         }
2324         fclose( fp );
2325
2326         if ( depth == 0 ) ch_free( cargv );
2327
2328         if ( !global_schemadn.bv_val ) {
2329                 ber_str2bv( SLAPD_SCHEMA_DN, sizeof(SLAPD_SCHEMA_DN)-1, 1,
2330                         &global_schemadn );
2331                 dnNormalize2( NULL, &global_schemadn, &global_schemandn );
2332         }
2333
2334         if ( load_ucdata( NULL ) < 0 ) return 1;
2335         return( 0 );
2336 }
2337
2338 static int
2339 fp_parse_line(
2340     int         lineno,
2341     char        *line
2342 )
2343 {
2344         char *  token;
2345         char *  logline;
2346         char    logbuf[sizeof("pseudorootpw ***")];
2347
2348         cargc = 0;
2349         token = strtok_quote( line, " \t" );
2350
2351         logline = line;
2352
2353         if ( token && ( strcasecmp( token, "rootpw" ) == 0 ||
2354                 strcasecmp( token, "replica" ) == 0 ||          /* contains "credentials" */
2355                 strcasecmp( token, "bindpw" ) == 0 ||           /* used in back-ldap */
2356                 strcasecmp( token, "pseudorootpw" ) == 0 ||     /* used in back-meta */
2357                 strcasecmp( token, "dbpasswd" ) == 0 ) )        /* used in back-sql */
2358         {
2359                 snprintf( logline = logbuf, sizeof logbuf, "%s ***", token );
2360         }
2361
2362         if ( strtok_quote_ptr ) {
2363                 *strtok_quote_ptr = ' ';
2364         }
2365
2366 #ifdef NEW_LOGGING
2367         LDAP_LOG( CONFIG, DETAIL1, "line %d (%s)\n", lineno, logline , 0 );
2368 #else
2369         Debug( LDAP_DEBUG_CONFIG, "line %d (%s)\n", lineno, logline, 0 );
2370 #endif
2371
2372         if ( strtok_quote_ptr ) {
2373                 *strtok_quote_ptr = '\0';
2374         }
2375
2376         for ( ; token != NULL; token = strtok_quote( NULL, " \t" ) ) {
2377                 if ( cargc == cargv_size - 1 ) {
2378                         char **tmp;
2379                         tmp = ch_realloc( cargv, (cargv_size + ARGS_STEP) *
2380                                             sizeof(*cargv) );
2381                         if ( tmp == NULL ) {
2382 #ifdef NEW_LOGGING
2383                                 LDAP_LOG( CONFIG, ERR, "line %d: out of memory\n", lineno, 0,0 );
2384 #else
2385                                 Debug( LDAP_DEBUG_ANY, 
2386                                                 "line %d: out of memory\n", 
2387                                                 lineno, 0, 0 );
2388 #endif
2389                                 return -1;
2390                         }
2391                         cargv = tmp;
2392                         cargv_size += ARGS_STEP;
2393                 }
2394                 cargv[cargc++] = token;
2395         }
2396         cargv[cargc] = NULL;
2397         return 0;
2398 }
2399
2400 static char *
2401 strtok_quote( char *line, char *sep )
2402 {
2403         int             inquote;
2404         char            *tmp;
2405         static char     *next;
2406
2407         strtok_quote_ptr = NULL;
2408         if ( line != NULL ) {
2409                 next = line;
2410         }
2411         while ( *next && strchr( sep, *next ) ) {
2412                 next++;
2413         }
2414
2415         if ( *next == '\0' ) {
2416                 next = NULL;
2417                 return( NULL );
2418         }
2419         tmp = next;
2420
2421         for ( inquote = 0; *next; ) {
2422                 switch ( *next ) {
2423                 case '"':
2424                         if ( inquote ) {
2425                                 inquote = 0;
2426                         } else {
2427                                 inquote = 1;
2428                         }
2429                         AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
2430                         break;
2431
2432                 case '\\':
2433                         if ( next[1] )
2434                                 AC_MEMCPY( next,
2435                                             next + 1, strlen( next + 1 ) + 1 );
2436                         next++;         /* dont parse the escaped character */
2437                         break;
2438
2439                 default:
2440                         if ( ! inquote ) {
2441                                 if ( strchr( sep, *next ) != NULL ) {
2442                                         strtok_quote_ptr = next;
2443                                         *next++ = '\0';
2444                                         return( tmp );
2445                                 }
2446                         }
2447                         next++;
2448                         break;
2449                 }
2450         }
2451
2452         return( tmp );
2453 }
2454
2455 static char     buf[BUFSIZ];
2456 static char     *line;
2457 static size_t lmax, lcur;
2458
2459 #define CATLINE( buf ) \
2460         do { \
2461                 size_t len = strlen( buf ); \
2462                 while ( lcur + len + 1 > lmax ) { \
2463                         lmax += BUFSIZ; \
2464                         line = (char *) ch_realloc( line, lmax ); \
2465                 } \
2466                 strcpy( line + lcur, buf ); \
2467                 lcur += len; \
2468         } while( 0 )
2469
2470 static char *
2471 fp_getline( FILE *fp, int *lineno )
2472 {
2473         char            *p;
2474
2475         lcur = 0;
2476         CATLINE( buf );
2477         (*lineno)++;
2478
2479         /* hack attack - keeps us from having to keep a stack of bufs... */
2480         if ( strncasecmp( line, "include", 7 ) == 0 ) {
2481                 buf[0] = '\0';
2482                 return( line );
2483         }
2484
2485         while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
2486                 /* trim off \r\n or \n */
2487                 if ( (p = strchr( buf, '\n' )) != NULL ) {
2488                         if( p > buf && p[-1] == '\r' ) --p;
2489                         *p = '\0';
2490                 }
2491                 
2492                 /* trim off trailing \ and append the next line */
2493                 if ( line[ 0 ] != '\0' 
2494                                 && (p = line + strlen( line ) - 1)[ 0 ] == '\\'
2495                                 && p[ -1 ] != '\\' ) {
2496                         p[ 0 ] = '\0';
2497                         lcur--;
2498
2499                 } else {
2500                         if ( ! isspace( (unsigned char) buf[0] ) ) {
2501                                 return( line );
2502                         }
2503
2504                         /* change leading whitespace to a space */
2505                         buf[0] = ' ';
2506                 }
2507
2508                 CATLINE( buf );
2509                 (*lineno)++;
2510         }
2511         buf[0] = '\0';
2512
2513         return( line[0] ? line : NULL );
2514 }
2515
2516 static void
2517 fp_getline_init( int *lineno )
2518 {
2519         *lineno = -1;
2520         buf[0] = '\0';
2521 }
2522
2523 /* Loads ucdata, returns 1 if loading, 0 if already loaded, -1 on error */
2524 static int
2525 load_ucdata( char *path )
2526 {
2527         static int loaded = 0;
2528         int err;
2529         
2530         if ( loaded ) {
2531                 return( 0 );
2532         }
2533         err = ucdata_load( path ? path : SLAPD_DEFAULT_UCDATA, UCDATA_ALL );
2534         if ( err ) {
2535 #ifdef NEW_LOGGING
2536                 LDAP_LOG( CONFIG, CRIT, 
2537                         "load_ucdata: Error %d loading ucdata.\n", err, 0,0 );
2538 #else
2539                 Debug( LDAP_DEBUG_ANY, "error loading ucdata (error %d)\n",
2540                        err, 0, 0 );
2541 #endif
2542
2543                 return( -1 );
2544         }
2545         loaded = 1;
2546         return( 1 );
2547 }
2548
2549 void
2550 config_destroy( )
2551 {
2552         ucdata_unload( UCDATA_ALL );
2553         free( global_schemandn.bv_val );
2554         free( global_schemadn.bv_val );
2555         free( line );
2556         if ( slapd_args_file )
2557                 free ( slapd_args_file );
2558         if ( slapd_pid_file )
2559                 free ( slapd_pid_file );
2560         acl_destroy( global_acl, NULL );
2561 }