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