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