]> git.sur5r.net Git - openldap/blob - servers/slapd/config.c
b7b16f13a1829186a38bd9826f902b06338101a6
[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;
923
924                                 if ( load_ucdata( NULL ) < 0 ) {
925                                         return( 1 );
926                                 }
927                                 dn = ch_strdup( cargv[1] );
928                                 if( dn_validate( dn ) == NULL ) {
929 #ifdef NEW_LOGGING
930                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
931                                                    "%s: line %d: suffix DN invalid\"%s\"\n",
932                                                    fname, lineno, cargv[1] ));
933 #else
934                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
935                                                 "suffix DN invalid \"%s\"\n",
936                                         fname, lineno, cargv[1] );
937 #endif
938                                         free( dn );
939                                         return 1;
940
941                                 } else if( *dn == '\0' && default_search_nbase != NULL ) {
942 #ifdef NEW_LOGGING
943                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
944                                                    "%s: line %d: suffix DN empty and default search "
945                                                    "base provided \"%s\" (assuming okay).\n",
946                                                    fname, lineno, default_search_base ));
947 #else
948                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
949                                                 "suffix DN empty and default "
950                                                 "search base provided \"%s\" (assuming okay)\n",
951                                         fname, lineno, default_search_base );
952 #endif
953
954                                 }
955                                 charray_add( &be->be_suffix, dn );
956                                 if ( dn_normalize( dn ) == NULL ) {
957 #ifdef NEW_LOGGING
958                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
959                                                 "%s: line %d: "
960                                                 "unable to normalize suffix "
961                                                 "\"%s\"\n", fname, lineno, dn ));
962 #else
963                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
964                                                 "unable to normalize suffix "
965                                                 "\"%s\"\n", fname, lineno, dn );
966 #endif
967                                         free( dn );
968                                         return 1;
969                                 }
970                                 ber_bvecadd( &be->be_nsuffix, ber_bvstr( dn ) );
971                         }
972
973                 /* set database suffixAlias */
974                 } else if ( strcasecmp( cargv[0], "suffixAlias" ) == 0 ) {
975                         Backend *tmp_be;
976                         if ( cargc < 2 ) {
977 #ifdef NEW_LOGGING
978                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
979                                            "%s: line %d: missing alias and aliased_dn in "
980                                            "\"suffixAlias <alias> <aliased_dn>\" line.\n",
981                                            fname, lineno ));
982 #else
983                                 Debug( LDAP_DEBUG_ANY,
984 "%s: line %d: missing alias and aliased_dn in \"suffixAlias <alias> <aliased_dn>\" line\n",
985                                         fname, lineno, 0 );
986 #endif
987
988                                 return( 1 );
989                         } else if ( cargc < 3 ) {
990 #ifdef NEW_LOGGING
991                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
992                                            "%s: line %d: missing aliased_dn in "
993                                            "\"suffixAlias <alias> <aliased_dn>\" line\n",
994                                            fname, lineno ));
995 #else
996                                 Debug( LDAP_DEBUG_ANY,
997 "%s: line %d: missing aliased_dn in \"suffixAlias <alias> <aliased_dn>\" line\n",
998                                 fname, lineno, 0 );
999 #endif
1000
1001                                 return( 1 );
1002                         } else if ( cargc > 3 ) {
1003 #ifdef NEW_LOGGING
1004                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1005                                            "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
1006                                            fname, lineno ));
1007 #else
1008                                 Debug( LDAP_DEBUG_ANY,
1009                                         "%s: line %d: extra cruft in suffixAlias line (ignored)\n",
1010                                 fname, lineno, 0 );
1011 #endif
1012
1013                         }
1014
1015                         if ( be == NULL ) {
1016 #ifdef NEW_LOGGING
1017                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1018                                            "%s: line %d: suffixAlias line must appear inside a "
1019                                            "database definition (ignored).\n", fname, lineno ));
1020 #else
1021                                 Debug( LDAP_DEBUG_ANY,
1022                                         "%s: line %d: suffixAlias line"
1023                                         " must appear inside a database definition (ignored)\n",
1024                                         fname, lineno, 0 );
1025 #endif
1026
1027                         } else if ( (tmp_be = select_backend( cargv[1], 0, 0 )) != NULL ) {
1028 #ifdef NEW_LOGGING
1029                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1030                                            "%s: line %d: suffixAlias served by a preceeding "
1031                                            "backend \"%s\" (ignored).\n", fname, lineno,
1032                                            tmp_be->be_suffix[0] ));
1033 #else
1034                                 Debug( LDAP_DEBUG_ANY,
1035                                         "%s: line %d: suffixAlias served by"
1036                                         "  a preceeding backend \"%s\" (ignored)\n",
1037                                         fname, lineno, tmp_be->be_suffix[0] );
1038 #endif
1039
1040
1041                         } else if ( (tmp_be = select_backend( cargv[2], 0, 0 )) != NULL ) {
1042 #ifdef NEW_LOGGING
1043                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1044                                            "%s: line %d: suffixAlias derefs to a different backend "
1045                                            "a preceeding backend \"%s\" (ignored)\n",
1046                                            fname, lineno, tmp_be->be_suffix[0] ));
1047 #else
1048                                 Debug( LDAP_DEBUG_ANY,
1049                                         "%s: line %d: suffixAlias derefs to differnet backend"
1050                                         "  a preceeding backend \"%s\" (ignored)\n",
1051                                         fname, lineno, tmp_be->be_suffix[0] );
1052 #endif
1053
1054
1055                         } else {
1056                                 char *alias, *aliased_dn;
1057
1058                                 if ( load_ucdata( NULL ) < 0 ) {
1059                                         return( 1 );
1060                                 }
1061
1062                                 alias = ch_strdup( cargv[1] );
1063                                 (void) dn_normalize( alias );
1064
1065                                 aliased_dn = ch_strdup( cargv[2] );
1066                                 (void) dn_normalize( aliased_dn );
1067
1068                                 ber_bvecadd( &be->be_suffixAlias, 
1069                                         ber_bvstr( alias ) );
1070                                 ber_bvecadd( &be->be_suffixAlias,
1071                                         ber_bvstr( aliased_dn ) );
1072                         }
1073
1074                /* set max deref depth */
1075                } else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
1076                                         int i;
1077                        if ( cargc < 2 ) {
1078 #ifdef NEW_LOGGING
1079                                LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1080                                           "%s: line %d: missing depth in \"maxDerefDepth <depth>\""
1081                                           " line\n", fname, lineno ));
1082 #else
1083                                Debug( LDAP_DEBUG_ANY,
1084                    "%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
1085                                    fname, lineno, 0 );
1086 #endif
1087
1088                                return( 1 );
1089                        }
1090                        if ( be == NULL ) {
1091 #ifdef NEW_LOGGING
1092                                LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1093                                           "%s: line %d: depth line must appear inside a database "
1094                                           "definition (ignored)\n", fname, lineno ));
1095 #else
1096                                Debug( LDAP_DEBUG_ANY,
1097 "%s: line %d: depth line must appear inside a database definition (ignored)\n",
1098                                    fname, lineno, 0 );
1099 #endif
1100
1101                        } else if ((i = atoi(cargv[1])) < 0) {
1102 #ifdef NEW_LOGGING
1103                                LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1104                                           "%s: line %d: depth must be positive (ignored).\n",
1105                                           fname, lineno ));
1106 #else
1107                                Debug( LDAP_DEBUG_ANY,
1108 "%s: line %d: depth must be positive (ignored)\n",
1109                                    fname, lineno, 0 );
1110 #endif
1111
1112
1113                        } else {
1114                            be->be_max_deref_depth = i;
1115                                            }
1116
1117
1118                 /* set magic "root" dn for this database */
1119                 } else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
1120                         if ( cargc < 2 ) {
1121 #ifdef NEW_LOGGING
1122                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1123                                            "%s: line %d: missing dn in \"rootdn <dn>\" line.\n",
1124                                            fname, lineno ));
1125 #else
1126                                 Debug( LDAP_DEBUG_ANY,
1127                     "%s: line %d: missing dn in \"rootdn <dn>\" line\n",
1128                                     fname, lineno, 0 );
1129 #endif
1130
1131                                 return( 1 );
1132                         }
1133                         if ( be == NULL ) {
1134 #ifdef NEW_LOGGING
1135                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1136                                            "%s: line %d: rootdn line must appear inside a database "
1137                                            "definition (ignored).\n", fname, lineno ));
1138 #else
1139                                 Debug( LDAP_DEBUG_ANY,
1140 "%s: line %d: rootdn line must appear inside a database definition (ignored)\n",
1141                                     fname, lineno, 0 );
1142 #endif
1143
1144                         } else {
1145                                 struct berval dn, *pdn = NULL, *ndn = NULL;
1146                                 
1147                                 if ( load_ucdata( NULL ) < 0 ) {
1148                                         return( 1 );
1149                                 }
1150
1151                                 dn.bv_val = cargv[1];
1152                                 dn.bv_len = strlen( cargv[1] );
1153
1154                                 rc = dnPretty( NULL, &dn, &pdn );
1155                                 if( rc != LDAP_SUCCESS ) {
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                                         return( 1 );
1166                                 }
1167
1168                                 rc = dnNormalize( NULL, &dn, &ndn );
1169                                 if( rc != LDAP_SUCCESS ) {
1170 #ifdef NEW_LOGGING
1171                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1172                                                 "%s: line %d: rootdn DN is invalid.\n",
1173                                                 fname, lineno ));
1174 #else
1175                                         Debug( LDAP_DEBUG_ANY,
1176                                                 "%s: line %d: rootdn DN is invalid\n",
1177                                            fname, lineno, 0 );
1178 #endif
1179                                         ber_bvfree( ndn );
1180                                         return( 1 );
1181                                 }
1182
1183                                 be->be_rootdn = *pdn;
1184                                 be->be_rootndn = *ndn;
1185
1186                                 free( pdn );
1187                                 free( ndn );
1188                         }
1189
1190                 /* set super-secret magic database password */
1191                 } else if ( strcasecmp( cargv[0], "rootpw" ) == 0 ) {
1192                         if ( cargc < 2 ) {
1193 #ifdef NEW_LOGGING
1194                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1195                                            "%s: line %d: missing passwd in \"rootpw <passwd>\""
1196                                            " line\n", fname, lineno ));
1197 #else
1198                                 Debug( LDAP_DEBUG_ANY,
1199             "%s: line %d: missing passwd in \"rootpw <passwd>\" line\n",
1200                                     fname, lineno, 0 );
1201 #endif
1202
1203                                 return( 1 );
1204                         }
1205                         if ( be == NULL ) {
1206 #ifdef NEW_LOGGING
1207                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1208                                            "%s: line %d: rootpw line must appear inside a database "
1209                                            "definition (ignored)\n", fname, lineno ));
1210 #else
1211                                 Debug( LDAP_DEBUG_ANY,
1212 "%s: line %d: rootpw line must appear inside a database definition (ignored)\n",
1213                                     fname, lineno, 0 );
1214 #endif
1215
1216                         } else {
1217                                 be->be_rootpw.bv_val = ch_strdup( cargv[1] );
1218                                 be->be_rootpw.bv_len = strlen( be->be_rootpw.bv_val );
1219                         }
1220
1221                 /* make this database read-only */
1222                 } else if ( strcasecmp( cargv[0], "readonly" ) == 0 ) {
1223                         if ( cargc < 2 ) {
1224 #ifdef NEW_LOGGING
1225                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1226                                            "%s: line %d: missing on|off in \"readonly <on|off>\" line.\n",
1227                                            fname, lineno ));
1228 #else
1229                                 Debug( LDAP_DEBUG_ANY,
1230             "%s: line %d: missing on|off in \"readonly <on|off>\" line\n",
1231                                     fname, lineno, 0 );
1232 #endif
1233
1234                                 return( 1 );
1235                         }
1236                         if ( be == NULL ) {
1237                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1238                                         global_restrictops |= SLAP_RESTRICT_OP_WRITES;
1239                                 } else {
1240                                         global_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
1241                                 }
1242                         } else {
1243                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1244                                         be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
1245                                 } else {
1246                                         be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
1247                                 }
1248                         }
1249
1250
1251                 /* allow these features */
1252                 } else if ( strcasecmp( cargv[0], "allows" ) == 0 ||
1253                         strcasecmp( cargv[0], "allow" ) == 0 )
1254                 {
1255                         slap_mask_t     allows;
1256
1257                         if ( be != NULL ) {
1258 #ifdef NEW_LOGGING
1259                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1260                                            "%s: line %d: allow line must appear prior to "
1261                                            "database definitions.\n", fname, lineno ));
1262 #else
1263                                 Debug( LDAP_DEBUG_ANY,
1264 "%s: line %d: allow line must appear prior to database definitions\n",
1265                                     fname, lineno, 0 );
1266 #endif
1267
1268                         }
1269
1270                         if ( cargc < 2 ) {
1271 #ifdef NEW_LOGGING
1272                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1273                                            "%s: line %d: missing feature(s) in \"allow <features>\""
1274                                            " line\n", fname, lineno ));
1275 #else
1276                                 Debug( LDAP_DEBUG_ANY,
1277             "%s: line %d: missing feature(s) in \"allow <features>\" line\n",
1278                                     fname, lineno, 0 );
1279 #endif
1280
1281                                 return( 1 );
1282                         }
1283
1284                         allows = 0;
1285
1286                         for( i=1; i < cargc; i++ ) {
1287                                 if( strcasecmp( cargv[i], "bind_v2" ) == 0 ) {
1288                                         allows |= SLAP_ALLOW_BIND_V2;
1289
1290                                 } else if( strcasecmp( cargv[i], "bind_anon_cred" ) == 0 ) {
1291                                         allows |= SLAP_ALLOW_BIND_ANON_CRED;
1292
1293                                 } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) {
1294                                         allows |= SLAP_ALLOW_BIND_ANON_DN;
1295
1296                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1297 #ifdef NEW_LOGGING
1298                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1299                                                    "%s: line %d: unknown feature %s in "
1300                                                    "\"allow <features>\" line.\n",
1301                                                    fname, lineno, cargv[1] ));
1302 #else
1303                                         Debug( LDAP_DEBUG_ANY,
1304                     "%s: line %d: unknown feature %s in \"allow <features>\" line\n",
1305                                             fname, lineno, cargv[i] );
1306 #endif
1307
1308                                         return( 1 );
1309                                 }
1310                         }
1311
1312                         global_allows = allows;
1313
1314                 /* disallow these features */
1315                 } else if ( strcasecmp( cargv[0], "disallows" ) == 0 ||
1316                         strcasecmp( cargv[0], "disallow" ) == 0 )
1317                 {
1318                         slap_mask_t     disallows;
1319
1320                         if ( be != NULL ) {
1321 #ifdef NEW_LOGGING
1322                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1323                                            "%s: line %d: disallow line must appear prior to "
1324                                            "database definitions.\n", fname, lineno ));
1325 #else
1326                                 Debug( LDAP_DEBUG_ANY,
1327 "%s: line %d: disallow line must appear prior to database definitions\n",
1328                                     fname, lineno, 0 );
1329 #endif
1330
1331                         }
1332
1333                         if ( cargc < 2 ) {
1334 #ifdef NEW_LOGGING
1335                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1336                                            "%s: line %d: missing feature(s) in \"disallow <features>\""
1337                                            " line.\n", fname, lineno ));
1338 #else
1339                                 Debug( LDAP_DEBUG_ANY,
1340             "%s: line %d: missing feature(s) in \"disallow <features>\" line\n",
1341                                     fname, lineno, 0 );
1342 #endif
1343
1344                                 return( 1 );
1345                         }
1346
1347                         disallows = 0;
1348
1349                         for( i=1; i < cargc; i++ ) {
1350                                 if( strcasecmp( cargv[i], "bind_anon" ) == 0 ) {
1351                                         disallows |= SLAP_DISALLOW_BIND_ANON;
1352
1353                                 } else if( strcasecmp( cargv[i], "bind_simple" ) == 0 ) {
1354                                         disallows |= SLAP_DISALLOW_BIND_SIMPLE;
1355
1356                                 } else if( strcasecmp( cargv[i], "bind_krbv4" ) == 0 ) {
1357                                         disallows |= SLAP_DISALLOW_BIND_KRBV4;
1358
1359                                 } else if( strcasecmp( cargv[i], "tls_2_anon" ) == 0 ) {
1360                                         disallows |= SLAP_DISALLOW_TLS_2_ANON;
1361
1362                                 } else if( strcasecmp( cargv[i], "tls_authc" ) == 0 ) {
1363                                         disallows |= SLAP_DISALLOW_TLS_AUTHC;
1364
1365                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1366 #ifdef NEW_LOGGING
1367                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1368                                                 "%s: line %d: unknown feature %s in "
1369                                                 "\"disallow <features>\" line.\n",
1370                                                 fname, lineno, cargv[i] ));
1371 #else
1372                                         Debug( LDAP_DEBUG_ANY,
1373                     "%s: line %d: unknown feature %s in \"disallow <features>\" line\n",
1374                                             fname, lineno, cargv[i] );
1375 #endif
1376
1377                                         return( 1 );
1378                                 }
1379                         }
1380
1381                         global_disallows = disallows;
1382
1383                 /* require these features */
1384                 } else if ( strcasecmp( cargv[0], "requires" ) == 0 ||
1385                         strcasecmp( cargv[0], "require" ) == 0 )
1386                 {
1387                         slap_mask_t     requires;
1388
1389                         if ( cargc < 2 ) {
1390 #ifdef NEW_LOGGING
1391                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1392                                            "%s: line %d: missing feature(s) in "
1393                                            "\"require <features>\" line.\n", fname, lineno ));
1394 #else
1395                                 Debug( LDAP_DEBUG_ANY,
1396             "%s: line %d: missing feature(s) in \"require <features>\" line\n",
1397                                     fname, lineno, 0 );
1398 #endif
1399
1400                                 return( 1 );
1401                         }
1402
1403                         requires = 0;
1404
1405                         for( i=1; i < cargc; i++ ) {
1406                                 if( strcasecmp( cargv[i], "bind" ) == 0 ) {
1407                                         requires |= SLAP_REQUIRE_BIND;
1408
1409                                 } else if( strcasecmp( cargv[i], "LDAPv3" ) == 0 ) {
1410                                         requires |= SLAP_REQUIRE_LDAP_V3;
1411
1412                                 } else if( strcasecmp( cargv[i], "authc" ) == 0 ) {
1413                                         requires |= SLAP_REQUIRE_AUTHC;
1414
1415                                 } else if( strcasecmp( cargv[i], "SASL" ) == 0 ) {
1416                                         requires |= SLAP_REQUIRE_SASL;
1417
1418                                 } else if( strcasecmp( cargv[i], "strong" ) == 0 ) {
1419                                         requires |= SLAP_REQUIRE_STRONG;
1420
1421                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1422 #ifdef NEW_LOGGING
1423                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1424                                                    "%s: line %d: unknown feature %s in "
1425                                                    "\"require <features>\" line.\n",
1426                                                    fname, lineno ));
1427 #else
1428                                         Debug( LDAP_DEBUG_ANY,
1429                     "%s: line %d: unknown feature %s in \"require <features>\" line\n",
1430                                             fname, lineno, cargv[i] );
1431 #endif
1432
1433                                         return( 1 );
1434                                 }
1435                         }
1436
1437                         if ( be == NULL ) {
1438                                 global_requires = requires;
1439                         } else {
1440                                 be->be_requires = requires;
1441                         }
1442
1443                 /* required security factors */
1444                 } else if ( strcasecmp( cargv[0], "security" ) == 0 ) {
1445                         slap_ssf_set_t *set;
1446
1447                         if ( cargc < 2 ) {
1448 #ifdef NEW_LOGGING
1449                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1450                                            "%s: line %d: missing factor(s) in \"security <factors>\""
1451                                            " line.\n", fname, lineno ));
1452 #else
1453                                 Debug( LDAP_DEBUG_ANY,
1454             "%s: line %d: missing factor(s) in \"security <factors>\" line\n",
1455                                     fname, lineno, 0 );
1456 #endif
1457
1458                                 return( 1 );
1459                         }
1460
1461                         if ( be == NULL ) {
1462                                 set = &global_ssf_set;
1463                         } else {
1464                                 set = &be->be_ssf_set;
1465                         }
1466
1467                         for( i=1; i < cargc; i++ ) {
1468                                 if( strncasecmp( cargv[i], "ssf=",
1469                                         sizeof("ssf") ) == 0 )
1470                                 {
1471                                         set->sss_ssf =
1472                                                 atoi( &cargv[i][sizeof("ssf")] );
1473
1474                                 } else if( strncasecmp( cargv[i], "transport=",
1475                                         sizeof("transport") ) == 0 )
1476                                 {
1477                                         set->sss_transport =
1478                                                 atoi( &cargv[i][sizeof("transport")] );
1479
1480                                 } else if( strncasecmp( cargv[i], "tls=",
1481                                         sizeof("tls") ) == 0 )
1482                                 {
1483                                         set->sss_tls =
1484                                                 atoi( &cargv[i][sizeof("tls")] );
1485
1486                                 } else if( strncasecmp( cargv[i], "sasl=",
1487                                         sizeof("sasl") ) == 0 )
1488                                 {
1489                                         set->sss_sasl =
1490                                                 atoi( &cargv[i][sizeof("sasl")] );
1491
1492                                 } else if( strncasecmp( cargv[i], "update_ssf=",
1493                                         sizeof("update_ssf") ) == 0 )
1494                                 {
1495                                         set->sss_update_ssf =
1496                                                 atoi( &cargv[i][sizeof("update_ssf")] );
1497
1498                                 } else if( strncasecmp( cargv[i], "update_transport=",
1499                                         sizeof("update_transport") ) == 0 )
1500                                 {
1501                                         set->sss_update_transport =
1502                                                 atoi( &cargv[i][sizeof("update_transport")] );
1503
1504                                 } else if( strncasecmp( cargv[i], "update_tls=",
1505                                         sizeof("update_tls") ) == 0 )
1506                                 {
1507                                         set->sss_update_tls =
1508                                                 atoi( &cargv[i][sizeof("update_tls")] );
1509
1510                                 } else if( strncasecmp( cargv[i], "update_sasl=",
1511                                         sizeof("update_sasl") ) == 0 )
1512                                 {
1513                                         set->sss_update_sasl =
1514                                                 atoi( &cargv[i][sizeof("update_sasl")] );
1515
1516                                 } else {
1517 #ifdef NEW_LOGGING
1518                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1519                                                    "%s: line %d: unknown factor %S in "
1520                                                    "\"security <factors>\" line.\n",
1521                                                    fname, lineno, cargv[1] ));
1522 #else
1523                                         Debug( LDAP_DEBUG_ANY,
1524                     "%s: line %d: unknown factor %s in \"security <factors>\" line\n",
1525                                             fname, lineno, cargv[i] );
1526 #endif
1527
1528                                         return( 1 );
1529                                 }
1530                         }
1531                 /* where to send clients when we don't hold it */
1532                 } else if ( strcasecmp( cargv[0], "referral" ) == 0 ) {
1533                         if ( cargc < 2 ) {
1534 #ifdef NEW_LOGGING
1535                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1536                                            "%s: line %d: missing URL in \"referral <URL>\""
1537                                            " line.\n", fname, lineno ));
1538 #else
1539                                 Debug( LDAP_DEBUG_ANY,
1540                     "%s: line %d: missing URL in \"referral <URL>\" line\n",
1541                                     fname, lineno, 0 );
1542 #endif
1543
1544                                 return( 1 );
1545                         }
1546
1547                         if( validate_global_referral( cargv[1] ) ) {
1548 #ifdef NEW_LOGGING
1549                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT, "%s: line %d: "
1550                                         "invalid URL (%s) in \"referral\" line.\n",
1551                                         fname, lineno, cargv[1] ));
1552 #else
1553                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1554                                         "invalid URL (%s) in \"referral\" line.\n",
1555                                     fname, lineno, cargv[1] );
1556 #endif
1557                                 return 1;
1558                         }
1559
1560                         vals[0]->bv_val = cargv[1];
1561                         vals[0]->bv_len = strlen( vals[0]->bv_val );
1562                         value_add( &default_referral, vals );
1563
1564 #ifdef NEW_LOGGING
1565                 } else if ( strcasecmp( cargv[0], "logfile" ) == 0 ) {
1566                         FILE *logfile;
1567                         if ( cargc < 2 ) {
1568 #ifdef NEW_LOGGING
1569                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1570                                            "%s: line %d: Error in logfile directive, "
1571                                            "\"logfile <filename>\"\n", fname, lineno ));
1572 #else
1573                                 Debug( LDAP_DEBUG_ANY,
1574                                        "%s: line %d: Error in logfile directive, \"logfile filename\"\n",
1575                                        fname, lineno, 0 );
1576 #endif
1577
1578                                 return( 1 );
1579                         }
1580                         logfile = fopen( cargv[1], "w" );
1581                         if ( logfile != NULL ) lutil_debug_file( logfile );
1582
1583 #endif
1584                 /* start of a new database definition */
1585                 } else if ( strcasecmp( cargv[0], "debug" ) == 0 ) {
1586                         int level;
1587                         if ( cargc < 3 ) {
1588 #ifdef NEW_LOGGING
1589                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1590                                            "%s: line %d: Error in debug directive, "
1591                                            "\"debug <subsys> <level>\"\n", fname, lineno ));
1592 #else
1593                                 Debug( LDAP_DEBUG_ANY,
1594                                         "%s: line %d: Error in debug directive, \"debug subsys level\"\n",
1595                                         fname, lineno, 0 );
1596 #endif
1597
1598                                 return( 1 );
1599                         }
1600                         level = atoi( cargv[2] );
1601                         if ( level <= 0 ) level = lutil_mnem2level( cargv[2] );
1602                         lutil_set_debug_level( cargv[1], level );
1603                 /* specify an Object Identifier macro */
1604                 } else if ( strcasecmp( cargv[0], "objectidentifier" ) == 0 ) {
1605                         rc = parse_oidm( fname, lineno, cargc, cargv );
1606                         if( rc ) return rc;
1607
1608                 /* specify an objectclass */
1609                 } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
1610                         if ( *cargv[1] == '(' ) {
1611                                 char * p;
1612                                 p = strchr(saveline,'(');
1613                                 rc = parse_oc( fname, lineno, p, cargv );
1614                                 if( rc ) return rc;
1615
1616                         } else {
1617 #ifdef NEW_LOGGING
1618                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1619                                            "%s: line %d: old objectclass format not supported\n",
1620                                            fname, lineno ));
1621 #else
1622                                 Debug( LDAP_DEBUG_ANY,
1623                                        "%s: line %d: old objectclass format not supported.\n",
1624                                        fname, lineno, 0 );
1625 #endif
1626
1627                         }
1628
1629                 /* specify an attribute type */
1630                 } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
1631                         || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
1632                 {
1633                         if ( *cargv[1] == '(' ) {
1634                                 char * p;
1635                                 p = strchr(saveline,'(');
1636                                 rc = parse_at( fname, lineno, p, cargv );
1637                                 if( rc ) return rc;
1638
1639                         } else {
1640 #ifdef NEW_LOGGING
1641                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1642                                            "%s: line %d: old attribute type format not supported.\n",
1643                                            fname, lineno ));
1644 #else
1645                                 Debug( LDAP_DEBUG_ANY,
1646     "%s: line %d: old attribute type format not supported.\n",
1647                                     fname, lineno, 0 );
1648 #endif
1649
1650                         }
1651
1652                 /* turn on/off schema checking */
1653                 } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
1654                         if ( cargc < 2 ) {
1655 #ifdef NEW_LOGGING
1656                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1657                                            "%s: line %d: missing on|off in "
1658                                            "\"schemacheck <on|off>\" line.\n",
1659                                            fname, lineno ));
1660 #else
1661                                 Debug( LDAP_DEBUG_ANY,
1662     "%s: line %d: missing on|off in \"schemacheck <on|off>\" line\n",
1663                                     fname, lineno, 0 );
1664 #endif
1665
1666                                 return( 1 );
1667                         }
1668                         if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1669                                 global_schemacheck = 0;
1670                         } else {
1671                                 global_schemacheck = 1;
1672                         }
1673
1674                 /* specify access control info */
1675                 } else if ( strcasecmp( cargv[0], "access" ) == 0 ) {
1676                         parse_acl( be, fname, lineno, cargc, cargv );
1677
1678                 /* debug level to log things to syslog */
1679                 } else if ( strcasecmp( cargv[0], "loglevel" ) == 0 ) {
1680                         if ( cargc < 2 ) {
1681 #ifdef NEW_LOGGING
1682                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1683                                            "%s: line %d: missing level in \"loglevel <level>\""
1684                                            " line.\n", fname, lineno ));
1685 #else
1686                                 Debug( LDAP_DEBUG_ANY,
1687                     "%s: line %d: missing level in \"loglevel <level>\" line\n",
1688                                     fname, lineno, 0 );
1689 #endif
1690
1691                                 return( 1 );
1692                         }
1693
1694                         ldap_syslog = 0;
1695
1696                         for( i=1; i < cargc; i++ ) {
1697                                 ldap_syslog += atoi( cargv[1] );
1698                         }
1699
1700                 /* list of replicas of the data in this backend (master only) */
1701                 } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
1702                         if ( cargc < 2 ) {
1703 #ifdef NEW_LOGGING
1704                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1705                                            "%s: line %d: missing host in \"replica "
1706                                            " <host[:port]\" line\n", fname, lineno ));
1707 #else
1708                                 Debug( LDAP_DEBUG_ANY,
1709             "%s: line %d: missing host in \"replica <host[:port]>\" line\n",
1710                                     fname, lineno, 0 );
1711 #endif
1712
1713                                 return( 1 );
1714                         }
1715                         if ( be == NULL ) {
1716 #ifdef NEW_LOGGING
1717                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1718                                            "%s: line %d: replica line must appear inside "
1719                                            "a database definition (ignored).\n", fname, lineno ));
1720 #else
1721                                 Debug( LDAP_DEBUG_ANY,
1722 "%s: line %d: replica line must appear inside a database definition (ignored)\n",
1723                                     fname, lineno, 0 );
1724 #endif
1725
1726                         } else {
1727                                 int nr = -1;
1728
1729                                 for ( i = 1; i < cargc; i++ ) {
1730                                         if ( strncasecmp( cargv[i], "host=", 5 )
1731                                             == 0 ) {
1732                                                 nr = add_replica_info( be, 
1733                                                         cargv[i] + 5 );
1734                                                 break;
1735                                         }
1736                                 }
1737                                 if ( i == cargc ) {
1738 #ifdef NEW_LOGGING
1739                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1740                                                    "%s: line %d: missing host in \"replica\" "
1741                                                    "line (ignored)\n", fname, lineno ));
1742 #else
1743                                         Debug( LDAP_DEBUG_ANY,
1744                     "%s: line %d: missing host in \"replica\" line (ignored)\n",
1745                                             fname, lineno, 0 );
1746 #endif
1747
1748                                 } else if ( nr == -1 ) {
1749 #ifdef NEW_LOGGING
1750                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1751                                                    "%s: line %d: unable to add"
1752                                                    " replica \"%s\""
1753                                                    " (ignored)\n",
1754                                                    fname, lineno, 
1755                                                    cargv[i] + 5 ));
1756 #else
1757                                         Debug( LDAP_DEBUG_ANY,
1758                 "%s: line %d: unable to add replica \"%s\" (ignored)\n",
1759                                                 fname, lineno, cargv[i] + 5 );
1760 #endif
1761                                 } else {
1762                                         for ( i = 1; i < cargc; i++ ) {
1763                                                 if ( strncasecmp( cargv[i], "suffix=", 7 ) == 0 ) {
1764
1765                                                         switch ( add_replica_suffix( be, nr, cargv[i] + 7 ) ) {
1766                                                         case 1:
1767 #ifdef NEW_LOGGING
1768                                                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1769                                                                                 "%s: line %d: suffix \"%s\" in \"replica\" line is not valid for backend (ignored)\n",
1770                                                                                 fname, lineno, cargv[i] + 7 ));
1771 #else
1772                                                                 Debug( LDAP_DEBUG_ANY,
1773                                                                                 "%s: line %d: suffix \"%s\" in \"replica\" line is not valid for backend (ignored)\n",
1774                                                                                 fname, lineno, cargv[i] + 7 );
1775 #endif
1776                                                                 break;
1777
1778                                                         case 2:
1779 #ifdef NEW_LOGGING
1780                                                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1781                                                                                         "%s: line %d: unable to normalize suffix in \"replica\" line (ignored)\n",
1782                                                                                         fname, lineno ));
1783 #else
1784                                                                 Debug( LDAP_DEBUG_ANY,
1785                                                                                  "%s: line %d: unable to normalize suffix in \"replica\" line (ignored)\n",
1786                                                                                  fname, lineno, 0 );
1787 #endif
1788                                                                 break;
1789                                                         }
1790                                                 }
1791                                         }
1792                                 }
1793                         }
1794
1795                 /* dn of master entity allowed to write to replica */
1796                 } else if ( strcasecmp( cargv[0], "updatedn" ) == 0 ) {
1797                         if ( cargc < 2 ) {
1798 #ifdef NEW_LOGGING
1799                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1800                                            "%s: line %d: missing dn in \"updatedn <dn>\""
1801                                            " line.\n", fname, lineno ));
1802 #else
1803                                 Debug( LDAP_DEBUG_ANY,
1804                     "%s: line %d: missing dn in \"updatedn <dn>\" line\n",
1805                                     fname, lineno, 0 );
1806 #endif
1807
1808                                 return( 1 );
1809                         }
1810                         if ( be == NULL ) {
1811 #ifdef NEW_LOGGING
1812                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
1813                                            "%s: line %d: updatedn line must appear inside "
1814                                            "a database definition (ignored)\n",
1815                                            fname, lineno ));
1816 #else
1817                                 Debug( LDAP_DEBUG_ANY,
1818 "%s: line %d: updatedn line must appear inside a database definition (ignored)\n",
1819                                     fname, lineno, 0 );
1820 #endif
1821
1822                         } else {
1823                                 struct berval dn, *ndn = NULL;
1824
1825                                 if ( load_ucdata( NULL ) < 0 ) {
1826                                         return( 1 );
1827                                 }
1828
1829                                 dn.bv_val = cargv[1];
1830                                 dn.bv_len = strlen( cargv[1] );
1831
1832                                 rc = dnNormalize( NULL, &dn, &ndn );
1833                                 if( rc != LDAP_SUCCESS ) {
1834 #ifdef NEW_LOGGING
1835                                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1836                                                 "%s: line %d: updatedn DN is invalid.\n",
1837                                                 fname, lineno ));
1838 #else
1839                                         Debug( LDAP_DEBUG_ANY,
1840                                                 "%s: line %d: updatedn DN is invalid\n",
1841                                             fname, lineno, 0 );
1842 #endif
1843                                         return 1;
1844                                 }
1845
1846                                 be->be_update_ndn = *ndn;
1847                                 free( ndn );
1848                         }
1849
1850                 } else if ( strcasecmp( cargv[0], "updateref" ) == 0 ) {
1851                         if ( cargc < 2 ) {
1852 #ifdef NEW_LOGGING
1853                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT, "%s: line %d: "
1854                                         "missing url in \"updateref <ldapurl>\" line.\n",
1855                                         fname, lineno ));
1856 #else
1857                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1858                                         "missing url in \"updateref <ldapurl>\" line\n",
1859                                     fname, lineno, 0 );
1860 #endif
1861
1862                                 return( 1 );
1863                         }
1864                         if ( be == NULL ) {
1865 #ifdef NEW_LOGGING
1866                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO, "%s: line %d: updateref"
1867                                         " line must appear inside a database definition\n",
1868                                         fname, lineno ));
1869 #else
1870                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: updateref"
1871                                         " line must appear inside a database definition\n",
1872                                         fname, lineno, 0 );
1873 #endif
1874                                 return 1;
1875
1876                         } else if ( !be->be_update_ndn.bv_len ) {
1877 #ifdef NEW_LOGGING
1878                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO, "%s: line %d: "
1879                                         "updateref line must come after updatedn.\n",
1880                                         fname, lineno ));
1881 #else
1882                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1883                                         "updateref line must after updatedn.\n",
1884                                     fname, lineno, 0 );
1885 #endif
1886                                 return 1;
1887                         }
1888
1889                         if( validate_global_referral( cargv[1] ) ) {
1890 #ifdef NEW_LOGGING
1891                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT, "%s: line %d: "
1892                                         "invalid URL (%s) in \"updateref\" line.\n",
1893                                         fname, lineno, cargv[1] ));
1894 #else
1895                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1896                                         "invalid URL (%s) in \"updateref\" line.\n",
1897                                     fname, lineno, cargv[1] );
1898 #endif
1899                                 return 1;
1900                         }
1901
1902                         vals[0]->bv_val = cargv[1];
1903                         vals[0]->bv_len = strlen( vals[0]->bv_val );
1904                         value_add( &be->be_update_refs, vals );
1905
1906                 /* replication log file to which changes are appended */
1907                 } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
1908                         if ( cargc < 2 ) {
1909 #ifdef NEW_LOGGING
1910                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1911                                            "%s: line %d: missing filename in \"replogfile <filename>\""
1912                                            " line.\n", fname, lineno ));
1913 #else
1914                                 Debug( LDAP_DEBUG_ANY,
1915             "%s: line %d: missing filename in \"replogfile <filename>\" line\n",
1916                                     fname, lineno, 0 );
1917 #endif
1918
1919                                 return( 1 );
1920                         }
1921                         if ( be ) {
1922                                 be->be_replogfile = ch_strdup( cargv[1] );
1923                         } else {
1924                                 replogfile = ch_strdup( cargv[1] );
1925                         }
1926
1927                 /* file from which to read additional rootdse attrs */
1928                 } else if ( strcasecmp( cargv[0], "rootdse" ) == 0) {
1929                         if ( cargc < 2 ) {
1930 #ifdef NEW_LOGGING
1931                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT, "%s: line %d: "
1932                                         "missing filename in \"rootDSEfile <filename>\" line.\n",
1933                                         fname, lineno ));
1934 #else
1935                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1936                                         "missing filename in \"rootDSEfile <filename>\" line.\n",
1937                                     fname, lineno, 0 );
1938 #endif
1939                                 return 1;
1940                         }
1941
1942                         if( read_root_dse_file( cargv[1] ) ) {
1943 #ifdef NEW_LOGGING
1944                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT, "%s: line %d: "
1945                                         "could not read \"rootDSEfile <filename>\" line.\n",
1946                                         fname, lineno ));
1947 #else
1948                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1949                                         "could not read \"rootDSEfile <filename>\" line\n",
1950                                     fname, lineno, 0 );
1951 #endif
1952                                 return 1;
1953                         }
1954
1955                 /* maintain lastmodified{by,time} attributes */
1956                 } else if ( strcasecmp( cargv[0], "lastmod" ) == 0 ) {
1957                         if ( cargc < 2 ) {
1958 #ifdef NEW_LOGGING
1959                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1960                                            "%s: line %d: missing on|off in \"lastmod <on|off>\""
1961                                            " line.\n", fname, lineno ));
1962 #else
1963                                 Debug( LDAP_DEBUG_ANY,
1964             "%s: line %d: missing on|off in \"lastmod <on|off>\" line\n",
1965                                     fname, lineno, 0 );
1966 #endif
1967
1968                                 return( 1 );
1969                         }
1970                         if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1971                                 if ( be )
1972                                         be->be_lastmod = ON;
1973                                 else
1974                                         global_lastmod = ON;
1975                         } else {
1976                                 if ( be )
1977                                         be->be_lastmod = OFF;
1978                                 else
1979                                         global_lastmod = OFF;
1980                         }
1981
1982                 /* set idle timeout value */
1983                 } else if ( strcasecmp( cargv[0], "idletimeout" ) == 0 ) {
1984                         int i;
1985                         if ( cargc < 2 ) {
1986 #ifdef NEW_LOGGING
1987                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
1988                                            "%s: line %d: missing timeout value in "
1989                                            "\"idletimeout <seconds>\" line.\n", fname, lineno ));
1990 #else
1991                                 Debug( LDAP_DEBUG_ANY,
1992             "%s: line %d: missing timeout value in \"idletimeout <seconds>\" line\n",
1993                                     fname, lineno, 0 );
1994 #endif
1995
1996                                 return( 1 );
1997                         }
1998
1999                         i = atoi( cargv[1] );
2000
2001                         if( i < 0 ) {
2002 #ifdef NEW_LOGGING
2003                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
2004                                            "%s: line %d: timeout value (%d) invalid "
2005                                            "\"idletimeout <seconds>\" line.\n",
2006                                            fname, lineno, i ));
2007 #else
2008                                 Debug( LDAP_DEBUG_ANY,
2009             "%s: line %d: timeout value (%d) invalid \"idletimeout <seconds>\" line\n",
2010                                     fname, lineno, i );
2011 #endif
2012
2013                                 return( 1 );
2014                         }
2015
2016                         global_idletimeout = i;
2017
2018                 /* include another config file */
2019                 } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
2020                         if ( cargc < 2 ) {
2021 #ifdef NEW_LOGGING
2022                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
2023                                            "%s: line %d: missing filename in \"include "
2024                                            "<filename>\" line.\n", fname, lineno ));
2025 #else
2026                                 Debug( LDAP_DEBUG_ANY,
2027     "%s: line %d: missing filename in \"include <filename>\" line\n",
2028                                     fname, lineno, 0 );
2029 #endif
2030
2031                                 return( 1 );
2032                         }
2033                         savefname = ch_strdup( cargv[1] );
2034                         savelineno = lineno;
2035
2036                         if ( read_config( savefname ) != 0 ) {
2037                                 return( 1 );
2038                         }
2039
2040                         free( savefname );
2041                         lineno = savelineno - 1;
2042
2043                 /* location of kerberos srvtab file */
2044                 } else if ( strcasecmp( cargv[0], "srvtab" ) == 0 ) {
2045                         if ( cargc < 2 ) {
2046 #ifdef NEW_LOGGING
2047                                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
2048                                            "%s: line %d: missing filename in \"srvtab "
2049                                            "<filename>\" line.\n", fname, lineno ));
2050 #else
2051                                 Debug( LDAP_DEBUG_ANY,
2052             "%s: line %d: missing filename in \"srvtab <filename>\" line\n",
2053                                     fname, lineno, 0 );
2054 #endif
2055
2056                                 return( 1 );
2057                         }
2058                         ldap_srvtab = ch_strdup( cargv[1] );
2059
2060 #ifdef SLAPD_MODULES
2061                 } else if (strcasecmp( cargv[0], "moduleload") == 0 ) {
2062                    if ( cargc < 2 ) {
2063 #ifdef NEW_LOGGING
2064                            LDAP_LOG(( "config", LDAP_LEVEL_INFO,
2065                                       "%s: line %d: missing filename in \"moduleload "
2066                                       "<filename>\" line.\n", fname, lineno ));
2067 #else
2068                       Debug( LDAP_DEBUG_ANY,
2069                              "%s: line %d: missing filename in \"moduleload <filename>\" line\n",
2070                              fname, lineno, 0 );
2071 #endif
2072
2073                       exit( EXIT_FAILURE );
2074                    }
2075                    if (module_load(cargv[1], cargc - 2, (cargc > 2) ? cargv + 2 : NULL)) {
2076 #ifdef NEW_LOGGING
2077                            LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
2078                                       "%s: line %d: failed to load or initialize module %s\n"<
2079                                       fname, lineno, cargv[1] ));
2080 #else
2081                       Debug( LDAP_DEBUG_ANY,
2082                              "%s: line %d: failed to load or initialize module %s\n",
2083                              fname, lineno, cargv[1]);
2084 #endif
2085
2086                       exit( EXIT_FAILURE );
2087                    }
2088                 } else if (strcasecmp( cargv[0], "modulepath") == 0 ) {
2089                    if ( cargc != 2 ) {
2090 #ifdef NEW_LOGGING
2091                            LDAP_LOG(( "config", LDAP_LEVEL_INFO,
2092                                       "%s: line %d: missing path in \"modulepath <path>\""
2093                                       " line\n", fname, lineno ));
2094 #else
2095                       Debug( LDAP_DEBUG_ANY,
2096                              "%s: line %d: missing path in \"modulepath <path>\" line\n",
2097                              fname, lineno, 0 );
2098 #endif
2099
2100                       exit( EXIT_FAILURE );
2101                    }
2102                    if (module_path( cargv[1] )) {
2103 #ifdef NEW_LOGGING
2104                            LDAP_LOG(( "cofig", LDAP_LEVEL_CRIT,
2105                                       "%s: line %d: failed to set module search path to %s.\n",
2106                                       fname, lineno, cargv[1] ));
2107 #else
2108                            Debug( LDAP_DEBUG_ANY,
2109                                   "%s: line %d: failed to set module search path to %s\n",
2110                                   fname, lineno, cargv[1]);
2111 #endif
2112
2113                       exit( EXIT_FAILURE );
2114                    }
2115                    
2116 #endif /*SLAPD_MODULES*/
2117
2118 #ifdef HAVE_TLS
2119                 } else if ( !strcasecmp( cargv[0], "TLSRandFile" ) ) {
2120                         rc = ldap_pvt_tls_set_option( NULL,
2121                                                       LDAP_OPT_X_TLS_RANDOM_FILE,
2122                                                       cargv[1] );
2123                         if ( rc )
2124                                 return rc;
2125
2126                 } else if ( !strcasecmp( cargv[0], "TLSCipherSuite" ) ) {
2127                         rc = ldap_pvt_tls_set_option( NULL,
2128                                                       LDAP_OPT_X_TLS_CIPHER_SUITE,
2129                                                       cargv[1] );
2130                         if ( rc )
2131                                 return rc;
2132
2133                 } else if ( !strcasecmp( cargv[0], "TLSCertificateFile" ) ) {
2134                         rc = ldap_pvt_tls_set_option( NULL,
2135                                                       LDAP_OPT_X_TLS_CERTFILE,
2136                                                       cargv[1] );
2137                         if ( rc )
2138                                 return rc;
2139
2140                 } else if ( !strcasecmp( cargv[0], "TLSCertificateKeyFile" ) ) {
2141                         rc = ldap_pvt_tls_set_option( NULL,
2142                                                       LDAP_OPT_X_TLS_KEYFILE,
2143                                                       cargv[1] );
2144                         if ( rc )
2145                                 return rc;
2146
2147                 } else if ( !strcasecmp( cargv[0], "TLSCACertificatePath" ) ) {
2148                         rc = ldap_pvt_tls_set_option( NULL,
2149                                                       LDAP_OPT_X_TLS_CACERTDIR,
2150                                                       cargv[1] );
2151                         if ( rc )
2152                                 return rc;
2153
2154                 } else if ( !strcasecmp( cargv[0], "TLSCACertificateFile" ) ) {
2155                         rc = ldap_pvt_tls_set_option( NULL,
2156                                                       LDAP_OPT_X_TLS_CACERTFILE,
2157                                                       cargv[1] );
2158                         if ( rc )
2159                                 return rc;
2160                 } else if ( !strcasecmp( cargv[0], "TLSVerifyClient" ) ) {
2161                         i = atoi(cargv[1]);
2162                         rc = ldap_pvt_tls_set_option( NULL,
2163                                                       LDAP_OPT_X_TLS_REQUIRE_CERT,
2164                                                       &i );
2165                         if ( rc )
2166                                 return rc;
2167
2168 #endif
2169
2170                 /* pass anything else to the current backend info/db config routine */
2171                 } else {
2172                         if ( bi != NULL ) {
2173                                 if ( bi->bi_config == 0 ) {
2174 #ifdef NEW_LOGGING
2175                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
2176                                                    "%s: line %d: unknown directive \"%s\" inside "
2177                                                    "backend info definition (ignored).\n",
2178                                                    fname, lineno, cargv[0] ));
2179 #else
2180                                         Debug( LDAP_DEBUG_ANY,
2181 "%s: line %d: unknown directive \"%s\" inside backend info definition (ignored)\n",
2182                                                 fname, lineno, cargv[0] );
2183 #endif
2184
2185                                 } else {
2186                                         if ( (*bi->bi_config)( bi, fname, lineno, cargc, cargv )
2187                                                 != 0 )
2188                                         {
2189                                                 return( 1 );
2190                                         }
2191                                 }
2192                         } else if ( be != NULL ) {
2193                                 if ( be->be_config == 0 ) {
2194 #ifdef NEW_LOGGING
2195                                         LDAP_LOG(( "config", LDAP_LEVEL_INFO,
2196                                                    "%s: line %d: uknown directive \"%s\" inside "
2197                                                    "backend database definition (ignored).\n",
2198                                                    fname, lineno, cargv[0] ));
2199 #else
2200                                         Debug( LDAP_DEBUG_ANY,
2201 "%s: line %d: unknown directive \"%s\" inside backend database definition (ignored)\n",
2202                                         fname, lineno, cargv[0] );
2203 #endif
2204
2205                                 } else {
2206                                         if ( (*be->be_config)( be, fname, lineno, cargc, cargv )
2207                                                 != 0 )
2208                                         {
2209                                                 return( 1 );
2210                                         }
2211                                 }
2212                         } else {
2213 #ifdef NEW_LOGGING
2214                                 LDAP_LOG(( "config", LDAP_LEVEL_INFO,
2215                                            "%s: line %d: unknown directive \"%s\" outside backend "
2216                                            "info and database definitions (ignored).\n",
2217                                            fname, lineno, cargv[0] ));
2218 #else
2219                                 Debug( LDAP_DEBUG_ANY,
2220 "%s: line %d: unknown directive \"%s\" outside backend info and database definitions (ignored)\n",
2221                                     fname, lineno, cargv[0] );
2222 #endif
2223
2224                         }
2225                 }
2226                 free( saveline );
2227         }
2228         fclose( fp );
2229         if ( load_ucdata( NULL ) < 0 ) {
2230                 return( 1 );
2231         }
2232         return( 0 );
2233 }
2234
2235 static int
2236 fp_parse_line(
2237     char        *line,
2238     int         *argcp,
2239     char        **argv
2240 )
2241 {
2242         char *  token;
2243
2244         *argcp = 0;
2245         for ( token = strtok_quote( line, " \t" ); token != NULL;
2246             token = strtok_quote( NULL, " \t" ) ) {
2247                 if ( *argcp == MAXARGS ) {
2248 #ifdef NEW_LOGGING
2249                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
2250                                    "fp_parse_line: too many tokens (%d max).\n",
2251                                    MAXARGS ));
2252 #else
2253                         Debug( LDAP_DEBUG_ANY, "Too many tokens (max %d)\n",
2254                             MAXARGS, 0, 0 );
2255 #endif
2256
2257                         return( 1 );
2258                 }
2259                 argv[(*argcp)++] = token;
2260         }
2261         argv[*argcp] = NULL;
2262         return 0;
2263 }
2264
2265 static char *
2266 strtok_quote( char *line, char *sep )
2267 {
2268         int             inquote;
2269         char            *tmp;
2270         static char     *next;
2271
2272         if ( line != NULL ) {
2273                 next = line;
2274         }
2275         while ( *next && strchr( sep, *next ) ) {
2276                 next++;
2277         }
2278
2279         if ( *next == '\0' ) {
2280                 next = NULL;
2281                 return( NULL );
2282         }
2283         tmp = next;
2284
2285         for ( inquote = 0; *next; ) {
2286                 switch ( *next ) {
2287                 case '"':
2288                         if ( inquote ) {
2289                                 inquote = 0;
2290                         } else {
2291                                 inquote = 1;
2292                         }
2293                         AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
2294                         break;
2295
2296                 case '\\':
2297                         if ( next[1] )
2298                                 AC_MEMCPY( next,
2299                                             next + 1, strlen( next + 1 ) + 1 );
2300                         next++;         /* dont parse the escaped character */
2301                         break;
2302
2303                 default:
2304                         if ( ! inquote ) {
2305                                 if ( strchr( sep, *next ) != NULL ) {
2306                                         *next++ = '\0';
2307                                         return( tmp );
2308                                 }
2309                         }
2310                         next++;
2311                         break;
2312                 }
2313         }
2314
2315         return( tmp );
2316 }
2317
2318 static char     buf[BUFSIZ];
2319 static char     *line;
2320 static int      lmax, lcur;
2321
2322 #define CATLINE( buf )  { \
2323         int     len; \
2324         len = strlen( buf ); \
2325         while ( lcur + len + 1 > lmax ) { \
2326                 lmax += BUFSIZ; \
2327                 line = (char *) ch_realloc( line, lmax ); \
2328         } \
2329         strcpy( line + lcur, buf ); \
2330         lcur += len; \
2331 }
2332
2333 static char *
2334 fp_getline( FILE *fp, int *lineno )
2335 {
2336         char            *p;
2337
2338         lcur = 0;
2339         CATLINE( buf );
2340         (*lineno)++;
2341
2342         /* hack attack - keeps us from having to keep a stack of bufs... */
2343         if ( strncasecmp( line, "include", 7 ) == 0 ) {
2344                 buf[0] = '\0';
2345                 return( line );
2346         }
2347
2348         while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
2349                 /* trim off \r\n or \n */
2350                 if ( (p = strchr( buf, '\n' )) != NULL ) {
2351                         if( p > buf && p[-1] == '\r' ) --p;
2352                         *p = '\0';
2353                 }
2354                 if ( ! isspace( (unsigned char) buf[0] ) ) {
2355                         return( line );
2356                 }
2357
2358                 /* change leading whitespace to a space */
2359                 buf[0] = ' ';
2360
2361                 CATLINE( buf );
2362                 (*lineno)++;
2363         }
2364         buf[0] = '\0';
2365
2366         return( line[0] ? line : NULL );
2367 }
2368
2369 static void
2370 fp_getline_init( int *lineno )
2371 {
2372         *lineno = -1;
2373         buf[0] = '\0';
2374 }
2375
2376 /* Loads ucdata, returns 1 if loading, 0 if already loaded, -1 on error */
2377 static int
2378 load_ucdata( char *path )
2379 {
2380         static int loaded = 0;
2381         int err;
2382         
2383         if ( loaded ) {
2384                 return( 0 );
2385         }
2386         err = ucdata_load( path ? path : SLAPD_DEFAULT_UCDATA, UCDATA_ALL );
2387         if ( err ) {
2388 #ifdef NEW_LOGGING
2389                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
2390                            "load_ucdata: Error %d loading ucdata.\n", err ));
2391 #else
2392                 Debug( LDAP_DEBUG_ANY, "error loading ucdata (error %d)\n",
2393                        err, 0, 0 );
2394 #endif
2395
2396                 return( -1 );
2397         }
2398         loaded = 1;
2399         return( 1 );
2400 }
2401
2402 void
2403 config_destroy( )
2404 {
2405         ucdata_unload( UCDATA_ALL );
2406         free( line );
2407         if ( slapd_args_file )
2408                 free ( slapd_args_file );
2409         if ( slapd_pid_file )
2410                 free ( slapd_pid_file );
2411         acl_destroy( global_acl, NULL );
2412 }