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