]> git.sur5r.net Git - openldap/blob - servers/slapd/config.c
- LDAP_SYNCREPL defined in include/ldap.h
[openldap] / servers / slapd / config.c
1 /* config.c - configuration file handling routines */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2003 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/signal.h>
15 #include <ac/socket.h>
16 #include <ac/errno.h>
17
18 #include "ldap_pvt.h"
19 #include "slap.h"
20 #ifdef LDAP_SLAPI
21 #include "slapi.h"
22 #endif
23 #include "lutil.h"
24
25 #define ARGS_STEP       512
26
27 /*
28  * defaults for various global variables
29  */
30 struct slap_limits_set deflimit = {
31         SLAPD_DEFAULT_TIMELIMIT,        /* backward compatible limits */
32         0,
33
34         SLAPD_DEFAULT_SIZELIMIT,        /* backward compatible limits */
35         0,
36         -1,                             /* no limit on unchecked size */
37         0,                              /* page limit */
38         0                               /* hide number of entries left */
39 };
40
41 AccessControl   *global_acl = NULL;
42 slap_access_t           global_default_access = ACL_READ;
43 slap_mask_t             global_restrictops = 0;
44 slap_mask_t             global_allows = 0;
45 slap_mask_t             global_disallows = 0;
46 slap_mask_t             global_requires = 0;
47 slap_ssf_set_t  global_ssf_set;
48 char            *replogfile;
49 int             global_gentlehup = 0;
50 int             global_idletimeout = 0;
51 char    *global_host = NULL;
52 char    *global_realm = NULL;
53 char            *ldap_srvtab = "";
54 char            *default_passwd_hash = NULL;
55 int             cargc = 0, cargv_size = 0;
56 char    **cargv;
57 struct berval default_search_base = { 0, NULL };
58 struct berval default_search_nbase = { 0, NULL };
59 unsigned                num_subordinates = 0;
60 struct berval global_schemadn = { 0, NULL };
61 struct berval global_schemandn = { 0, NULL };
62
63 ber_len_t sockbuf_max_incoming = SLAP_SB_MAX_INCOMING_DEFAULT;
64 ber_len_t sockbuf_max_incoming_auth= SLAP_SB_MAX_INCOMING_AUTH;
65
66 int     slap_conn_max_pending = SLAP_CONN_MAX_PENDING_DEFAULT;
67 int     slap_conn_max_pending_auth = SLAP_CONN_MAX_PENDING_AUTH;
68
69 char   *slapd_pid_file  = NULL;
70 char   *slapd_args_file = NULL;
71
72 char   *strtok_quote_ptr;
73
74 int use_reverse_lookup = 0;
75
76 static char     *fp_getline(FILE *fp, int *lineno);
77 static void     fp_getline_init(int *lineno);
78 static int      fp_parse_line(int lineno, char *line);
79
80 static char     *strtok_quote(char *line, char *sep);
81 static int      load_ucdata(char *path);
82
83 #ifdef LDAP_SYNCREPL
84 static void     add_syncrepl LDAP_P(( Backend *, char **, int ));
85 static int      parse_syncrepl_line LDAP_P(( char **, int, syncinfo_t *));
86 #endif
87
88 int
89 read_config( const char *fname, int depth )
90 {
91         FILE    *fp;
92         char    *line, *savefname, *saveline;
93         int savelineno;
94         int     lineno, i;
95         int rc;
96         struct berval vals[2];
97
98         static int lastmod = 1;
99         static BackendInfo *bi = NULL;
100         static BackendDB        *be = NULL;
101
102         vals[1].bv_val = NULL;
103
104         if ( depth == 0 ) {
105                 cargv = ch_calloc( ARGS_STEP + 1, sizeof(*cargv) );
106                 cargv_size = ARGS_STEP + 1;
107         }
108
109         if ( (fp = fopen( fname, "r" )) == NULL ) {
110                 ldap_syslog = 1;
111 #ifdef NEW_LOGGING
112                 LDAP_LOG( CONFIG, ENTRY, 
113                         "read_config: " "could not open config file \"%s\": %s (%d)\n",
114                     fname, strerror(errno), errno );
115 #else
116                 Debug( LDAP_DEBUG_ANY,
117                     "could not open config file \"%s\": %s (%d)\n",
118                     fname, strerror(errno), errno );
119 #endif
120                 return 1;
121         }
122
123 #ifdef NEW_LOGGING
124         LDAP_LOG( CONFIG, ENTRY, 
125                 "read_config: reading config file %s\n", fname, 0, 0 );
126 #else
127         Debug( LDAP_DEBUG_CONFIG, "reading config file %s\n", fname, 0, 0 );
128 #endif
129
130
131         fp_getline_init( &lineno );
132
133         while ( (line = fp_getline( fp, &lineno )) != NULL ) {
134                 /* skip comments and blank lines */
135                 if ( line[0] == '#' || line[0] == '\0' ) {
136                         continue;
137                 }
138
139                 /* fp_parse_line is destructive, we save a copy */
140                 saveline = ch_strdup( line );
141
142                 if ( fp_parse_line( lineno, line ) != 0 ) {
143                         return( 1 );
144                 }
145
146                 if ( cargc < 1 ) {
147 #ifdef NEW_LOGGING
148                         LDAP_LOG( CONFIG, INFO, 
149                                 "%s: line %d: bad config line (ignored)\n", fname, lineno, 0 );
150 #else
151                         Debug( LDAP_DEBUG_ANY,
152                             "%s: line %d: bad config line (ignored)\n",
153                             fname, lineno, 0 );
154 #endif
155
156                         continue;
157                 }
158
159                 if ( strcasecmp( cargv[0], "backend" ) == 0 ) {
160                         if ( cargc < 2 ) {
161 #ifdef NEW_LOGGING
162                                 LDAP_LOG( CONFIG, CRIT, 
163                                            "%s : line %d: missing type in \"backend\" line.\n",
164                                            fname, lineno, 0 );
165 #else
166                                 Debug( LDAP_DEBUG_ANY,
167                 "%s: line %d: missing type in \"backend <type>\" line\n",
168                                     fname, lineno, 0 );
169 #endif
170
171                                 return( 1 );
172                         }
173
174                         if( be != NULL ) {
175 #ifdef NEW_LOGGING
176                                 LDAP_LOG( CONFIG, CRIT, 
177                                            "%s: line %d: backend line must appear before any "
178                                            "database definition.\n", fname, lineno , 0 );
179 #else
180                                 Debug( LDAP_DEBUG_ANY,
181 "%s: line %d: backend line must appear before any database definition\n",
182                                     fname, lineno, 0 );
183 #endif
184
185                                 return( 1 );
186                         }
187
188                         bi = backend_info( cargv[1] );
189
190                         if( bi == NULL ) {
191 #ifdef NEW_LOGGING
192                                 LDAP_LOG( CONFIG, CRIT, 
193                                            "read_config: backend %s initialization failed.\n",
194                                            cargv[1], 0, 0 );
195 #else
196                                 Debug( LDAP_DEBUG_ANY,
197                                         "backend %s initialization failed.\n",
198                                     cargv[1], 0, 0 );
199 #endif
200
201                                 return( 1 );
202                         }
203                 } else if ( strcasecmp( cargv[0], "database" ) == 0 ) {
204                         if ( cargc < 2 ) {
205 #ifdef NEW_LOGGING
206                                 LDAP_LOG( CONFIG, CRIT, 
207                                         "%s: line %d: missing type in \"database <type>\" line\n",
208                                         fname, lineno, 0 );
209 #else
210                                 Debug( LDAP_DEBUG_ANY,
211                 "%s: line %d: missing type in \"database <type>\" line\n",
212                                     fname, lineno, 0 );
213 #endif
214
215                                 return( 1 );
216                         }
217
218                         bi = NULL;
219                         be = backend_db_init( cargv[1] );
220
221                         if( be == NULL ) {
222 #ifdef NEW_LOGGING
223                                 LDAP_LOG( CONFIG, CRIT, 
224                                         "database %s initialization failed.\n", cargv[1], 0, 0 );
225 #else
226                                 Debug( LDAP_DEBUG_ANY,
227                                         "database %s initialization failed.\n",
228                                     cargv[1], 0, 0 );
229 #endif
230
231                                 return( 1 );
232                         }
233
234                 /* set thread concurrency */
235                 } else if ( strcasecmp( cargv[0], "concurrency" ) == 0 ) {
236                         int c;
237                         if ( cargc < 2 ) {
238 #ifdef NEW_LOGGING
239                                 LDAP_LOG( CONFIG, CRIT, 
240                                         "%s: line %d: missing level in \"concurrency <level\" "
241                                         " line\n", fname, lineno, 0 );
242 #else
243                                 Debug( LDAP_DEBUG_ANY,
244             "%s: line %d: missing level in \"concurrency <level>\" line\n",
245                                     fname, lineno, 0 );
246 #endif
247
248                                 return( 1 );
249                         }
250
251                         c = atoi( cargv[1] );
252
253                         if( c < 1 ) {
254 #ifdef NEW_LOGGING
255                                 LDAP_LOG( CONFIG, CRIT, 
256                                         "%s: line %d: invalid level (%d) in "
257                                         "\"concurrency <level>\" line.\n", fname, lineno, c );
258 #else
259                                 Debug( LDAP_DEBUG_ANY,
260             "%s: line %d: invalid level (%d) in \"concurrency <level>\" line\n",
261                                     fname, lineno, c );
262 #endif
263
264                                 return( 1 );
265                         }
266
267                         ldap_pvt_thread_set_concurrency( c );
268
269                 /* set sockbuf max */
270                 } else if ( strcasecmp( cargv[0], "sockbuf_max_incoming" ) == 0 ) {
271                         long max;
272                         if ( cargc < 2 ) {
273 #ifdef NEW_LOGGING
274                                 LDAP_LOG( CONFIG, CRIT, 
275                                    "%s: line %d: missing max in \"sockbuf_max_incoming "
276                                    "<bytes>\" line\n", fname, lineno, 0 );
277 #else
278                                 Debug( LDAP_DEBUG_ANY,
279                                            "%s: line %d: missing max in \"sockbuf_max_incoming <bytes>\" line\n",
280                                     fname, lineno, 0 );
281 #endif
282
283                                 return( 1 );
284                         }
285
286                         max = atol( cargv[1] );
287
288                         if( max < 0 ) {
289 #ifdef NEW_LOGGING
290                                 LDAP_LOG( CONFIG, CRIT, 
291                                            "%s: line %d: invalid max value (%ld) in "
292                                            "\"sockbuf_max_incoming <bytes>\" line.\n",
293                                            fname, lineno, max );
294 #else
295                                 Debug( LDAP_DEBUG_ANY,
296                                         "%s: line %d: invalid max value (%ld) in "
297                                         "\"sockbuf_max_incoming <bytes>\" line.\n",
298                                     fname, lineno, max );
299 #endif
300
301                                 return( 1 );
302                         }
303
304                         sockbuf_max_incoming = max;
305
306                 /* set sockbuf max authenticated */
307                 } else if ( strcasecmp( cargv[0], "sockbuf_max_incoming_auth" ) == 0 ) {
308                         long max;
309                         if ( cargc < 2 ) {
310 #ifdef NEW_LOGGING
311                                 LDAP_LOG( CONFIG, CRIT, 
312                                    "%s: line %d: missing max in \"sockbuf_max_incoming_auth "
313                                    "<bytes>\" line\n", fname, lineno, 0 );
314 #else
315                                 Debug( LDAP_DEBUG_ANY,
316                                            "%s: line %d: missing max in \"sockbuf_max_incoming_auth <bytes>\" line\n",
317                                     fname, lineno, 0 );
318 #endif
319
320                                 return( 1 );
321                         }
322
323                         max = atol( cargv[1] );
324
325                         if( max < 0 ) {
326 #ifdef NEW_LOGGING
327                                 LDAP_LOG( CONFIG, CRIT, 
328                                            "%s: line %d: invalid max value (%ld) in "
329                                            "\"sockbuf_max_incoming_auth <bytes>\" line.\n",
330                                            fname, lineno, max );
331 #else
332                                 Debug( LDAP_DEBUG_ANY,
333                                         "%s: line %d: invalid max value (%ld) in "
334                                         "\"sockbuf_max_incoming_auth <bytes>\" line.\n",
335                                     fname, lineno, max );
336 #endif
337
338                                 return( 1 );
339                         }
340
341                         sockbuf_max_incoming_auth = max;
342
343                 /* set conn pending max */
344                 } else if ( strcasecmp( cargv[0], "conn_max_pending" ) == 0 ) {
345                         long max;
346                         if ( cargc < 2 ) {
347 #ifdef NEW_LOGGING
348                                 LDAP_LOG( CONFIG, CRIT, 
349                                    "%s: line %d: missing max in \"conn_max_pending "
350                                    "<requests>\" line\n", fname, lineno, 0 );
351 #else
352                                 Debug( LDAP_DEBUG_ANY,
353                                            "%s: line %d: missing max in \"conn_max_pending <requests>\" line\n",
354                                     fname, lineno, 0 );
355 #endif
356
357                                 return( 1 );
358                         }
359
360                         max = atol( cargv[1] );
361
362                         if( max < 0 ) {
363 #ifdef NEW_LOGGING
364                                 LDAP_LOG( CONFIG, CRIT, 
365                                            "%s: line %d: invalid max value (%ld) in "
366                                            "\"conn_max_pending <requests>\" line.\n",
367                                            fname, lineno, max );
368 #else
369                                 Debug( LDAP_DEBUG_ANY,
370                                         "%s: line %d: invalid max value (%ld) in "
371                                         "\"conn_max_pending <requests>\" line.\n",
372                                     fname, lineno, max );
373 #endif
374
375                                 return( 1 );
376                         }
377
378                         slap_conn_max_pending = max;
379
380                 /* set conn pending max authenticated */
381                 } else if ( strcasecmp( cargv[0], "conn_max_pending_auth" ) == 0 ) {
382                         long max;
383                         if ( cargc < 2 ) {
384 #ifdef NEW_LOGGING
385                                 LDAP_LOG( CONFIG, CRIT, 
386                                    "%s: line %d: missing max in \"conn_max_pending_auth "
387                                    "<requests>\" line\n", fname, lineno, 0 );
388 #else
389                                 Debug( LDAP_DEBUG_ANY,
390                                            "%s: line %d: missing max in \"conn_max_pending_auth <requests>\" line\n",
391                                     fname, lineno, 0 );
392 #endif
393
394                                 return( 1 );
395                         }
396
397                         max = atol( cargv[1] );
398
399                         if( max < 0 ) {
400 #ifdef NEW_LOGGING
401                                 LDAP_LOG( CONFIG, CRIT, 
402                                            "%s: line %d: invalid max value (%ld) in "
403                                            "\"conn_max_pending_auth <requests>\" line.\n",
404                                            fname, lineno, max );
405 #else
406                                 Debug( LDAP_DEBUG_ANY,
407                                         "%s: line %d: invalid max value (%ld) in "
408                                         "\"conn_max_pending_auth <requests>\" line.\n",
409                                     fname, lineno, max );
410 #endif
411
412                                 return( 1 );
413                         }
414
415                         slap_conn_max_pending_auth = max;
416
417                 /* default search base */
418                 } else if ( strcasecmp( cargv[0], "defaultSearchBase" ) == 0 ) {
419                         if ( cargc < 2 ) {
420 #ifdef NEW_LOGGING
421                                 LDAP_LOG( CONFIG, CRIT, 
422                                         "%s: line %d: missing dn in \"defaultSearchBase <dn\" "
423                                         "line\n", fname, lineno, 0 );
424 #else
425                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
426                                         "missing dn in \"defaultSearchBase <dn>\" line\n",
427                                         fname, lineno, 0 );
428 #endif
429
430                                 return 1;
431
432                         } else if ( cargc > 2 ) {
433 #ifdef NEW_LOGGING
434                                 LDAP_LOG( CONFIG, INFO, 
435                                         "%s: line %d: extra cruft after <dn> in "
436                                         "\"defaultSearchBase %s\" line (ignored)\n",
437                                         fname, lineno, cargv[1] );
438 #else
439                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
440                                         "extra cruft after <dn> in \"defaultSearchBase %s\", "
441                                         "line (ignored)\n",
442                                         fname, lineno, cargv[1] );
443 #endif
444                         }
445
446                         if ( bi != NULL || be != NULL ) {
447 #ifdef NEW_LOGGING
448                                 LDAP_LOG( CONFIG, CRIT, 
449                                         "%s: line %d: defaultSearchBase line must appear "
450                                         "prior to any backend or database definitions\n",
451                                         fname, lineno, 0 );
452 #else
453                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
454                                         "defaultSearchBaase line must appear prior to "
455                                         "any backend or database definition\n",
456                                     fname, lineno, 0 );
457 #endif
458
459                                 return 1;
460                         }
461
462                         if ( default_search_nbase.bv_len ) {
463 #ifdef NEW_LOGGING
464                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
465                                         "default search base \"%s\" already defined "
466                                         "(discarding old)\n", fname, lineno,
467                                         default_search_base.bv_val );
468 #else
469                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
470                                         "default search base \"%s\" already defined "
471                                         "(discarding old)\n",
472                                         fname, lineno, default_search_base.bv_val );
473 #endif
474
475                                 free( default_search_base.bv_val );
476                                 free( default_search_nbase.bv_val );
477                         }
478
479                         if ( load_ucdata( NULL ) < 0 ) return 1;
480
481                         {
482                                 struct berval dn;
483
484                                 dn.bv_val = cargv[1];
485                                 dn.bv_len = strlen( dn.bv_val );
486
487                                 rc = dnPrettyNormal( NULL, &dn,
488                                         &default_search_base,
489                                         &default_search_nbase, NULL );
490
491                                 if( rc != LDAP_SUCCESS ) {
492 #ifdef NEW_LOGGING
493                                         LDAP_LOG( CONFIG, CRIT, 
494                                                 "%s: line %d: defaultSearchBase DN is invalid.\n",
495                                                 fname, lineno, 0 );
496 #else
497                                         Debug( LDAP_DEBUG_ANY,
498                                                 "%s: line %d: defaultSearchBase DN is invalid\n",
499                                            fname, lineno, 0 );
500 #endif
501                                         return( 1 );
502                                 }
503                         }
504
505                 /* set maximum threads in thread pool */
506                 } else if ( strcasecmp( cargv[0], "threads" ) == 0 ) {
507                         int c;
508                         if ( cargc < 2 ) {
509 #ifdef NEW_LOGGING
510                                 LDAP_LOG( CONFIG, CRIT, 
511                                         "%s: line %d: missing count in \"threads <count>\" line\n",
512                                         fname, lineno, 0 );
513 #else
514                                 Debug( LDAP_DEBUG_ANY,
515             "%s: line %d: missing count in \"threads <count>\" line\n",
516                                     fname, lineno, 0 );
517 #endif
518
519                                 return( 1 );
520                         }
521
522                         c = atoi( cargv[1] );
523
524                         if( c < 0 ) {
525 #ifdef NEW_LOGGING
526                                 LDAP_LOG( CONFIG, CRIT, 
527                                            "%s: line %d: invalid level (%d) in \"threads <count>\""
528                                            "line\n", fname, lineno, c );
529 #else
530                                 Debug( LDAP_DEBUG_ANY,
531             "%s: line %d: invalid level (%d) in \"threads <count>\" line\n",
532                                     fname, lineno, c );
533 #endif
534
535                                 return( 1 );
536                         }
537
538                         ldap_pvt_thread_pool_maxthreads( &connection_pool, c );
539
540                         /* save for later use */
541                         connection_pool_max = c;
542
543                 /* get pid file name */
544                 } else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) {
545                         if ( cargc < 2 ) {
546 #ifdef NEW_LOGGING
547                                 LDAP_LOG( CONFIG, CRIT, 
548                                         "%s: line %d missing file name in \"pidfile <file>\" "
549                                         "line.\n", fname, lineno, 0 );
550 #else
551                                 Debug( LDAP_DEBUG_ANY,
552             "%s: line %d: missing file name in \"pidfile <file>\" line\n",
553                                     fname, lineno, 0 );
554 #endif
555
556                                 return( 1 );
557                         }
558
559                         slapd_pid_file = ch_strdup( cargv[1] );
560
561                 /* get args file name */
562                 } else if ( strcasecmp( cargv[0], "argsfile" ) == 0 ) {
563                         if ( cargc < 2 ) {
564 #ifdef NEW_LOGGING
565                                 LDAP_LOG( CONFIG, CRIT, 
566                                            "%s: %d: missing file name in "
567                                            "\"argsfile <file>\" line.\n",
568                                            fname, lineno, 0 );
569 #else
570                                 Debug( LDAP_DEBUG_ANY,
571             "%s: line %d: missing file name in \"argsfile <file>\" line\n",
572                                     fname, lineno, 0 );
573 #endif
574
575                                 return( 1 );
576                         }
577
578                         slapd_args_file = ch_strdup( cargv[1] );
579
580                 } else if ( strcasecmp( cargv[0], "replica-pidfile" ) == 0 ) {
581                         /* ignore */ ;
582
583                 } else if ( strcasecmp( cargv[0], "replica-argsfile" ) == 0 ) {
584                         /* ignore */ ;
585
586                 /* default password hash */
587                 } else if ( strcasecmp( cargv[0], "password-hash" ) == 0 ) {
588                         if ( cargc < 2 ) {
589 #ifdef NEW_LOGGING
590                                 LDAP_LOG( CONFIG, CRIT, 
591                                            "%s: line %d: missing hash in "
592                                            "\"password-hash <hash>\" line.\n",
593                                            fname, lineno, 0 );
594 #else
595                                 Debug( LDAP_DEBUG_ANY,
596             "%s: line %d: missing hash in \"password-hash <hash>\" line\n",
597                                     fname, lineno, 0 );
598 #endif
599
600                                 return( 1 );
601                         }
602                         if ( default_passwd_hash != NULL ) {
603 #ifdef NEW_LOGGING
604                                 LDAP_LOG( CONFIG, CRIT, 
605                                            "%s: line %d: already set default password_hash!\n",
606                                            fname, lineno, 0 );
607 #else
608                                 Debug( LDAP_DEBUG_ANY,
609                                         "%s: line %d: already set default password_hash!\n",
610                                         fname, lineno, 0 );
611 #endif
612
613                                 return 1;
614
615                         }
616
617                         if ( lutil_passwd_scheme( cargv[1] ) == 0 ) {
618 #ifdef NEW_LOGGING
619                                 LDAP_LOG( CONFIG, CRIT, 
620                                            "%s: line %d: password scheme \"%s\" not available\n",
621                                            fname, lineno, cargv[1] );
622 #else
623                                 Debug( LDAP_DEBUG_ANY,
624                                         "%s: line %d: password scheme \"%s\" not available\n",
625                                         fname, lineno, cargv[1] );
626 #endif
627                                 return 1;
628                         }
629
630                         default_passwd_hash = ch_strdup( cargv[1] );
631
632                 } else if ( strcasecmp( cargv[0], "password-crypt-salt-format" ) == 0 ) 
633                 {
634                         if ( cargc < 2 ) {
635 #ifdef NEW_LOGGING
636                                 LDAP_LOG( CONFIG, CRIT, 
637                                         "%s: line %d: missing format in "
638                                         "\"password-crypt-salt-format <format>\" line\n",
639                                         fname, lineno, 0 );
640 #else
641                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: missing format in "
642                                         "\"password-crypt-salt-format <format>\" line\n",
643                                     fname, lineno, 0 );
644 #endif
645
646                                 return 1;
647                         }
648
649                         lutil_salt_format( cargv[1] );
650
651                 /* SASL config options */
652                 } else if ( strncasecmp( cargv[0], "sasl", 4 ) == 0 ) {
653                         if ( slap_sasl_config( cargc, cargv, line, fname, lineno ) )
654                                 return 1;
655
656                 } else if ( strcasecmp( cargv[0], "schemadn" ) == 0 ) {
657                         struct berval dn;
658                         if ( cargc < 2 ) {
659 #ifdef NEW_LOGGING
660                                 LDAP_LOG( CONFIG, CRIT, 
661                                            "%s: line %d: missing dn in "
662                                            "\"schemadn <dn>\" line.\n", fname, lineno, 0  );
663 #else
664                                 Debug( LDAP_DEBUG_ANY,
665             "%s: line %d: missing dn in \"schemadn <dn>\" line\n",
666                                     fname, lineno, 0 );
667 #endif
668                                 return 1 ;
669                         }
670                         ber_str2bv( cargv[1], 0, 0, &dn );
671                         if ( be ) {
672                                 rc = dnPrettyNormal( NULL, &dn, &be->be_schemadn,
673                                         &be->be_schemandn, NULL );
674                         } else {
675                                 rc = dnPrettyNormal( NULL, &dn, &global_schemadn,
676                                         &global_schemandn, NULL );
677                         }
678                         if ( rc != LDAP_SUCCESS ) {
679 #ifdef NEW_LOGGING
680                                 LDAP_LOG( CONFIG, CRIT, 
681                                         "%s: line %d: schemadn DN is invalid.\n",
682                                         fname, lineno , 0 );
683 #else
684                                 Debug( LDAP_DEBUG_ANY,
685                                         "%s: line %d: schemadn DN is invalid\n",
686                                         fname, lineno, 0 );
687 #endif
688                                 return 1;
689                         }
690
691                 /* set UCDATA path */
692                 } else if ( strcasecmp( cargv[0], "ucdata-path" ) == 0 ) {
693                         int err;
694                         if ( cargc < 2 ) {
695 #ifdef NEW_LOGGING
696                                 LDAP_LOG( CONFIG, CRIT, 
697                                            "%s: line %d: missing path in "
698                                            "\"ucdata-path <path>\" line.\n", fname, lineno, 0  );
699 #else
700                                 Debug( LDAP_DEBUG_ANY,
701             "%s: line %d: missing path in \"ucdata-path <path>\" line\n",
702                                     fname, lineno, 0 );
703 #endif
704
705                                 return( 1 );
706                         }
707
708                         err = load_ucdata( cargv[1] );
709                         if ( err <= 0 ) {
710                                 if ( err == 0 ) {
711 #ifdef NEW_LOGGING
712                                         LDAP_LOG( CONFIG, CRIT, 
713                                                    "%s: line %d: ucdata already loaded, ucdata-path "
714                                                    "must be set earlier in the file and/or be "
715                                                    "specified only once!\n", fname, lineno, 0 );
716 #else
717                                         Debug( LDAP_DEBUG_ANY,
718                                                "%s: line %d: ucdata already loaded, ucdata-path must be set earlier in the file and/or be specified only once!\n",
719                                                fname, lineno, 0 );
720 #endif
721
722                                 }
723                                 return( 1 );
724                         }
725
726                 /* set size limit */
727                 } else if ( strcasecmp( cargv[0], "sizelimit" ) == 0 ) {
728                         int rc = 0, i;
729                         struct slap_limits_set *lim;
730                         
731                         if ( cargc < 2 ) {
732 #ifdef NEW_LOGGING
733                                 LDAP_LOG( CONFIG, CRIT, 
734                                    "%s: line %d: missing limit in \"sizelimit <limit>\" "
735                                    "line.\n", fname, lineno, 0 );
736 #else
737                                 Debug( LDAP_DEBUG_ANY,
738             "%s: line %d: missing limit in \"sizelimit <limit>\" line\n",
739                                     fname, lineno, 0 );
740 #endif
741
742                                 return( 1 );
743                         }
744
745                         if ( be == NULL ) {
746                                 lim = &deflimit;
747                         } else {
748                                 lim = &be->be_def_limit;
749                         }
750
751                         for ( i = 1; i < cargc; i++ ) {
752                                 if ( strncasecmp( cargv[i], "size", 4 ) == 0 ) {
753                                         rc = parse_limit( cargv[i], lim );
754                                         if ( rc ) {
755 #ifdef NEW_LOGGING
756                                                 LDAP_LOG( CONFIG, CRIT, 
757                                                         "%s: line %d: unable "
758                                                            "to parse value \"%s\" in \"sizelimit "
759                                                            "<limit>\" line.\n", fname, lineno, cargv[i] );
760 #else
761                                                 Debug( LDAP_DEBUG_ANY,
762                                                         "%s: line %d: unable "
763                                                         "to parse value \"%s\" "
764                                                         "in \"sizelimit "
765                                                         "<limit>\" line\n",
766                                                         fname, lineno, cargv[i] );
767 #endif
768                                                 return( 1 );
769                                         }
770
771                                 } else {
772                                         if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) {
773                                                 lim->lms_s_soft = -1;
774                                         } else {
775                                                 char *next;
776
777                                                 lim->lms_s_soft = strtol( cargv[i] , &next, 0 );
778                                                 if ( next == cargv[i] ) {
779 #ifdef NEW_LOGGING
780                                                         LDAP_LOG( CONFIG, CRIT, 
781                                                            "%s: line %d: unable to parse limit \"%s\" in \"sizelimit <limit>\" "
782                                                            "line.\n", fname, lineno, cargv[i] );
783 #else
784                                                         Debug( LDAP_DEBUG_ANY,
785                                                             "%s: line %d: unable to parse limit \"%s\" in \"sizelimit <limit>\" line\n",
786                                                             fname, lineno, cargv[i] );
787 #endif
788                                                         return( 1 );
789
790                                                 } else if ( next[0] != '\0' ) {
791 #ifdef NEW_LOGGING
792                                                         LDAP_LOG( CONFIG, CRIT, 
793                                                            "%s: line %d: trailing chars \"%s\" in \"sizelimit <limit>\" "
794                                                            "line ignored.\n", fname, lineno, next );
795 #else
796                                                         Debug( LDAP_DEBUG_ANY,
797                                                             "%s: line %d: trailing chars \"%s\" in \"sizelimit <limit>\" line ignored\n",
798                                                             fname, lineno, next );
799 #endif
800                                                 }
801                                         }
802                                         lim->lms_s_hard = 0;
803                                 }
804                         }
805
806                 /* set time limit */
807                 } else if ( strcasecmp( cargv[0], "timelimit" ) == 0 ) {
808                         int rc = 0, i;
809                         struct slap_limits_set *lim;
810                         
811                         if ( cargc < 2 ) {
812 #ifdef NEW_LOGGING
813                                 LDAP_LOG( CONFIG, CRIT, 
814                                         "%s: line %d missing limit in \"timelimit <limit>\" "
815                                         "line.\n", fname, lineno, 0 );
816 #else
817                                 Debug( LDAP_DEBUG_ANY,
818             "%s: line %d: missing limit in \"timelimit <limit>\" line\n",
819                                     fname, lineno, 0 );
820 #endif
821
822                                 return( 1 );
823                         }
824                         
825                         if ( be == NULL ) {
826                                 lim = &deflimit;
827                         } else {
828                                 lim = &be->be_def_limit;
829                         }
830
831                         for ( i = 1; i < cargc; i++ ) {
832                                 if ( strncasecmp( cargv[i], "time", 4 ) == 0 ) {
833                                         rc = parse_limit( cargv[i], lim );
834                                         if ( rc ) {
835 #ifdef NEW_LOGGING
836                                                 LDAP_LOG( CONFIG, CRIT, 
837                                                             "%s: line %d: unable to parse value \"%s\" "
838                                                            "in \"timelimit <limit>\" line.\n",
839                                                            fname, lineno, cargv[i] );
840 #else
841                                                 Debug( LDAP_DEBUG_ANY,
842                                                         "%s: line %d: unable "
843                                                         "to parse value \"%s\" "
844                                                         "in \"timelimit "
845                                                         "<limit>\" line\n",
846                                                         fname, lineno, cargv[i] );
847 #endif
848                                                 return( 1 );
849                                         }
850
851                                 } else {
852                                         if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) {
853                                                 lim->lms_t_soft = -1;
854                                         } else {
855                                                 char *next;
856
857                                                 lim->lms_t_soft = strtol( cargv[i] , &next, 0 );
858                                                 if ( next == cargv[i] ) {
859 #ifdef NEW_LOGGING
860                                                         LDAP_LOG( CONFIG, CRIT, 
861                                                            "%s: line %d: unable to parse limit \"%s\" in \"timelimit <limit>\" "
862                                                            "line.\n", fname, lineno, cargv[i] );
863 #else
864                                                         Debug( LDAP_DEBUG_ANY,
865                                                             "%s: line %d: unable to parse limit \"%s\" in \"timelimit <limit>\" line\n",
866                                                             fname, lineno, cargv[i] );
867 #endif
868                                                         return( 1 );
869
870                                                 } else if ( next[0] != '\0' ) {
871 #ifdef NEW_LOGGING
872                                                         LDAP_LOG( CONFIG, CRIT, 
873                                                            "%s: line %d: trailing chars \"%s\" in \"timelimit <limit>\" "
874                                                            "line ignored.\n", fname, lineno, next );
875 #else
876                                                         Debug( LDAP_DEBUG_ANY,
877                                                             "%s: line %d: trailing chars \"%s\" in \"timelimit <limit>\" line ignored\n",
878                                                             fname, lineno, next );
879 #endif
880                                                 }
881                                         }
882                                         lim->lms_t_hard = 0;
883                                 }
884                         }
885
886                 /* set regex-based limits */
887                 } else if ( strcasecmp( cargv[0], "limits" ) == 0 ) {
888                         if ( be == NULL ) {
889 #ifdef NEW_LOGGING
890                                 LDAP_LOG( CONFIG, WARNING, 
891                                            "%s: line %d \"limits\" allowed only in database "
892                                            "environment.\n", fname, lineno, 0 );
893 #else
894                                 Debug( LDAP_DEBUG_ANY,
895         "%s: line %d \"limits\" allowed only in database environment.\n%s",
896                                         fname, lineno, "" );
897 #endif
898                                 return( 1 );
899                         }
900
901                         if ( parse_limits( be, fname, lineno, cargc, cargv ) ) {
902                                 return( 1 );
903                         }
904
905                 /* mark this as a subordinate database */
906                 } else if ( strcasecmp( cargv[0], "subordinate" ) == 0 ) {
907                         if ( be == NULL ) {
908 #ifdef NEW_LOGGING
909                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
910                                         "subordinate keyword must appear inside a database "
911                                         "definition.\n", fname, lineno, 0 );
912 #else
913                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix line "
914                                         "must appear inside a database definition.\n",
915                                     fname, lineno, 0 );
916 #endif
917                                 return 1;
918
919                         } else {
920                                 be->be_flags |= SLAP_BFLAG_GLUE_SUBORDINATE;
921                                 num_subordinates++;
922                         }
923
924                 /* set database suffix */
925                 } else if ( strcasecmp( cargv[0], "suffix" ) == 0 ) {
926                         Backend *tmp_be;
927                         struct berval dn, pdn, ndn;
928
929                         if ( cargc < 2 ) {
930 #ifdef NEW_LOGGING
931                                 LDAP_LOG( CONFIG, CRIT, 
932                                         "%s: line %d: missing dn in \"suffix <dn>\" line.\n",
933                                         fname, lineno, 0 );
934 #else
935                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
936                                         "missing dn in \"suffix <dn>\" line\n",
937                                     fname, lineno, 0 );
938 #endif
939
940                                 return( 1 );
941
942                         } else if ( cargc > 2 ) {
943 #ifdef NEW_LOGGING
944                                 LDAP_LOG( CONFIG, INFO, 
945                                         "%s: line %d: extra cruft after <dn> in \"suffix %s\""
946                                         " line (ignored).\n", fname, lineno, cargv[1] );
947 #else
948                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: extra cruft "
949                                         "after <dn> in \"suffix %s\" line (ignored)\n",
950                                     fname, lineno, cargv[1] );
951 #endif
952                         }
953
954                         if ( be == NULL ) {
955 #ifdef NEW_LOGGING
956                                 LDAP_LOG( CONFIG, INFO, 
957                                         "%s: line %d: suffix line must appear inside a database "
958                                         "definition.\n", fname, lineno, 0 );
959 #else
960                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix line "
961                                         "must appear inside a database definition\n",
962                                     fname, lineno, 0 );
963 #endif
964                                 return( 1 );
965
966 #if defined(SLAPD_MONITOR_DN)
967                         /* "cn=Monitor" is reserved for monitoring slap */
968                         } else if ( strcasecmp( cargv[1], SLAPD_MONITOR_DN ) == 0 ) {
969 #ifdef NEW_LOGGING
970                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: \""
971                                         SLAPD_MONITOR_DN "\" is reserved for monitoring slapd\n", 
972                                         fname, lineno, 0 );
973 #else
974                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: \""
975                                         SLAPD_MONITOR_DN "\" is reserved for monitoring slapd\n", 
976                                         fname, lineno, 0 );
977 #endif
978                                 return( 1 );
979 #endif /* SLAPD_MONITOR_DN */
980                         }
981
982                         if ( load_ucdata( NULL ) < 0 ) return 1;
983
984                         dn.bv_val = cargv[1];
985                         dn.bv_len = strlen( cargv[1] );
986
987                         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL );
988                         if( rc != LDAP_SUCCESS ) {
989 #ifdef NEW_LOGGING
990                                 LDAP_LOG( CONFIG, CRIT, 
991                                         "%s: line %d: suffix DN is invalid.\n",
992                                         fname, lineno, 0 );
993 #else
994                                 Debug( LDAP_DEBUG_ANY,
995                                         "%s: line %d: suffix DN is invalid\n",
996                                    fname, lineno, 0 );
997 #endif
998                                 return( 1 );
999                         }
1000
1001                         tmp_be = select_backend( &ndn, 0, 0 );
1002                         if ( tmp_be == be ) {
1003 #ifdef NEW_LOGGING
1004                                 LDAP_LOG( CONFIG, INFO, 
1005                                         "%s: line %d: suffix already served by this backend "
1006                                         "(ignored)\n", fname, lineno, 0 );
1007 #else
1008                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
1009                                         "already served by this backend (ignored)\n",
1010                                     fname, lineno, 0 );
1011 #endif
1012                                 free( pdn.bv_val );
1013                                 free( ndn.bv_val );
1014
1015                         } else if ( tmp_be  != NULL ) {
1016 #ifdef NEW_LOGGING
1017                                 LDAP_LOG( CONFIG, INFO, 
1018                                         "%s: line %d: suffix already served by a preceding "
1019                                         "backend \"%s\"\n", fname, lineno,
1020                                         tmp_be->be_suffix[0].bv_val );
1021 #else
1022                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
1023                                         "already served by a preceeding backend \"%s\"\n",
1024                                     fname, lineno, tmp_be->be_suffix[0].bv_val );
1025 #endif
1026                                 free( pdn.bv_val );
1027                                 free( ndn.bv_val );
1028                                 return( 1 );
1029
1030                         } else if( pdn.bv_len == 0 && default_search_nbase.bv_len ) {
1031 #ifdef NEW_LOGGING
1032                                         LDAP_LOG( CONFIG, INFO, 
1033                                                 "%s: line %d: suffix DN empty and default search "
1034                                                 "base provided \"%s\" (assuming okay).\n",
1035                                                 fname, lineno, default_search_base.bv_val );
1036 #else
1037                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1038                                                 "suffix DN empty and default "
1039                                                 "search base provided \"%s\" (assuming okay)\n",
1040                                         fname, lineno, default_search_base.bv_val );
1041 #endif
1042                         }
1043
1044                         ber_bvarray_add( &be->be_suffix, &pdn );
1045                         ber_bvarray_add( &be->be_nsuffix, &ndn );
1046
1047                /* set max deref depth */
1048                } else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
1049                                         int i;
1050                        if ( cargc < 2 ) {
1051 #ifdef NEW_LOGGING
1052                                LDAP_LOG( CONFIG, CRIT, 
1053                                           "%s: line %d: missing depth in \"maxDerefDepth <depth>\""
1054                                           " line\n", fname, lineno, 0 );
1055 #else
1056                                Debug( LDAP_DEBUG_ANY,
1057                    "%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
1058                                    fname, lineno, 0 );
1059 #endif
1060
1061                                return( 1 );
1062                        }
1063                        if ( be == NULL ) {
1064 #ifdef NEW_LOGGING
1065                                LDAP_LOG( CONFIG, INFO, 
1066                                           "%s: line %d: depth line must appear inside a database "
1067                                           "definition.\n", fname, lineno ,0 );
1068 #else
1069                                Debug( LDAP_DEBUG_ANY,
1070 "%s: line %d: depth line must appear inside a database definition.\n",
1071                                    fname, lineno, 0 );
1072 #endif
1073                                                         return 1;
1074
1075                        } else if ((i = atoi(cargv[1])) < 0) {
1076 #ifdef NEW_LOGGING
1077                                LDAP_LOG( CONFIG, INFO, 
1078                                           "%s: line %d: depth must be positive.\n",
1079                                           fname, lineno ,0 );
1080 #else
1081                                Debug( LDAP_DEBUG_ANY,
1082 "%s: line %d: depth must be positive.\n",
1083                                    fname, lineno, 0 );
1084 #endif
1085                                                         return 1;
1086
1087
1088                        } else {
1089                            be->be_max_deref_depth = i;
1090                                            }
1091
1092
1093                 /* set magic "root" dn for this database */
1094                 } else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
1095                         if ( cargc < 2 ) {
1096 #ifdef NEW_LOGGING
1097                                 LDAP_LOG( CONFIG, INFO, 
1098                                            "%s: line %d: missing dn in \"rootdn <dn>\" line.\n",
1099                                            fname, lineno ,0 );
1100 #else
1101                                 Debug( LDAP_DEBUG_ANY,
1102                     "%s: line %d: missing dn in \"rootdn <dn>\" line\n",
1103                                     fname, lineno, 0 );
1104 #endif
1105
1106                                 return( 1 );
1107                         }
1108
1109                         if ( be == NULL ) {
1110 #ifdef NEW_LOGGING
1111                                 LDAP_LOG( CONFIG, INFO, 
1112                                            "%s: line %d: rootdn line must appear inside a database "
1113                                            "definition.\n", fname, lineno ,0 );
1114 #else
1115                                 Debug( LDAP_DEBUG_ANY,
1116 "%s: line %d: rootdn line must appear inside a database definition.\n",
1117                                     fname, lineno, 0 );
1118 #endif
1119                                 return 1;
1120
1121                         } else {
1122                                 struct berval dn;
1123                                 
1124                                 if ( load_ucdata( NULL ) < 0 ) return 1;
1125
1126                                 dn.bv_val = cargv[1];
1127                                 dn.bv_len = strlen( cargv[1] );
1128
1129                                 rc = dnPrettyNormal( NULL, &dn,
1130                                         &be->be_rootdn,
1131                                         &be->be_rootndn, NULL );
1132
1133                                 if( rc != LDAP_SUCCESS ) {
1134 #ifdef NEW_LOGGING
1135                                         LDAP_LOG( CONFIG, CRIT, 
1136                                                 "%s: line %d: rootdn DN is invalid.\n", 
1137                                                 fname, lineno ,0 );
1138 #else
1139                                         Debug( LDAP_DEBUG_ANY,
1140                                                 "%s: line %d: rootdn DN is invalid\n",
1141                                            fname, lineno, 0 );
1142 #endif
1143                                         return( 1 );
1144                                 }
1145                         }
1146
1147                 /* set super-secret magic database password */
1148                 } else if ( strcasecmp( cargv[0], "rootpw" ) == 0 ) {
1149                         if ( cargc < 2 ) {
1150 #ifdef NEW_LOGGING
1151                                 LDAP_LOG( CONFIG, CRIT, 
1152                                         "%s: line %d: missing passwd in \"rootpw <passwd>\""
1153                                         " line\n", fname, lineno ,0 );
1154 #else
1155                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1156                                         "missing passwd in \"rootpw <passwd>\" line\n",
1157                                     fname, lineno, 0 );
1158 #endif
1159
1160                                 return( 1 );
1161                         }
1162
1163                         if ( be == NULL ) {
1164 #ifdef NEW_LOGGING
1165                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
1166                                         "rootpw line must appear inside a database "
1167                                         "definition.\n", fname, lineno ,0 );
1168 #else
1169                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1170                                         "rootpw line must appear inside a database "
1171                                         "definition.\n",
1172                                     fname, lineno, 0 );
1173 #endif
1174                                 return 1;
1175
1176                         } else {
1177                                 Backend *tmp_be = select_backend( &be->be_rootndn, 0, 0 );
1178
1179                                 if( tmp_be != be ) {
1180 #ifdef NEW_LOGGING
1181                                         LDAP_LOG( CONFIG, INFO,
1182                                                 "%s: line %d: "
1183                                                 "rootpw can only be set when rootdn is under suffix\n",
1184                                                 fname, lineno, "" );
1185 #else
1186                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1187                                                 "rootpw can only be set when rootdn is under suffix\n",
1188                                         fname, lineno, 0 );
1189 #endif
1190                                         return 1;
1191                                 }
1192
1193                                 be->be_rootpw.bv_val = ch_strdup( cargv[1] );
1194                                 be->be_rootpw.bv_len = strlen( be->be_rootpw.bv_val );
1195                         }
1196
1197                 /* make this database read-only */
1198                 } else if ( strcasecmp( cargv[0], "readonly" ) == 0 ) {
1199                         if ( cargc < 2 ) {
1200 #ifdef NEW_LOGGING
1201                                 LDAP_LOG( CONFIG, CRIT, 
1202                                         "%s: line %d: missing on|off in \"readonly <on|off>\" "
1203                                         "line.\n", fname, lineno ,0 );
1204 #else
1205                                 Debug( LDAP_DEBUG_ANY,
1206             "%s: line %d: missing on|off in \"readonly <on|off>\" line\n",
1207                                     fname, lineno, 0 );
1208 #endif
1209
1210                                 return( 1 );
1211                         }
1212                         if ( be == NULL ) {
1213                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1214                                         global_restrictops |= SLAP_RESTRICT_OP_WRITES;
1215                                 } else {
1216                                         global_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
1217                                 }
1218                         } else {
1219                                 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1220                                         be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
1221                                 } else {
1222                                         be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
1223                                 }
1224                         }
1225
1226
1227                 /* allow these features */
1228                 } else if ( strcasecmp( cargv[0], "allows" ) == 0 ||
1229                         strcasecmp( cargv[0], "allow" ) == 0 )
1230                 {
1231                         slap_mask_t     allows;
1232
1233                         if ( be != NULL ) {
1234 #ifdef NEW_LOGGING
1235                                 LDAP_LOG( CONFIG, INFO, 
1236                                            "%s: line %d: allow line must appear prior to "
1237                                            "database definitions.\n", fname, lineno ,0 );
1238 #else
1239                                 Debug( LDAP_DEBUG_ANY,
1240 "%s: line %d: allow line must appear prior to database definitions\n",
1241                                     fname, lineno, 0 );
1242 #endif
1243
1244                         }
1245
1246                         if ( cargc < 2 ) {
1247 #ifdef NEW_LOGGING
1248                                 LDAP_LOG( CONFIG, CRIT, 
1249                                            "%s: line %d: missing feature(s) in \"allow <features>\""
1250                                            " line\n", fname, lineno ,0 );
1251 #else
1252                                 Debug( LDAP_DEBUG_ANY,
1253             "%s: line %d: missing feature(s) in \"allow <features>\" line\n",
1254                                     fname, lineno, 0 );
1255 #endif
1256
1257                                 return( 1 );
1258                         }
1259
1260                         allows = 0;
1261
1262                         for( i=1; i < cargc; i++ ) {
1263                                 if( strcasecmp( cargv[i], "bind_v2" ) == 0 ) {
1264                                         allows |= SLAP_ALLOW_BIND_V2;
1265
1266                                 } else if( strcasecmp( cargv[i], "bind_anon_cred" ) == 0 ) {
1267                                         allows |= SLAP_ALLOW_BIND_ANON_CRED;
1268
1269                                 } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) {
1270                                         allows |= SLAP_ALLOW_BIND_ANON_DN;
1271
1272                                 } else if( strcasecmp( cargv[i], "update_anon" ) == 0 ) {
1273                                         allows |= SLAP_ALLOW_UPDATE_ANON;
1274
1275                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1276 #ifdef NEW_LOGGING
1277                                         LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1278                                                 "unknown feature %s in \"allow <features>\" line.\n",
1279                                                 fname, lineno, cargv[1] );
1280 #else
1281                                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1282                                                 "unknown feature %s in \"allow <features>\" line\n",
1283                                                 fname, lineno, cargv[i] );
1284 #endif
1285
1286                                         return( 1 );
1287                                 }
1288                         }
1289
1290                         global_allows = allows;
1291
1292                 /* disallow these features */
1293                 } else if ( strcasecmp( cargv[0], "disallows" ) == 0 ||
1294                         strcasecmp( cargv[0], "disallow" ) == 0 )
1295                 {
1296                         slap_mask_t     disallows;
1297
1298                         if ( be != NULL ) {
1299 #ifdef NEW_LOGGING
1300                                 LDAP_LOG( CONFIG, INFO, 
1301                                            "%s: line %d: disallow line must appear prior to "
1302                                            "database definitions.\n", fname, lineno ,0 );
1303 #else
1304                                 Debug( LDAP_DEBUG_ANY,
1305 "%s: line %d: disallow line must appear prior to database definitions\n",
1306                                     fname, lineno, 0 );
1307 #endif
1308
1309                         }
1310
1311                         if ( cargc < 2 ) {
1312 #ifdef NEW_LOGGING
1313                                 LDAP_LOG( CONFIG, CRIT, 
1314                                         "%s: line %d: missing feature(s) in \"disallow <features>\""
1315                                         " line.\n", fname, lineno ,0 );
1316 #else
1317                                 Debug( LDAP_DEBUG_ANY,
1318             "%s: line %d: missing feature(s) in \"disallow <features>\" line\n",
1319                                     fname, lineno, 0 );
1320 #endif
1321
1322                                 return( 1 );
1323                         }
1324
1325                         disallows = 0;
1326
1327                         for( i=1; i < cargc; i++ ) {
1328                                 if( strcasecmp( cargv[i], "bind_anon" ) == 0 ) {
1329                                         disallows |= SLAP_DISALLOW_BIND_ANON;
1330
1331                                 } else if( strcasecmp( cargv[i], "bind_simple" ) == 0 ) {
1332                                         disallows |= SLAP_DISALLOW_BIND_SIMPLE;
1333
1334                                 } else if( strcasecmp( cargv[i], "bind_krbv4" ) == 0 ) {
1335                                         disallows |= SLAP_DISALLOW_BIND_KRBV4;
1336
1337                                 } else if( strcasecmp( cargv[i], "tls_2_anon" ) == 0 ) {
1338                                         disallows |= SLAP_DISALLOW_TLS_2_ANON;
1339
1340                                 } else if( strcasecmp( cargv[i], "tls_authc" ) == 0 ) {
1341                                         disallows |= SLAP_DISALLOW_TLS_AUTHC;
1342
1343                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1344 #ifdef NEW_LOGGING
1345                                         LDAP_LOG( CONFIG, CRIT, 
1346                                                 "%s: line %d: unknown feature %s in "
1347                                                 "\"disallow <features>\" line.\n",
1348                                                 fname, lineno, cargv[i] );
1349 #else
1350                                         Debug( LDAP_DEBUG_ANY,
1351                     "%s: line %d: unknown feature %s in \"disallow <features>\" line\n",
1352                                             fname, lineno, cargv[i] );
1353 #endif
1354
1355                                         return( 1 );
1356                                 }
1357                         }
1358
1359                         global_disallows = disallows;
1360
1361                 /* require these features */
1362                 } else if ( strcasecmp( cargv[0], "requires" ) == 0 ||
1363                         strcasecmp( cargv[0], "require" ) == 0 )
1364                 {
1365                         slap_mask_t     requires;
1366
1367                         if ( cargc < 2 ) {
1368 #ifdef NEW_LOGGING
1369                                 LDAP_LOG( CONFIG, CRIT, 
1370                                            "%s: line %d: missing feature(s) in "
1371                                            "\"require <features>\" line.\n", fname, lineno ,0 );
1372 #else
1373                                 Debug( LDAP_DEBUG_ANY,
1374             "%s: line %d: missing feature(s) in \"require <features>\" line\n",
1375                                     fname, lineno, 0 );
1376 #endif
1377
1378                                 return( 1 );
1379                         }
1380
1381                         requires = 0;
1382
1383                         for( i=1; i < cargc; i++ ) {
1384                                 if( strcasecmp( cargv[i], "bind" ) == 0 ) {
1385                                         requires |= SLAP_REQUIRE_BIND;
1386
1387                                 } else if( strcasecmp( cargv[i], "LDAPv3" ) == 0 ) {
1388                                         requires |= SLAP_REQUIRE_LDAP_V3;
1389
1390                                 } else if( strcasecmp( cargv[i], "authc" ) == 0 ) {
1391                                         requires |= SLAP_REQUIRE_AUTHC;
1392
1393                                 } else if( strcasecmp( cargv[i], "SASL" ) == 0 ) {
1394                                         requires |= SLAP_REQUIRE_SASL;
1395
1396                                 } else if( strcasecmp( cargv[i], "strong" ) == 0 ) {
1397                                         requires |= SLAP_REQUIRE_STRONG;
1398
1399                                 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1400 #ifdef NEW_LOGGING
1401                                         LDAP_LOG( CONFIG, CRIT, 
1402                                                    "%s: line %d: unknown feature %s in "
1403                                                    "\"require <features>\" line.\n", 
1404                                                    fname, lineno , cargv[i] );
1405 #else
1406                                         Debug( LDAP_DEBUG_ANY,
1407                     "%s: line %d: unknown feature %s in \"require <features>\" line\n",
1408                                             fname, lineno, cargv[i] );
1409 #endif
1410
1411                                         return( 1 );
1412                                 }
1413                         }
1414
1415                         if ( be == NULL ) {
1416                                 global_requires = requires;
1417                         } else {
1418                                 be->be_requires = requires;
1419                         }
1420
1421                 /* required security factors */
1422                 } else if ( strcasecmp( cargv[0], "security" ) == 0 ) {
1423                         slap_ssf_set_t *set;
1424
1425                         if ( cargc < 2 ) {
1426 #ifdef NEW_LOGGING
1427                                 LDAP_LOG( CONFIG, CRIT, 
1428                                         "%s: line %d: missing factor(s) in \"security <factors>\""
1429                                         " line.\n", fname, lineno ,0 );
1430 #else
1431                                 Debug( LDAP_DEBUG_ANY,
1432             "%s: line %d: missing factor(s) in \"security <factors>\" line\n",
1433                                     fname, lineno, 0 );
1434 #endif
1435
1436                                 return( 1 );
1437                         }
1438
1439                         if ( be == NULL ) {
1440                                 set = &global_ssf_set;
1441                         } else {
1442                                 set = &be->be_ssf_set;
1443                         }
1444
1445                         for( i=1; i < cargc; i++ ) {
1446                                 if( strncasecmp( cargv[i], "ssf=",
1447                                         sizeof("ssf") ) == 0 )
1448                                 {
1449                                         set->sss_ssf =
1450                                                 atoi( &cargv[i][sizeof("ssf")] );
1451
1452                                 } else if( strncasecmp( cargv[i], "transport=",
1453                                         sizeof("transport") ) == 0 )
1454                                 {
1455                                         set->sss_transport =
1456                                                 atoi( &cargv[i][sizeof("transport")] );
1457
1458                                 } else if( strncasecmp( cargv[i], "tls=",
1459                                         sizeof("tls") ) == 0 )
1460                                 {
1461                                         set->sss_tls =
1462                                                 atoi( &cargv[i][sizeof("tls")] );
1463
1464                                 } else if( strncasecmp( cargv[i], "sasl=",
1465                                         sizeof("sasl") ) == 0 )
1466                                 {
1467                                         set->sss_sasl =
1468                                                 atoi( &cargv[i][sizeof("sasl")] );
1469
1470                                 } else if( strncasecmp( cargv[i], "update_ssf=",
1471                                         sizeof("update_ssf") ) == 0 )
1472                                 {
1473                                         set->sss_update_ssf =
1474                                                 atoi( &cargv[i][sizeof("update_ssf")] );
1475
1476                                 } else if( strncasecmp( cargv[i], "update_transport=",
1477                                         sizeof("update_transport") ) == 0 )
1478                                 {
1479                                         set->sss_update_transport =
1480                                                 atoi( &cargv[i][sizeof("update_transport")] );
1481
1482                                 } else if( strncasecmp( cargv[i], "update_tls=",
1483                                         sizeof("update_tls") ) == 0 )
1484                                 {
1485                                         set->sss_update_tls =
1486                                                 atoi( &cargv[i][sizeof("update_tls")] );
1487
1488                                 } else if( strncasecmp( cargv[i], "update_sasl=",
1489                                         sizeof("update_sasl") ) == 0 )
1490                                 {
1491                                         set->sss_update_sasl =
1492                                                 atoi( &cargv[i][sizeof("update_sasl")] );
1493
1494                                 } else if( strncasecmp( cargv[i], "simple_bind=",
1495                                         sizeof("simple_bind") ) == 0 )
1496                                 {
1497                                         set->sss_simple_bind =
1498                                                 atoi( &cargv[i][sizeof("simple_bind")] );
1499
1500                                 } else {
1501 #ifdef NEW_LOGGING
1502                                         LDAP_LOG( CONFIG, CRIT, 
1503                                                    "%s: line %d: unknown factor %S in "
1504                                                    "\"security <factors>\" line.\n",
1505                                                    fname, lineno, cargv[1] );
1506 #else
1507                                         Debug( LDAP_DEBUG_ANY,
1508                     "%s: line %d: unknown factor %s in \"security <factors>\" line\n",
1509                                             fname, lineno, cargv[i] );
1510 #endif
1511
1512                                         return( 1 );
1513                                 }
1514                         }
1515                 /* where to send clients when we don't hold it */
1516                 } else if ( strcasecmp( cargv[0], "referral" ) == 0 ) {
1517                         if ( cargc < 2 ) {
1518 #ifdef NEW_LOGGING
1519                                 LDAP_LOG( CONFIG, CRIT, 
1520                                         "%s: line %d: missing URL in \"referral <URL>\""
1521                                         " line.\n", fname, lineno , 0 );
1522 #else
1523                                 Debug( LDAP_DEBUG_ANY,
1524                     "%s: line %d: missing URL in \"referral <URL>\" line\n",
1525                                     fname, lineno, 0 );
1526 #endif
1527
1528                                 return( 1 );
1529                         }
1530
1531                         if( validate_global_referral( cargv[1] ) ) {
1532 #ifdef NEW_LOGGING
1533                                 LDAP_LOG( CONFIG, CRIT, 
1534                                         "%s: line %d: invalid URL (%s) in \"referral\" line.\n",
1535                                         fname, lineno, cargv[1]  );
1536 #else
1537                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1538                                         "invalid URL (%s) in \"referral\" line.\n",
1539                                     fname, lineno, cargv[1] );
1540 #endif
1541                                 return 1;
1542                         }
1543
1544                         vals[0].bv_val = cargv[1];
1545                         vals[0].bv_len = strlen( vals[0].bv_val );
1546                         if( value_add( &default_referral, vals ) )
1547                                 return LDAP_OTHER;
1548
1549 #ifdef NEW_LOGGING
1550                 } else if ( strcasecmp( cargv[0], "logfile" ) == 0 ) {
1551                         FILE *logfile;
1552                         if ( cargc < 2 ) {
1553 #ifdef NEW_LOGGING
1554                                 LDAP_LOG( CONFIG, CRIT, 
1555                                         "%s: line %d: Error in logfile directive, "
1556                                         "\"logfile <filename>\"\n", fname, lineno , 0 );
1557 #else
1558                                 Debug( LDAP_DEBUG_ANY,
1559                                        "%s: line %d: Error in logfile directive, \"logfile filename\"\n",
1560                                        fname, lineno, 0 );
1561 #endif
1562
1563                                 return( 1 );
1564                         }
1565                         logfile = fopen( cargv[1], "w" );
1566                         if ( logfile != NULL ) lutil_debug_file( logfile  );
1567
1568 #endif
1569                 /* start of a new database definition */
1570                 } else if ( strcasecmp( cargv[0], "debug" ) == 0 ) {
1571                         int level;
1572                         if ( cargc < 3 ) {
1573 #ifdef NEW_LOGGING
1574                                 LDAP_LOG( CONFIG, CRIT, 
1575                                            "%s: line %d: Error in debug directive, "
1576                                            "\"debug <subsys> <level>\"\n", fname, lineno , 0 );
1577 #else
1578                                 Debug( LDAP_DEBUG_ANY,
1579                                         "%s: line %d: Error in debug directive, \"debug subsys level\"\n",
1580                                         fname, lineno, 0 );
1581 #endif
1582
1583                                 return( 1 );
1584                         }
1585                         level = atoi( cargv[2] );
1586                         if ( level <= 0 ) level = lutil_mnem2level( cargv[2] );
1587                         lutil_set_debug_level( cargv[1], level );
1588                 /* specify an Object Identifier macro */
1589                 } else if ( strcasecmp( cargv[0], "objectidentifier" ) == 0 ) {
1590                         rc = parse_oidm( fname, lineno, cargc, cargv );
1591                         if( rc ) return rc;
1592
1593                 /* specify an objectclass */
1594                 } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
1595                         if ( cargc < 2 ) {
1596 #ifdef NEW_LOGGING
1597                                 LDAP_LOG( CONFIG, INFO, 
1598                                         "%s: line %d: illegal objectclass format.\n",
1599                                         fname, lineno , 0 );
1600 #else
1601                                 Debug( LDAP_DEBUG_ANY,
1602                                        "%s: line %d: illegal objectclass format.\n",
1603                                        fname, lineno, 0 );
1604 #endif
1605                                 return( 1 );
1606
1607                         } else if ( *cargv[1] == '('  /*')'*/) {
1608                                 char * p;
1609                                 p = strchr(saveline,'(' /*')'*/);
1610                                 rc = parse_oc( fname, lineno, p, cargv );
1611                                 if( rc ) return rc;
1612
1613                         } else {
1614 #ifdef NEW_LOGGING
1615                                 LDAP_LOG( CONFIG, INFO, 
1616                                         "%s: line %d: old objectclass format not supported\n",
1617                                         fname, lineno , 0 );
1618 #else
1619                                 Debug( LDAP_DEBUG_ANY,
1620                                        "%s: line %d: old objectclass format not supported.\n",
1621                                        fname, lineno, 0 );
1622 #endif
1623                         }
1624
1625 #ifdef SLAP_EXTENDED_SCHEMA
1626                 } else if ( strcasecmp( cargv[0], "ditcontentrule" ) == 0 ) {
1627                         char * p;
1628                         p = strchr(saveline,'(' /*')'*/);
1629                         rc = parse_cr( fname, lineno, p, cargv );
1630                         if( rc ) return rc;
1631 #endif
1632
1633                 /* specify an attribute type */
1634                 } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
1635                         || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
1636                 {
1637                         if ( cargc < 2 ) {
1638 #ifdef NEW_LOGGING
1639                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
1640                                         "illegal attribute type format.\n",
1641                                         fname, lineno , 0 );
1642 #else
1643                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1644                                         "illegal attribute type format.\n",
1645                                         fname, lineno, 0 );
1646 #endif
1647                                 return( 1 );
1648
1649                         } else if ( *cargv[1] == '(' /*')'*/) {
1650                                 char * p;
1651                                 p = strchr(saveline,'(' /*')'*/);
1652                                 rc = parse_at( fname, lineno, p, cargv );
1653                                 if( rc ) return rc;
1654
1655                         } else {
1656 #ifdef NEW_LOGGING
1657                                 LDAP_LOG( CONFIG, INFO, 
1658                                         "%s: line %d: old attribute type format not supported.\n",
1659                                         fname, lineno , 0 );
1660 #else
1661                                 Debug( LDAP_DEBUG_ANY,
1662     "%s: line %d: old attribute type format not supported.\n",
1663                                     fname, lineno, 0 );
1664 #endif
1665
1666                         }
1667
1668                 /* define attribute option(s) */
1669                 } else if ( strcasecmp( cargv[0], "attributeoptions" ) == 0 ) {
1670                         ad_define_option( NULL, NULL, 0 );
1671                         for ( i = 1; i < cargc; i++ )
1672                                 if ( ad_define_option( cargv[i], fname, lineno ) != 0 )
1673                                         return 1;
1674
1675                 /* turn on/off schema checking */
1676                 } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
1677                         if ( cargc < 2 ) {
1678 #ifdef NEW_LOGGING
1679                                 LDAP_LOG( CONFIG, CRIT, 
1680                                         "%s: line %d: missing on|off in \"schemacheck <on|off>\""
1681                                         " line.\n", fname, lineno , 0 );
1682 #else
1683                                 Debug( LDAP_DEBUG_ANY,
1684     "%s: line %d: missing on|off in \"schemacheck <on|off>\" line\n",
1685                                     fname, lineno, 0 );
1686 #endif
1687
1688                                 return( 1 );
1689                         }
1690                         if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1691 #ifdef NEW_LOGGING
1692                                 LDAP_LOG( CONFIG, CRIT, 
1693                                         "%s: line %d: schema checking disabled! your mileage may "
1694                                         "vary!\n", fname, lineno , 0 );
1695 #else
1696                                 Debug( LDAP_DEBUG_ANY,
1697                                         "%s: line %d: schema checking disabled! your mileage may vary!\n",
1698                                     fname, lineno, 0 );
1699 #endif
1700                                 global_schemacheck = 0;
1701                         } else {
1702                                 global_schemacheck = 1;
1703                         }
1704
1705                 /* specify access control info */
1706                 } else if ( strcasecmp( cargv[0], "access" ) == 0 ) {
1707                         parse_acl( be, fname, lineno, cargc, cargv );
1708
1709                 /* debug level to log things to syslog */
1710                 } else if ( strcasecmp( cargv[0], "loglevel" ) == 0 ) {
1711                         if ( cargc < 2 ) {
1712 #ifdef NEW_LOGGING
1713                                 LDAP_LOG( CONFIG, CRIT, 
1714                                         "%s: line %d: missing level in \"loglevel <level>\""
1715                                         " line.\n", fname, lineno , 0 );
1716 #else
1717                                 Debug( LDAP_DEBUG_ANY,
1718                     "%s: line %d: missing level in \"loglevel <level>\" line\n",
1719                                     fname, lineno, 0 );
1720 #endif
1721
1722                                 return( 1 );
1723                         }
1724
1725                         ldap_syslog = 0;
1726
1727                         for( i=1; i < cargc; i++ ) {
1728                                 ldap_syslog += atoi( cargv[1] );
1729                         }
1730
1731 #ifdef LDAP_SYNCREPL
1732                 /* list of sync replication information in this backend (slave only) */
1733                 } else if ( strcasecmp( cargv[0], "syncrepl" ) == 0 ) {
1734
1735                         add_syncrepl( be, cargv, cargc );
1736 #endif
1737
1738                 /* list of replicas of the data in this backend (master only) */
1739                 } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
1740                         if ( cargc < 2 ) {
1741 #ifdef NEW_LOGGING
1742                                 LDAP_LOG( CONFIG, CRIT, 
1743                                         "%s: line %d: missing host in \"replica "
1744                                         " <host[:port]\" line\n", fname, lineno , 0 );
1745 #else
1746                                 Debug( LDAP_DEBUG_ANY,
1747             "%s: line %d: missing host in \"replica <host[:port]>\" line\n",
1748                                     fname, lineno, 0 );
1749 #endif
1750
1751                                 return( 1 );
1752                         }
1753                         if ( be == NULL ) {
1754 #ifdef NEW_LOGGING
1755                                 LDAP_LOG( CONFIG, INFO, 
1756                                             "%s: line %d: replica line must appear inside "
1757                                             "a database definition.\n", fname, lineno, 0);
1758 #else
1759                                 Debug( LDAP_DEBUG_ANY,
1760 "%s: line %d: replica line must appear inside a database definition\n",
1761                                     fname, lineno, 0 );
1762 #endif
1763                                 return 1;
1764
1765                         } else {
1766                                 int nr = -1;
1767
1768                                 for ( i = 1; i < cargc; i++ ) {
1769                                         if ( strncasecmp( cargv[i], "host=", 5 )
1770                                             == 0 ) {
1771                                                 nr = add_replica_info( be, 
1772                                                         cargv[i] + 5 );
1773                                                 break;
1774                                         }
1775                                 }
1776                                 if ( i == cargc ) {
1777 #ifdef NEW_LOGGING
1778                                         LDAP_LOG( CONFIG, INFO, 
1779                                                 "%s: line %d: missing host in \"replica\" line\n", 
1780                                                 fname, lineno , 0 );
1781 #else
1782                                         Debug( LDAP_DEBUG_ANY,
1783                     "%s: line %d: missing host in \"replica\" line\n",
1784                                             fname, lineno, 0 );
1785 #endif
1786                                         return 1;
1787
1788                                 } else if ( nr == -1 ) {
1789 #ifdef NEW_LOGGING
1790                                         LDAP_LOG( CONFIG, INFO, 
1791                                                    "%s: line %d: unable to add"
1792                                                    " replica \"%s\"\n",
1793                                                    fname, lineno, 
1794                                                    cargv[i] + 5 );
1795 #else
1796                                         Debug( LDAP_DEBUG_ANY,
1797                 "%s: line %d: unable to add replica \"%s\"\n",
1798                                                 fname, lineno, cargv[i] + 5 );
1799 #endif
1800                                         return 1;
1801                                 } else {
1802                                         for ( i = 1; i < cargc; i++ ) {
1803                                                 if ( strncasecmp( cargv[i], "suffix=", 7 ) == 0 ) {
1804
1805                                                         switch ( add_replica_suffix( be, nr, cargv[i] + 7 ) ) {
1806                                                         case 1:
1807 #ifdef NEW_LOGGING
1808                                                                 LDAP_LOG( CONFIG, INFO, 
1809                                                                         "%s: line %d: suffix \"%s\" in \"replica\""
1810                                                                         " line is not valid for backend(ignored)\n",
1811                                                                         fname, lineno, cargv[i] + 7 );
1812 #else
1813                                                                 Debug( LDAP_DEBUG_ANY,
1814                                                                                 "%s: line %d: suffix \"%s\" in \"replica\" line is not valid for backend (ignored)\n",
1815                                                                                 fname, lineno, cargv[i] + 7 );
1816 #endif
1817                                                                 break;
1818
1819                                                         case 2:
1820 #ifdef NEW_LOGGING
1821                                                                 LDAP_LOG( CONFIG, INFO, 
1822                                                                         "%s: line %d: unable to normalize suffix"
1823                                                                         " in \"replica\" line (ignored)\n",
1824                                                                         fname, lineno , 0 );
1825 #else
1826                                                                 Debug( LDAP_DEBUG_ANY,
1827                                                                                  "%s: line %d: unable to normalize suffix in \"replica\" line (ignored)\n",
1828                                                                                  fname, lineno, 0 );
1829 #endif
1830                                                                 break;
1831                                                         }
1832
1833                                                 } else if ( strncasecmp( cargv[i], "attr", 4 ) == 0 ) {
1834                                                         int exclude = 0;
1835                                                         char *arg = cargv[i] + 4;
1836
1837                                                         if ( arg[0] == '!' ) {
1838                                                                 arg++;
1839                                                                 exclude = 1;
1840                                                         }
1841
1842                                                         if ( arg[0] != '=' ) {
1843                                                                 continue;
1844                                                         }
1845
1846                                                         if ( add_replica_attrs( be, nr, arg + 1, exclude ) ) {
1847 #ifdef NEW_LOGGING
1848                                                                 LDAP_LOG( CONFIG, INFO, 
1849                                                                         "%s: line %d: attribute \"%s\" in "
1850                                                                         "\"replica\" line is unknown\n",
1851                                                                         fname, lineno, arg + 1 ); 
1852 #else
1853                                                                 Debug( LDAP_DEBUG_ANY,
1854                                                                                 "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
1855                                                                                 fname, lineno, arg + 1 );
1856 #endif
1857                                                                 return( 1 );
1858                                                         }
1859                                                 }
1860                                         }
1861                                 }
1862                         }
1863
1864                 /* dn of master entity allowed to write to replica */
1865                 } else if ( strcasecmp( cargv[0], "updatedn" ) == 0 ) {
1866                         if ( cargc < 2 ) {
1867 #ifdef NEW_LOGGING
1868                                 LDAP_LOG( CONFIG, CRIT, 
1869                                         "%s: line %d: missing dn in \"updatedn <dn>\""
1870                                         " line.\n", fname, lineno , 0 );
1871 #else
1872                                 Debug( LDAP_DEBUG_ANY,
1873                     "%s: line %d: missing dn in \"updatedn <dn>\" line\n",
1874                                     fname, lineno, 0 );
1875 #endif
1876
1877                                 return( 1 );
1878                         }
1879                         if ( be == NULL ) {
1880 #ifdef NEW_LOGGING
1881                                 LDAP_LOG( CONFIG, INFO, 
1882                                         "%s: line %d: updatedn line must appear inside "
1883                                         "a database definition\n", 
1884                                         fname, lineno , 0 );
1885 #else
1886                                 Debug( LDAP_DEBUG_ANY,
1887 "%s: line %d: updatedn line must appear inside a database definition\n",
1888                                     fname, lineno, 0 );
1889 #endif
1890                                 return 1;
1891
1892                         } else {
1893                                 struct berval dn;
1894
1895                                 if ( load_ucdata( NULL ) < 0 ) return 1;
1896
1897                                 dn.bv_val = cargv[1];
1898                                 dn.bv_len = strlen( cargv[1] );
1899
1900                                 rc = dnNormalize( 0, NULL, NULL, &dn, &be->be_update_ndn, NULL );
1901                                 if( rc != LDAP_SUCCESS ) {
1902 #ifdef NEW_LOGGING
1903                                         LDAP_LOG( CONFIG, CRIT, 
1904                                                 "%s: line %d: updatedn DN is invalid.\n",
1905                                                 fname, lineno , 0 );
1906 #else
1907                                         Debug( LDAP_DEBUG_ANY,
1908                                                 "%s: line %d: updatedn DN is invalid\n",
1909                                             fname, lineno, 0 );
1910 #endif
1911                                         return 1;
1912                                 }
1913                         }
1914
1915                 } else if ( strcasecmp( cargv[0], "updateref" ) == 0 ) {
1916                         if ( cargc < 2 ) {
1917 #ifdef NEW_LOGGING
1918                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1919                                         "missing url in \"updateref <ldapurl>\" line.\n",
1920                                         fname, lineno , 0 );
1921 #else
1922                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1923                                         "missing url in \"updateref <ldapurl>\" line\n",
1924                                     fname, lineno, 0 );
1925 #endif
1926
1927                                 return( 1 );
1928                         }
1929                         if ( be == NULL ) {
1930 #ifdef NEW_LOGGING
1931                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: updateref"
1932                                         " line must appear inside a database definition\n",
1933                                         fname, lineno , 0 );
1934 #else
1935                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: updateref"
1936                                         " line must appear inside a database definition\n",
1937                                         fname, lineno, 0 );
1938 #endif
1939                                 return 1;
1940
1941                         } else if ( !be->be_update_ndn.bv_len ) {
1942 #ifdef NEW_LOGGING
1943                                 LDAP_LOG( CONFIG, INFO, "%s: line %d: "
1944                                         "updateref line must come after updatedn.\n",
1945                                         fname, lineno , 0 );
1946 #else
1947                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1948                                         "updateref line must after updatedn.\n",
1949                                     fname, lineno, 0 );
1950 #endif
1951                                 return 1;
1952                         }
1953
1954                         if( validate_global_referral( cargv[1] ) ) {
1955 #ifdef NEW_LOGGING
1956                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1957                                         "invalid URL (%s) in \"updateref\" line.\n",
1958                                         fname, lineno, cargv[1] );
1959 #else
1960                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1961                                         "invalid URL (%s) in \"updateref\" line.\n",
1962                                     fname, lineno, cargv[1] );
1963 #endif
1964                                 return 1;
1965                         }
1966
1967                         vals[0].bv_val = cargv[1];
1968                         vals[0].bv_len = strlen( vals[0].bv_val );
1969                         if( value_add( &be->be_update_refs, vals ) )
1970                                 return LDAP_OTHER;
1971
1972                 /* replication log file to which changes are appended */
1973                 } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
1974                         if ( cargc < 2 ) {
1975 #ifdef NEW_LOGGING
1976                                 LDAP_LOG( CONFIG, CRIT, 
1977                                         "%s: line %d: missing filename in \"replogfile <filename>\""
1978                                         " line.\n", fname, lineno , 0 );
1979 #else
1980                                 Debug( LDAP_DEBUG_ANY,
1981             "%s: line %d: missing filename in \"replogfile <filename>\" line\n",
1982                                     fname, lineno, 0 );
1983 #endif
1984
1985                                 return( 1 );
1986                         }
1987                         if ( be ) {
1988                                 be->be_replogfile = ch_strdup( cargv[1] );
1989                         } else {
1990                                 replogfile = ch_strdup( cargv[1] );
1991                         }
1992
1993                 /* file from which to read additional rootdse attrs */
1994                 } else if ( strcasecmp( cargv[0], "rootDSE" ) == 0) {
1995                         if ( cargc < 2 ) {
1996 #ifdef NEW_LOGGING
1997                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
1998                                         "missing filename in \"rootDSE <filename>\" line.\n",
1999                                         fname, lineno , 0 );
2000 #else
2001                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
2002                                         "missing filename in \"rootDSE <filename>\" line.\n",
2003                                     fname, lineno, 0 );
2004 #endif
2005                                 return 1;
2006                         }
2007
2008                         if( read_root_dse_file( cargv[1] ) ) {
2009 #ifdef NEW_LOGGING
2010                                 LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
2011                                         "could not read \"rootDSE <filename>\" line.\n",
2012                                         fname, lineno , 0 );
2013 #else
2014                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
2015                                         "could not read \"rootDSE <filename>\" line\n",
2016                                     fname, lineno, 0 );
2017 #endif
2018                                 return 1;
2019                         }
2020
2021                 /* maintain lastmodified{by,time} attributes */
2022                 } else if ( strcasecmp( cargv[0], "lastmod" ) == 0 ) {
2023                         if ( cargc < 2 ) {
2024 #ifdef NEW_LOGGING
2025                                 LDAP_LOG( CONFIG, CRIT, 
2026                                            "%s: line %d: missing on|off in \"lastmod <on|off>\""
2027                                            " line.\n", fname, lineno , 0 );
2028 #else
2029                                 Debug( LDAP_DEBUG_ANY,
2030             "%s: line %d: missing on|off in \"lastmod <on|off>\" line\n",
2031                                     fname, lineno, 0 );
2032 #endif
2033
2034                                 return( 1 );
2035                         }
2036                         if ( strcasecmp( cargv[1], "on" ) == 0 ) {
2037                                 if ( be ) {
2038                                         be->be_flags &= ~SLAP_BFLAG_NOLASTMOD;
2039                                 } else {
2040                                         lastmod = 1;
2041                                 }
2042                         } else {
2043                                 if ( be ) {
2044                                         be->be_flags |= SLAP_BFLAG_NOLASTMOD;
2045                                 } else {
2046                                         lastmod = 0;
2047                                 }
2048                         }
2049
2050 #ifdef SIGHUP
2051                 /* turn on/off gentle SIGHUP handling */
2052                 } else if ( strcasecmp( cargv[0], "gentlehup" ) == 0 ) {
2053                         if ( cargc < 2 ) {
2054                                 Debug( LDAP_DEBUG_ANY,
2055     "%s: line %d: missing on|off in \"gentlehup <on|off>\" line\n",
2056                                     fname, lineno, 0 );
2057                                 return( 1 );
2058                         }
2059                         if ( strcasecmp( cargv[1], "off" ) == 0 ) {
2060                                 global_gentlehup = 0;
2061                         } else {
2062                                 global_gentlehup = 1;
2063                         }
2064 #endif
2065
2066                 /* set idle timeout value */
2067                 } else if ( strcasecmp( cargv[0], "idletimeout" ) == 0 ) {
2068                         int i;
2069                         if ( cargc < 2 ) {
2070 #ifdef NEW_LOGGING
2071                                 LDAP_LOG( CONFIG, CRIT, 
2072                                         "%s: line %d: missing timeout value in "
2073                                         "\"idletimeout <seconds>\" line.\n", fname, lineno , 0 );
2074 #else
2075                                 Debug( LDAP_DEBUG_ANY,
2076             "%s: line %d: missing timeout value in \"idletimeout <seconds>\" line\n",
2077                                     fname, lineno, 0 );
2078 #endif
2079
2080                                 return( 1 );
2081                         }
2082
2083                         i = atoi( cargv[1] );
2084
2085                         if( i < 0 ) {
2086 #ifdef NEW_LOGGING
2087                                 LDAP_LOG( CONFIG, CRIT, 
2088                                         "%s: line %d: timeout value (%d) invalid "
2089                                         "\"idletimeout <seconds>\" line.\n", fname, lineno, i );
2090 #else
2091                                 Debug( LDAP_DEBUG_ANY,
2092             "%s: line %d: timeout value (%d) invalid \"idletimeout <seconds>\" line\n",
2093                                     fname, lineno, i );
2094 #endif
2095
2096                                 return( 1 );
2097                         }
2098
2099                         global_idletimeout = i;
2100
2101                 /* include another config file */
2102                 } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
2103                         if ( cargc < 2 ) {
2104 #ifdef NEW_LOGGING
2105                                 LDAP_LOG( CONFIG, CRIT, 
2106                                         "%s: line %d: missing filename in \"include "
2107                                         "<filename>\" line.\n", fname, lineno , 0 );
2108 #else
2109                                 Debug( LDAP_DEBUG_ANY,
2110     "%s: line %d: missing filename in \"include <filename>\" line\n",
2111                                     fname, lineno, 0 );
2112 #endif
2113
2114                                 return( 1 );
2115                         }
2116                         savefname = ch_strdup( cargv[1] );
2117                         savelineno = lineno;
2118
2119                         if ( read_config( savefname, depth+1 ) != 0 ) {
2120                                 return( 1 );
2121                         }
2122
2123                         free( savefname );
2124                         lineno = savelineno - 1;
2125
2126                 /* location of kerberos srvtab file */
2127                 } else if ( strcasecmp( cargv[0], "srvtab" ) == 0 ) {
2128                         if ( cargc < 2 ) {
2129 #ifdef NEW_LOGGING
2130                                 LDAP_LOG( CONFIG, CRIT, 
2131                                         "%s: line %d: missing filename in \"srvtab "
2132                                         "<filename>\" line.\n", fname, lineno , 0 );
2133 #else
2134                                 Debug( LDAP_DEBUG_ANY,
2135             "%s: line %d: missing filename in \"srvtab <filename>\" line\n",
2136                                     fname, lineno, 0 );
2137 #endif
2138
2139                                 return( 1 );
2140                         }
2141                         ldap_srvtab = ch_strdup( cargv[1] );
2142
2143 #ifdef SLAPD_MODULES
2144                 } else if (strcasecmp( cargv[0], "moduleload") == 0 ) {
2145                    if ( cargc < 2 ) {
2146 #ifdef NEW_LOGGING
2147                            LDAP_LOG( CONFIG, INFO, 
2148                                    "%s: line %d: missing filename in \"moduleload "
2149                                    "<filename>\" line.\n", fname, lineno , 0 );
2150 #else
2151                       Debug( LDAP_DEBUG_ANY,
2152                              "%s: line %d: missing filename in \"moduleload <filename>\" line\n",
2153                              fname, lineno, 0 );
2154 #endif
2155
2156                       exit( EXIT_FAILURE );
2157                    }
2158                    if (module_load(cargv[1], cargc - 2, (cargc > 2) ? cargv + 2 : NULL)) {
2159 #ifdef NEW_LOGGING
2160                            LDAP_LOG( CONFIG, CRIT, 
2161                                    "%s: line %d: failed to load or initialize module %s\n",
2162                                    fname, lineno, cargv[1] );
2163 #else
2164                       Debug( LDAP_DEBUG_ANY,
2165                              "%s: line %d: failed to load or initialize module %s\n",
2166                              fname, lineno, cargv[1]);
2167 #endif
2168
2169                       exit( EXIT_FAILURE );
2170                    }
2171                 } else if (strcasecmp( cargv[0], "modulepath") == 0 ) {
2172                    if ( cargc != 2 ) {
2173 #ifdef NEW_LOGGING
2174                            LDAP_LOG( CONFIG, INFO, 
2175                                   "%s: line %d: missing path in \"modulepath <path>\""
2176                                   " line\n", fname, lineno , 0 );
2177 #else
2178                       Debug( LDAP_DEBUG_ANY,
2179                              "%s: line %d: missing path in \"modulepath <path>\" line\n",
2180                              fname, lineno, 0 );
2181 #endif
2182
2183                       exit( EXIT_FAILURE );
2184                    }
2185                    if (module_path( cargv[1] )) {
2186 #ifdef NEW_LOGGING
2187                            LDAP_LOG( CONFIG, CRIT, 
2188                                   "%s: line %d: failed to set module search path to %s.\n",
2189                                   fname, lineno, cargv[1] );
2190 #else
2191                            Debug( LDAP_DEBUG_ANY,
2192                                   "%s: line %d: failed to set module search path to %s\n",
2193                                   fname, lineno, cargv[1]);
2194 #endif
2195
2196                       exit( EXIT_FAILURE );
2197                    }
2198                    
2199 #endif /*SLAPD_MODULES*/
2200
2201 #ifdef HAVE_TLS
2202                 } else if ( !strcasecmp( cargv[0], "TLSRandFile" ) ) {
2203                         rc = ldap_pvt_tls_set_option( NULL,
2204                                                       LDAP_OPT_X_TLS_RANDOM_FILE,
2205                                                       cargv[1] );
2206                         if ( rc )
2207                                 return rc;
2208
2209                 } else if ( !strcasecmp( cargv[0], "TLSCipherSuite" ) ) {
2210                         rc = ldap_pvt_tls_set_option( NULL,
2211                                                       LDAP_OPT_X_TLS_CIPHER_SUITE,
2212                                                       cargv[1] );
2213                         if ( rc )
2214                                 return rc;
2215
2216                 } else if ( !strcasecmp( cargv[0], "TLSCertificateFile" ) ) {
2217                         rc = ldap_pvt_tls_set_option( NULL,
2218                                                       LDAP_OPT_X_TLS_CERTFILE,
2219                                                       cargv[1] );
2220                         if ( rc )
2221                                 return rc;
2222
2223                 } else if ( !strcasecmp( cargv[0], "TLSCertificateKeyFile" ) ) {
2224                         rc = ldap_pvt_tls_set_option( NULL,
2225                                                       LDAP_OPT_X_TLS_KEYFILE,
2226                                                       cargv[1] );
2227                         if ( rc )
2228                                 return rc;
2229
2230                 } else if ( !strcasecmp( cargv[0], "TLSCACertificatePath" ) ) {
2231                         rc = ldap_pvt_tls_set_option( NULL,
2232                                                       LDAP_OPT_X_TLS_CACERTDIR,
2233                                                       cargv[1] );
2234                         if ( rc )
2235                                 return rc;
2236
2237                 } else if ( !strcasecmp( cargv[0], "TLSCACertificateFile" ) ) {
2238                         rc = ldap_pvt_tls_set_option( NULL,
2239                                                       LDAP_OPT_X_TLS_CACERTFILE,
2240                                                       cargv[1] );
2241                         if ( rc )
2242                                 return rc;
2243                 } else if ( !strcasecmp( cargv[0], "TLSVerifyClient" ) ) {
2244                         if ( isdigit( (unsigned char) cargv[1][0] ) ) {
2245                                 i = atoi(cargv[1]);
2246                                 rc = ldap_pvt_tls_set_option( NULL,
2247                                                       LDAP_OPT_X_TLS_REQUIRE_CERT,
2248                                                       &i );
2249                         } else {
2250                                 rc = ldap_int_tls_config( NULL,
2251                                                       LDAP_OPT_X_TLS_REQUIRE_CERT,
2252                                                       cargv[1] );
2253                         }
2254
2255                         if ( rc )
2256                                 return rc;
2257
2258 #endif
2259
2260                 } else if ( !strcasecmp( cargv[0], "reverse-lookup" ) ) {
2261 #ifdef SLAPD_RLOOKUPS
2262                         if ( cargc < 2 ) {
2263 #ifdef NEW_LOGGING
2264                                 LDAP_LOG( CONFIG, INFO, 
2265                                         "%s: line %d: reverse-lookup: missing \"on\" or \"off\"\n",
2266                                         fname, lineno , 0 );
2267 #else
2268                                 Debug( LDAP_DEBUG_ANY,
2269 "%s: line %d: reverse-lookup: missing \"on\" or \"off\"\n",
2270                                         fname, lineno, 0 );
2271 #endif
2272                                 return( 1 );
2273                         }
2274
2275                         if ( !strcasecmp( cargv[1], "on" ) ) {
2276                                 use_reverse_lookup = 1;
2277                         } else if ( !strcasecmp( cargv[1], "off" ) ) {
2278                                 use_reverse_lookup = 0;
2279                         } else {
2280 #ifdef NEW_LOGGING
2281                                 LDAP_LOG( CONFIG, INFO, 
2282                                         "%s: line %d: reverse-lookup: "
2283                                         "must be \"on\" (default) or \"off\"\n", fname, lineno, 0 );
2284 #else
2285                                 Debug( LDAP_DEBUG_ANY,
2286 "%s: line %d: reverse-lookup: must be \"on\" (default) or \"off\"\n",
2287                                         fname, lineno, 0 );
2288 #endif
2289                                 return( 1 );
2290                         }
2291
2292 #else /* !SLAPD_RLOOKUPS */
2293 #ifdef NEW_LOGGING
2294                         LDAP_LOG( CONFIG, INFO, 
2295                                 "%s: line %d: reverse lookups "
2296                                 "are not configured (ignored).\n", fname, lineno , 0 );
2297 #else
2298                         Debug( LDAP_DEBUG_ANY,
2299 "%s: line %d: reverse lookups are not configured (ignored).\n",
2300                                 fname, lineno, 0 );
2301 #endif
2302 #endif /* !SLAPD_RLOOKUPS */
2303
2304                 /* Netscape plugins */
2305                 } else if ( strcasecmp( cargv[0], "plugin" ) == 0 ) {
2306 #if defined( LDAP_SLAPI )
2307
2308 #ifdef notdef /* allow global plugins, too */
2309                         /*
2310                          * a "plugin" line must be inside a database
2311                          * definition, since we implement pre-,post- 
2312                          * and extended operation plugins
2313                          */
2314                         if ( be == NULL ) {
2315 #ifdef NEW_LOGGING
2316                                 LDAP_LOG( CONFIG, INFO, 
2317                                         "%s: line %d: plugin line must appear "
2318                                         "inside a database definition.\n",
2319                                         fname, lineno, 0 );
2320 #else
2321                                 Debug( LDAP_DEBUG_ANY, "%s: line %d: plugin "
2322                                     "line must appear inside a database "
2323                                     "definition\n", fname, lineno, 0 );
2324 #endif
2325                                 return( 1 );
2326                         }
2327 #endif /* notdef */
2328
2329                         if ( netscape_plugin( be, fname, lineno, cargc, cargv ) 
2330                                         != LDAP_SUCCESS ) {
2331                                 return( 1 );
2332                         }
2333
2334 #else /* !defined( LDAP_SLAPI ) */
2335 #ifdef NEW_LOGGING
2336                         LDAP_LOG( CONFIG, INFO, 
2337                                 "%s: line %d: SLAPI not supported.\n",
2338                                 fname, lineno, 0 );
2339 #else
2340                         Debug( LDAP_DEBUG_ANY, "%s: line %d: SLAPI "
2341                             "not supported.\n", fname, lineno, 0 );
2342 #endif
2343                         return( 1 );
2344                         
2345 #endif /* !defined( LDAP_SLAPI ) */
2346
2347                 /* Netscape plugins */
2348                 } else if ( strcasecmp( cargv[0], "pluginlog" ) == 0 ) {
2349 #if defined( LDAP_SLAPI )
2350                         if ( cargc < 2 ) {
2351 #ifdef NEW_LOGGING
2352                                 LDAP_LOG( CONFIG, INFO, 
2353                                         "%s: line %d: missing file name "
2354                                         "in pluginlog <filename> line.\n",
2355                                         fname, lineno, 0 );
2356 #else
2357                                 Debug( LDAP_DEBUG_ANY, 
2358                                         "%s: line %d: missing file name "
2359                                         "in pluginlog <filename> line.\n",
2360                                         fname, lineno, 0 );
2361 #endif
2362                                 return( 1 );
2363                         }
2364
2365                         if ( slapi_log_file != NULL ) {
2366                                 ch_free( slapi_log_file );
2367                         }
2368
2369                         slapi_log_file = ch_strdup( cargv[1] );
2370 #endif /* !defined( LDAP_SLAPI ) */
2371
2372                 /* pass anything else to the current backend info/db config routine */
2373                 } else {
2374                         if ( bi != NULL ) {
2375                                 if ( bi->bi_config == 0 ) {
2376 #ifdef NEW_LOGGING
2377                                         LDAP_LOG( CONFIG, INFO, 
2378                                                 "%s: line %d: unknown directive \"%s\" inside "
2379                                                 "backend info definition (ignored).\n",
2380                                                 fname, lineno, cargv[0] );
2381 #else
2382                                         Debug( LDAP_DEBUG_ANY,
2383 "%s: line %d: unknown directive \"%s\" inside backend info definition (ignored)\n",
2384                                                 fname, lineno, cargv[0] );
2385 #endif
2386
2387                                 } else {
2388                                         if ( (*bi->bi_config)( bi, fname, lineno, cargc, cargv )
2389                                                 != 0 )
2390                                         {
2391                                                 return( 1 );
2392                                         }
2393                                 }
2394                         } else if ( be != NULL ) {
2395                                 if ( be->be_config == 0 ) {
2396 #ifdef NEW_LOGGING
2397                                         LDAP_LOG( CONFIG, INFO, 
2398                                                 "%s: line %d: uknown directive \"%s\" inside "
2399                                                 "backend database definition (ignored).\n",
2400                                                 fname, lineno, cargv[0] );
2401 #else
2402                                         Debug( LDAP_DEBUG_ANY,
2403 "%s: line %d: unknown directive \"%s\" inside backend database definition (ignored)\n",
2404                                         fname, lineno, cargv[0] );
2405 #endif
2406
2407                                 } else {
2408                                         if ( (*be->be_config)( be, fname, lineno, cargc, cargv )
2409                                                 != 0 )
2410                                         {
2411                                                 return( 1 );
2412                                         }
2413                                 }
2414                         } else {
2415 #ifdef NEW_LOGGING
2416                                 LDAP_LOG( CONFIG, INFO, 
2417                                         "%s: line %d: unknown directive \"%s\" outside backend "
2418                                         "info and database definitions (ignored).\n",
2419                                         fname, lineno, cargv[0] );
2420 #else
2421                                 Debug( LDAP_DEBUG_ANY,
2422 "%s: line %d: unknown directive \"%s\" outside backend info and database definitions (ignored)\n",
2423                                     fname, lineno, cargv[0] );
2424 #endif
2425
2426                         }
2427                 }
2428                 free( saveline );
2429         }
2430         fclose( fp );
2431
2432         if ( depth == 0 ) ch_free( cargv );
2433
2434         if ( !global_schemadn.bv_val ) {
2435                 ber_str2bv( SLAPD_SCHEMA_DN, sizeof(SLAPD_SCHEMA_DN)-1, 1,
2436                         &global_schemadn );
2437                 dnNormalize( 0, NULL, NULL, &global_schemadn, &global_schemandn, NULL );
2438         }
2439
2440         if ( load_ucdata( NULL ) < 0 ) return 1;
2441         return( 0 );
2442 }
2443
2444 static int
2445 fp_parse_line(
2446     int         lineno,
2447     char        *line
2448 )
2449 {
2450         char *  token;
2451         char *  logline;
2452         char    logbuf[sizeof("pseudorootpw ***")];
2453
2454         cargc = 0;
2455         token = strtok_quote( line, " \t" );
2456
2457         logline = line;
2458
2459         if ( token && ( strcasecmp( token, "rootpw" ) == 0 ||
2460                 strcasecmp( token, "replica" ) == 0 ||          /* contains "credentials" */
2461                 strcasecmp( token, "bindpw" ) == 0 ||           /* used in back-ldap */
2462                 strcasecmp( token, "pseudorootpw" ) == 0 ||     /* used in back-meta */
2463                 strcasecmp( token, "dbpasswd" ) == 0 ) )        /* used in back-sql */
2464         {
2465                 snprintf( logline = logbuf, sizeof logbuf, "%s ***", token );
2466         }
2467
2468         if ( strtok_quote_ptr ) {
2469                 *strtok_quote_ptr = ' ';
2470         }
2471
2472 #ifdef NEW_LOGGING
2473         LDAP_LOG( CONFIG, DETAIL1, "line %d (%s)\n", lineno, logline , 0 );
2474 #else
2475         Debug( LDAP_DEBUG_CONFIG, "line %d (%s)\n", lineno, logline, 0 );
2476 #endif
2477
2478         if ( strtok_quote_ptr ) {
2479                 *strtok_quote_ptr = '\0';
2480         }
2481
2482         for ( ; token != NULL; token = strtok_quote( NULL, " \t" ) ) {
2483                 if ( cargc == cargv_size - 1 ) {
2484                         char **tmp;
2485                         tmp = ch_realloc( cargv, (cargv_size + ARGS_STEP) *
2486                                             sizeof(*cargv) );
2487                         if ( tmp == NULL ) {
2488 #ifdef NEW_LOGGING
2489                                 LDAP_LOG( CONFIG, ERR, "line %d: out of memory\n", lineno, 0,0 );
2490 #else
2491                                 Debug( LDAP_DEBUG_ANY, 
2492                                                 "line %d: out of memory\n", 
2493                                                 lineno, 0, 0 );
2494 #endif
2495                                 return -1;
2496                         }
2497                         cargv = tmp;
2498                         cargv_size += ARGS_STEP;
2499                 }
2500                 cargv[cargc++] = token;
2501         }
2502         cargv[cargc] = NULL;
2503         return 0;
2504 }
2505
2506 static char *
2507 strtok_quote( char *line, char *sep )
2508 {
2509         int             inquote;
2510         char            *tmp;
2511         static char     *next;
2512
2513         strtok_quote_ptr = NULL;
2514         if ( line != NULL ) {
2515                 next = line;
2516         }
2517         while ( *next && strchr( sep, *next ) ) {
2518                 next++;
2519         }
2520
2521         if ( *next == '\0' ) {
2522                 next = NULL;
2523                 return( NULL );
2524         }
2525         tmp = next;
2526
2527         for ( inquote = 0; *next; ) {
2528                 switch ( *next ) {
2529                 case '"':
2530                         if ( inquote ) {
2531                                 inquote = 0;
2532                         } else {
2533                                 inquote = 1;
2534                         }
2535                         AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
2536                         break;
2537
2538                 case '\\':
2539                         if ( next[1] )
2540                                 AC_MEMCPY( next,
2541                                             next + 1, strlen( next + 1 ) + 1 );
2542                         next++;         /* dont parse the escaped character */
2543                         break;
2544
2545                 default:
2546                         if ( ! inquote ) {
2547                                 if ( strchr( sep, *next ) != NULL ) {
2548                                         strtok_quote_ptr = next;
2549                                         *next++ = '\0';
2550                                         return( tmp );
2551                                 }
2552                         }
2553                         next++;
2554                         break;
2555                 }
2556         }
2557
2558         return( tmp );
2559 }
2560
2561 static char     buf[BUFSIZ];
2562 static char     *line;
2563 static size_t lmax, lcur;
2564
2565 #define CATLINE( buf ) \
2566         do { \
2567                 size_t len = strlen( buf ); \
2568                 while ( lcur + len + 1 > lmax ) { \
2569                         lmax += BUFSIZ; \
2570                         line = (char *) ch_realloc( line, lmax ); \
2571                 } \
2572                 strcpy( line + lcur, buf ); \
2573                 lcur += len; \
2574         } while( 0 )
2575
2576 static char *
2577 fp_getline( FILE *fp, int *lineno )
2578 {
2579         char            *p;
2580
2581         lcur = 0;
2582         CATLINE( buf );
2583         (*lineno)++;
2584
2585         /* hack attack - keeps us from having to keep a stack of bufs... */
2586         if ( strncasecmp( line, "include", 7 ) == 0 ) {
2587                 buf[0] = '\0';
2588                 return( line );
2589         }
2590
2591         while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
2592                 /* trim off \r\n or \n */
2593                 if ( (p = strchr( buf, '\n' )) != NULL ) {
2594                         if( p > buf && p[-1] == '\r' ) --p;
2595                         *p = '\0';
2596                 }
2597                 
2598                 /* trim off trailing \ and append the next line */
2599                 if ( line[ 0 ] != '\0' 
2600                                 && (p = line + strlen( line ) - 1)[ 0 ] == '\\'
2601                                 && p[ -1 ] != '\\' ) {
2602                         p[ 0 ] = '\0';
2603                         lcur--;
2604
2605                 } else {
2606                         if ( ! isspace( (unsigned char) buf[0] ) ) {
2607                                 return( line );
2608                         }
2609
2610                         /* change leading whitespace to a space */
2611                         buf[0] = ' ';
2612                 }
2613
2614                 CATLINE( buf );
2615                 (*lineno)++;
2616         }
2617         buf[0] = '\0';
2618
2619         return( line[0] ? line : NULL );
2620 }
2621
2622 static void
2623 fp_getline_init( int *lineno )
2624 {
2625         *lineno = -1;
2626         buf[0] = '\0';
2627 }
2628
2629 /* Loads ucdata, returns 1 if loading, 0 if already loaded, -1 on error */
2630 static int
2631 load_ucdata( char *path )
2632 {
2633         static int loaded = 0;
2634         int err;
2635         
2636         if ( loaded ) {
2637                 return( 0 );
2638         }
2639         err = ucdata_load( path ? path : SLAPD_DEFAULT_UCDATA, UCDATA_ALL );
2640         if ( err ) {
2641 #ifdef NEW_LOGGING
2642                 LDAP_LOG( CONFIG, CRIT, 
2643                         "load_ucdata: Error %d loading ucdata.\n", err, 0,0 );
2644 #else
2645                 Debug( LDAP_DEBUG_ANY, "error loading ucdata (error %d)\n",
2646                        err, 0, 0 );
2647 #endif
2648
2649                 return( -1 );
2650         }
2651         loaded = 1;
2652         return( 1 );
2653 }
2654
2655 void
2656 config_destroy( )
2657 {
2658         ucdata_unload( UCDATA_ALL );
2659         free( global_schemandn.bv_val );
2660         free( global_schemadn.bv_val );
2661         free( line );
2662         if ( slapd_args_file )
2663                 free ( slapd_args_file );
2664         if ( slapd_pid_file )
2665                 free ( slapd_pid_file );
2666         if ( default_passwd_hash )
2667                 free( default_passwd_hash );
2668         acl_destroy( global_acl, NULL );
2669 }
2670
2671 #ifdef LDAP_SYNCREPL
2672 static void
2673 add_syncrepl(
2674         Backend *be,
2675         char    **cargv,
2676         int     cargc
2677 )
2678 {
2679         syncinfo_t *si;
2680
2681         si = be->syncinfo = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );
2682
2683         if ( si == NULL ) {
2684 #ifdef NEW_LOGGING
2685                 LDAP_LOG( CONFIG, ERR, "out of memory in add_syncrepl\n", 0, 0,0 );
2686 #else
2687                 Debug( LDAP_DEBUG_ANY, "out of memory in add_syncrepl\n", 0, 0, 0 );
2688 #endif
2689                 exit( EXIT_FAILURE );
2690         }
2691
2692         if ( parse_syncrepl_line( cargv, cargc, si ) < 0 ) {
2693                 /* Something bad happened - back out */
2694 #ifdef NEW_LOGGING
2695                 LDAP_LOG( CONFIG, ERR, "failed to add syncinfo\n", 0, 0,0 );
2696 #else
2697                 Debug( LDAP_DEBUG_ANY, "failed to add syncinfo\n", 0, 0, 0 );
2698 #endif
2699                 free( si );
2700                 be->syncinfo = NULL;
2701         } else {
2702 #ifdef NEW_LOGGING
2703                 LDAP_LOG ( CONFIG, RESULTS,
2704                         "add_syncrepl: Config: ** successfully added syncrepl \"%s%d\"\n",
2705                         si->mastername == NULL ? "(null)" : si->mastername,
2706                         si->masterport, 0 );
2707 #else
2708                 Debug( LDAP_DEBUG_CONFIG,
2709                         "Config: ** successfully added syncrepl \"%s:%d\"\n",
2710                         si->mastername == NULL ? "(null)" : si->mastername,
2711                         si->masterport, 0 );
2712 #endif
2713         }
2714
2715         si->be = be;
2716 }
2717
2718 #define GOT_ID                  0x0001
2719 #define GOT_HOST                0x0002
2720 #define GOT_DN                  0x0004
2721 #define GOT_METHOD              0x0008
2722 #define GOT_MECH                0x0010
2723 #define GOT_FILTER              0x0020
2724 #define GOT_SEARCHBASE  0x0040
2725 #define GOT_SCOPE               0x0080
2726 #define GOT_ATTRS               0x0100
2727 #define GOT_TYPE                0x0200
2728 #define GOT_INTERVAL    0x0400
2729 #define GOT_LASTMOD             0x0800
2730 #define GOT_UPDATEDN    0x1000
2731
2732 #define GOT_ALL                 0x1FFF
2733
2734 static int
2735 parse_syncrepl_line(
2736         char            **cargv,
2737         int             cargc,
2738         syncinfo_t      *si
2739 )
2740 {
2741         int     gots = 0;
2742         int     i, j;
2743         char    *hp, *val;
2744         int     nr_attr = 0;
2745
2746         for ( i = 1; i < cargc; i++ ) {
2747                 if ( !strncasecmp( cargv[ i ], IDSTR, sizeof( IDSTR ) - 1 )) {
2748                         /* '\0' string terminator accounts for '=' */
2749                         val = cargv[ i ] + sizeof( IDSTR );
2750                         si->id = atoi( val );
2751                         gots |= GOT_ID;
2752                 } else if ( !strncasecmp( cargv[ i ], MASTERSTR,
2753                                         sizeof( MASTERSTR ) - 1 )) {
2754                         val = cargv[ i ] + sizeof( MASTERSTR );
2755                         si->masteruri = strdup( val );
2756                         if (( hp = strchr( val, ':' )) != NULL ) {
2757                                 if ( *( hp + 1 ) == '/' ) {
2758                                         if ( *( hp + 2 ) == '/' ) {
2759                                                 val = hp + 3;
2760                                         }
2761                                         if (( hp = strchr( hp+1, ':' )) != NULL ) {
2762                                                 *hp = '\0';
2763                                                 hp++;
2764                                                 si->masterport = atoi( hp );
2765                                         }
2766                                 } else {
2767                                         *hp = '\0';
2768                                         hp++;
2769                                         si->masterport = atoi( hp );
2770                                 }
2771                         }
2772                         if ( si->masterport <= 0 ) {
2773                                 si->masterport = 0;
2774                         }
2775                         si->mastername = strdup( val );
2776                         si->master_bv = (BerVarray) ch_calloc( 2, sizeof (struct berval ));
2777                         ber_str2bv( si->masteruri, strlen(si->masteruri), 0,
2778                                                         &si->master_bv[0] );
2779                         si->master_bv[1].bv_len = 0;
2780                         si->master_bv[1].bv_val = NULL;
2781                         gots |= GOT_HOST;
2782                 } else if ( !strncasecmp( cargv[ i ], TLSSTR, sizeof( TLSSTR ) - 1 ) ) {
2783                         val = cargv[ i ] + sizeof( TLSSTR );
2784                         if( !strcasecmp( val, TLSCRITICALSTR ) ) {
2785                                 si->tls = TLS_CRITICAL;
2786                         } else {
2787                                 si->tls = TLS_ON;
2788                         }
2789                 } else if ( !strncasecmp( cargv[ i ],
2790                                 UPDATEDNSTR, sizeof( UPDATEDNSTR ) - 1 ) ) {
2791                         char *str;
2792                         struct berval updatedn = {0, NULL};
2793                         val = cargv[ i ] + sizeof( UPDATEDNSTR );
2794                         str = strdup( val );
2795                         ber_str2bv( str, strlen(str), 1, &updatedn );
2796                         dnNormalize( 0, NULL, NULL, &updatedn, &si->updatedn, NULL );
2797                         ch_free( str );
2798                         ch_free( updatedn.bv_val );
2799                         gots |= GOT_UPDATEDN;
2800                 } else if ( !strncasecmp( cargv[ i ],
2801                                 BINDDNSTR, sizeof( BINDDNSTR ) - 1 ) ) {
2802                         val = cargv[ i ] + sizeof( BINDDNSTR );
2803                         si->binddn = strdup( val );
2804                         gots |= GOT_DN;
2805                 } else if ( !strncasecmp( cargv[ i ], BINDMETHSTR,
2806                                 sizeof( BINDMETHSTR ) - 1 ) ) {
2807                         val = cargv[ i ] + sizeof( BINDMETHSTR );
2808                         if ( !strcasecmp( val, SIMPLESTR )) {
2809                                 si->bindmethod = LDAP_AUTH_SIMPLE;
2810                                 gots |= GOT_METHOD;
2811                         } else if ( !strcasecmp( val, SASLSTR )) {
2812                                 si->bindmethod = LDAP_AUTH_SASL;
2813                                 gots |= GOT_METHOD;
2814                         } else {
2815                                 si->bindmethod = -1;
2816                         }
2817                 } else if ( !strncasecmp( cargv[ i ], LASTMODSTR,
2818                                 sizeof( LASTMODSTR ) - 1 ) ) {
2819                         val = cargv[ i ] + sizeof( LASTMODSTR );
2820                         if ( !strcasecmp( val, LMREQSTR )) {
2821                                 si->lastmod = LASTMOD_REQ;
2822                                 gots |= GOT_LASTMOD;
2823                         } else if ( !strcasecmp( val, LMGENSTR )) {
2824                                 si->lastmod = LASTMOD_GEN;
2825                                 gots |= GOT_LASTMOD;
2826                         } else if ( !strcasecmp( val, LMNOSTR )) {
2827                                 si->lastmod = LASTMOD_NO;
2828                                 gots |= GOT_LASTMOD;
2829                         } else {
2830                                 si->lastmod = -1;
2831                         }
2832                 } else if ( !strncasecmp( cargv[ i ],
2833                                 SASLMECHSTR, sizeof( SASLMECHSTR ) - 1 ) ) {
2834                         val = cargv[ i ] + sizeof( SASLMECHSTR );
2835                         gots |= GOT_MECH;
2836                         si->saslmech = strdup( val );
2837                 } else if ( !strncasecmp( cargv[ i ],
2838                                 CREDSTR, sizeof( CREDSTR ) - 1 ) ) {
2839                         val = cargv[ i ] + sizeof( CREDSTR );
2840                         si->passwd = strdup( val );
2841                 } else if ( !strncasecmp( cargv[ i ],
2842                                 SECPROPSSTR, sizeof( SECPROPSSTR ) - 1 ) ) {
2843                         val = cargv[ i ] + sizeof( SECPROPSSTR );
2844                         si->secprops = strdup( val );
2845                 } else if ( !strncasecmp( cargv[ i ],
2846                                 REALMSTR, sizeof( REALMSTR ) - 1 ) ) {
2847                         val = cargv[ i ] + sizeof( REALMSTR );
2848                         si->realm = strdup( val );
2849                 } else if ( !strncasecmp( cargv[ i ],
2850                                 AUTHCSTR, sizeof( AUTHCSTR ) - 1 ) ) {
2851                         val = cargv[ i ] + sizeof( AUTHCSTR );
2852                         si->authcId = strdup( val );
2853                 } else if ( !strncasecmp( cargv[ i ],
2854                                 OLDAUTHCSTR, sizeof( OLDAUTHCSTR ) - 1 ) ) {
2855                         /* Old authcID is provided for some backwards compatibility */
2856                         val = cargv[ i ] + sizeof( OLDAUTHCSTR );
2857                         si->authcId = strdup( val );
2858                 } else if ( !strncasecmp( cargv[ i ],
2859                                 AUTHZSTR, sizeof( AUTHZSTR ) - 1 ) ) {
2860                         val = cargv[ i ] + sizeof( AUTHZSTR );
2861                         si->authzId = strdup( val );
2862                 } else if ( !strncasecmp( cargv[ i ],
2863                                 SRVTABSTR, sizeof( SRVTABSTR ) - 1 ) ) {
2864                         val = cargv[ i ] + sizeof( SRVTABSTR );
2865                         if ( si->srvtab != NULL ) {
2866                                 free( si->srvtab );
2867                         }
2868                         si->srvtab = strdup( val );
2869                 } else if ( !strncasecmp( cargv[ i ],
2870                                 FILTERSTR, sizeof( FILTERSTR ) - 1 ) ) {
2871                         val = cargv[ i ] + sizeof( FILTERSTR );
2872                         gots |= GOT_FILTER;
2873                         si->filterstr = strdup( val );
2874                 } else if ( !strncasecmp( cargv[ i ],
2875                                 SEARCHBASESTR, sizeof( SEARCHBASESTR ) - 1 ) ) {
2876                         val = cargv[ i ] + sizeof( SEARCHBASESTR );
2877                         gots |= GOT_SEARCHBASE;
2878                         si->base = strdup( val );
2879                 } else if ( !strncasecmp( cargv[ i ],
2880                                 SCOPESTR, sizeof( SCOPESTR ) - 1 ) ) {
2881                         val = cargv[ i ] + sizeof( SCOPESTR );
2882                         gots |= GOT_SCOPE;
2883                         if ( !strncasecmp( val, "base", sizeof( "base" ) - 1 )) {
2884                                 si->scope = LDAP_SCOPE_BASE;
2885                         } else if ( !strncasecmp( val, "one", sizeof( "one" ) - 1 )) {
2886                                 si->scope = LDAP_SCOPE_ONELEVEL;
2887                         } else if ( !strncasecmp( val, "sub", sizeof( "sub" ) - 1 )) {
2888                                 si->scope = LDAP_SCOPE_SUBTREE;
2889                         } else {
2890                                 fprintf( stderr, "Error: parse_syncrepl_line: "
2891                                                                  "unknown scope \"%s\"\n", val);
2892                                 return 1;
2893                         }
2894                 } else if ( !strncasecmp( cargv[ i ],
2895                                 ATTRSONLYSTR, sizeof( ATTRSONLYSTR ) - 1 ) ) {
2896                         si->attrsonly = 1;
2897                 } else if ( !strncasecmp( cargv[ i ],
2898                                 ATTRSSTR, sizeof( ATTRSSTR ) - 1 ) ) {
2899                         char **tmp;
2900                         val = cargv[ i ] + sizeof( ATTRSSTR );
2901                         for ( ; hp = strchr( val, ' ' ); val = ++hp ) {
2902                                 *hp = '\0';
2903                                 if ( *val != '\0' ) {
2904                                         nr_attr++;
2905                                         tmp = (char **) ch_realloc( si->attrs, nr_attr * sizeof( char * ));
2906                                         if ( tmp == NULL ) {
2907 #ifdef NEW_LOGGING
2908                                                 LDAP_LOG( CONFIG, ERR, "out of memory\n", 0,0,0 );
2909 #else
2910                                                 Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
2911 #endif
2912                                                 return -1;
2913                                         }
2914                                         si->attrs = tmp;
2915                                         si->attrs[ nr_attr - 1 ] = strdup( val );
2916                                 }
2917                         }
2918                         if ( *val != '\0' ) {
2919                                 nr_attr++;
2920                                 tmp = (char **) ch_realloc( si->attrs, nr_attr * sizeof( char * ));
2921                                 if ( tmp == NULL ) {
2922 #ifdef NEW_LOGGING
2923                                         LDAP_LOG( CONFIG, ERR, "out of memory\n", 0,0,0 );
2924 #else
2925                                         Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
2926 #endif
2927                                         return -1;
2928                                 }
2929                                 si->attrs = tmp;
2930                                 si->attrs[ nr_attr - 1 ] = strdup( val );
2931                         }
2932                         nr_attr++;
2933                         tmp = (char **) ch_realloc( si->attrs, nr_attr * sizeof( char * ));
2934                         if ( tmp == NULL ) {
2935 #ifdef NEW_LOGGING
2936                                 LDAP_LOG( CONFIG, ERR, "out of memory\n", 0,0,0 );
2937 #else
2938                                 Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
2939 #endif
2940                                 return -1;
2941                         }
2942                         si->attrs = tmp;
2943                         si->attrs[ nr_attr - 1 ] = NULL;
2944                         gots |= GOT_ATTRS;
2945                 } else if ( !strncasecmp( cargv[ i ],
2946                                 TYPESTR, sizeof( TYPESTR ) - 1 ) ) {
2947                         val = cargv[ i ] + sizeof( TYPESTR );
2948                         gots |= GOT_TYPE;
2949                         if ( !strncasecmp( val, "refreshOnly", sizeof( "refreshOnly" ) - 1 )) {
2950                                 si->type = LDAP_SYNC_REFRESH_ONLY;
2951                         } else if ( !strncasecmp( val, "refreshAndPersist", sizeof( "refreshAndPersist" ) - 1 )) {
2952                                 gots |= GOT_INTERVAL;
2953                                 si->type = LDAP_SYNC_REFRESH_AND_PERSIST;
2954                                 si->interval = 0;
2955                         } else {
2956                                 fprintf( stderr, "Error: parse_syncrepl_line: "
2957                                                                  "unknown sync type \"%s\"\n", val);
2958                                 return 1;
2959                         }
2960                 } else if ( !strncasecmp( cargv[ i ],
2961                                 INTERVALSTR, sizeof( INTERVALSTR ) - 1 ) ) {
2962                         val = cargv[ i ] + sizeof( INTERVALSTR );
2963                         gots |= GOT_INTERVAL;
2964                         if ( gots & GOT_TYPE && si->type == LDAP_SYNC_REFRESH_AND_PERSIST )
2965                                 si->interval = 0;
2966                         else
2967                                 si->interval = atoi( val );
2968                         if ( si->interval < 0 ) {
2969                                 fprintf( stderr, "Error: parse_syncrepl_line: "
2970                                                                  "invalid interval \"%d\"\n", si->interval);
2971                                 return 1;
2972                         }
2973                 } else if ( !strncasecmp( cargv[ i ],
2974                                 COOKIESTR, sizeof( COOKIESTR ) - 1 ) ) {
2975                         val = cargv[ i ] + sizeof( COOKIESTR );
2976                         si->syncCookie = ber_str2bv( val, strlen( val ), 1, NULL );
2977                 } else {
2978                         fprintf( stderr, "Error: parse_syncrepl_line: "
2979                                                          "unknown keyword \"%s\"\n", cargv[ i ] );
2980                 }
2981         }
2982
2983         if ( si->bindmethod == LDAP_AUTH_SASL) {
2984                 if ((gots & GOT_MECH) == 0) {
2985                         fprintf( stderr, "Error: \"syncrepl\" line needs SASLmech flag " 
2986                                          "in slapd config file\n" );
2987                         return -1;
2988                 }
2989         }
2990
2991         gots |= GOT_MECH;
2992
2993         if ( gots != GOT_ALL ) {
2994                 fprintf( stderr, "Error: Malformed \"syncrepl\" line in slapd config file"
2995  );
2996                 return -1;
2997         }
2998
2999         return 0;
3000 }
3001 #endif /* LDAP_SYNCREPL */