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