]> git.sur5r.net Git - openldap/blob - servers/slapd/config.c
if continuation line starts with a tab, rewrite it to a space
[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                         parse_oidm( fname, lineno, cargc, cargv );
1372
1373                 /* specify an objectclass */
1374                 } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
1375                         if ( *cargv[1] == '(' ) {
1376                                 char * p;
1377                                 p = strchr(saveline,'(');
1378                                 parse_oc( fname, lineno, p, cargv );
1379                         } else {
1380 #ifdef NEW_LOGGING
1381                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1382                                            "%s: line %d: old objectclass format not supported\n",
1383                                            fname, lineno ));
1384 #else
1385                                 Debug( LDAP_DEBUG_ANY,
1386                                        "%s: line %d: old objectclass format not supported.\n",
1387                                        fname, lineno, 0 );
1388 #endif
1389
1390                         }
1391
1392                 /* specify an attribute type */
1393                 } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
1394                         || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
1395                 {
1396                         if ( *cargv[1] == '(' ) {
1397                                 char * p;
1398                                 p = strchr(saveline,'(');
1399                                 parse_at( fname, lineno, p, cargv );
1400                         } else {
1401 #ifdef NEW_LOGGING
1402                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1403                                            "%s: line %d: old attribute type format not supported.\n",
1404                                            fname, lineno ));
1405 #else
1406                                 Debug( LDAP_DEBUG_ANY,
1407     "%s: line %d: old attribute type format not supported.\n",
1408                                     fname, lineno, 0 );
1409 #endif
1410
1411                         }
1412
1413                 /* turn on/off schema checking */
1414                 } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
1415                         if ( cargc < 2 ) {
1416 #ifdef NEW_LOGGING
1417                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1418                                            "%s: line %d: missing on|off in "
1419                                            "\"schemacheck <on|off>\" line.\n",
1420                                            fname, lineno ));
1421 #else
1422                                 Debug( LDAP_DEBUG_ANY,
1423     "%s: line %d: missing on|off in \"schemacheck <on|off>\" line\n",
1424                                     fname, lineno, 0 );
1425 #endif
1426
1427                                 return( 1 );
1428                         }
1429                         if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1430                                 global_schemacheck = 0;
1431                         } else {
1432                                 global_schemacheck = 1;
1433                         }
1434
1435                 /* specify access control info */
1436                 } else if ( strcasecmp( cargv[0], "access" ) == 0 ) {
1437                         parse_acl( be, fname, lineno, cargc, cargv );
1438
1439                 /* debug level to log things to syslog */
1440                 } else if ( strcasecmp( cargv[0], "loglevel" ) == 0 ) {
1441                         if ( cargc < 2 ) {
1442 #ifdef NEW_LOGGING
1443                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1444                                            "%s: line %d: missing level in \"loglevel <level>\""
1445                                            " line.\n", fname, lineno ));
1446 #else
1447                                 Debug( LDAP_DEBUG_ANY,
1448                     "%s: line %d: missing level in \"loglevel <level>\" line\n",
1449                                     fname, lineno, 0 );
1450 #endif
1451
1452                                 return( 1 );
1453                         }
1454
1455                         ldap_syslog = 0;
1456
1457                         for( i=1; i < cargc; i++ ) {
1458                                 ldap_syslog += atoi( cargv[1] );
1459                         }
1460
1461                 /* list of replicas of the data in this backend (master only) */
1462                 } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
1463                         if ( cargc < 2 ) {
1464 #ifdef NEW_LOGGING
1465                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1466                                            "%s: line %d: missing host in \"replica "
1467                                            " <host[:port]\" line\n", fname, lineno ));
1468 #else
1469                                 Debug( LDAP_DEBUG_ANY,
1470             "%s: line %d: missing host in \"replica <host[:port]>\" line\n",
1471                                     fname, lineno, 0 );
1472 #endif
1473
1474                                 return( 1 );
1475                         }
1476                         if ( be == NULL ) {
1477 #ifdef NEW_LOGGING
1478                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1479                                            "%s: line %d: replica line must appear inside "
1480                                            "a database definition (ignored).\n", fname, lineno ));
1481 #else
1482                                 Debug( LDAP_DEBUG_ANY,
1483 "%s: line %d: replica line must appear inside a database definition (ignored)\n",
1484                                     fname, lineno, 0 );
1485 #endif
1486
1487                         } else {
1488                                 for ( i = 1; i < cargc; i++ ) {
1489                                         if ( strncasecmp( cargv[i], "host=", 5 )
1490                                             == 0 ) {
1491                                                 charray_add( &be->be_replica,
1492                                                              cargv[i] + 5 );
1493                                                 break;
1494                                         }
1495                                 }
1496                                 if ( i == cargc ) {
1497 #ifdef NEW_LOGGING
1498                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1499                                                    "%s: line %d: missing host in \"replica\" "
1500                                                    "line (ignored)\n", fname, lineno ));
1501 #else
1502                                         Debug( LDAP_DEBUG_ANY,
1503                     "%s: line %d: missing host in \"replica\" line (ignored)\n",
1504                                             fname, lineno, 0 );
1505 #endif
1506
1507                                 }
1508                         }
1509
1510                 /* dn of master entity allowed to write to replica */
1511                 } else if ( strcasecmp( cargv[0], "updatedn" ) == 0 ) {
1512                         if ( cargc < 2 ) {
1513 #ifdef NEW_LOGGING
1514                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1515                                            "%s: line %d: missing dn in \"updatedn <dn>\""
1516                                            " line.\n", fname, lineno ));
1517 #else
1518                                 Debug( LDAP_DEBUG_ANY,
1519                     "%s: line %d: missing dn in \"updatedn <dn>\" line\n",
1520                                     fname, lineno, 0 );
1521 #endif
1522
1523                                 return( 1 );
1524                         }
1525                         if ( be == NULL ) {
1526 #ifdef NEW_LOGGING
1527                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1528                                            "%s: line %d: updatedn line must appear inside "
1529                                            "a database definition (ignored)\n",
1530                                            fname, lineno ));
1531 #else
1532                                 Debug( LDAP_DEBUG_ANY,
1533 "%s: line %d: updatedn line must appear inside a database definition (ignored)\n",
1534                                     fname, lineno, 0 );
1535 #endif
1536
1537                         } else {
1538                                 be->be_update_ndn = ch_strdup( cargv[1] );
1539                                 if ( load_ucdata( NULL ) < 0 ) {
1540                                         return( 1 );
1541                                 }
1542                                 if( dn_normalize( be->be_update_ndn ) == NULL ) {
1543 #ifdef NEW_LOGGING
1544                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1545                                                    "%s: line %d: updatedn DN is invalid.\n",
1546                                                    fname, lineno ));
1547 #else
1548                                         Debug( LDAP_DEBUG_ANY,
1549 "%s: line %d: updatedn DN is invalid\n",
1550                                             fname, lineno, 0 );
1551 #endif
1552
1553                                         return 1;
1554                                 }
1555                         }
1556
1557                 } else if ( strcasecmp( cargv[0], "updateref" ) == 0 ) {
1558                         if ( cargc < 2 ) {
1559 #ifdef NEW_LOGGING
1560                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1561                                            "%s: line %d: missing dn in \"updateref <ldapurl>\" "
1562                                            "line.\n", fname, lineno ));
1563 #else
1564                                 Debug( LDAP_DEBUG_ANY,
1565                     "%s: line %d: missing dn in \"updateref <ldapurl>\" line\n",
1566                                     fname, lineno, 0 );
1567 #endif
1568
1569                                 return( 1 );
1570                         }
1571                         if ( be == NULL ) {
1572 #ifdef NEW_LOGGING
1573                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1574                                            "%s: line %d: updateref line must appear inside "
1575                                            "a database definition (ignored)\n", fname, lineno ));
1576 #else
1577                                 Debug( LDAP_DEBUG_ANY,
1578 "%s: line %d: updateref line must appear inside a database definition (ignored)\n",
1579                                     fname, lineno, 0 );
1580 #endif
1581
1582                         } else if ( be->be_update_ndn == NULL ) {
1583 #ifdef NEW_LOGGING
1584                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1585                                            "%s: line %d: updateref line must come after updatedn "
1586                                            "(ignored).\n", fname, lineno ));
1587 #else
1588                                 Debug( LDAP_DEBUG_ANY,
1589 "%s: line %d: updateref line must after updatedn (ignored)\n",
1590                                     fname, lineno, 0 );
1591 #endif
1592
1593                         } else {
1594                                 vals[0]->bv_val = cargv[1];
1595                                 vals[0]->bv_len = strlen( vals[0]->bv_val );
1596                                 value_add( &be->be_update_refs, vals );
1597                         }
1598
1599                 /* replication log file to which changes are appended */
1600                 } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
1601                         if ( cargc < 2 ) {
1602 #ifdef NEW_LOGGING
1603                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1604                                            "%s: line %d: missing filename in \"replogfile <filename>\""
1605                                            " line.\n", fname, lineno ));
1606 #else
1607                                 Debug( LDAP_DEBUG_ANY,
1608             "%s: line %d: missing dn in \"replogfile <filename>\" line\n",
1609                                     fname, lineno, 0 );
1610 #endif
1611
1612                                 return( 1 );
1613                         }
1614                         if ( be ) {
1615                                 be->be_replogfile = ch_strdup( cargv[1] );
1616                         } else {
1617                                 replogfile = ch_strdup( cargv[1] );
1618                         }
1619
1620                 /* maintain lastmodified{by,time} attributes */
1621                 } else if ( strcasecmp( cargv[0], "lastmod" ) == 0 ) {
1622                         if ( cargc < 2 ) {
1623 #ifdef NEW_LOGGING
1624                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1625                                            "%s: line %d: missing on|off in \"lastmod <on|off>\""
1626                                            " line.\n", fname, lineno ));
1627 #else
1628                                 Debug( LDAP_DEBUG_ANY,
1629             "%s: line %d: missing on|off in \"lastmod <on|off>\" line\n",
1630                                     fname, lineno, 0 );
1631 #endif
1632
1633                                 return( 1 );
1634                         }
1635                         if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1636                                 if ( be )
1637                                         be->be_lastmod = ON;
1638                                 else
1639                                         global_lastmod = ON;
1640                         } else {
1641                                 if ( be )
1642                                         be->be_lastmod = OFF;
1643                                 else
1644                                         global_lastmod = OFF;
1645                         }
1646
1647                 /* set idle timeout value */
1648                 } else if ( strcasecmp( cargv[0], "idletimeout" ) == 0 ) {
1649                         int i;
1650                         if ( cargc < 2 ) {
1651 #ifdef NEW_LOGGING
1652                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1653                                            "%s: line %d: missing timeout value in "
1654                                            "\"idletimeout <seconds>\" line.\n", fname, lineno ));
1655 #else
1656                                 Debug( LDAP_DEBUG_ANY,
1657             "%s: line %d: missing timeout value in \"idletimeout <seconds>\" line\n",
1658                                     fname, lineno, 0 );
1659 #endif
1660
1661                                 return( 1 );
1662                         }
1663
1664                         i = atoi( cargv[1] );
1665
1666                         if( i < 0 ) {
1667 #ifdef NEW_LOGGING
1668                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1669                                            "%s: line %d: timeout value (%d) invalid "
1670                                            "\"idletimeout <seconds>\" line.\n",
1671                                            fname, lineno, i ));
1672 #else
1673                                 Debug( LDAP_DEBUG_ANY,
1674             "%s: line %d: timeout value (%d) invalid \"idletimeout <seconds>\" line\n",
1675                                     fname, lineno, i );
1676 #endif
1677
1678                                 return( 1 );
1679                         }
1680
1681                         global_idletimeout = i;
1682
1683                 /* include another config file */
1684                 } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
1685                         if ( cargc < 2 ) {
1686 #ifdef NEW_LOGGING
1687                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1688                                            "%s: line %d: missing filename in \"include "
1689                                            "<filename>\" line.\n", fname, lineno ));
1690 #else
1691                                 Debug( LDAP_DEBUG_ANY,
1692     "%s: line %d: missing filename in \"include <filename>\" line\n",
1693                                     fname, lineno, 0 );
1694 #endif
1695
1696                                 return( 1 );
1697                         }
1698                         savefname = ch_strdup( cargv[1] );
1699                         savelineno = lineno;
1700
1701                         if ( read_config( savefname ) != 0 ) {
1702                                 return( 1 );
1703                         }
1704
1705                         free( savefname );
1706                         lineno = savelineno - 1;
1707
1708                 /* location of kerberos srvtab file */
1709                 } else if ( strcasecmp( cargv[0], "srvtab" ) == 0 ) {
1710                         if ( cargc < 2 ) {
1711 #ifdef NEW_LOGGING
1712                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1713                                            "%s: line %d: missing filename in \"srvtab "
1714                                            "<filename>\" line.\n", fname, lineno ));
1715 #else
1716                                 Debug( LDAP_DEBUG_ANY,
1717             "%s: line %d: missing filename in \"srvtab <filename>\" line\n",
1718                                     fname, lineno, 0 );
1719 #endif
1720
1721                                 return( 1 );
1722                         }
1723                         ldap_srvtab = ch_strdup( cargv[1] );
1724
1725 #ifdef SLAPD_MODULES
1726                 } else if (strcasecmp( cargv[0], "moduleload") == 0 ) {
1727                    if ( cargc < 2 ) {
1728 #ifdef NEW_LOGGING
1729                            LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1730                                       "%s: line %d: missing filename in \"moduleload "
1731                                       "<filename>\" line.\n", fname, lineno ));
1732 #else
1733                       Debug( LDAP_DEBUG_ANY,
1734                              "%s: line %d: missing filename in \"moduleload <filename>\" line\n",
1735                              fname, lineno, 0 );
1736 #endif
1737
1738                       exit( EXIT_FAILURE );
1739                    }
1740                    if (module_load(cargv[1], cargc - 2, (cargc > 2) ? cargv + 2 : NULL)) {
1741 #ifdef NEW_LOGGING
1742                            LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1743                                       "%s: line %d: failed to load or initialize module %s\n"<
1744                                       fname, lineno, cargv[1] ));
1745 #else
1746                       Debug( LDAP_DEBUG_ANY,
1747                              "%s: line %d: failed to load or initialize module %s\n",
1748                              fname, lineno, cargv[1]);
1749 #endif
1750
1751                       exit( EXIT_FAILURE );
1752                    }
1753                 } else if (strcasecmp( cargv[0], "modulepath") == 0 ) {
1754                    if ( cargc != 2 ) {
1755 #ifdef NEW_LOGGING
1756                            LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1757                                       "%s: line %d: missing path in \"modulepath <path>\""
1758                                       " line\n", fname, lineno ));
1759 #else
1760                       Debug( LDAP_DEBUG_ANY,
1761                              "%s: line %d: missing path in \"modulepath <path>\" line\n",
1762                              fname, lineno, 0 );
1763 #endif
1764
1765                       exit( EXIT_FAILURE );
1766                    }
1767                    if (module_path( cargv[1] )) {
1768 #ifdef NEW_LOGGING
1769                            LDAP_LOG(( "cofig", LDAP_LEVEL_CRIT,
1770                                       "%s: line %d: failed to set module search path to %s.\n",
1771                                       fname, lineno, cargv[1] ));
1772 #else
1773                            Debug( LDAP_DEBUG_ANY,
1774                                   "%s: line %d: failed to set module search path to %s\n",
1775                                   fname, lineno, cargv[1]);
1776 #endif
1777
1778                       exit( EXIT_FAILURE );
1779                    }
1780                    
1781 #endif /*SLAPD_MODULES*/
1782
1783 #ifdef HAVE_TLS
1784                 } else if ( !strcasecmp( cargv[0], "TLSProtocol" ) ) {
1785                         rc = ldap_pvt_tls_set_option( NULL,
1786                                                       LDAP_OPT_X_TLS_PROTOCOL,
1787                                                       cargv[1] );
1788                         if ( rc )
1789                                 return rc;
1790
1791                 } else if ( !strcasecmp( cargv[0], "TLSRandFile" ) ) {
1792                         rc = ldap_pvt_tls_set_option( NULL,
1793                                                       LDAP_OPT_X_TLS_RANDOM_FILE,
1794                                                       cargv[1] );
1795                         if ( rc )
1796                                 return rc;
1797
1798                 } else if ( !strcasecmp( cargv[0], "TLSCipherSuite" ) ) {
1799                         rc = ldap_pvt_tls_set_option( NULL,
1800                                                       LDAP_OPT_X_TLS_CIPHER_SUITE,
1801                                                       cargv[1] );
1802                         if ( rc )
1803                                 return rc;
1804
1805                 } else if ( !strcasecmp( cargv[0], "TLSCertificateFile" ) ) {
1806                         rc = ldap_pvt_tls_set_option( NULL,
1807                                                       LDAP_OPT_X_TLS_CERTFILE,
1808                                                       cargv[1] );
1809                         if ( rc )
1810                                 return rc;
1811
1812                 } else if ( !strcasecmp( cargv[0], "TLSCertificateKeyFile" ) ) {
1813                         rc = ldap_pvt_tls_set_option( NULL,
1814                                                       LDAP_OPT_X_TLS_KEYFILE,
1815                                                       cargv[1] );
1816                         if ( rc )
1817                                 return rc;
1818
1819                 } else if ( !strcasecmp( cargv[0], "TLSCACertificatePath" ) ) {
1820                         rc = ldap_pvt_tls_set_option( NULL,
1821                                                       LDAP_OPT_X_TLS_CACERTDIR,
1822                                                       cargv[1] );
1823                         if ( rc )
1824                                 return rc;
1825
1826                 } else if ( !strcasecmp( cargv[0], "TLSCACertificateFile" ) ) {
1827                         rc = ldap_pvt_tls_set_option( NULL,
1828                                                       LDAP_OPT_X_TLS_CACERTFILE,
1829                                                       cargv[1] );
1830                         if ( rc )
1831                                 return rc;
1832                 } else if ( !strcasecmp( cargv[0], "TLSVerifyClient" ) ) {
1833                         i = atoi(cargv[1]);
1834                         rc = ldap_pvt_tls_set_option( NULL,
1835                                                       LDAP_OPT_X_TLS_REQUIRE_CERT,
1836                                                       &i );
1837                         if ( rc )
1838                                 return rc;
1839
1840 #endif
1841
1842                 /* pass anything else to the current backend info/db config routine */
1843                 } else {
1844                         if ( bi != NULL ) {
1845                                 if ( bi->bi_config == 0 ) {
1846 #ifdef NEW_LOGGING
1847                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1848                                                    "%s: line %d: unknown directive \"%s\" inside "
1849                                                    "backend info definition (ignored).\n",
1850                                                    fname, lineno, cargv[0] ));
1851 #else
1852                                         Debug( LDAP_DEBUG_ANY,
1853 "%s: line %d: unknown directive \"%s\" inside backend info definition (ignored)\n",
1854                                                 fname, lineno, cargv[0] );
1855 #endif
1856
1857                                 } else {
1858                                         if ( (*bi->bi_config)( bi, fname, lineno, cargc, cargv )
1859                                                 != 0 )
1860                                         {
1861                                                 return( 1 );
1862                                         }
1863                                 }
1864                         } else if ( be != NULL ) {
1865                                 if ( be->be_config == 0 ) {
1866 #ifdef NEW_LOGGING
1867                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1868                                                    "%s: line %d: uknown directive \"%s\" inside "
1869                                                    "backend database definition (ignored).\n",
1870                                                    fname, lineno, cargv[0] ));
1871 #else
1872                                         Debug( LDAP_DEBUG_ANY,
1873 "%s: line %d: unknown directive \"%s\" inside backend database definition (ignored)\n",
1874                                         fname, lineno, cargv[0] );
1875 #endif
1876
1877                                 } else {
1878                                         if ( (*be->be_config)( be, fname, lineno, cargc, cargv )
1879                                                 != 0 )
1880                                         {
1881                                                 return( 1 );
1882                                         }
1883                                 }
1884                         } else {
1885 #ifdef NEW_LOGGING
1886                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1887                                            "%s: line %d: unknown directive \"%s\" outside backend "
1888                                            "info and database definitions (ignored).\n",
1889                                            fname, lineno, cargv[0] ));
1890 #else
1891                                 Debug( LDAP_DEBUG_ANY,
1892 "%s: line %d: unknown directive \"%s\" outside backend info and database definitions (ignored)\n",
1893                                     fname, lineno, cargv[0] );
1894 #endif
1895
1896                         }
1897                 }
1898                 free( saveline );
1899         }
1900         fclose( fp );
1901         if ( load_ucdata( NULL ) < 0 ) {
1902                 return( 1 );
1903         }
1904         return( 0 );
1905 }
1906
1907 static int
1908 fp_parse_line(
1909     char        *line,
1910     int         *argcp,
1911     char        **argv
1912 )
1913 {
1914         char *  token;
1915
1916         *argcp = 0;
1917         for ( token = strtok_quote( line, " \t" ); token != NULL;
1918             token = strtok_quote( NULL, " \t" ) ) {
1919                 if ( *argcp == MAXARGS ) {
1920 #ifdef NEW_LOGGING
1921                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1922                                    "fp_parse_line: too many tokens (%d max).\n",
1923                                    MAXARGS ));
1924 #else
1925                         Debug( LDAP_DEBUG_ANY, "Too many tokens (max %d)\n",
1926                             MAXARGS, 0, 0 );
1927 #endif
1928
1929                         return( 1 );
1930                 }
1931                 argv[(*argcp)++] = token;
1932         }
1933         argv[*argcp] = NULL;
1934         return 0;
1935 }
1936
1937 static char *
1938 strtok_quote( char *line, char *sep )
1939 {
1940         int             inquote;
1941         char            *tmp;
1942         static char     *next;
1943
1944         if ( line != NULL ) {
1945                 next = line;
1946         }
1947         while ( *next && strchr( sep, *next ) ) {
1948                 next++;
1949         }
1950
1951         if ( *next == '\0' ) {
1952                 next = NULL;
1953                 return( NULL );
1954         }
1955         tmp = next;
1956
1957         for ( inquote = 0; *next; ) {
1958                 switch ( *next ) {
1959                 case '"':
1960                         if ( inquote ) {
1961                                 inquote = 0;
1962                         } else {
1963                                 inquote = 1;
1964                         }
1965                         AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
1966                         break;
1967
1968                 case '\\':
1969                         if ( next[1] )
1970                                 AC_MEMCPY( next,
1971                                             next + 1, strlen( next + 1 ) + 1 );
1972                         next++;         /* dont parse the escaped character */
1973                         break;
1974
1975                 default:
1976                         if ( ! inquote ) {
1977                                 if ( strchr( sep, *next ) != NULL ) {
1978                                         *next++ = '\0';
1979                                         return( tmp );
1980                                 }
1981                         }
1982                         next++;
1983                         break;
1984                 }
1985         }
1986
1987         return( tmp );
1988 }
1989
1990 static char     buf[BUFSIZ];
1991 static char     *line;
1992 static int      lmax, lcur;
1993
1994 #define CATLINE( buf )  { \
1995         int     len; \
1996         len = strlen( buf ); \
1997         while ( lcur + len + 1 > lmax ) { \
1998                 lmax += BUFSIZ; \
1999                 line = (char *) ch_realloc( line, lmax ); \
2000         } \
2001         strcpy( line + lcur, buf ); \
2002         lcur += len; \
2003 }
2004
2005 static char *
2006 fp_getline( FILE *fp, int *lineno )
2007 {
2008         char            *p;
2009
2010         lcur = 0;
2011         CATLINE( buf );
2012         (*lineno)++;
2013
2014         /* hack attack - keeps us from having to keep a stack of bufs... */
2015         if ( strncasecmp( line, "include", 7 ) == 0 ) {
2016                 buf[0] = '\0';
2017                 return( line );
2018         }
2019
2020         while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
2021                 if ( (p = strchr( buf, '\n' )) != NULL ) {
2022                         *p = '\0';
2023                 }
2024                 if ( ! isspace( (unsigned char) buf[0] ) ) {
2025                         return( line );
2026                 }
2027
2028                 /* change leading whitespace to a space */
2029                 buf[0] = ' ';
2030
2031                 CATLINE( buf );
2032                 (*lineno)++;
2033         }
2034         buf[0] = '\0';
2035
2036         return( line[0] ? line : NULL );
2037 }
2038
2039 static void
2040 fp_getline_init( int *lineno )
2041 {
2042         *lineno = -1;
2043         buf[0] = '\0';
2044 }
2045
2046 /* Loads ucdata, returns 1 if loading, 0 if already loaded, -1 on error */
2047 static int
2048 load_ucdata( char *path )
2049 {
2050         static int loaded = 0;
2051         int err;
2052         
2053         if ( loaded ) {
2054                 return( 0 );
2055         }
2056         err = ucdata_load( path ? path : SLAPD_DEFAULT_UCDATA, UCDATA_ALL );
2057         if ( err ) {
2058 #ifdef NEW_LOGGING
2059                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
2060                            "load_ucdata: Error %d loading ucdata.\n", err ));
2061 #else
2062                 Debug( LDAP_DEBUG_ANY, "error loading ucdata (error %d)\n",
2063                        err, 0, 0 );
2064 #endif
2065
2066                 return( -1 );
2067         }
2068         loaded = 1;
2069         return( 1 );
2070 }