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