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