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