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