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