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