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