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