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