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