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