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