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