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