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