1 /* config.c - configuration file handling routines */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2004 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
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>.
16 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
17 * All rights reserved.
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.
31 #include <ac/string.h>
33 #include <ac/signal.h>
34 #include <ac/socket.h>
40 #include "slapi/slapi.h"
47 * defaults for various global variables
49 slap_mask_t global_allows = 0;
50 slap_mask_t global_disallows = 0;
52 int global_gentlehup = 0;
53 int global_idletimeout = 0;
54 char *global_host = NULL;
55 char *global_realm = NULL;
56 char *ldap_srvtab = "";
57 char **default_passwd_hash = NULL;
58 int cargc = 0, cargv_size = 0;
60 struct berval default_search_base = BER_BVNULL;
61 struct berval default_search_nbase = BER_BVNULL;
62 unsigned num_subordinates = 0;
64 ber_len_t sockbuf_max_incoming = SLAP_SB_MAX_INCOMING_DEFAULT;
65 ber_len_t sockbuf_max_incoming_auth= SLAP_SB_MAX_INCOMING_AUTH;
67 int slap_conn_max_pending = SLAP_CONN_MAX_PENDING_DEFAULT;
68 int slap_conn_max_pending_auth = SLAP_CONN_MAX_PENDING_AUTH;
70 char *slapd_pid_file = NULL;
71 char *slapd_args_file = NULL;
73 char *strtok_quote_ptr;
75 int use_reverse_lookup = 0;
78 int slapi_plugins_used = 0;
81 static char *fp_getline(FILE *fp, int *lineno);
82 static void fp_getline_init(int *lineno);
83 static int fp_parse_line(int lineno, char *line);
85 static char *strtok_quote(char *line, char *sep);
86 static int load_ucdata(char *path);
88 static int add_syncrepl LDAP_P(( Backend *, char **, int ));
89 static int parse_syncrepl_line LDAP_P(( char **, int, syncinfo_t *));
91 static int get_attrs_from_file LDAP_P(( char ***, const char *, const char * ));
94 read_config( const char *fname, int depth )
97 char *line, *savefname, *saveline;
101 struct berval vals[2];
104 static BackendInfo *bi = NULL;
105 static BackendDB *be = NULL;
108 vals[1].bv_val = NULL;
111 cargv = ch_calloc( ARGS_STEP + 1, sizeof(*cargv) );
112 cargv_size = ARGS_STEP + 1;
115 if ( (fp = fopen( fname, "r" )) == NULL ) {
117 Debug( LDAP_DEBUG_ANY,
118 "could not open config file \"%s\": %s (%d)\n",
119 fname, strerror(errno), errno );
123 Debug( LDAP_DEBUG_CONFIG, "reading config file %s\n", fname, 0, 0 );
126 fp_getline_init( &lineno );
128 while ( (line = fp_getline( fp, &lineno )) != NULL ) {
129 /* skip comments and blank lines */
130 if ( line[0] == '#' || line[0] == '\0' ) {
134 /* fp_parse_line is destructive, we save a copy */
135 saveline = ch_strdup( line );
137 if ( fp_parse_line( lineno, line ) != 0 ) {
142 Debug( LDAP_DEBUG_ANY,
143 "%s: line %d: bad config line (ignored)\n",
149 if ( strcasecmp( cargv[0], "backend" ) == 0 ) {
151 Debug( LDAP_DEBUG_ANY,
152 "%s: line %d: missing type in \"backend <type>\" line\n",
159 Debug( LDAP_DEBUG_ANY,
160 "%s: line %d: backend line must appear before any database definition\n",
166 bi = backend_info( cargv[1] );
169 Debug( LDAP_DEBUG_ANY,
170 "backend %s initialization failed.\n",
175 } else if ( strcasecmp( cargv[0], "database" ) == 0 ) {
177 Debug( LDAP_DEBUG_ANY,
178 "%s: line %d: missing type in \"database <type>\" line\n",
185 be = backend_db_init( cargv[1] );
188 Debug( LDAP_DEBUG_ANY,
189 "database %s initialization failed.\n",
195 /* set local security factor */
196 } else if ( strcasecmp( cargv[0], "localSSF" ) == 0 ) {
199 Debug( LDAP_DEBUG_ANY,
200 "%s: line %d: missing ssf in \"localSSF <ssf>\" line\n",
205 ssf = atol( cargv[1] );
208 Debug( LDAP_DEBUG_ANY,
209 "%s: line %d: invalid ssf value (%ld) in "
210 "\"localSSF <ssf>\" line.\n",
211 fname, lineno, ssf );
217 /* set thread concurrency */
218 } else if ( strcasecmp( cargv[0], "concurrency" ) == 0 ) {
221 Debug( LDAP_DEBUG_ANY,
222 "%s: line %d: missing level in \"concurrency <level>\" line\n",
228 c = strtol( cargv[1], &next, 10 );
229 if ( next == NULL || next[0] != '\0' ) {
230 Debug( LDAP_DEBUG_ANY,
231 "%s: line %d: unable to parse level \"%s\" in \"concurrency <level>\" line\n",
232 fname, lineno, cargv[1] );
237 Debug( LDAP_DEBUG_ANY,
238 "%s: line %d: invalid level (%d) in \"concurrency <level>\" line\n",
244 ldap_pvt_thread_set_concurrency( c );
246 /* set sockbuf max */
247 } else if ( strcasecmp( cargv[0], "sockbuf_max_incoming" ) == 0 ) {
250 Debug( LDAP_DEBUG_ANY,
251 "%s: line %d: missing max in \"sockbuf_max_incoming <bytes>\" line\n",
257 max = atol( cargv[1] );
260 Debug( LDAP_DEBUG_ANY,
261 "%s: line %d: invalid max value (%ld) in "
262 "\"sockbuf_max_incoming <bytes>\" line.\n",
263 fname, lineno, max );
268 sockbuf_max_incoming = max;
270 /* set sockbuf max authenticated */
271 } else if ( strcasecmp( cargv[0], "sockbuf_max_incoming_auth" ) == 0 ) {
274 Debug( LDAP_DEBUG_ANY,
275 "%s: line %d: missing max in \"sockbuf_max_incoming_auth <bytes>\" line\n",
281 max = atol( cargv[1] );
284 Debug( LDAP_DEBUG_ANY,
285 "%s: line %d: invalid max value (%ld) in "
286 "\"sockbuf_max_incoming_auth <bytes>\" line.\n",
287 fname, lineno, max );
292 sockbuf_max_incoming_auth = max;
294 /* set conn pending max */
295 } else if ( strcasecmp( cargv[0], "conn_max_pending" ) == 0 ) {
298 Debug( LDAP_DEBUG_ANY,
299 "%s: line %d: missing max in \"conn_max_pending <requests>\" line\n",
305 max = atol( cargv[1] );
308 Debug( LDAP_DEBUG_ANY,
309 "%s: line %d: invalid max value (%ld) in "
310 "\"conn_max_pending <requests>\" line.\n",
311 fname, lineno, max );
316 slap_conn_max_pending = max;
318 /* set conn pending max authenticated */
319 } else if ( strcasecmp( cargv[0], "conn_max_pending_auth" ) == 0 ) {
322 Debug( LDAP_DEBUG_ANY,
323 "%s: line %d: missing max in \"conn_max_pending_auth <requests>\" line\n",
329 max = atol( cargv[1] );
332 Debug( LDAP_DEBUG_ANY,
333 "%s: line %d: invalid max value (%ld) in "
334 "\"conn_max_pending_auth <requests>\" line.\n",
335 fname, lineno, max );
340 slap_conn_max_pending_auth = max;
342 /* default search base */
343 } else if ( strcasecmp( cargv[0], "defaultSearchBase" ) == 0 ) {
345 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
346 "missing dn in \"defaultSearchBase <dn>\" line\n",
351 } else if ( cargc > 2 ) {
352 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
353 "extra cruft after <dn> in \"defaultSearchBase %s\", "
355 fname, lineno, cargv[1] );
358 if ( bi != NULL || be != NULL ) {
359 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
360 "defaultSearchBaase line must appear prior to "
361 "any backend or database definition\n",
367 if ( default_search_nbase.bv_len ) {
368 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
369 "default search base \"%s\" already defined "
370 "(discarding old)\n",
371 fname, lineno, default_search_base.bv_val );
373 free( default_search_base.bv_val );
374 free( default_search_nbase.bv_val );
377 if ( load_ucdata( NULL ) < 0 ) return 1;
382 dn.bv_val = cargv[1];
383 dn.bv_len = strlen( dn.bv_val );
385 rc = dnPrettyNormal( NULL, &dn,
386 &default_search_base,
387 &default_search_nbase, NULL );
389 if( rc != LDAP_SUCCESS ) {
390 Debug( LDAP_DEBUG_ANY,
391 "%s: line %d: defaultSearchBase DN is invalid\n",
397 /* set maximum threads in thread pool */
398 } else if ( strcasecmp( cargv[0], "threads" ) == 0 ) {
401 Debug( LDAP_DEBUG_ANY,
402 "%s: line %d: missing count in \"threads <count>\" line\n",
408 c = strtol( cargv[1], &next, 10 );
409 if (next == NULL || next[0] != '\0' ) {
410 Debug( LDAP_DEBUG_ANY,
411 "%s: line %d: unable to parse count \"%s\" in \"threads <count>\" line\n",
412 fname, lineno, cargv[1] );
417 Debug( LDAP_DEBUG_ANY,
418 "%s: line %d: invalid level (%d) in \"threads <count>\" line\n",
424 ldap_pvt_thread_pool_maxthreads( &connection_pool, c );
426 /* save for later use */
427 connection_pool_max = c;
429 /* get pid file name */
430 } else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) {
432 Debug( LDAP_DEBUG_ANY,
433 "%s: line %d: missing file name in \"pidfile <file>\" line\n",
439 slapd_pid_file = ch_strdup( cargv[1] );
441 /* get args file name */
442 } else if ( strcasecmp( cargv[0], "argsfile" ) == 0 ) {
444 Debug( LDAP_DEBUG_ANY,
445 "%s: line %d: missing file name in \"argsfile <file>\" line\n",
451 slapd_args_file = ch_strdup( cargv[1] );
453 } else if ( strcasecmp( cargv[0], "replica-pidfile" ) == 0 ) {
456 } else if ( strcasecmp( cargv[0], "replica-argsfile" ) == 0 ) {
459 /* default password hash */
460 } else if ( strcasecmp( cargv[0], "password-hash" ) == 0 ) {
462 Debug( LDAP_DEBUG_ANY,
463 "%s: line %d: missing hash in \"password-hash <hash>\" line\n",
468 if ( default_passwd_hash != NULL ) {
469 Debug( LDAP_DEBUG_ANY,
470 "%s: line %d: already set default password_hash!\n",
476 for(i = 1; i < cargc; i++) {
477 if ( lutil_passwd_scheme( cargv[i] ) == 0 ) {
478 Debug( LDAP_DEBUG_ANY,
479 "%s: line %d: password scheme \"%s\" not available\n",
480 fname, lineno, cargv[i] );
482 ldap_charray_add( &default_passwd_hash, cargv[i] );
485 if( !default_passwd_hash ) {
486 Debug( LDAP_DEBUG_ANY,
487 "%s: line %d: no valid hashes found\n",
492 } else if ( strcasecmp( cargv[0], "password-crypt-salt-format" ) == 0 )
495 Debug( LDAP_DEBUG_ANY, "%s: line %d: missing format in "
496 "\"password-crypt-salt-format <format>\" line\n",
502 lutil_salt_format( cargv[1] );
504 #ifdef SLAP_AUTH_REWRITE
505 /* use authid rewrite instead of sasl regexp */
506 } else if ( strncasecmp( cargv[0], "auth-rewrite",
507 STRLENOF("auth-rewrite") ) == 0 )
509 int rc = slap_sasl_rewrite_config( fname, lineno,
514 #endif /* SLAP_AUTH_REWRITE */
516 /* Auth + SASL config options */
517 } else if ( !strncasecmp( cargv[0], "auth", STRLENOF("auth") ) ||
518 !strncasecmp( cargv[0], "sasl", STRLENOF("sasl") ))
520 if ( slap_sasl_config( cargc, cargv, line, fname, lineno ) )
524 } else if ( strcasecmp( cargv[0], "schemadn" ) == 0 ) {
527 Debug( LDAP_DEBUG_ANY,
528 "%s: line %d: missing dn in \"schemadn <dn>\" line\n",
532 ber_str2bv( cargv[1], 0, 0, &dn );
534 rc = dnPrettyNormal( NULL, &dn, &be->be_schemadn,
535 &be->be_schemandn, NULL );
537 rc = dnPrettyNormal( NULL, &dn, &frontendDB->be_schemadn,
538 &frontendDB->be_schemandn, NULL );
540 if ( rc != LDAP_SUCCESS ) {
541 Debug( LDAP_DEBUG_ANY,
542 "%s: line %d: schemadn DN is invalid\n",
547 /* set UCDATA path */
548 } else if ( strcasecmp( cargv[0], "ucdata-path" ) == 0 ) {
551 Debug( LDAP_DEBUG_ANY,
552 "%s: line %d: missing path in \"ucdata-path <path>\" line\n",
558 err = load_ucdata( cargv[1] );
561 Debug( LDAP_DEBUG_ANY,
562 "%s: line %d: ucdata already loaded, ucdata-path must be set earlier in the file and/or be specified only once!\n",
570 } else if ( strcasecmp( cargv[0], "sizelimit" ) == 0 ) {
572 struct slap_limits_set *lim;
575 Debug( LDAP_DEBUG_ANY,
576 "%s: line %d: missing limit in \"sizelimit <limit>\" line\n",
583 lim = &frontendDB->be_def_limit;
585 lim = &be->be_def_limit;
588 for ( i = 1; i < cargc; i++ ) {
589 if ( strncasecmp( cargv[i], "size", 4 ) == 0 ) {
590 rc = limits_parse_one( cargv[i], lim );
592 Debug( LDAP_DEBUG_ANY,
593 "%s: line %d: unable "
594 "to parse value \"%s\" "
597 fname, lineno, cargv[i] );
602 if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) {
603 lim->lms_s_soft = -1;
605 lim->lms_s_soft = strtol( cargv[i] , &next, 0 );
606 if ( next == cargv[i] ) {
607 Debug( LDAP_DEBUG_ANY,
608 "%s: line %d: unable to parse limit \"%s\" in \"sizelimit <limit>\" line\n",
609 fname, lineno, cargv[i] );
612 } else if ( next[0] != '\0' ) {
613 Debug( LDAP_DEBUG_ANY,
614 "%s: line %d: trailing chars \"%s\" in \"sizelimit <limit>\" line ignored\n",
615 fname, lineno, next );
623 } else if ( strcasecmp( cargv[0], "timelimit" ) == 0 ) {
625 struct slap_limits_set *lim;
628 Debug( LDAP_DEBUG_ANY,
629 "%s: line %d: missing limit in \"timelimit <limit>\" line\n",
636 lim = &frontendDB->be_def_limit;
638 lim = &be->be_def_limit;
641 for ( i = 1; i < cargc; i++ ) {
642 if ( strncasecmp( cargv[i], "time", 4 ) == 0 ) {
643 rc = limits_parse_one( cargv[i], lim );
645 Debug( LDAP_DEBUG_ANY,
646 "%s: line %d: unable "
647 "to parse value \"%s\" "
650 fname, lineno, cargv[i] );
655 if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) {
656 lim->lms_t_soft = -1;
658 lim->lms_t_soft = strtol( cargv[i] , &next, 0 );
659 if ( next == cargv[i] ) {
660 Debug( LDAP_DEBUG_ANY,
661 "%s: line %d: unable to parse limit \"%s\" in \"timelimit <limit>\" line\n",
662 fname, lineno, cargv[i] );
665 } else if ( next[0] != '\0' ) {
666 Debug( LDAP_DEBUG_ANY,
667 "%s: line %d: trailing chars \"%s\" in \"timelimit <limit>\" line ignored\n",
668 fname, lineno, next );
675 /* set regex-based limits */
676 } else if ( strcasecmp( cargv[0], "limits" ) == 0 ) {
678 Debug( LDAP_DEBUG_ANY,
679 "%s: line %d \"limits\" allowed only in database environment.\n%s",
684 if ( limits_parse( be, fname, lineno, cargc, cargv ) ) {
688 /* mark this as a subordinate database */
689 } else if ( strcasecmp( cargv[0], "subordinate" ) == 0 ) {
691 Debug( LDAP_DEBUG_ANY, "%s: line %d: subordinate keyword "
692 "must appear inside a database definition.\n",
697 SLAP_DBFLAGS(be) |= SLAP_DBFLAG_GLUE_SUBORDINATE;
701 /* add an overlay to this backend */
702 } else if ( strcasecmp( cargv[0], "overlay" ) == 0 ) {
704 if ( cargv[1][0] == '-' && overlay_config( frontendDB, &cargv[1][1] ) ) {
706 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
707 "(optional) global overlay \"%s\" configuration "
708 "failed (ignored)\n", fname, lineno, &cargv[1][1] );
709 } else if ( overlay_config( frontendDB, cargv[1] ) ) {
714 if ( cargv[1][0] == '-' && overlay_config( be, &cargv[1][1] ) ) {
716 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
717 "(optional) overlay \"%s\" configuration "
718 "failed (ignored)\n", fname, lineno, &cargv[1][1] );
719 } else if ( overlay_config( be, cargv[1] ) ) {
724 /* set database suffix */
725 } else if ( strcasecmp( cargv[0], "suffix" ) == 0 ) {
727 struct berval dn, pdn, ndn;
730 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
731 "missing dn in \"suffix <dn>\" line\n",
736 } else if ( cargc > 2 ) {
737 Debug( LDAP_DEBUG_ANY, "%s: line %d: extra cruft "
738 "after <dn> in \"suffix %s\" line (ignored)\n",
739 fname, lineno, cargv[1] );
743 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix line "
744 "must appear inside a database definition\n",
748 #if defined(SLAPD_MONITOR_DN)
749 /* "cn=Monitor" is reserved for monitoring slap */
750 } else if ( strcasecmp( cargv[1], SLAPD_MONITOR_DN ) == 0 ) {
751 Debug( LDAP_DEBUG_ANY, "%s: line %d: \""
752 "%s\" is reserved for monitoring slapd\n",
753 fname, lineno, SLAPD_MONITOR_DN );
755 #endif /* SLAPD_MONITOR_DN */
758 if ( load_ucdata( NULL ) < 0 ) return 1;
760 dn.bv_val = cargv[1];
761 dn.bv_len = strlen( cargv[1] );
763 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL );
764 if( rc != LDAP_SUCCESS ) {
765 Debug( LDAP_DEBUG_ANY,
766 "%s: line %d: suffix DN is invalid\n",
771 tmp_be = select_backend( &ndn, 0, 0 );
772 if ( tmp_be == be ) {
773 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
774 "already served by this backend (ignored)\n",
779 } else if ( tmp_be != NULL ) {
780 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
781 "already served by a preceeding backend \"%s\"\n",
782 fname, lineno, tmp_be->be_suffix[0].bv_val );
787 } else if( pdn.bv_len == 0 && default_search_nbase.bv_len ) {
788 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
789 "suffix DN empty and default "
790 "search base provided \"%s\" (assuming okay)\n",
791 fname, lineno, default_search_base.bv_val );
794 ber_bvarray_add( &be->be_suffix, &pdn );
795 ber_bvarray_add( &be->be_nsuffix, &ndn );
797 /* set max deref depth */
798 } else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
801 Debug( LDAP_DEBUG_ANY,
802 "%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
808 Debug( LDAP_DEBUG_ANY,
809 "%s: line %d: depth line must appear inside a database definition.\n",
814 i = strtol( cargv[1], &next, 10 );
815 if ( next == NULL || next[0] != '\0' ) {
816 Debug( LDAP_DEBUG_ANY,
817 "%s: line %d: unable to parse depth \"%s\" in \"maxDerefDepth <depth>\" "
818 "line.\n", fname, lineno, cargv[1] );
823 Debug( LDAP_DEBUG_ANY,
824 "%s: line %d: depth must be positive.\n",
830 be->be_max_deref_depth = i;
832 /* set magic "root" dn for this database */
833 } else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
835 Debug( LDAP_DEBUG_ANY,
836 "%s: line %d: missing dn in \"rootdn <dn>\" line\n",
843 Debug( LDAP_DEBUG_ANY,
844 "%s: line %d: rootdn line must appear inside a database definition.\n",
851 if ( load_ucdata( NULL ) < 0 ) return 1;
853 dn.bv_val = cargv[1];
854 dn.bv_len = strlen( cargv[1] );
856 rc = dnPrettyNormal( NULL, &dn,
858 &be->be_rootndn, NULL );
860 if( rc != LDAP_SUCCESS ) {
861 Debug( LDAP_DEBUG_ANY,
862 "%s: line %d: rootdn DN is invalid\n",
868 /* set super-secret magic database password */
869 } else if ( strcasecmp( cargv[0], "rootpw" ) == 0 ) {
871 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
872 "missing passwd in \"rootpw <passwd>\" line\n",
879 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
880 "rootpw line must appear inside a database "
886 Backend *tmp_be = select_backend( &be->be_rootndn, 0, 0 );
889 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
890 "rootpw can only be set when rootdn is under suffix\n",
895 be->be_rootpw.bv_val = ch_strdup( cargv[1] );
896 be->be_rootpw.bv_len = strlen( be->be_rootpw.bv_val );
899 /* make this database read-only */
900 } else if ( strcasecmp( cargv[0], "readonly" ) == 0 ) {
902 Debug( LDAP_DEBUG_ANY,
903 "%s: line %d: missing on|off in \"readonly <on|off>\" line\n",
909 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
910 frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
912 frontendDB->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
916 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
917 be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
919 be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
923 /* restricts specific operations */
924 } else if ( strcasecmp( cargv[0], "restrict" ) == 0 ) {
925 slap_mask_t restrictops = 0;
926 struct restrictable_exops_t {
929 } restrictable_exops[] = {
930 { LDAP_EXOP_START_TLS, SLAP_RESTRICT_EXOP_START_TLS },
931 { LDAP_EXOP_MODIFY_PASSWD, SLAP_RESTRICT_EXOP_MODIFY_PASSWD },
932 { LDAP_EXOP_X_WHO_AM_I, SLAP_RESTRICT_EXOP_WHOAMI },
933 { LDAP_EXOP_X_CANCEL, SLAP_RESTRICT_EXOP_CANCEL },
939 Debug( LDAP_DEBUG_ANY,
940 "%s: line %d: missing <op_list> in \"restrict <op_list>\" "
941 "line.\n", fname, lineno, 0 );
945 for ( i = 1; i < cargc; i++ ) {
946 if ( strcasecmp( cargv[ i ], "read" ) == 0 ) {
947 restrictops |= SLAP_RESTRICT_OP_READS;
949 } else if ( strcasecmp( cargv[ i ], "write" ) == 0 ) {
950 restrictops |= SLAP_RESTRICT_OP_WRITES;
952 } else if ( strcasecmp( cargv[ i ], "add" ) == 0 ) {
953 restrictops |= SLAP_RESTRICT_OP_ADD;
955 } else if ( strcasecmp( cargv[ i ], "bind" ) == 0 ) {
956 restrictops |= SLAP_RESTRICT_OP_BIND;
958 } else if ( strcasecmp( cargv[ i ], "compare" ) == 0 ) {
959 restrictops |= SLAP_RESTRICT_OP_COMPARE;
961 } else if ( strcasecmp( cargv[ i ], "delete" ) == 0 ) {
962 restrictops |= SLAP_RESTRICT_OP_DELETE;
964 } else if ( strncasecmp( cargv[ i ], "extended",
965 STRLENOF( "extended" ) ) == 0 )
967 char *e = cargv[ i ] + STRLENOF( "extended" );
973 for ( j = 0; restrictable_exops[ j ].name; j++ ) {
974 if ( strcmp( e, restrictable_exops[j].name ) == 0 )
976 restrictops |= restrictable_exops[ j ].flag;
981 if ( restrictable_exops[ j ].name == NULL ) {
982 goto restrict_unknown;
985 restrictops &= ~SLAP_RESTRICT_OP_EXTENDED;
987 } else if ( e[0] == '\0' ) {
988 restrictops &= ~SLAP_RESTRICT_EXOP_MASK;
989 restrictops |= SLAP_RESTRICT_OP_EXTENDED;
992 goto restrict_unknown;
995 } else if ( strcasecmp( cargv[ i ], "modify" ) == 0 ) {
996 restrictops |= SLAP_RESTRICT_OP_MODIFY;
998 } else if ( strcasecmp( cargv[ i ], "rename" ) == 0
999 || strcasecmp( cargv[ i ], "modrdn" ) == 0 )
1001 restrictops |= SLAP_RESTRICT_OP_RENAME;
1003 } else if ( strcasecmp( cargv[ i ], "search" ) == 0 ) {
1004 restrictops |= SLAP_RESTRICT_OP_SEARCH;
1009 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1010 "unknown operation %s in \"allow <features>\" line\n",
1011 fname, lineno, cargv[i] );
1017 frontendDB->be_restrictops |= restrictops;
1019 be->be_restrictops |= restrictops;
1022 /* allow these features */
1023 } else if ( strcasecmp( cargv[0], "allows" ) == 0 ||
1024 strcasecmp( cargv[0], "allow" ) == 0 )
1026 slap_mask_t allows = 0;
1029 Debug( LDAP_DEBUG_ANY,
1030 "%s: line %d: allow line must appear prior to database definitions\n",
1036 Debug( LDAP_DEBUG_ANY,
1037 "%s: line %d: missing feature(s) in \"allow <features>\" line\n",
1043 for( i=1; i < cargc; i++ ) {
1044 if( strcasecmp( cargv[i], "bind_v2" ) == 0 ) {
1045 allows |= SLAP_ALLOW_BIND_V2;
1047 } else if( strcasecmp( cargv[i], "bind_anon_cred" ) == 0 ) {
1048 allows |= SLAP_ALLOW_BIND_ANON_CRED;
1050 } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) {
1051 allows |= SLAP_ALLOW_BIND_ANON_DN;
1053 } else if( strcasecmp( cargv[i], "update_anon" ) == 0 ) {
1054 allows |= SLAP_ALLOW_UPDATE_ANON;
1057 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1058 "unknown feature %s in \"allow <features>\" line\n",
1059 fname, lineno, cargv[i] );
1065 global_allows |= allows;
1067 /* disallow these features */
1068 } else if ( strcasecmp( cargv[0], "disallows" ) == 0 ||
1069 strcasecmp( cargv[0], "disallow" ) == 0 )
1071 slap_mask_t disallows = 0;
1074 Debug( LDAP_DEBUG_ANY,
1075 "%s: line %d: disallow line must appear prior to database definitions\n",
1081 Debug( LDAP_DEBUG_ANY,
1082 "%s: line %d: missing feature(s) in \"disallow <features>\" line\n",
1088 for( i=1; i < cargc; i++ ) {
1089 if( strcasecmp( cargv[i], "bind_anon" ) == 0 ) {
1090 disallows |= SLAP_DISALLOW_BIND_ANON;
1092 } else if( strcasecmp( cargv[i], "bind_simple" ) == 0 ) {
1093 disallows |= SLAP_DISALLOW_BIND_SIMPLE;
1095 } else if( strcasecmp( cargv[i], "bind_krbv4" ) == 0 ) {
1096 disallows |= SLAP_DISALLOW_BIND_KRBV4;
1098 } else if( strcasecmp( cargv[i], "tls_2_anon" ) == 0 ) {
1099 disallows |= SLAP_DISALLOW_TLS_2_ANON;
1101 } else if( strcasecmp( cargv[i], "tls_authc" ) == 0 ) {
1102 disallows |= SLAP_DISALLOW_TLS_AUTHC;
1105 Debug( LDAP_DEBUG_ANY,
1106 "%s: line %d: unknown feature %s in \"disallow <features>\" line\n",
1107 fname, lineno, cargv[i] );
1113 global_disallows |= disallows;
1115 /* require these features */
1116 } else if ( strcasecmp( cargv[0], "requires" ) == 0 ||
1117 strcasecmp( cargv[0], "require" ) == 0 )
1119 slap_mask_t requires = 0;
1122 Debug( LDAP_DEBUG_ANY,
1123 "%s: line %d: missing feature(s) in \"require <features>\" line\n",
1129 for( i=1; i < cargc; i++ ) {
1130 if( strcasecmp( cargv[i], "bind" ) == 0 ) {
1131 requires |= SLAP_REQUIRE_BIND;
1133 } else if( strcasecmp( cargv[i], "LDAPv3" ) == 0 ) {
1134 requires |= SLAP_REQUIRE_LDAP_V3;
1136 } else if( strcasecmp( cargv[i], "authc" ) == 0 ) {
1137 requires |= SLAP_REQUIRE_AUTHC;
1139 } else if( strcasecmp( cargv[i], "SASL" ) == 0 ) {
1140 requires |= SLAP_REQUIRE_SASL;
1142 } else if( strcasecmp( cargv[i], "strong" ) == 0 ) {
1143 requires |= SLAP_REQUIRE_STRONG;
1145 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1146 Debug( LDAP_DEBUG_ANY,
1147 "%s: line %d: unknown feature %s in \"require <features>\" line\n",
1148 fname, lineno, cargv[i] );
1155 frontendDB->be_requires = requires;
1157 be->be_requires = requires;
1160 } else if ( strcasecmp( cargv[0], "security" ) == 0 ) {
1161 slap_ssf_set_t *set;
1164 Debug( LDAP_DEBUG_ANY,
1165 "%s: line %d: missing factor(s) in \"security <factors>\" line\n",
1172 set = &frontendDB->be_ssf_set;
1174 set = &be->be_ssf_set;
1177 for( i=1; i < cargc; i++ ) {
1181 if ( strncasecmp( cargv[i], "ssf=",
1182 STRLENOF("ssf=") ) == 0 )
1184 tgt = &set->sss_ssf;
1185 src = &cargv[i][STRLENOF("ssf=")];
1187 } else if ( strncasecmp( cargv[i], "transport=",
1188 STRLENOF("transport=") ) == 0 )
1190 tgt = &set->sss_transport;
1191 src = &cargv[i][STRLENOF("transport=")];
1193 } else if ( strncasecmp( cargv[i], "tls=",
1194 STRLENOF("tls=") ) == 0 )
1196 tgt = &set->sss_tls;
1197 src = &cargv[i][STRLENOF("tls=")];
1199 } else if ( strncasecmp( cargv[i], "sasl=",
1200 STRLENOF("sasl=") ) == 0 )
1202 tgt = &set->sss_sasl;
1203 src = &cargv[i][STRLENOF("sasl=")];
1205 } else if ( strncasecmp( cargv[i], "update_ssf=",
1206 STRLENOF("update_ssf=") ) == 0 )
1208 tgt = &set->sss_update_ssf;
1209 src = &cargv[i][STRLENOF("update_ssf=")];
1211 } else if ( strncasecmp( cargv[i], "update_transport=",
1212 STRLENOF("update_transport=") ) == 0 )
1214 tgt = &set->sss_update_transport;
1215 src = &cargv[i][STRLENOF("update_transport=")];
1217 } else if ( strncasecmp( cargv[i], "update_tls=",
1218 STRLENOF("update_tls=") ) == 0 )
1220 tgt = &set->sss_update_tls;
1221 src = &cargv[i][STRLENOF("update_tls=")];
1223 } else if ( strncasecmp( cargv[i], "update_sasl=",
1224 STRLENOF("update_sasl=") ) == 0 )
1226 tgt = &set->sss_update_sasl;
1227 src = &cargv[i][STRLENOF("update_sasl=")];
1229 } else if ( strncasecmp( cargv[i], "simple_bind=",
1230 STRLENOF("simple_bind=") ) == 0 )
1232 tgt = &set->sss_simple_bind;
1233 src = &cargv[i][STRLENOF("simple_bind=")];
1236 Debug( LDAP_DEBUG_ANY,
1237 "%s: line %d: unknown factor %s in \"security <factors>\" line\n",
1238 fname, lineno, cargv[i] );
1243 *tgt = strtol( src, &next, 10 );
1244 if ( next == NULL || next[0] != '\0' ) {
1245 Debug( LDAP_DEBUG_ANY,
1246 "%s: line %d: unable to parse factor \"%s\" in \"security <factors>\" line\n",
1247 fname, lineno, cargv[i] );
1253 /* where to send clients when we don't hold it */
1254 } else if ( strcasecmp( cargv[0], "referral" ) == 0 ) {
1256 Debug( LDAP_DEBUG_ANY,
1257 "%s: line %d: missing URL in \"referral <URL>\" line\n",
1263 if( validate_global_referral( cargv[1] ) ) {
1264 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1265 "invalid URL (%s) in \"referral\" line.\n",
1266 fname, lineno, cargv[1] );
1270 vals[0].bv_val = cargv[1];
1271 vals[0].bv_len = strlen( vals[0].bv_val );
1272 if( value_add( &default_referral, vals ) )
1275 /* start of a new database definition */
1276 } else if ( strcasecmp( cargv[0], "debug" ) == 0 ) {
1279 Debug( LDAP_DEBUG_ANY,
1280 "%s: line %d: Error in debug directive, \"debug subsys level\"\n",
1284 level = strtol( cargv[2], &next, 10 );
1285 if ( next == NULL || next[0] != '\0' ){
1286 Debug( LDAP_DEBUG_ANY,
1287 "%s: line %d: unable to parse level \"%s\" in debug directive, "
1288 "\"debug <subsys> <level>\"\n", fname, lineno , cargv[2] );
1292 if ( level <= 0 ) level = lutil_mnem2level( cargv[2] );
1293 lutil_set_debug_level( cargv[1], level );
1294 /* specify an Object Identifier macro */
1295 } else if ( strcasecmp( cargv[0], "objectidentifier" ) == 0 ) {
1296 rc = parse_oidm( fname, lineno, cargc, cargv );
1299 /* specify an objectclass */
1300 } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
1302 Debug( LDAP_DEBUG_ANY,
1303 "%s: line %d: illegal objectclass format.\n",
1307 } else if ( *cargv[1] == '(' /*')'*/) {
1309 p = strchr(saveline,'(' /*')'*/);
1310 rc = parse_oc( fname, lineno, p, cargv );
1314 Debug( LDAP_DEBUG_ANY,
1315 "%s: line %d: old objectclass format not supported.\n",
1319 } else if ( strcasecmp( cargv[0], "ditcontentrule" ) == 0 ) {
1321 p = strchr(saveline,'(' /*')'*/);
1322 rc = parse_cr( fname, lineno, p, cargv );
1325 /* specify an attribute type */
1326 } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
1327 || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
1330 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1331 "illegal attribute type format.\n",
1335 } else if ( *cargv[1] == '(' /*')'*/) {
1337 p = strchr(saveline,'(' /*')'*/);
1338 rc = parse_at( fname, lineno, p, cargv );
1342 Debug( LDAP_DEBUG_ANY,
1343 "%s: line %d: old attribute type format not supported.\n",
1348 /* define attribute option(s) */
1349 } else if ( strcasecmp( cargv[0], "attributeoptions" ) == 0 ) {
1350 ad_define_option( NULL, NULL, 0 );
1351 for ( i = 1; i < cargc; i++ )
1352 if ( ad_define_option( cargv[i], fname, lineno ) != 0 )
1355 /* turn on/off schema checking */
1356 } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
1358 Debug( LDAP_DEBUG_ANY,
1359 "%s: line %d: missing on|off in \"schemacheck <on|off>\" line\n",
1364 if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1365 Debug( LDAP_DEBUG_ANY,
1366 "%s: line %d: schema checking disabled! your mileage may vary!\n",
1368 global_schemacheck = 0;
1370 global_schemacheck = 1;
1373 /* specify access control info */
1374 } else if ( strcasecmp( cargv[0], "access" ) == 0 ) {
1375 parse_acl( be, fname, lineno, cargc, cargv );
1377 /* debug level to log things to syslog */
1378 } else if ( strcasecmp( cargv[0], "loglevel" ) == 0 ) {
1380 Debug( LDAP_DEBUG_ANY,
1381 "%s: line %d: missing level(s) in \"loglevel <level> [...]\" line\n",
1389 for( i=1; i < cargc; i++ ) {
1392 if ( isdigit( cargv[i][0] ) ) {
1393 level = strtol( cargv[i], &next, 10 );
1394 if ( next == NULL || next[0] != '\0' ) {
1395 Debug( LDAP_DEBUG_ANY,
1396 "%s: line %d: unable to parse level \"%s\" "
1397 "in \"loglevel <level> [...]\" line.\n",
1398 fname, lineno , cargv[i] );
1407 { LDAP_DEBUG_TRACE, "Trace" },
1408 { LDAP_DEBUG_PACKETS, "Packets" },
1409 { LDAP_DEBUG_ARGS, "Args" },
1410 { LDAP_DEBUG_CONNS, "Conns" },
1411 { LDAP_DEBUG_BER, "BER" },
1412 { LDAP_DEBUG_FILTER, "Filter" },
1413 { LDAP_DEBUG_CONFIG, "Config" },
1414 { LDAP_DEBUG_ACL, "ACL" },
1415 { LDAP_DEBUG_STATS, "Stats" },
1416 { LDAP_DEBUG_STATS2, "Stats2" },
1417 { LDAP_DEBUG_SHELL, "Shell" },
1418 { LDAP_DEBUG_PARSE, "Parse" },
1419 { LDAP_DEBUG_CACHE, "Cache" },
1420 { LDAP_DEBUG_INDEX, "Index" },
1426 for ( j = 0; int_2_level[j].s; j++ ) {
1427 if ( strcasecmp( cargv[i], int_2_level[j].s ) == 0 ) {
1428 level = int_2_level[j].i;
1433 if ( int_2_level[j].s == NULL ) {
1434 Debug( LDAP_DEBUG_ANY,
1435 "%s: line %d: unknown level \"%s\" "
1436 "in \"loglevel <level> [...]\" line.\n",
1437 fname, lineno , cargv[i] );
1442 ldap_syslog |= level;
1445 /* list of sync replication information in this backend (slave only) */
1446 } else if ( strcasecmp( cargv[0], "syncrepl" ) == 0 ) {
1449 Debug( LDAP_DEBUG_ANY,
1450 "%s: line %d: syncrepl line must appear inside "
1451 "a database definition.\n", fname, lineno, 0);
1454 } else if ( SLAP_SHADOW( be )) {
1455 Debug( LDAP_DEBUG_ANY,
1456 "%s: line %d: syncrepl: database already shadowed.\n",
1460 } else if ( add_syncrepl( be, cargv, cargc )) {
1464 SLAP_DBFLAGS(be) |= ( SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SYNC_SHADOW );
1466 /* list of replicas of the data in this backend (master only) */
1467 } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
1469 Debug( LDAP_DEBUG_ANY,
1470 "%s: line %d: missing host or uri in \"replica <host[:port]>\" line\n",
1476 Debug( LDAP_DEBUG_ANY,
1477 "%s: line %d: replica line must appear inside a database definition\n",
1484 for ( i = 1; i < cargc; i++ ) {
1485 if ( strncasecmp( cargv[i], "host=", 5 )
1487 nr = add_replica_info( be,
1490 } else if (strncasecmp( cargv[i], "uri=", 4 )
1492 if ( ldap_url_parse( cargv[ i ] + 4, &ludp )
1494 Debug( LDAP_DEBUG_ANY,
1495 "%s: line %d: replica line contains invalid "
1496 "uri definition.\n", fname, lineno, 0);
1499 if (ludp->lud_host == NULL ) {
1500 Debug( LDAP_DEBUG_ANY,
1501 "%s: line %d: replica line contains invalid "
1502 "uri definition - missing hostname.\n", fname, lineno, 0);
1505 replicahost = ch_malloc( strlen( cargv[ i ] ) );
1506 if ( replicahost == NULL ) {
1507 Debug( LDAP_DEBUG_ANY,
1508 "out of memory in read_config\n", 0, 0, 0 );
1509 ldap_free_urldesc( ludp );
1510 exit( EXIT_FAILURE );
1512 sprintf(replicahost, "%s:%d",
1513 ludp->lud_host, ludp->lud_port);
1514 nr = add_replica_info( be, replicahost );
1515 ldap_free_urldesc( ludp );
1516 ch_free(replicahost);
1521 Debug( LDAP_DEBUG_ANY,
1522 "%s: line %d: missing host or uri in \"replica\" line\n",
1526 } else if ( nr == -1 ) {
1527 Debug( LDAP_DEBUG_ANY,
1528 "%s: line %d: unable to add replica \"%s\"\n",
1529 fname, lineno, cargv[i] + 5 );
1532 for ( i = 1; i < cargc; i++ ) {
1533 if ( strncasecmp( cargv[i], "suffix=", 7 ) == 0 ) {
1535 switch ( add_replica_suffix( be, nr, cargv[i] + 7 ) ) {
1537 Debug( LDAP_DEBUG_ANY,
1538 "%s: line %d: suffix \"%s\" in \"replica\" line is not valid for backend (ignored)\n",
1539 fname, lineno, cargv[i] + 7 );
1543 Debug( LDAP_DEBUG_ANY,
1544 "%s: line %d: unable to normalize suffix in \"replica\" line (ignored)\n",
1549 } else if ( strncasecmp( cargv[i], "attr", 4 ) == 0 ) {
1551 char *arg = cargv[i] + 4;
1553 if ( arg[0] == '!' ) {
1558 if ( arg[0] != '=' ) {
1562 if ( add_replica_attrs( be, nr, arg + 1, exclude ) ) {
1563 Debug( LDAP_DEBUG_ANY,
1564 "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
1565 fname, lineno, arg + 1 );
1573 } else if ( strcasecmp( cargv[0], "replicationInterval" ) == 0 ) {
1576 /* dn of slave entity allowed to write to replica */
1577 } else if ( strcasecmp( cargv[0], "updatedn" ) == 0 ) {
1579 Debug( LDAP_DEBUG_ANY,
1580 "%s: line %d: missing dn in \"updatedn <dn>\" line\n",
1586 Debug( LDAP_DEBUG_ANY,
1587 "%s: line %d: updatedn line must appear inside a database definition\n",
1591 } else if ( SLAP_SHADOW(be) ) {
1592 Debug( LDAP_DEBUG_ANY,
1593 "%s: line %d: updatedn: database already shadowed.\n",
1600 if ( load_ucdata( NULL ) < 0 ) return 1;
1602 dn.bv_val = cargv[1];
1603 dn.bv_len = strlen( cargv[1] );
1605 rc = dnNormalize( 0, NULL, NULL, &dn, &be->be_update_ndn, NULL );
1606 if( rc != LDAP_SUCCESS ) {
1607 Debug( LDAP_DEBUG_ANY,
1608 "%s: line %d: updatedn DN is invalid\n",
1614 SLAP_DBFLAGS(be) |= ( SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SLURP_SHADOW );
1616 } else if ( strcasecmp( cargv[0], "updateref" ) == 0 ) {
1618 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1619 "missing url in \"updateref <ldapurl>\" line\n",
1625 Debug( LDAP_DEBUG_ANY, "%s: line %d: updateref"
1626 " line must appear inside a database definition\n",
1630 } else if ( !SLAP_SHADOW(be) ) {
1631 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1632 "updateref line must after syncrepl or updatedn.\n",
1637 if( validate_global_referral( cargv[1] ) ) {
1638 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1639 "invalid URL (%s) in \"updateref\" line.\n",
1640 fname, lineno, cargv[1] );
1644 vals[0].bv_val = cargv[1];
1645 vals[0].bv_len = strlen( vals[0].bv_val );
1646 if( value_add( &be->be_update_refs, vals ) ) {
1650 /* replication log file to which changes are appended */
1651 } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
1653 Debug( LDAP_DEBUG_ANY,
1654 "%s: line %d: missing filename in \"replogfile <filename>\" line\n",
1660 be->be_replogfile = ch_strdup( cargv[1] );
1662 replogfile = ch_strdup( cargv[1] );
1665 /* file from which to read additional rootdse attrs */
1666 } else if ( strcasecmp( cargv[0], "rootDSE" ) == 0) {
1668 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1669 "missing filename in \"rootDSE <filename>\" line.\n",
1674 if( read_root_dse_file( cargv[1] ) ) {
1675 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1676 "could not read \"rootDSE <filename>\" line\n",
1681 /* maintain lastmodified{by,time} attributes */
1682 } else if ( strcasecmp( cargv[0], "lastmod" ) == 0 ) {
1684 Debug( LDAP_DEBUG_ANY,
1685 "%s: line %d: missing on|off in \"lastmod <on|off>\" line\n",
1692 Debug( LDAP_DEBUG_ANY, "%s: line %d: lastmod"
1693 " line must appear inside a database definition\n",
1697 } else if ( SLAP_NOLASTMODCMD(be) ) {
1698 Debug( LDAP_DEBUG_ANY, "%s: line %d: lastmod"
1699 " not available for %s databases\n",
1700 fname, lineno, be->bd_info->bi_type );
1704 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1705 SLAP_DBFLAGS(be) &= ~SLAP_DBFLAG_NOLASTMOD;
1707 SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NOLASTMOD;
1711 /* turn on/off gentle SIGHUP handling */
1712 } else if ( strcasecmp( cargv[0], "gentlehup" ) == 0 ) {
1714 Debug( LDAP_DEBUG_ANY,
1715 "%s: line %d: missing on|off in \"gentlehup <on|off>\" line\n",
1719 if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1720 global_gentlehup = 0;
1722 global_gentlehup = 1;
1726 /* set idle timeout value */
1727 } else if ( strcasecmp( cargv[0], "idletimeout" ) == 0 ) {
1730 Debug( LDAP_DEBUG_ANY,
1731 "%s: line %d: missing timeout value in \"idletimeout <seconds>\" line\n",
1737 i = atoi( cargv[1] );
1740 Debug( LDAP_DEBUG_ANY,
1741 "%s: line %d: timeout value (%d) invalid \"idletimeout <seconds>\" line\n",
1747 global_idletimeout = i;
1749 /* include another config file */
1750 } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
1752 Debug( LDAP_DEBUG_ANY,
1753 "%s: line %d: missing filename in \"include <filename>\" line\n",
1758 savefname = ch_strdup( cargv[1] );
1759 savelineno = lineno;
1761 if ( read_config( savefname, depth+1 ) != 0 ) {
1766 lineno = savelineno - 1;
1768 /* location of kerberos srvtab file */
1769 } else if ( strcasecmp( cargv[0], "srvtab" ) == 0 ) {
1771 Debug( LDAP_DEBUG_ANY,
1772 "%s: line %d: missing filename in \"srvtab <filename>\" line\n",
1777 ldap_srvtab = ch_strdup( cargv[1] );
1779 #ifdef SLAPD_MODULES
1780 } else if (strcasecmp( cargv[0], "moduleload") == 0 ) {
1782 Debug( LDAP_DEBUG_ANY,
1783 "%s: line %d: missing filename in \"moduleload <filename>\" line\n",
1786 exit( EXIT_FAILURE );
1788 if (module_load(cargv[1], cargc - 2, (cargc > 2) ? cargv + 2 : NULL)) {
1789 Debug( LDAP_DEBUG_ANY,
1790 "%s: line %d: failed to load or initialize module %s\n",
1791 fname, lineno, cargv[1]);
1793 exit( EXIT_FAILURE );
1795 } else if (strcasecmp( cargv[0], "modulepath") == 0 ) {
1797 Debug( LDAP_DEBUG_ANY,
1798 "%s: line %d: missing path in \"modulepath <path>\" line\n",
1801 exit( EXIT_FAILURE );
1803 if (module_path( cargv[1] )) {
1804 Debug( LDAP_DEBUG_ANY,
1805 "%s: line %d: failed to set module search path to %s\n",
1806 fname, lineno, cargv[1]);
1808 exit( EXIT_FAILURE );
1811 #endif /*SLAPD_MODULES*/
1814 } else if ( !strcasecmp( cargv[0], "TLSRandFile" ) ) {
1815 rc = ldap_pvt_tls_set_option( NULL,
1816 LDAP_OPT_X_TLS_RANDOM_FILE,
1821 } else if ( !strcasecmp( cargv[0], "TLSCipherSuite" ) ) {
1822 rc = ldap_pvt_tls_set_option( NULL,
1823 LDAP_OPT_X_TLS_CIPHER_SUITE,
1828 } else if ( !strcasecmp( cargv[0], "TLSCertificateFile" ) ) {
1829 rc = ldap_pvt_tls_set_option( NULL,
1830 LDAP_OPT_X_TLS_CERTFILE,
1835 } else if ( !strcasecmp( cargv[0], "TLSCertificateKeyFile" ) ) {
1836 rc = ldap_pvt_tls_set_option( NULL,
1837 LDAP_OPT_X_TLS_KEYFILE,
1842 } else if ( !strcasecmp( cargv[0], "TLSCACertificatePath" ) ) {
1843 rc = ldap_pvt_tls_set_option( NULL,
1844 LDAP_OPT_X_TLS_CACERTDIR,
1849 } else if ( !strcasecmp( cargv[0], "TLSCACertificateFile" ) ) {
1850 rc = ldap_pvt_tls_set_option( NULL,
1851 LDAP_OPT_X_TLS_CACERTFILE,
1855 } else if ( !strcasecmp( cargv[0], "TLSVerifyClient" ) ) {
1856 if ( isdigit( (unsigned char) cargv[1][0] ) ) {
1858 rc = ldap_pvt_tls_set_option( NULL,
1859 LDAP_OPT_X_TLS_REQUIRE_CERT,
1862 rc = ldap_int_tls_config( NULL,
1863 LDAP_OPT_X_TLS_REQUIRE_CERT,
1872 } else if ( !strcasecmp( cargv[0], "reverse-lookup" ) ) {
1873 #ifdef SLAPD_RLOOKUPS
1875 Debug( LDAP_DEBUG_ANY,
1876 "%s: line %d: reverse-lookup: missing \"on\" or \"off\"\n",
1881 if ( !strcasecmp( cargv[1], "on" ) ) {
1882 use_reverse_lookup = 1;
1883 } else if ( !strcasecmp( cargv[1], "off" ) ) {
1884 use_reverse_lookup = 0;
1886 Debug( LDAP_DEBUG_ANY,
1887 "%s: line %d: reverse-lookup: must be \"on\" (default) or \"off\"\n",
1892 #else /* !SLAPD_RLOOKUPS */
1893 Debug( LDAP_DEBUG_ANY,
1894 "%s: line %d: reverse lookups are not configured (ignored).\n",
1896 #endif /* !SLAPD_RLOOKUPS */
1898 /* Netscape plugins */
1899 } else if ( strcasecmp( cargv[0], "plugin" ) == 0 ) {
1900 #if defined( LDAP_SLAPI )
1902 #ifdef notdef /* allow global plugins, too */
1904 * a "plugin" line must be inside a database
1905 * definition, since we implement pre-,post-
1906 * and extended operation plugins
1909 Debug( LDAP_DEBUG_ANY, "%s: line %d: plugin "
1910 "line must appear inside a database "
1911 "definition\n", fname, lineno, 0 );
1916 if ( slapi_int_read_config( be, fname, lineno, cargc, cargv )
1919 Debug( LDAP_DEBUG_ANY, "%s: line %d: SLAPI "
1920 "config read failed.\n", fname, lineno, 0 );
1923 slapi_plugins_used++;
1925 #else /* !defined( LDAP_SLAPI ) */
1926 Debug( LDAP_DEBUG_ANY, "%s: line %d: SLAPI "
1927 "not supported.\n", fname, lineno, 0 );
1930 #endif /* !defined( LDAP_SLAPI ) */
1932 /* Netscape plugins */
1933 } else if ( strcasecmp( cargv[0], "pluginlog" ) == 0 ) {
1934 #if defined( LDAP_SLAPI )
1936 Debug( LDAP_DEBUG_ANY,
1937 "%s: line %d: missing file name "
1938 "in pluginlog <filename> line.\n",
1943 if ( slapi_log_file != NULL ) {
1944 ch_free( slapi_log_file );
1947 slapi_log_file = ch_strdup( cargv[1] );
1948 #endif /* !defined( LDAP_SLAPI ) */
1950 /* pass anything else to the current backend info/db config routine */
1953 if ( bi->bi_config ) {
1954 rc = (*bi->bi_config)( bi, fname, lineno, cargc, cargv );
1960 case SLAP_CONF_UNKNOWN:
1961 Debug( LDAP_DEBUG_ANY,
1962 "%s: line %d: unknown directive \"%s\" inside backend info definition (ignored)\n",
1963 fname, lineno, cargv[0] );
1971 } else if ( be != NULL ) {
1972 if ( be->be_config ) {
1973 rc = (*be->be_config)( be, fname, lineno, cargc, cargv );
1979 case SLAP_CONF_UNKNOWN:
1980 Debug( LDAP_DEBUG_ANY,
1981 "%s: line %d: unknown directive \"%s\" inside backend database definition (ignored)\n",
1982 fname, lineno, cargv[0] );
1991 if ( frontendDB->be_config ) {
1992 rc = (*frontendDB->be_config)( frontendDB, fname, lineno, cargc, cargv );
1998 case SLAP_CONF_UNKNOWN:
1999 Debug( LDAP_DEBUG_ANY,
2000 "%s: line %d: unknown directive \"%s\" inside global database definition (ignored)\n",
2001 fname, lineno, cargv[0] );
2014 if ( depth == 0 ) ch_free( cargv );
2016 if ( BER_BVISNULL( &frontendDB->be_schemadn ) ) {
2017 ber_str2bv( SLAPD_SCHEMA_DN, sizeof(SLAPD_SCHEMA_DN)-1, 1,
2018 &frontendDB->be_schemadn );
2019 dnNormalize( 0, NULL, NULL, &frontendDB->be_schemadn, &frontendDB->be_schemandn, NULL );
2022 if ( load_ucdata( NULL ) < 0 ) return 1;
2034 char logbuf[sizeof("pseudorootpw ***")];
2037 token = strtok_quote( line, " \t" );
2041 if ( token && ( strcasecmp( token, "rootpw" ) == 0 ||
2042 strcasecmp( token, "replica" ) == 0 || /* contains "credentials" */
2043 strcasecmp( token, "bindpw" ) == 0 || /* used in back-ldap */
2044 strcasecmp( token, "pseudorootpw" ) == 0 || /* used in back-meta */
2045 strcasecmp( token, "dbpasswd" ) == 0 ) ) /* used in back-sql */
2047 snprintf( logline = logbuf, sizeof logbuf, "%s ***", token );
2050 if ( strtok_quote_ptr ) {
2051 *strtok_quote_ptr = ' ';
2054 Debug( LDAP_DEBUG_CONFIG, "line %d (%s)\n", lineno, logline, 0 );
2056 if ( strtok_quote_ptr ) {
2057 *strtok_quote_ptr = '\0';
2060 for ( ; token != NULL; token = strtok_quote( NULL, " \t" ) ) {
2061 if ( cargc == cargv_size - 1 ) {
2063 tmp = ch_realloc( cargv, (cargv_size + ARGS_STEP) *
2065 if ( tmp == NULL ) {
2066 Debug( LDAP_DEBUG_ANY,
2067 "line %d: out of memory\n",
2072 cargv_size += ARGS_STEP;
2074 cargv[cargc++] = token;
2076 cargv[cargc] = NULL;
2081 strtok_quote( char *line, char *sep )
2087 strtok_quote_ptr = NULL;
2088 if ( line != NULL ) {
2091 while ( *next && strchr( sep, *next ) ) {
2095 if ( *next == '\0' ) {
2101 for ( inquote = 0; *next; ) {
2109 AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
2115 next + 1, strlen( next + 1 ) + 1 );
2116 next++; /* dont parse the escaped character */
2121 if ( strchr( sep, *next ) != NULL ) {
2122 strtok_quote_ptr = next;
2135 static char buf[BUFSIZ];
2137 static size_t lmax, lcur;
2139 #define CATLINE( buf ) \
2141 size_t len = strlen( buf ); \
2142 while ( lcur + len + 1 > lmax ) { \
2144 line = (char *) ch_realloc( line, lmax ); \
2146 strcpy( line + lcur, buf ); \
2151 fp_getline( FILE *fp, int *lineno )
2159 /* hack attack - keeps us from having to keep a stack of bufs... */
2160 if ( strncasecmp( line, "include", 7 ) == 0 ) {
2165 while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
2166 /* trim off \r\n or \n */
2167 if ( (p = strchr( buf, '\n' )) != NULL ) {
2168 if( p > buf && p[-1] == '\r' ) --p;
2172 /* trim off trailing \ and append the next line */
2173 if ( line[ 0 ] != '\0'
2174 && (p = line + strlen( line ) - 1)[ 0 ] == '\\'
2175 && p[ -1 ] != '\\' ) {
2180 if ( ! isspace( (unsigned char) buf[0] ) ) {
2184 /* change leading whitespace to a space */
2193 return( line[0] ? line : NULL );
2197 fp_getline_init( int *lineno )
2203 /* Loads ucdata, returns 1 if loading, 0 if already loaded, -1 on error */
2205 load_ucdata( char *path )
2208 static int loaded = 0;
2214 err = ucdata_load( path ? path : SLAPD_DEFAULT_UCDATA, UCDATA_ALL );
2216 Debug( LDAP_DEBUG_ANY, "error loading ucdata (error %d)\n",
2224 /* ucdata is now hardcoded */
2232 ucdata_unload( UCDATA_ALL );
2234 /* NOTE: in case of early exit, frontendDB can be NULL */
2235 if ( frontendDB->be_schemandn.bv_val )
2236 free( frontendDB->be_schemandn.bv_val );
2237 if ( frontendDB->be_schemadn.bv_val )
2238 free( frontendDB->be_schemadn.bv_val );
2239 if ( frontendDB->be_acl )
2240 acl_destroy( frontendDB->be_acl, NULL );
2243 if ( slapd_args_file )
2244 free ( slapd_args_file );
2245 if ( slapd_pid_file )
2246 free ( slapd_pid_file );
2247 if ( default_passwd_hash )
2248 ldap_charray_free( default_passwd_hash );
2259 syncinfo_t *si_entry;
2261 int duplicated_replica_id = 0;
2263 si = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );
2266 Debug( LDAP_DEBUG_ANY, "out of memory in add_syncrepl\n", 0, 0, 0 );
2270 si->si_tls = SYNCINFO_TLS_OFF;
2271 if ( be->be_rootndn.bv_val ) {
2272 ber_dupbv( &si->si_updatedn, &be->be_rootndn );
2274 si->si_bindmethod = LDAP_AUTH_SIMPLE;
2275 si->si_schemachecking = 0;
2276 ber_str2bv( "(objectclass=*)", STRLENOF("(objectclass=*)"), 1,
2277 &si->si_filterstr );
2278 si->si_base.bv_val = NULL;
2279 si->si_scope = LDAP_SCOPE_SUBTREE;
2280 si->si_attrsonly = 0;
2281 si->si_attrs = (char **) ch_calloc( 1, sizeof( char * ));
2282 si->si_attrs[0] = NULL;
2283 si->si_exattrs = (char **) ch_calloc( 1, sizeof( char * ));
2284 si->si_exattrs[0] = NULL;
2285 si->si_type = LDAP_SYNC_REFRESH_ONLY;
2286 si->si_interval = 86400;
2287 si->si_retryinterval = NULL;
2288 si->si_retrynum_init = NULL;
2289 si->si_retrynum = NULL;
2290 si->si_syncCookie.ctxcsn = NULL;
2291 si->si_syncCookie.octet_str = NULL;
2292 si->si_syncCookie.sid = -1;
2293 si->si_manageDSAit = 0;
2296 si->si_syncUUID_ndn.bv_val = NULL;
2297 si->si_syncUUID_ndn.bv_len = 0;
2299 si->si_presentlist = NULL;
2300 LDAP_LIST_INIT( &si->si_nonpresentlist );
2302 rc = parse_syncrepl_line( cargv, cargc, si );
2304 LDAP_STAILQ_FOREACH( si_entry, &be->be_syncinfo, si_next ) {
2305 if ( si->si_rid == si_entry->si_rid ) {
2306 Debug( LDAP_DEBUG_ANY,
2307 "add_syncrepl: duplicated replica id\n",0, 0, 0 );
2308 duplicated_replica_id = 1;
2313 if ( rc < 0 || duplicated_replica_id ) {
2314 Debug( LDAP_DEBUG_ANY, "failed to add syncinfo\n", 0, 0, 0 );
2317 Debug( LDAP_DEBUG_CONFIG,
2318 "Config: ** successfully added syncrepl \"%s\"\n",
2319 si->si_provideruri == NULL ? "(null)" : si->si_provideruri, 0, 0 );
2320 if ( !si->si_schemachecking ) {
2321 SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK;
2324 LDAP_STAILQ_INSERT_TAIL( &be->be_syncinfo, si, si_next );
2330 #define PROVIDERSTR "provider"
2331 #define SUFFIXSTR "suffix"
2332 #define UPDATEDNSTR "updatedn"
2333 #define BINDMETHSTR "bindmethod"
2334 #define SIMPLESTR "simple"
2335 #define SASLSTR "sasl"
2336 #define BINDDNSTR "binddn"
2337 #define CREDSTR "credentials"
2338 #define OLDAUTHCSTR "bindprincipal"
2339 #define AUTHCSTR "authcID"
2340 #define AUTHZSTR "authzID"
2341 #define SRVTABSTR "srvtab"
2342 #define SASLMECHSTR "saslmech"
2343 #define REALMSTR "realm"
2344 #define SECPROPSSTR "secprops"
2345 #define STARTTLSSTR "starttls"
2346 #define CRITICALSTR "critical"
2348 #define SCHEMASTR "schemachecking"
2349 #define FILTERSTR "filter"
2350 #define SEARCHBASESTR "searchbase"
2351 #define SCOPESTR "scope"
2352 #define ATTRSSTR "attrs"
2353 #define ATTRSONLYSTR "attrsonly"
2354 #define EXATTRSSTR "exattrs"
2355 #define TYPESTR "type"
2356 #define INTERVALSTR "interval"
2357 #define LASTMODSTR "lastmod"
2358 #define LMREQSTR "req"
2359 #define LMGENSTR "gen"
2360 #define LMNOSTR "no"
2361 #define MANAGEDSAITSTR "manageDSAit"
2362 #define SLIMITSTR "sizelimit"
2363 #define TLIMITSTR "timelimit"
2365 #define RETRYSTR "retry"
2367 #define GOT_ID 0x0001
2368 #define GOT_PROVIDER 0x0002
2369 #define GOT_METHOD 0x0004
2370 #define GOT_ALL 0x0007
2373 parse_syncrepl_line(
2384 for ( i = 1; i < cargc; i++ ) {
2385 if ( !strncasecmp( cargv[ i ], IDSTR, sizeof( IDSTR ) - 1 )) {
2387 /* '\0' string terminator accounts for '=' */
2388 val = cargv[ i ] + sizeof( IDSTR );
2390 if ( tmp >= 1000 || tmp < 0 ) {
2391 fprintf( stderr, "Error: parse_syncrepl_line: "
2392 "syncrepl id %d is out of range [0..999]\n", tmp );
2397 } else if ( !strncasecmp( cargv[ i ], PROVIDERSTR,
2398 sizeof( PROVIDERSTR ) - 1 )) {
2399 val = cargv[ i ] + sizeof( PROVIDERSTR );
2400 si->si_provideruri = ch_strdup( val );
2401 si->si_provideruri_bv = (BerVarray)
2402 ch_calloc( 2, sizeof( struct berval ));
2403 ber_str2bv( si->si_provideruri, strlen( si->si_provideruri ),
2404 1, &si->si_provideruri_bv[0] );
2405 si->si_provideruri_bv[1].bv_len = 0;
2406 si->si_provideruri_bv[1].bv_val = NULL;
2407 gots |= GOT_PROVIDER;
2408 } else if ( !strncasecmp( cargv[ i ], STARTTLSSTR,
2409 sizeof(STARTTLSSTR) - 1 ) )
2411 val = cargv[ i ] + sizeof( STARTTLSSTR );
2412 if( !strcasecmp( val, CRITICALSTR ) ) {
2413 si->si_tls = SYNCINFO_TLS_CRITICAL;
2415 si->si_tls = SYNCINFO_TLS_ON;
2417 } else if ( !strncasecmp( cargv[ i ],
2418 UPDATEDNSTR, sizeof( UPDATEDNSTR ) - 1 ) )
2420 struct berval updatedn = {0, NULL};
2421 val = cargv[ i ] + sizeof( UPDATEDNSTR );
2422 ber_str2bv( val, 0, 0, &updatedn );
2423 ch_free( si->si_updatedn.bv_val );
2424 dnNormalize( 0, NULL, NULL, &updatedn, &si->si_updatedn, NULL );
2425 } else if ( !strncasecmp( cargv[ i ], BINDMETHSTR,
2426 sizeof( BINDMETHSTR ) - 1 ) )
2428 val = cargv[ i ] + sizeof( BINDMETHSTR );
2429 if ( !strcasecmp( val, SIMPLESTR )) {
2430 si->si_bindmethod = LDAP_AUTH_SIMPLE;
2432 } else if ( !strcasecmp( val, SASLSTR )) {
2433 #ifdef HAVE_CYRUS_SASL
2434 si->si_bindmethod = LDAP_AUTH_SASL;
2436 #else /* HAVE_CYRUS_SASL */
2437 fprintf( stderr, "Error: parse_syncrepl_line: "
2438 "not compiled with SASL support\n" );
2440 #endif /* HAVE_CYRUS_SASL */
2442 si->si_bindmethod = -1;
2444 } else if ( !strncasecmp( cargv[ i ],
2445 BINDDNSTR, sizeof( BINDDNSTR ) - 1 ) ) {
2446 val = cargv[ i ] + sizeof( BINDDNSTR );
2447 si->si_binddn = ch_strdup( val );
2448 } else if ( !strncasecmp( cargv[ i ],
2449 CREDSTR, sizeof( CREDSTR ) - 1 ) ) {
2450 val = cargv[ i ] + sizeof( CREDSTR );
2451 si->si_passwd = ch_strdup( val );
2452 } else if ( !strncasecmp( cargv[ i ],
2453 SASLMECHSTR, sizeof( SASLMECHSTR ) - 1 ) ) {
2454 val = cargv[ i ] + sizeof( SASLMECHSTR );
2455 si->si_saslmech = ch_strdup( val );
2456 } else if ( !strncasecmp( cargv[ i ],
2457 SECPROPSSTR, sizeof( SECPROPSSTR ) - 1 ) ) {
2458 val = cargv[ i ] + sizeof( SECPROPSSTR );
2459 si->si_secprops = ch_strdup( val );
2460 } else if ( !strncasecmp( cargv[ i ],
2461 REALMSTR, sizeof( REALMSTR ) - 1 ) ) {
2462 val = cargv[ i ] + sizeof( REALMSTR );
2463 si->si_realm = ch_strdup( val );
2464 } else if ( !strncasecmp( cargv[ i ],
2465 AUTHCSTR, sizeof( AUTHCSTR ) - 1 ) ) {
2466 val = cargv[ i ] + sizeof( AUTHCSTR );
2467 if ( si->si_authcId )
2468 ch_free( si->si_authcId );
2469 si->si_authcId = ch_strdup( val );
2470 } else if ( !strncasecmp( cargv[ i ],
2471 OLDAUTHCSTR, sizeof( OLDAUTHCSTR ) - 1 ) ) {
2472 /* Old authcID is provided for some backwards compatibility */
2473 val = cargv[ i ] + sizeof( OLDAUTHCSTR );
2474 if ( si->si_authcId )
2475 ch_free( si->si_authcId );
2476 si->si_authcId = ch_strdup( val );
2477 } else if ( !strncasecmp( cargv[ i ],
2478 AUTHZSTR, sizeof( AUTHZSTR ) - 1 ) ) {
2479 val = cargv[ i ] + sizeof( AUTHZSTR );
2480 si->si_authzId = ch_strdup( val );
2481 } else if ( !strncasecmp( cargv[ i ],
2482 SCHEMASTR, sizeof( SCHEMASTR ) - 1 ) )
2484 val = cargv[ i ] + sizeof( SCHEMASTR );
2485 if ( !strncasecmp( val, "on", STRLENOF( "on" ) )) {
2486 si->si_schemachecking = 1;
2487 } else if ( !strncasecmp( val, "off", STRLENOF( "off" ) ) ) {
2488 si->si_schemachecking = 0;
2490 si->si_schemachecking = 1;
2492 } else if ( !strncasecmp( cargv[ i ],
2493 FILTERSTR, sizeof( FILTERSTR ) - 1 ) )
2495 val = cargv[ i ] + sizeof( FILTERSTR );
2496 ber_str2bv( val, 0, 1, &si->si_filterstr );
2497 } else if ( !strncasecmp( cargv[ i ],
2498 SEARCHBASESTR, sizeof( SEARCHBASESTR ) - 1 ) )
2501 val = cargv[ i ] + sizeof( SEARCHBASESTR );
2502 if ( si->si_base.bv_val ) {
2503 ch_free( si->si_base.bv_val );
2505 ber_str2bv( val, 0, 0, &bv );
2506 if ( dnNormalize( 0, NULL, NULL, &bv, &si->si_base, NULL )) {
2507 fprintf( stderr, "Invalid base DN \"%s\"\n", val );
2510 } else if ( !strncasecmp( cargv[ i ],
2511 SCOPESTR, sizeof( SCOPESTR ) - 1 ) )
2513 val = cargv[ i ] + sizeof( SCOPESTR );
2514 if ( !strncasecmp( val, "base", STRLENOF( "base" ) )) {
2515 si->si_scope = LDAP_SCOPE_BASE;
2516 } else if ( !strncasecmp( val, "one", STRLENOF( "one" ) )) {
2517 si->si_scope = LDAP_SCOPE_ONELEVEL;
2518 #ifdef LDAP_SCOPE_SUBORDINATE
2519 } else if ( !strcasecmp( val, "subordinate" ) ||
2520 !strcasecmp( val, "children" ))
2522 si->si_scope = LDAP_SCOPE_SUBORDINATE;
2524 } else if ( !strncasecmp( val, "sub", STRLENOF( "sub" ) )) {
2525 si->si_scope = LDAP_SCOPE_SUBTREE;
2527 fprintf( stderr, "Error: parse_syncrepl_line: "
2528 "unknown scope \"%s\"\n", val);
2531 } else if ( !strncasecmp( cargv[ i ],
2532 ATTRSONLYSTR, sizeof( ATTRSONLYSTR ) - 1 ) )
2534 si->si_attrsonly = 1;
2535 } else if ( !strncasecmp( cargv[ i ],
2536 ATTRSSTR, sizeof( ATTRSSTR ) - 1 ) )
2538 val = cargv[ i ] + sizeof( ATTRSSTR );
2539 if ( !strncasecmp( val, ":include:", STRLENOF(":include:") )) {
2541 attr_fname = ch_strdup( val + STRLENOF(":include:") );
2542 if ( get_attrs_from_file( &si->si_attrs, attr_fname, " ,\t" )) {
2543 ch_free( attr_fname );
2546 ch_free( attr_fname );
2548 str2clist( &si->si_attrs, val, " ,\t" );
2550 } else if ( !strncasecmp( cargv[ i ],
2551 EXATTRSSTR, sizeof( EXATTRSSTR ) - 1 ) )
2553 val = cargv[ i ] + sizeof( EXATTRSSTR );
2554 if ( !strncasecmp( val, ":include:", STRLENOF(":include:") )) {
2556 attr_fname = ch_strdup( val + STRLENOF(":include:") );
2557 if ( get_attrs_from_file( &si->si_exattrs,
2558 attr_fname, " ,\t" )) {
2559 ch_free( attr_fname );
2562 ch_free( attr_fname );
2564 str2clist( &si->si_exattrs, val, " ,\t" );
2566 } else if ( !strncasecmp( cargv[ i ],
2567 TYPESTR, sizeof( TYPESTR ) - 1 ) )
2569 val = cargv[ i ] + sizeof( TYPESTR );
2570 if ( !strncasecmp( val, "refreshOnly", STRLENOF("refreshOnly") )) {
2571 si->si_type = LDAP_SYNC_REFRESH_ONLY;
2572 } else if ( !strncasecmp( val, "refreshAndPersist",
2573 STRLENOF("refreshAndPersist") ))
2575 si->si_type = LDAP_SYNC_REFRESH_AND_PERSIST;
2576 si->si_interval = 60;
2578 fprintf( stderr, "Error: parse_syncrepl_line: "
2579 "unknown sync type \"%s\"\n", val);
2582 } else if ( !strncasecmp( cargv[ i ],
2583 INTERVALSTR, sizeof( INTERVALSTR ) - 1 ) )
2585 val = cargv[ i ] + sizeof( INTERVALSTR );
2586 if ( si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ) {
2587 si->si_interval = 0;
2595 hstr = strchr( dstr, ':' );
2596 if ( hstr == NULL ) {
2597 fprintf( stderr, "Error: parse_syncrepl_line: "
2598 "invalid interval \"%s\"\n", val );
2602 mstr = strchr( hstr, ':' );
2603 if ( mstr == NULL ) {
2604 fprintf( stderr, "Error: parse_syncrepl_line: "
2605 "invalid interval \"%s\"\n", val );
2609 sstr = strchr( mstr, ':' );
2610 if ( sstr == NULL ) {
2611 fprintf( stderr, "Error: parse_syncrepl_line: "
2612 "invalid interval \"%s\"\n", val );
2621 if (( hh > 24 ) || ( hh < 0 ) ||
2622 ( mm > 60 ) || ( mm < 0 ) ||
2623 ( ss > 60 ) || ( ss < 0 ) || ( dd < 0 )) {
2624 fprintf( stderr, "Error: parse_syncrepl_line: "
2625 "invalid interval \"%s\"\n", val );
2628 si->si_interval = (( dd * 24 + hh ) * 60 + mm ) * 60 + ss;
2630 if ( si->si_interval < 0 ) {
2631 fprintf( stderr, "Error: parse_syncrepl_line: "
2632 "invalid interval \"%ld\"\n",
2633 (long) si->si_interval);
2636 } else if ( !strncasecmp( cargv[ i ],
2637 RETRYSTR, sizeof( RETRYSTR ) - 1 ) )
2643 val = cargv[ i ] + sizeof( RETRYSTR );
2644 retry_list = (char **) ch_calloc( 1, sizeof( char * ));
2645 retry_list[0] = NULL;
2647 str2clist( &retry_list, val, " ,\t" );
2649 for ( k = 0; retry_list && retry_list[k]; k++ ) ;
2653 "Error: incomplete syncrepl retry list\n" );
2654 for ( k = 0; retry_list && retry_list[k]; k++ ) {
2655 ch_free( retry_list[k] );
2657 ch_free( retry_list );
2658 exit( EXIT_FAILURE );
2660 si->si_retryinterval = (time_t *) ch_calloc( n + 1, sizeof( time_t ));
2661 si->si_retrynum = (int *) ch_calloc( n + 1, sizeof( int ));
2662 si->si_retrynum_init = (int *) ch_calloc( n + 1, sizeof( int ));
2663 for ( j = 0; j < n; j++ ) {
2664 si->si_retryinterval[j] = atoi( retry_list[j*2] );
2665 if ( *retry_list[j*2+1] == '+' ) {
2666 si->si_retrynum_init[j] = -1;
2667 si->si_retrynum[j] = -1;
2671 si->si_retrynum_init[j] = atoi( retry_list[j*2+1] );
2672 si->si_retrynum[j] = atoi( retry_list[j*2+1] );
2675 si->si_retrynum_init[j] = -2;
2676 si->si_retrynum[j] = -2;
2677 si->si_retryinterval[j] = 0;
2679 for ( k = 0; retry_list && retry_list[k]; k++ ) {
2680 ch_free( retry_list[k] );
2682 ch_free( retry_list );
2683 } else if ( !strncasecmp( cargv[ i ],
2684 MANAGEDSAITSTR, sizeof( MANAGEDSAITSTR ) - 1 ) )
2686 val = cargv[ i ] + sizeof( MANAGEDSAITSTR );
2687 si->si_manageDSAit = atoi( val );
2688 } else if ( !strncasecmp( cargv[ i ],
2689 SLIMITSTR, sizeof( SLIMITSTR ) - 1 ) )
2691 val = cargv[ i ] + sizeof( SLIMITSTR );
2692 si->si_slimit = atoi( val );
2693 } else if ( !strncasecmp( cargv[ i ],
2694 TLIMITSTR, sizeof( TLIMITSTR ) - 1 ) )
2696 val = cargv[ i ] + sizeof( TLIMITSTR );
2697 si->si_tlimit = atoi( val );
2699 fprintf( stderr, "Error: parse_syncrepl_line: "
2700 "unknown keyword \"%s\"\n", cargv[ i ] );
2704 if ( gots != GOT_ALL ) {
2706 "Error: Malformed \"syncrepl\" line in slapd config file" );
2714 str2clist( char ***out, char *in, const char *brkstr )
2723 /* find last element in list */
2724 for (i = 0; *out && (*out)[i]; i++);
2726 /* protect the input string from strtok */
2727 str = ch_strdup( in );
2729 if ( *str == '\0' ) {
2734 /* Count words in string */
2736 for ( s = str; *s; s++ ) {
2737 if ( strchr( brkstr, *s ) != NULL ) {
2742 *out = ch_realloc( *out, ( i + j + 1 ) * sizeof( char * ) );
2744 for ( s = ldap_pvt_strtok( str, brkstr, &lasts );
2746 s = ldap_pvt_strtok( NULL, brkstr, &lasts ) )
2748 *new = ch_strdup( s );
2759 get_attrs_from_file( char ***attrs, const char *fname, const char *brkstr )
2765 size_t lmax = LBUFSIZ;
2767 fp = fopen( fname, "r" );
2769 Debug( LDAP_DEBUG_ANY,
2770 "get_attrs_from_file: failed to open attribute list file "
2771 "\"%s\": %s\n", fname, strerror(errno), 0 );
2775 lcur = line = (char *) ch_malloc( lmax );
2777 Debug( LDAP_DEBUG_ANY,
2778 "get_attrs_from_file: could not allocate memory\n",
2784 while ( fgets( lcur, LBUFSIZ, fp ) != NULL ) {
2785 if (c = strchr( lcur, '\n' )) {
2788 } else if ( *(c-1) == '\r' ) {
2795 line = (char *) ch_realloc( line, lmax );
2797 Debug( LDAP_DEBUG_ANY,
2798 "get_attrs_from_file: could not allocate memory\n",
2803 lcur = line + strlen( line );
2806 str2clist( attrs, line, brkstr );