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