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