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