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