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