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 *));
92 read_config( const char *fname, int depth )
95 char *line, *savefname, *saveline;
99 struct berval vals[2];
102 static BackendInfo *bi = NULL;
103 static BackendDB *be = NULL;
107 vals[1].bv_val = NULL;
110 cargv = ch_calloc( ARGS_STEP + 1, sizeof(*cargv) );
111 cargv_size = ARGS_STEP + 1;
114 if ( (fp = fopen( fname, "r" )) == NULL ) {
116 Debug( LDAP_DEBUG_ANY,
117 "could not open config file \"%s\": %s (%d)\n",
118 fname, strerror(errno), errno );
122 Debug( LDAP_DEBUG_CONFIG, "reading config file %s\n", fname, 0, 0 );
125 fp_getline_init( &lineno );
127 while ( (line = fp_getline( fp, &lineno )) != NULL ) {
128 /* skip comments and blank lines */
129 if ( line[0] == '#' || line[0] == '\0' ) {
133 /* fp_parse_line is destructive, we save a copy */
134 saveline = ch_strdup( line );
136 if ( fp_parse_line( lineno, line ) != 0 ) {
141 Debug( LDAP_DEBUG_ANY,
142 "%s: line %d: bad config line (ignored)\n",
148 if ( strcasecmp( cargv[0], "backend" ) == 0 ) {
150 Debug( LDAP_DEBUG_ANY,
151 "%s: line %d: missing type in \"backend <type>\" line\n",
158 Debug( LDAP_DEBUG_ANY,
159 "%s: line %d: backend line must appear before any database definition\n",
165 bi = backend_info( cargv[1] );
168 Debug( LDAP_DEBUG_ANY,
169 "backend %s initialization failed.\n",
174 } else if ( strcasecmp( cargv[0], "database" ) == 0 ) {
176 Debug( LDAP_DEBUG_ANY,
177 "%s: line %d: missing type in \"database <type>\" line\n",
184 be = backend_db_init( cargv[1] );
187 Debug( LDAP_DEBUG_ANY,
188 "database %s initialization failed.\n",
194 /* set local security factor */
195 } else if ( strcasecmp( cargv[0], "localSSF" ) == 0 ) {
198 Debug( LDAP_DEBUG_ANY,
199 "%s: line %d: missing ssf in \"localSSF <ssf>\" line\n",
204 ssf = atol( cargv[1] );
207 Debug( LDAP_DEBUG_ANY,
208 "%s: line %d: invalid ssf value (%ld) in "
209 "\"localSSF <ssf>\" line.\n",
210 fname, lineno, ssf );
216 /* set thread concurrency */
217 } else if ( strcasecmp( cargv[0], "concurrency" ) == 0 ) {
220 Debug( LDAP_DEBUG_ANY,
221 "%s: line %d: missing level in \"concurrency <level>\" line\n",
227 c = strtol( cargv[1], &next, 10 );
228 if ( next == NULL || next[0] != '\0' ) {
229 Debug( LDAP_DEBUG_ANY,
230 "%s: line %d: unable to parse level \"%s\" in \"concurrency <level>\" line\n",
231 fname, lineno, cargv[1] );
236 Debug( LDAP_DEBUG_ANY,
237 "%s: line %d: invalid level (%d) in \"concurrency <level>\" line\n",
243 ldap_pvt_thread_set_concurrency( c );
245 /* set sockbuf max */
246 } else if ( strcasecmp( cargv[0], "sockbuf_max_incoming" ) == 0 ) {
249 Debug( LDAP_DEBUG_ANY,
250 "%s: line %d: missing max in \"sockbuf_max_incoming <bytes>\" line\n",
256 max = atol( cargv[1] );
259 Debug( LDAP_DEBUG_ANY,
260 "%s: line %d: invalid max value (%ld) in "
261 "\"sockbuf_max_incoming <bytes>\" line.\n",
262 fname, lineno, max );
267 sockbuf_max_incoming = max;
269 /* set sockbuf max authenticated */
270 } else if ( strcasecmp( cargv[0], "sockbuf_max_incoming_auth" ) == 0 ) {
273 Debug( LDAP_DEBUG_ANY,
274 "%s: line %d: missing max in \"sockbuf_max_incoming_auth <bytes>\" line\n",
280 max = atol( cargv[1] );
283 Debug( LDAP_DEBUG_ANY,
284 "%s: line %d: invalid max value (%ld) in "
285 "\"sockbuf_max_incoming_auth <bytes>\" line.\n",
286 fname, lineno, max );
291 sockbuf_max_incoming_auth = max;
293 /* set conn pending max */
294 } else if ( strcasecmp( cargv[0], "conn_max_pending" ) == 0 ) {
297 Debug( LDAP_DEBUG_ANY,
298 "%s: line %d: missing max in \"conn_max_pending <requests>\" line\n",
304 max = atol( cargv[1] );
307 Debug( LDAP_DEBUG_ANY,
308 "%s: line %d: invalid max value (%ld) in "
309 "\"conn_max_pending <requests>\" line.\n",
310 fname, lineno, max );
315 slap_conn_max_pending = max;
317 /* set conn pending max authenticated */
318 } else if ( strcasecmp( cargv[0], "conn_max_pending_auth" ) == 0 ) {
321 Debug( LDAP_DEBUG_ANY,
322 "%s: line %d: missing max in \"conn_max_pending_auth <requests>\" line\n",
328 max = atol( cargv[1] );
331 Debug( LDAP_DEBUG_ANY,
332 "%s: line %d: invalid max value (%ld) in "
333 "\"conn_max_pending_auth <requests>\" line.\n",
334 fname, lineno, max );
339 slap_conn_max_pending_auth = max;
341 /* default search base */
342 } else if ( strcasecmp( cargv[0], "defaultSearchBase" ) == 0 ) {
344 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
345 "missing dn in \"defaultSearchBase <dn>\" line\n",
350 } else if ( cargc > 2 ) {
351 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
352 "extra cruft after <dn> in \"defaultSearchBase %s\", "
354 fname, lineno, cargv[1] );
357 if ( bi != NULL || be != NULL ) {
358 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
359 "defaultSearchBaase line must appear prior to "
360 "any backend or database definition\n",
366 if ( default_search_nbase.bv_len ) {
367 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
368 "default search base \"%s\" already defined "
369 "(discarding old)\n",
370 fname, lineno, default_search_base.bv_val );
372 free( default_search_base.bv_val );
373 free( default_search_nbase.bv_val );
376 if ( load_ucdata( NULL ) < 0 ) return 1;
381 dn.bv_val = cargv[1];
382 dn.bv_len = strlen( dn.bv_val );
384 rc = dnPrettyNormal( NULL, &dn,
385 &default_search_base,
386 &default_search_nbase, NULL );
388 if( rc != LDAP_SUCCESS ) {
389 Debug( LDAP_DEBUG_ANY,
390 "%s: line %d: defaultSearchBase DN is invalid\n",
396 /* set maximum threads in thread pool */
397 } else if ( strcasecmp( cargv[0], "threads" ) == 0 ) {
400 Debug( LDAP_DEBUG_ANY,
401 "%s: line %d: missing count in \"threads <count>\" line\n",
407 c = strtol( cargv[1], &next, 10 );
408 if (next == NULL || next[0] != '\0' ) {
409 Debug( LDAP_DEBUG_ANY,
410 "%s: line %d: unable to parse count \"%s\" in \"threads <count>\" line\n",
411 fname, lineno, cargv[1] );
416 Debug( LDAP_DEBUG_ANY,
417 "%s: line %d: invalid level (%d) in \"threads <count>\" line\n",
423 ldap_pvt_thread_pool_maxthreads( &connection_pool, c );
425 /* save for later use */
426 connection_pool_max = c;
428 /* get pid file name */
429 } else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) {
431 Debug( LDAP_DEBUG_ANY,
432 "%s: line %d: missing file name in \"pidfile <file>\" line\n",
438 slapd_pid_file = ch_strdup( cargv[1] );
440 /* get args file name */
441 } else if ( strcasecmp( cargv[0], "argsfile" ) == 0 ) {
443 Debug( LDAP_DEBUG_ANY,
444 "%s: line %d: missing file name in \"argsfile <file>\" line\n",
450 slapd_args_file = ch_strdup( cargv[1] );
452 } else if ( strcasecmp( cargv[0], "replica-pidfile" ) == 0 ) {
455 } else if ( strcasecmp( cargv[0], "replica-argsfile" ) == 0 ) {
458 /* default password hash */
459 } else if ( strcasecmp( cargv[0], "password-hash" ) == 0 ) {
461 Debug( LDAP_DEBUG_ANY,
462 "%s: line %d: missing hash in \"password-hash <hash>\" line\n",
467 if ( default_passwd_hash != NULL ) {
468 Debug( LDAP_DEBUG_ANY,
469 "%s: line %d: already set default password_hash!\n",
475 for(i = 1; i < cargc; i++) {
476 if ( lutil_passwd_scheme( cargv[i] ) == 0 ) {
477 Debug( LDAP_DEBUG_ANY,
478 "%s: line %d: password scheme \"%s\" not available\n",
479 fname, lineno, cargv[i] );
481 ldap_charray_add( &default_passwd_hash, cargv[i] );
484 if( !default_passwd_hash ) {
485 Debug( LDAP_DEBUG_ANY,
486 "%s: line %d: no valid hashes found\n",
491 } else if ( strcasecmp( cargv[0], "password-crypt-salt-format" ) == 0 )
494 Debug( LDAP_DEBUG_ANY, "%s: line %d: missing format in "
495 "\"password-crypt-salt-format <format>\" line\n",
501 lutil_salt_format( cargv[1] );
503 #ifdef SLAP_AUTH_REWRITE
504 /* use authid rewrite instead of sasl regexp */
505 } else if ( strncasecmp( cargv[0], "auth-rewrite",
506 STRLENOF("auth-rewrite") ) == 0 )
508 int rc = slap_sasl_rewrite_config( fname, lineno,
513 #endif /* SLAP_AUTH_REWRITE */
515 /* Auth + SASL config options */
516 } else if ( !strncasecmp( cargv[0], "auth", STRLENOF("auth") ) ||
517 !strncasecmp( cargv[0], "sasl", STRLENOF("sasl") ))
519 if ( slap_sasl_config( cargc, cargv, line, fname, lineno ) )
523 } else if ( strcasecmp( cargv[0], "schemadn" ) == 0 ) {
526 Debug( LDAP_DEBUG_ANY,
527 "%s: line %d: missing dn in \"schemadn <dn>\" line\n",
531 ber_str2bv( cargv[1], 0, 0, &dn );
533 rc = dnPrettyNormal( NULL, &dn, &be->be_schemadn,
534 &be->be_schemandn, NULL );
536 rc = dnPrettyNormal( NULL, &dn, &frontendDB->be_schemadn,
537 &frontendDB->be_schemandn, NULL );
539 if ( rc != LDAP_SUCCESS ) {
540 Debug( LDAP_DEBUG_ANY,
541 "%s: line %d: schemadn DN is invalid\n",
546 /* set UCDATA path */
547 } else if ( strcasecmp( cargv[0], "ucdata-path" ) == 0 ) {
550 Debug( LDAP_DEBUG_ANY,
551 "%s: line %d: missing path in \"ucdata-path <path>\" line\n",
557 err = load_ucdata( cargv[1] );
560 Debug( LDAP_DEBUG_ANY,
561 "%s: line %d: ucdata already loaded, ucdata-path must be set earlier in the file and/or be specified only once!\n",
569 } else if ( strcasecmp( cargv[0], "sizelimit" ) == 0 ) {
571 struct slap_limits_set *lim;
574 Debug( LDAP_DEBUG_ANY,
575 "%s: line %d: missing limit in \"sizelimit <limit>\" line\n",
582 lim = &frontendDB->be_def_limit;
584 lim = &be->be_def_limit;
587 for ( i = 1; i < cargc; i++ ) {
588 if ( strncasecmp( cargv[i], "size", 4 ) == 0 ) {
589 rc = limits_parse_one( cargv[i], lim );
591 Debug( LDAP_DEBUG_ANY,
592 "%s: line %d: unable "
593 "to parse value \"%s\" "
596 fname, lineno, cargv[i] );
601 if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) {
602 lim->lms_s_soft = -1;
604 lim->lms_s_soft = strtol( cargv[i] , &next, 0 );
605 if ( next == cargv[i] ) {
606 Debug( LDAP_DEBUG_ANY,
607 "%s: line %d: unable to parse limit \"%s\" in \"sizelimit <limit>\" line\n",
608 fname, lineno, cargv[i] );
611 } else if ( next[0] != '\0' ) {
612 Debug( LDAP_DEBUG_ANY,
613 "%s: line %d: trailing chars \"%s\" in \"sizelimit <limit>\" line ignored\n",
614 fname, lineno, next );
622 } else if ( strcasecmp( cargv[0], "timelimit" ) == 0 ) {
624 struct slap_limits_set *lim;
627 Debug( LDAP_DEBUG_ANY,
628 "%s: line %d: missing limit in \"timelimit <limit>\" line\n",
635 lim = &frontendDB->be_def_limit;
637 lim = &be->be_def_limit;
640 for ( i = 1; i < cargc; i++ ) {
641 if ( strncasecmp( cargv[i], "time", 4 ) == 0 ) {
642 rc = limits_parse_one( cargv[i], lim );
644 Debug( LDAP_DEBUG_ANY,
645 "%s: line %d: unable "
646 "to parse value \"%s\" "
649 fname, lineno, cargv[i] );
654 if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) {
655 lim->lms_t_soft = -1;
657 lim->lms_t_soft = strtol( cargv[i] , &next, 0 );
658 if ( next == cargv[i] ) {
659 Debug( LDAP_DEBUG_ANY,
660 "%s: line %d: unable to parse limit \"%s\" in \"timelimit <limit>\" line\n",
661 fname, lineno, cargv[i] );
664 } else if ( next[0] != '\0' ) {
665 Debug( LDAP_DEBUG_ANY,
666 "%s: line %d: trailing chars \"%s\" in \"timelimit <limit>\" line ignored\n",
667 fname, lineno, next );
674 /* set regex-based limits */
675 } else if ( strcasecmp( cargv[0], "limits" ) == 0 ) {
677 Debug( LDAP_DEBUG_ANY,
678 "%s: line %d \"limits\" allowed only in database environment.\n%s",
683 if ( limits_parse( be, fname, lineno, cargc, cargv ) ) {
687 /* mark this as a subordinate database */
688 } else if ( strcasecmp( cargv[0], "subordinate" ) == 0 ) {
690 Debug( LDAP_DEBUG_ANY, "%s: line %d: subordinate keyword "
691 "must appear inside a database definition.\n",
696 SLAP_DBFLAGS(be) |= SLAP_DBFLAG_GLUE_SUBORDINATE;
700 /* add an overlay to this backend */
701 } else if ( strcasecmp( cargv[0], "overlay" ) == 0 ) {
703 if ( cargv[1][0] == '-' && overlay_config( frontendDB, &cargv[1][1] ) ) {
705 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
706 "(optional) global overlay \"%s\" configuration "
707 "failed (ignored)\n", fname, lineno, &cargv[1][1] );
708 } else if ( overlay_config( frontendDB, cargv[1] ) ) {
713 if ( cargv[1][0] == '-' && overlay_config( be, &cargv[1][1] ) ) {
715 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
716 "(optional) overlay \"%s\" configuration "
717 "failed (ignored)\n", fname, lineno, &cargv[1][1] );
718 } else if ( overlay_config( be, cargv[1] ) ) {
723 /* set database suffix */
724 } else if ( strcasecmp( cargv[0], "suffix" ) == 0 ) {
726 struct berval dn, pdn, ndn;
729 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
730 "missing dn in \"suffix <dn>\" line\n",
735 } else if ( cargc > 2 ) {
736 Debug( LDAP_DEBUG_ANY, "%s: line %d: extra cruft "
737 "after <dn> in \"suffix %s\" line (ignored)\n",
738 fname, lineno, cargv[1] );
742 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix line "
743 "must appear inside a database definition\n",
747 #if defined(SLAPD_MONITOR_DN)
748 /* "cn=Monitor" is reserved for monitoring slap */
749 } else if ( strcasecmp( cargv[1], SLAPD_MONITOR_DN ) == 0 ) {
750 Debug( LDAP_DEBUG_ANY, "%s: line %d: \""
751 "%s\" is reserved for monitoring slapd\n",
752 fname, lineno, SLAPD_MONITOR_DN );
754 #endif /* SLAPD_MONITOR_DN */
757 if ( load_ucdata( NULL ) < 0 ) return 1;
759 dn.bv_val = cargv[1];
760 dn.bv_len = strlen( cargv[1] );
762 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL );
763 if( rc != LDAP_SUCCESS ) {
764 Debug( LDAP_DEBUG_ANY,
765 "%s: line %d: suffix DN is invalid\n",
770 tmp_be = select_backend( &ndn, 0, 0 );
771 if ( tmp_be == be ) {
772 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
773 "already served by this backend (ignored)\n",
778 } else if ( tmp_be != NULL ) {
779 Debug( LDAP_DEBUG_ANY, "%s: line %d: suffix "
780 "already served by a preceeding backend \"%s\"\n",
781 fname, lineno, tmp_be->be_suffix[0].bv_val );
786 } else if( pdn.bv_len == 0 && default_search_nbase.bv_len ) {
787 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
788 "suffix DN empty and default "
789 "search base provided \"%s\" (assuming okay)\n",
790 fname, lineno, default_search_base.bv_val );
793 ber_bvarray_add( &be->be_suffix, &pdn );
794 ber_bvarray_add( &be->be_nsuffix, &ndn );
796 /* set max deref depth */
797 } else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
800 Debug( LDAP_DEBUG_ANY,
801 "%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
807 Debug( LDAP_DEBUG_ANY,
808 "%s: line %d: depth line must appear inside a database definition.\n",
813 i = strtol( cargv[1], &next, 10 );
814 if ( next == NULL || next[0] != '\0' ) {
815 Debug( LDAP_DEBUG_ANY,
816 "%s: line %d: unable to parse depth \"%s\" in \"maxDerefDepth <depth>\" "
817 "line.\n", fname, lineno, cargv[1] );
822 Debug( LDAP_DEBUG_ANY,
823 "%s: line %d: depth must be positive.\n",
829 be->be_max_deref_depth = i;
831 /* set magic "root" dn for this database */
832 } else if ( strcasecmp( cargv[0], "rootdn" ) == 0 ) {
834 Debug( LDAP_DEBUG_ANY,
835 "%s: line %d: missing dn in \"rootdn <dn>\" line\n",
842 Debug( LDAP_DEBUG_ANY,
843 "%s: line %d: rootdn line must appear inside a database definition.\n",
850 if ( load_ucdata( NULL ) < 0 ) return 1;
852 dn.bv_val = cargv[1];
853 dn.bv_len = strlen( cargv[1] );
855 rc = dnPrettyNormal( NULL, &dn,
857 &be->be_rootndn, NULL );
859 if( rc != LDAP_SUCCESS ) {
860 Debug( LDAP_DEBUG_ANY,
861 "%s: line %d: rootdn DN is invalid\n",
867 /* set super-secret magic database password */
868 } else if ( strcasecmp( cargv[0], "rootpw" ) == 0 ) {
870 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
871 "missing passwd in \"rootpw <passwd>\" line\n",
878 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
879 "rootpw line must appear inside a database "
885 Backend *tmp_be = select_backend( &be->be_rootndn, 0, 0 );
888 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
889 "rootpw can only be set when rootdn is under suffix\n",
894 be->be_rootpw.bv_val = ch_strdup( cargv[1] );
895 be->be_rootpw.bv_len = strlen( be->be_rootpw.bv_val );
898 /* make this database read-only */
899 } else if ( strcasecmp( cargv[0], "readonly" ) == 0 ) {
901 Debug( LDAP_DEBUG_ANY,
902 "%s: line %d: missing on|off in \"readonly <on|off>\" line\n",
908 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
909 frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
911 frontendDB->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
915 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
916 be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
918 be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
922 /* restricts specific operations */
923 } else if ( strcasecmp( cargv[0], "restrict" ) == 0 ) {
924 slap_mask_t restrictops = 0;
925 struct restrictable_exops_t {
928 } restrictable_exops[] = {
929 { LDAP_EXOP_START_TLS, SLAP_RESTRICT_EXOP_START_TLS },
930 { LDAP_EXOP_MODIFY_PASSWD, SLAP_RESTRICT_EXOP_MODIFY_PASSWD },
931 { LDAP_EXOP_X_WHO_AM_I, SLAP_RESTRICT_EXOP_WHOAMI },
932 { LDAP_EXOP_X_CANCEL, SLAP_RESTRICT_EXOP_CANCEL },
938 Debug( LDAP_DEBUG_ANY,
939 "%s: line %d: missing <op_list> in \"restrict <op_list>\" "
940 "line.\n", fname, lineno, 0 );
944 for ( i = 1; i < cargc; i++ ) {
945 if ( strcasecmp( cargv[ i ], "read" ) == 0 ) {
946 restrictops |= SLAP_RESTRICT_OP_READS;
948 } else if ( strcasecmp( cargv[ i ], "write" ) == 0 ) {
949 restrictops |= SLAP_RESTRICT_OP_WRITES;
951 } else if ( strcasecmp( cargv[ i ], "add" ) == 0 ) {
952 restrictops |= SLAP_RESTRICT_OP_ADD;
954 } else if ( strcasecmp( cargv[ i ], "bind" ) == 0 ) {
955 restrictops |= SLAP_RESTRICT_OP_BIND;
957 } else if ( strcasecmp( cargv[ i ], "compare" ) == 0 ) {
958 restrictops |= SLAP_RESTRICT_OP_COMPARE;
960 } else if ( strcasecmp( cargv[ i ], "delete" ) == 0 ) {
961 restrictops |= SLAP_RESTRICT_OP_DELETE;
963 } else if ( strncasecmp( cargv[ i ], "extended",
964 STRLENOF( "extended" ) ) == 0 )
966 char *e = cargv[ i ] + STRLENOF( "extended" );
972 for ( j = 0; restrictable_exops[ j ].name; j++ ) {
973 if ( strcmp( e, restrictable_exops[j].name ) == 0 )
975 restrictops |= restrictable_exops[ j ].flag;
980 if ( restrictable_exops[ j ].name == NULL ) {
981 goto restrict_unknown;
984 restrictops &= ~SLAP_RESTRICT_OP_EXTENDED;
986 } else if ( e[0] == '\0' ) {
987 restrictops &= ~SLAP_RESTRICT_EXOP_MASK;
988 restrictops |= SLAP_RESTRICT_OP_EXTENDED;
991 goto restrict_unknown;
994 } else if ( strcasecmp( cargv[ i ], "modify" ) == 0 ) {
995 restrictops |= SLAP_RESTRICT_OP_MODIFY;
997 } else if ( strcasecmp( cargv[ i ], "rename" ) == 0
998 || strcasecmp( cargv[ i ], "modrdn" ) == 0 )
1000 restrictops |= SLAP_RESTRICT_OP_RENAME;
1002 } else if ( strcasecmp( cargv[ i ], "search" ) == 0 ) {
1003 restrictops |= SLAP_RESTRICT_OP_SEARCH;
1008 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1009 "unknown operation %s in \"allow <features>\" line\n",
1010 fname, lineno, cargv[i] );
1016 frontendDB->be_restrictops |= restrictops;
1018 be->be_restrictops |= restrictops;
1021 /* allow these features */
1022 } else if ( strcasecmp( cargv[0], "allows" ) == 0 ||
1023 strcasecmp( cargv[0], "allow" ) == 0 )
1025 slap_mask_t allows = 0;
1028 Debug( LDAP_DEBUG_ANY,
1029 "%s: line %d: allow line must appear prior to database definitions\n",
1035 Debug( LDAP_DEBUG_ANY,
1036 "%s: line %d: missing feature(s) in \"allow <features>\" line\n",
1042 for( i=1; i < cargc; i++ ) {
1043 if( strcasecmp( cargv[i], "bind_v2" ) == 0 ) {
1044 allows |= SLAP_ALLOW_BIND_V2;
1046 } else if( strcasecmp( cargv[i], "bind_anon_cred" ) == 0 ) {
1047 allows |= SLAP_ALLOW_BIND_ANON_CRED;
1049 } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) {
1050 allows |= SLAP_ALLOW_BIND_ANON_DN;
1052 } else if( strcasecmp( cargv[i], "update_anon" ) == 0 ) {
1053 allows |= SLAP_ALLOW_UPDATE_ANON;
1056 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1057 "unknown feature %s in \"allow <features>\" line\n",
1058 fname, lineno, cargv[i] );
1064 global_allows |= allows;
1066 /* disallow these features */
1067 } else if ( strcasecmp( cargv[0], "disallows" ) == 0 ||
1068 strcasecmp( cargv[0], "disallow" ) == 0 )
1070 slap_mask_t disallows = 0;
1073 Debug( LDAP_DEBUG_ANY,
1074 "%s: line %d: disallow line must appear prior to database definitions\n",
1080 Debug( LDAP_DEBUG_ANY,
1081 "%s: line %d: missing feature(s) in \"disallow <features>\" line\n",
1087 for( i=1; i < cargc; i++ ) {
1088 if( strcasecmp( cargv[i], "bind_anon" ) == 0 ) {
1089 disallows |= SLAP_DISALLOW_BIND_ANON;
1091 } else if( strcasecmp( cargv[i], "bind_simple" ) == 0 ) {
1092 disallows |= SLAP_DISALLOW_BIND_SIMPLE;
1094 } else if( strcasecmp( cargv[i], "bind_krbv4" ) == 0 ) {
1095 disallows |= SLAP_DISALLOW_BIND_KRBV4;
1097 } else if( strcasecmp( cargv[i], "tls_2_anon" ) == 0 ) {
1098 disallows |= SLAP_DISALLOW_TLS_2_ANON;
1100 } else if( strcasecmp( cargv[i], "tls_authc" ) == 0 ) {
1101 disallows |= SLAP_DISALLOW_TLS_AUTHC;
1104 Debug( LDAP_DEBUG_ANY,
1105 "%s: line %d: unknown feature %s in \"disallow <features>\" line\n",
1106 fname, lineno, cargv[i] );
1112 global_disallows |= disallows;
1114 /* require these features */
1115 } else if ( strcasecmp( cargv[0], "requires" ) == 0 ||
1116 strcasecmp( cargv[0], "require" ) == 0 )
1118 slap_mask_t requires = 0;
1121 Debug( LDAP_DEBUG_ANY,
1122 "%s: line %d: missing feature(s) in \"require <features>\" line\n",
1128 for( i=1; i < cargc; i++ ) {
1129 if( strcasecmp( cargv[i], "bind" ) == 0 ) {
1130 requires |= SLAP_REQUIRE_BIND;
1132 } else if( strcasecmp( cargv[i], "LDAPv3" ) == 0 ) {
1133 requires |= SLAP_REQUIRE_LDAP_V3;
1135 } else if( strcasecmp( cargv[i], "authc" ) == 0 ) {
1136 requires |= SLAP_REQUIRE_AUTHC;
1138 } else if( strcasecmp( cargv[i], "SASL" ) == 0 ) {
1139 requires |= SLAP_REQUIRE_SASL;
1141 } else if( strcasecmp( cargv[i], "strong" ) == 0 ) {
1142 requires |= SLAP_REQUIRE_STRONG;
1144 } else if( strcasecmp( cargv[i], "none" ) != 0 ) {
1145 Debug( LDAP_DEBUG_ANY,
1146 "%s: line %d: unknown feature %s in \"require <features>\" line\n",
1147 fname, lineno, cargv[i] );
1154 frontendDB->be_requires = requires;
1156 be->be_requires = requires;
1159 } else if ( strcasecmp( cargv[0], "security" ) == 0 ) {
1160 slap_ssf_set_t *set;
1163 Debug( LDAP_DEBUG_ANY,
1164 "%s: line %d: missing factor(s) in \"security <factors>\" line\n",
1171 set = &frontendDB->be_ssf_set;
1173 set = &be->be_ssf_set;
1176 for( i=1; i < cargc; i++ ) {
1180 if ( strncasecmp( cargv[i], "ssf=",
1181 STRLENOF("ssf=") ) == 0 )
1183 tgt = &set->sss_ssf;
1184 src = &cargv[i][STRLENOF("ssf=")];
1186 } else if ( strncasecmp( cargv[i], "transport=",
1187 STRLENOF("transport=") ) == 0 )
1189 tgt = &set->sss_transport;
1190 src = &cargv[i][STRLENOF("transport=")];
1192 } else if ( strncasecmp( cargv[i], "tls=",
1193 STRLENOF("tls=") ) == 0 )
1195 tgt = &set->sss_tls;
1196 src = &cargv[i][STRLENOF("tls=")];
1198 } else if ( strncasecmp( cargv[i], "sasl=",
1199 STRLENOF("sasl=") ) == 0 )
1201 tgt = &set->sss_sasl;
1202 src = &cargv[i][STRLENOF("sasl=")];
1204 } else if ( strncasecmp( cargv[i], "update_ssf=",
1205 STRLENOF("update_ssf=") ) == 0 )
1207 tgt = &set->sss_update_ssf;
1208 src = &cargv[i][STRLENOF("update_ssf=")];
1210 } else if ( strncasecmp( cargv[i], "update_transport=",
1211 STRLENOF("update_transport=") ) == 0 )
1213 tgt = &set->sss_update_transport;
1214 src = &cargv[i][STRLENOF("update_transport=")];
1216 } else if ( strncasecmp( cargv[i], "update_tls=",
1217 STRLENOF("update_tls=") ) == 0 )
1219 tgt = &set->sss_update_tls;
1220 src = &cargv[i][STRLENOF("update_tls=")];
1222 } else if ( strncasecmp( cargv[i], "update_sasl=",
1223 STRLENOF("update_sasl=") ) == 0 )
1225 tgt = &set->sss_update_sasl;
1226 src = &cargv[i][STRLENOF("update_sasl=")];
1228 } else if ( strncasecmp( cargv[i], "simple_bind=",
1229 STRLENOF("simple_bind=") ) == 0 )
1231 tgt = &set->sss_simple_bind;
1232 src = &cargv[i][STRLENOF("simple_bind=")];
1235 Debug( LDAP_DEBUG_ANY,
1236 "%s: line %d: unknown factor %s in \"security <factors>\" line\n",
1237 fname, lineno, cargv[i] );
1242 *tgt = strtol( src, &next, 10 );
1243 if ( next == NULL || next[0] != '\0' ) {
1244 Debug( LDAP_DEBUG_ANY,
1245 "%s: line %d: unable to parse factor \"%s\" in \"security <factors>\" line\n",
1246 fname, lineno, cargv[i] );
1252 /* where to send clients when we don't hold it */
1253 } else if ( strcasecmp( cargv[0], "referral" ) == 0 ) {
1255 Debug( LDAP_DEBUG_ANY,
1256 "%s: line %d: missing URL in \"referral <URL>\" line\n",
1262 if( validate_global_referral( cargv[1] ) ) {
1263 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1264 "invalid URL (%s) in \"referral\" line.\n",
1265 fname, lineno, cargv[1] );
1269 vals[0].bv_val = cargv[1];
1270 vals[0].bv_len = strlen( vals[0].bv_val );
1271 if( value_add( &default_referral, vals ) )
1274 /* start of a new database definition */
1275 } else if ( strcasecmp( cargv[0], "debug" ) == 0 ) {
1278 Debug( LDAP_DEBUG_ANY,
1279 "%s: line %d: Error in debug directive, \"debug subsys level\"\n",
1283 level = strtol( cargv[2], &next, 10 );
1284 if ( next == NULL || next[0] != '\0' ){
1285 Debug( LDAP_DEBUG_ANY,
1286 "%s: line %d: unable to parse level \"%s\" in debug directive, "
1287 "\"debug <subsys> <level>\"\n", fname, lineno , cargv[2] );
1291 if ( level <= 0 ) level = lutil_mnem2level( cargv[2] );
1292 lutil_set_debug_level( cargv[1], level );
1293 /* specify an Object Identifier macro */
1294 } else if ( strcasecmp( cargv[0], "objectidentifier" ) == 0 ) {
1295 rc = parse_oidm( fname, lineno, cargc, cargv );
1298 /* specify an objectclass */
1299 } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
1301 Debug( LDAP_DEBUG_ANY,
1302 "%s: line %d: illegal objectclass format.\n",
1306 } else if ( *cargv[1] == '(' /*')'*/) {
1308 p = strchr(saveline,'(' /*')'*/);
1309 rc = parse_oc( fname, lineno, p, cargv );
1313 Debug( LDAP_DEBUG_ANY,
1314 "%s: line %d: old objectclass format not supported.\n",
1318 } else if ( strcasecmp( cargv[0], "ditcontentrule" ) == 0 ) {
1320 p = strchr(saveline,'(' /*')'*/);
1321 rc = parse_cr( fname, lineno, p, cargv );
1324 /* specify an attribute type */
1325 } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 )
1326 || ( strcasecmp( cargv[0], "attribute" ) == 0 ))
1329 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1330 "illegal attribute type format.\n",
1334 } else if ( *cargv[1] == '(' /*')'*/) {
1336 p = strchr(saveline,'(' /*')'*/);
1337 rc = parse_at( fname, lineno, p, cargv );
1341 Debug( LDAP_DEBUG_ANY,
1342 "%s: line %d: old attribute type format not supported.\n",
1347 /* define attribute option(s) */
1348 } else if ( strcasecmp( cargv[0], "attributeoptions" ) == 0 ) {
1349 ad_define_option( NULL, NULL, 0 );
1350 for ( i = 1; i < cargc; i++ )
1351 if ( ad_define_option( cargv[i], fname, lineno ) != 0 )
1354 /* turn on/off schema checking */
1355 } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
1357 Debug( LDAP_DEBUG_ANY,
1358 "%s: line %d: missing on|off in \"schemacheck <on|off>\" line\n",
1363 if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1364 Debug( LDAP_DEBUG_ANY,
1365 "%s: line %d: schema checking disabled! your mileage may vary!\n",
1367 global_schemacheck = 0;
1369 global_schemacheck = 1;
1372 /* specify access control info */
1373 } else if ( strcasecmp( cargv[0], "access" ) == 0 ) {
1374 parse_acl( be, fname, lineno, cargc, cargv );
1376 /* debug level to log things to syslog */
1377 } else if ( strcasecmp( cargv[0], "loglevel" ) == 0 ) {
1379 Debug( LDAP_DEBUG_ANY,
1380 "%s: line %d: missing level(s) in \"loglevel <level> [...]\" line\n",
1388 for( i=1; i < cargc; i++ ) {
1391 if ( isdigit( cargv[i][0] ) ) {
1392 level = strtol( cargv[i], &next, 10 );
1393 if ( next == NULL || next[0] != '\0' ) {
1394 Debug( LDAP_DEBUG_ANY,
1395 "%s: line %d: unable to parse level \"%s\" "
1396 "in \"loglevel <level> [...]\" line.\n",
1397 fname, lineno , cargv[i] );
1406 { LDAP_DEBUG_TRACE, "Trace" },
1407 { LDAP_DEBUG_PACKETS, "Packets" },
1408 { LDAP_DEBUG_ARGS, "Args" },
1409 { LDAP_DEBUG_CONNS, "Conns" },
1410 { LDAP_DEBUG_BER, "BER" },
1411 { LDAP_DEBUG_FILTER, "Filter" },
1412 { LDAP_DEBUG_CONFIG, "Config" },
1413 { LDAP_DEBUG_ACL, "ACL" },
1414 { LDAP_DEBUG_STATS, "Stats" },
1415 { LDAP_DEBUG_STATS2, "Stats2" },
1416 { LDAP_DEBUG_SHELL, "Shell" },
1417 { LDAP_DEBUG_PARSE, "Parse" },
1418 { LDAP_DEBUG_CACHE, "Cache" },
1419 { LDAP_DEBUG_INDEX, "Index" },
1425 for ( j = 0; int_2_level[j].s; j++ ) {
1426 if ( strcasecmp( cargv[i], int_2_level[j].s ) == 0 ) {
1427 level = int_2_level[j].i;
1432 if ( int_2_level[j].s == NULL ) {
1433 Debug( LDAP_DEBUG_ANY,
1434 "%s: line %d: unknown level \"%s\" "
1435 "in \"loglevel <level> [...]\" line.\n",
1436 fname, lineno , cargv[i] );
1441 ldap_syslog |= level;
1444 /* list of sync replication information in this backend (slave only) */
1445 } else if ( strcasecmp( cargv[0], "syncrepl" ) == 0 ) {
1448 Debug( LDAP_DEBUG_ANY,
1449 "%s: line %d: syncrepl line must appear inside "
1450 "a database definition.\n", fname, lineno, 0);
1453 } else if ( SLAP_SHADOW( be )) {
1454 Debug( LDAP_DEBUG_ANY,
1455 "%s: line %d: syncrepl: database already shadowed.\n",
1459 } else if ( add_syncrepl( be, cargv, cargc )) {
1463 SLAP_DBFLAGS(be) |= ( SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SYNC_SHADOW );
1465 /* list of replicas of the data in this backend (master only) */
1466 } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
1468 Debug( LDAP_DEBUG_ANY,
1469 "%s: line %d: missing host or uri in \"replica <host[:port]>\" line\n",
1475 Debug( LDAP_DEBUG_ANY,
1476 "%s: line %d: replica line must appear inside a database definition\n",
1483 for ( i = 1; i < cargc; i++ ) {
1484 if ( strncasecmp( cargv[i], "host=", 5 )
1486 nr = add_replica_info( be,
1489 } else if (strncasecmp( cargv[i], "uri=", 4 )
1491 if ( ldap_url_parse( cargv[ i ] + 4, &ludp )
1493 Debug( LDAP_DEBUG_ANY,
1494 "%s: line %d: replica line contains invalid "
1495 "uri definition.\n", fname, lineno, 0);
1498 if (ludp->lud_host == NULL ) {
1499 Debug( LDAP_DEBUG_ANY,
1500 "%s: line %d: replica line contains invalid "
1501 "uri definition - missing hostname.\n", fname, lineno, 0);
1504 replicahost = ch_malloc( strlen( cargv[ i ] ) );
1505 if ( replicahost == NULL ) {
1506 Debug( LDAP_DEBUG_ANY,
1507 "out of memory in read_config\n", 0, 0, 0 );
1508 ldap_free_urldesc( ludp );
1509 exit( EXIT_FAILURE );
1511 sprintf(replicahost, "%s:%d",
1512 ludp->lud_host, ludp->lud_port);
1513 nr = add_replica_info( be, replicahost );
1514 ldap_free_urldesc( ludp );
1515 ch_free(replicahost);
1520 Debug( LDAP_DEBUG_ANY,
1521 "%s: line %d: missing host or uri in \"replica\" line\n",
1525 } else if ( nr == -1 ) {
1526 Debug( LDAP_DEBUG_ANY,
1527 "%s: line %d: unable to add replica \"%s\"\n",
1528 fname, lineno, cargv[i] + 5 );
1531 for ( i = 1; i < cargc; i++ ) {
1532 if ( strncasecmp( cargv[i], "suffix=", 7 ) == 0 ) {
1534 switch ( add_replica_suffix( be, nr, cargv[i] + 7 ) ) {
1536 Debug( LDAP_DEBUG_ANY,
1537 "%s: line %d: suffix \"%s\" in \"replica\" line is not valid for backend (ignored)\n",
1538 fname, lineno, cargv[i] + 7 );
1542 Debug( LDAP_DEBUG_ANY,
1543 "%s: line %d: unable to normalize suffix in \"replica\" line (ignored)\n",
1548 } else if ( strncasecmp( cargv[i], "attr", 4 ) == 0 ) {
1550 char *arg = cargv[i] + 4;
1552 if ( arg[0] == '!' ) {
1557 if ( arg[0] != '=' ) {
1561 if ( add_replica_attrs( be, nr, arg + 1, exclude ) ) {
1562 Debug( LDAP_DEBUG_ANY,
1563 "%s: line %d: attribute \"%s\" in \"replica\" line is unknown\n",
1564 fname, lineno, arg + 1 );
1572 } else if ( strcasecmp( cargv[0], "replicationInterval" ) == 0 ) {
1575 /* dn of slave entity allowed to write to replica */
1576 } else if ( strcasecmp( cargv[0], "updatedn" ) == 0 ) {
1578 Debug( LDAP_DEBUG_ANY,
1579 "%s: line %d: missing dn in \"updatedn <dn>\" line\n",
1585 Debug( LDAP_DEBUG_ANY,
1586 "%s: line %d: updatedn line must appear inside a database definition\n",
1590 } else if ( SLAP_SHADOW(be) ) {
1591 Debug( LDAP_DEBUG_ANY,
1592 "%s: line %d: updatedn: database already shadowed.\n",
1599 if ( load_ucdata( NULL ) < 0 ) return 1;
1601 dn.bv_val = cargv[1];
1602 dn.bv_len = strlen( cargv[1] );
1604 rc = dnNormalize( 0, NULL, NULL, &dn, &be->be_update_ndn, NULL );
1605 if( rc != LDAP_SUCCESS ) {
1606 Debug( LDAP_DEBUG_ANY,
1607 "%s: line %d: updatedn DN is invalid\n",
1613 SLAP_DBFLAGS(be) |= ( SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SLURP_SHADOW );
1615 } else if ( strcasecmp( cargv[0], "updateref" ) == 0 ) {
1617 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1618 "missing url in \"updateref <ldapurl>\" line\n",
1624 Debug( LDAP_DEBUG_ANY, "%s: line %d: updateref"
1625 " line must appear inside a database definition\n",
1629 } else if ( !SLAP_SHADOW(be) ) {
1630 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1631 "updateref line must after syncrepl or updatedn.\n",
1636 if( validate_global_referral( cargv[1] ) ) {
1637 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1638 "invalid URL (%s) in \"updateref\" line.\n",
1639 fname, lineno, cargv[1] );
1643 vals[0].bv_val = cargv[1];
1644 vals[0].bv_len = strlen( vals[0].bv_val );
1645 if( value_add( &be->be_update_refs, vals ) ) {
1649 /* replication log file to which changes are appended */
1650 } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) {
1652 Debug( LDAP_DEBUG_ANY,
1653 "%s: line %d: missing filename in \"replogfile <filename>\" line\n",
1659 be->be_replogfile = ch_strdup( cargv[1] );
1661 replogfile = ch_strdup( cargv[1] );
1664 /* file from which to read additional rootdse attrs */
1665 } else if ( strcasecmp( cargv[0], "rootDSE" ) == 0) {
1667 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1668 "missing filename in \"rootDSE <filename>\" line.\n",
1673 if( read_root_dse_file( cargv[1] ) ) {
1674 Debug( LDAP_DEBUG_ANY, "%s: line %d: "
1675 "could not read \"rootDSE <filename>\" line\n",
1680 /* maintain lastmodified{by,time} attributes */
1681 } else if ( strcasecmp( cargv[0], "lastmod" ) == 0 ) {
1683 Debug( LDAP_DEBUG_ANY,
1684 "%s: line %d: missing on|off in \"lastmod <on|off>\" line\n",
1691 Debug( LDAP_DEBUG_ANY, "%s: line %d: lastmod"
1692 " line must appear inside a database definition\n",
1696 } else if ( SLAP_NOLASTMODCMD(be) ) {
1697 Debug( LDAP_DEBUG_ANY, "%s: line %d: lastmod"
1698 " not available for %s databases\n",
1699 fname, lineno, be->bd_info->bi_type );
1703 if ( strcasecmp( cargv[1], "on" ) == 0 ) {
1704 SLAP_DBFLAGS(be) &= ~SLAP_DBFLAG_NOLASTMOD;
1706 SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NOLASTMOD;
1710 /* turn on/off gentle SIGHUP handling */
1711 } else if ( strcasecmp( cargv[0], "gentlehup" ) == 0 ) {
1713 Debug( LDAP_DEBUG_ANY,
1714 "%s: line %d: missing on|off in \"gentlehup <on|off>\" line\n",
1718 if ( strcasecmp( cargv[1], "off" ) == 0 ) {
1719 global_gentlehup = 0;
1721 global_gentlehup = 1;
1725 /* set idle timeout value */
1726 } else if ( strcasecmp( cargv[0], "idletimeout" ) == 0 ) {
1729 Debug( LDAP_DEBUG_ANY,
1730 "%s: line %d: missing timeout value in \"idletimeout <seconds>\" line\n",
1736 i = atoi( cargv[1] );
1739 Debug( LDAP_DEBUG_ANY,
1740 "%s: line %d: timeout value (%d) invalid \"idletimeout <seconds>\" line\n",
1746 global_idletimeout = i;
1748 /* include another config file */
1749 } else if ( strcasecmp( cargv[0], "include" ) == 0 ) {
1751 Debug( LDAP_DEBUG_ANY,
1752 "%s: line %d: missing filename in \"include <filename>\" line\n",
1757 savefname = ch_strdup( cargv[1] );
1758 savelineno = lineno;
1760 if ( read_config( savefname, depth+1 ) != 0 ) {
1765 lineno = savelineno - 1;
1767 /* location of kerberos srvtab file */
1768 } else if ( strcasecmp( cargv[0], "srvtab" ) == 0 ) {
1770 Debug( LDAP_DEBUG_ANY,
1771 "%s: line %d: missing filename in \"srvtab <filename>\" line\n",
1776 ldap_srvtab = ch_strdup( cargv[1] );
1778 #ifdef SLAPD_MODULES
1779 } else if (strcasecmp( cargv[0], "moduleload") == 0 ) {
1781 Debug( LDAP_DEBUG_ANY,
1782 "%s: line %d: missing filename in \"moduleload <filename>\" line\n",
1785 exit( EXIT_FAILURE );
1787 if (module_load(cargv[1], cargc - 2, (cargc > 2) ? cargv + 2 : NULL)) {
1788 Debug( LDAP_DEBUG_ANY,
1789 "%s: line %d: failed to load or initialize module %s\n",
1790 fname, lineno, cargv[1]);
1792 exit( EXIT_FAILURE );
1794 } else if (strcasecmp( cargv[0], "modulepath") == 0 ) {
1796 Debug( LDAP_DEBUG_ANY,
1797 "%s: line %d: missing path in \"modulepath <path>\" line\n",
1800 exit( EXIT_FAILURE );
1802 if (module_path( cargv[1] )) {
1803 Debug( LDAP_DEBUG_ANY,
1804 "%s: line %d: failed to set module search path to %s\n",
1805 fname, lineno, cargv[1]);
1807 exit( EXIT_FAILURE );
1810 #endif /*SLAPD_MODULES*/
1813 } else if ( !strcasecmp( cargv[0], "TLSRandFile" ) ) {
1814 rc = ldap_pvt_tls_set_option( NULL,
1815 LDAP_OPT_X_TLS_RANDOM_FILE,
1820 } else if ( !strcasecmp( cargv[0], "TLSCipherSuite" ) ) {
1821 rc = ldap_pvt_tls_set_option( NULL,
1822 LDAP_OPT_X_TLS_CIPHER_SUITE,
1827 } else if ( !strcasecmp( cargv[0], "TLSCertificateFile" ) ) {
1828 rc = ldap_pvt_tls_set_option( NULL,
1829 LDAP_OPT_X_TLS_CERTFILE,
1834 } else if ( !strcasecmp( cargv[0], "TLSCertificateKeyFile" ) ) {
1835 rc = ldap_pvt_tls_set_option( NULL,
1836 LDAP_OPT_X_TLS_KEYFILE,
1841 } else if ( !strcasecmp( cargv[0], "TLSCACertificatePath" ) ) {
1842 rc = ldap_pvt_tls_set_option( NULL,
1843 LDAP_OPT_X_TLS_CACERTDIR,
1848 } else if ( !strcasecmp( cargv[0], "TLSCACertificateFile" ) ) {
1849 rc = ldap_pvt_tls_set_option( NULL,
1850 LDAP_OPT_X_TLS_CACERTFILE,
1854 } else if ( !strcasecmp( cargv[0], "TLSVerifyClient" ) ) {
1855 if ( isdigit( (unsigned char) cargv[1][0] ) ) {
1857 rc = ldap_pvt_tls_set_option( NULL,
1858 LDAP_OPT_X_TLS_REQUIRE_CERT,
1861 rc = ldap_int_tls_config( NULL,
1862 LDAP_OPT_X_TLS_REQUIRE_CERT,
1871 } else if ( !strcasecmp( cargv[0], "reverse-lookup" ) ) {
1872 #ifdef SLAPD_RLOOKUPS
1874 Debug( LDAP_DEBUG_ANY,
1875 "%s: line %d: reverse-lookup: missing \"on\" or \"off\"\n",
1880 if ( !strcasecmp( cargv[1], "on" ) ) {
1881 use_reverse_lookup = 1;
1882 } else if ( !strcasecmp( cargv[1], "off" ) ) {
1883 use_reverse_lookup = 0;
1885 Debug( LDAP_DEBUG_ANY,
1886 "%s: line %d: reverse-lookup: must be \"on\" (default) or \"off\"\n",
1891 #else /* !SLAPD_RLOOKUPS */
1892 Debug( LDAP_DEBUG_ANY,
1893 "%s: line %d: reverse lookups are not configured (ignored).\n",
1895 #endif /* !SLAPD_RLOOKUPS */
1897 /* Netscape plugins */
1898 } else if ( strcasecmp( cargv[0], "plugin" ) == 0 ) {
1899 #if defined( LDAP_SLAPI )
1901 #ifdef notdef /* allow global plugins, too */
1903 * a "plugin" line must be inside a database
1904 * definition, since we implement pre-,post-
1905 * and extended operation plugins
1908 Debug( LDAP_DEBUG_ANY, "%s: line %d: plugin "
1909 "line must appear inside a database "
1910 "definition\n", fname, lineno, 0 );
1915 if ( slapi_int_read_config( be, fname, lineno, cargc, cargv )
1918 Debug( LDAP_DEBUG_ANY, "%s: line %d: SLAPI "
1919 "config read failed.\n", fname, lineno, 0 );
1922 slapi_plugins_used++;
1924 #else /* !defined( LDAP_SLAPI ) */
1925 Debug( LDAP_DEBUG_ANY, "%s: line %d: SLAPI "
1926 "not supported.\n", fname, lineno, 0 );
1929 #endif /* !defined( LDAP_SLAPI ) */
1931 /* Netscape plugins */
1932 } else if ( strcasecmp( cargv[0], "pluginlog" ) == 0 ) {
1933 #if defined( LDAP_SLAPI )
1935 Debug( LDAP_DEBUG_ANY,
1936 "%s: line %d: missing file name "
1937 "in pluginlog <filename> line.\n",
1942 if ( slapi_log_file != NULL ) {
1943 ch_free( slapi_log_file );
1946 slapi_log_file = ch_strdup( cargv[1] );
1947 #endif /* !defined( LDAP_SLAPI ) */
1949 /* pass anything else to the current backend info/db config routine */
1952 if ( bi->bi_config ) {
1953 rc = (*bi->bi_config)( bi, fname, lineno, cargc, cargv );
1959 case SLAP_CONF_UNKNOWN:
1960 Debug( LDAP_DEBUG_ANY,
1961 "%s: line %d: unknown directive \"%s\" inside backend info definition (ignored)\n",
1962 fname, lineno, cargv[0] );
1970 } else if ( be != NULL ) {
1971 if ( be->be_config ) {
1972 rc = (*be->be_config)( be, fname, lineno, cargc, cargv );
1978 case SLAP_CONF_UNKNOWN:
1979 Debug( LDAP_DEBUG_ANY,
1980 "%s: line %d: unknown directive \"%s\" inside backend database definition (ignored)\n",
1981 fname, lineno, cargv[0] );
1990 if ( frontendDB->be_config ) {
1991 rc = (*frontendDB->be_config)( frontendDB, fname, lineno, cargc, cargv );
1997 case SLAP_CONF_UNKNOWN:
1998 Debug( LDAP_DEBUG_ANY,
1999 "%s: line %d: unknown directive \"%s\" inside global database definition (ignored)\n",
2000 fname, lineno, cargv[0] );
2013 if ( depth == 0 ) ch_free( cargv );
2015 if ( BER_BVISNULL( &frontendDB->be_schemadn ) ) {
2016 ber_str2bv( SLAPD_SCHEMA_DN, sizeof(SLAPD_SCHEMA_DN)-1, 1,
2017 &frontendDB->be_schemadn );
2018 dnNormalize( 0, NULL, NULL, &frontendDB->be_schemadn, &frontendDB->be_schemandn, NULL );
2021 if ( load_ucdata( NULL ) < 0 ) return 1;
2033 char logbuf[sizeof("pseudorootpw ***")];
2036 token = strtok_quote( line, " \t" );
2040 if ( token && ( strcasecmp( token, "rootpw" ) == 0 ||
2041 strcasecmp( token, "replica" ) == 0 || /* contains "credentials" */
2042 strcasecmp( token, "bindpw" ) == 0 || /* used in back-ldap */
2043 strcasecmp( token, "pseudorootpw" ) == 0 || /* used in back-meta */
2044 strcasecmp( token, "dbpasswd" ) == 0 ) ) /* used in back-sql */
2046 snprintf( logline = logbuf, sizeof logbuf, "%s ***", token );
2049 if ( strtok_quote_ptr ) {
2050 *strtok_quote_ptr = ' ';
2053 Debug( LDAP_DEBUG_CONFIG, "line %d (%s)\n", lineno, logline, 0 );
2055 if ( strtok_quote_ptr ) {
2056 *strtok_quote_ptr = '\0';
2059 for ( ; token != NULL; token = strtok_quote( NULL, " \t" ) ) {
2060 if ( cargc == cargv_size - 1 ) {
2062 tmp = ch_realloc( cargv, (cargv_size + ARGS_STEP) *
2064 if ( tmp == NULL ) {
2065 Debug( LDAP_DEBUG_ANY,
2066 "line %d: out of memory\n",
2071 cargv_size += ARGS_STEP;
2073 cargv[cargc++] = token;
2075 cargv[cargc] = NULL;
2080 strtok_quote( char *line, char *sep )
2086 strtok_quote_ptr = NULL;
2087 if ( line != NULL ) {
2090 while ( *next && strchr( sep, *next ) ) {
2094 if ( *next == '\0' ) {
2100 for ( inquote = 0; *next; ) {
2108 AC_MEMCPY( next, next + 1, strlen( next + 1 ) + 1 );
2114 next + 1, strlen( next + 1 ) + 1 );
2115 next++; /* dont parse the escaped character */
2120 if ( strchr( sep, *next ) != NULL ) {
2121 strtok_quote_ptr = next;
2134 static char buf[BUFSIZ];
2136 static size_t lmax, lcur;
2138 #define CATLINE( buf ) \
2140 size_t len = strlen( buf ); \
2141 while ( lcur + len + 1 > lmax ) { \
2143 line = (char *) ch_realloc( line, lmax ); \
2145 strcpy( line + lcur, buf ); \
2150 fp_getline( FILE *fp, int *lineno )
2158 /* hack attack - keeps us from having to keep a stack of bufs... */
2159 if ( strncasecmp( line, "include", 7 ) == 0 ) {
2164 while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
2165 /* trim off \r\n or \n */
2166 if ( (p = strchr( buf, '\n' )) != NULL ) {
2167 if( p > buf && p[-1] == '\r' ) --p;
2171 /* trim off trailing \ and append the next line */
2172 if ( line[ 0 ] != '\0'
2173 && (p = line + strlen( line ) - 1)[ 0 ] == '\\'
2174 && p[ -1 ] != '\\' ) {
2179 if ( ! isspace( (unsigned char) buf[0] ) ) {
2183 /* change leading whitespace to a space */
2192 return( line[0] ? line : NULL );
2196 fp_getline_init( int *lineno )
2202 /* Loads ucdata, returns 1 if loading, 0 if already loaded, -1 on error */
2204 load_ucdata( char *path )
2207 static int loaded = 0;
2213 err = ucdata_load( path ? path : SLAPD_DEFAULT_UCDATA, UCDATA_ALL );
2215 Debug( LDAP_DEBUG_ANY, "error loading ucdata (error %d)\n",
2223 /* ucdata is now hardcoded */
2231 ucdata_unload( UCDATA_ALL );
2233 /* NOTE: in case of early exit, frontendDB can be NULL */
2234 if ( frontendDB->be_schemandn.bv_val )
2235 free( frontendDB->be_schemandn.bv_val );
2236 if ( frontendDB->be_schemadn.bv_val )
2237 free( frontendDB->be_schemadn.bv_val );
2238 if ( frontendDB->be_acl )
2239 acl_destroy( frontendDB->be_acl, NULL );
2242 if ( slapd_args_file )
2243 free ( slapd_args_file );
2244 if ( slapd_pid_file )
2245 free ( slapd_pid_file );
2246 if ( default_passwd_hash )
2247 ldap_charray_free( default_passwd_hash );
2258 syncinfo_t *si_entry;
2260 int duplicated_replica_id = 0;
2262 si = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );
2265 Debug( LDAP_DEBUG_ANY, "out of memory in add_syncrepl\n", 0, 0, 0 );
2269 si->si_tls = SYNCINFO_TLS_OFF;
2270 if ( be->be_rootndn.bv_val ) {
2271 ber_dupbv( &si->si_updatedn, &be->be_rootndn );
2273 si->si_bindmethod = LDAP_AUTH_SIMPLE;
2274 si->si_schemachecking = 0;
2275 ber_str2bv( "(objectclass=*)", STRLENOF("(objectclass=*)"), 1,
2276 &si->si_filterstr );
2277 si->si_base.bv_val = NULL;
2278 si->si_scope = LDAP_SCOPE_SUBTREE;
2279 si->si_attrsonly = 0;
2280 si->si_attrs = (char **) ch_calloc( 1, sizeof( char * ));
2281 si->si_attrs[0] = NULL;
2282 si->si_exattrs = (char **) ch_calloc( 1, sizeof( char * ));
2283 si->si_exattrs[0] = NULL;
2284 si->si_type = LDAP_SYNC_REFRESH_ONLY;
2285 si->si_interval = 86400;
2286 si->si_retryinterval = NULL;
2287 si->si_retrynum_init = NULL;
2288 si->si_retrynum = NULL;
2289 si->si_syncCookie.ctxcsn = NULL;
2290 si->si_syncCookie.octet_str = NULL;
2291 si->si_syncCookie.sid = -1;
2292 si->si_manageDSAit = 0;
2295 si->si_syncUUID_ndn.bv_val = NULL;
2296 si->si_syncUUID_ndn.bv_len = 0;
2298 si->si_presentlist = NULL;
2299 LDAP_LIST_INIT( &si->si_nonpresentlist );
2301 rc = parse_syncrepl_line( cargv, cargc, si );
2303 LDAP_STAILQ_FOREACH( si_entry, &be->be_syncinfo, si_next ) {
2304 if ( si->si_rid == si_entry->si_rid ) {
2305 Debug( LDAP_DEBUG_ANY,
2306 "add_syncrepl: duplicated replica id\n",0, 0, 0 );
2307 duplicated_replica_id = 1;
2312 if ( rc < 0 || duplicated_replica_id ) {
2313 Debug( LDAP_DEBUG_ANY, "failed to add syncinfo\n", 0, 0, 0 );
2316 Debug( LDAP_DEBUG_CONFIG,
2317 "Config: ** successfully added syncrepl \"%s\"\n",
2318 si->si_provideruri == NULL ? "(null)" : si->si_provideruri, 0, 0 );
2319 if ( !si->si_schemachecking ) {
2320 SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK;
2323 LDAP_STAILQ_INSERT_TAIL( &be->be_syncinfo, si, si_next );
2329 #define PROVIDERSTR "provider"
2330 #define SUFFIXSTR "suffix"
2331 #define UPDATEDNSTR "updatedn"
2332 #define BINDMETHSTR "bindmethod"
2333 #define SIMPLESTR "simple"
2334 #define SASLSTR "sasl"
2335 #define BINDDNSTR "binddn"
2336 #define CREDSTR "credentials"
2337 #define OLDAUTHCSTR "bindprincipal"
2338 #define AUTHCSTR "authcID"
2339 #define AUTHZSTR "authzID"
2340 #define SRVTABSTR "srvtab"
2341 #define SASLMECHSTR "saslmech"
2342 #define REALMSTR "realm"
2343 #define SECPROPSSTR "secprops"
2344 #define STARTTLSSTR "starttls"
2345 #define CRITICALSTR "critical"
2347 #define SCHEMASTR "schemachecking"
2348 #define FILTERSTR "filter"
2349 #define SEARCHBASESTR "searchbase"
2350 #define SCOPESTR "scope"
2351 #define ATTRSSTR "attrs"
2352 #define ATTRSONLYSTR "attrsonly"
2353 #define EXATTRSSTR "exattrs"
2354 #define TYPESTR "type"
2355 #define INTERVALSTR "interval"
2356 #define LASTMODSTR "lastmod"
2357 #define LMREQSTR "req"
2358 #define LMGENSTR "gen"
2359 #define LMNOSTR "no"
2360 #define MANAGEDSAITSTR "manageDSAit"
2361 #define SLIMITSTR "sizelimit"
2362 #define TLIMITSTR "timelimit"
2364 #define RETRYSTR "retry"
2366 #define GOT_ID 0x0001
2367 #define GOT_PROVIDER 0x0002
2368 #define GOT_METHOD 0x0004
2369 #define GOT_ALL 0x0007
2372 parse_syncrepl_line(
2383 for ( i = 1; i < cargc; i++ ) {
2384 if ( !strncasecmp( cargv[ i ], IDSTR, sizeof( IDSTR ) - 1 )) {
2386 /* '\0' string terminator accounts for '=' */
2387 val = cargv[ i ] + sizeof( IDSTR );
2389 if ( tmp >= 1000 || tmp < 0 ) {
2390 fprintf( stderr, "Error: parse_syncrepl_line: "
2391 "syncrepl id %d is out of range [0..999]\n", tmp );
2396 } else if ( !strncasecmp( cargv[ i ], PROVIDERSTR,
2397 sizeof( PROVIDERSTR ) - 1 )) {
2398 val = cargv[ i ] + sizeof( PROVIDERSTR );
2399 si->si_provideruri = ch_strdup( val );
2400 si->si_provideruri_bv = (BerVarray)
2401 ch_calloc( 2, sizeof( struct berval ));
2402 ber_str2bv( si->si_provideruri, strlen( si->si_provideruri ),
2403 1, &si->si_provideruri_bv[0] );
2404 si->si_provideruri_bv[1].bv_len = 0;
2405 si->si_provideruri_bv[1].bv_val = NULL;
2406 gots |= GOT_PROVIDER;
2407 } else if ( !strncasecmp( cargv[ i ], STARTTLSSTR,
2408 sizeof(STARTTLSSTR) - 1 ) )
2410 val = cargv[ i ] + sizeof( STARTTLSSTR );
2411 if( !strcasecmp( val, CRITICALSTR ) ) {
2412 si->si_tls = SYNCINFO_TLS_CRITICAL;
2414 si->si_tls = SYNCINFO_TLS_ON;
2416 } else if ( !strncasecmp( cargv[ i ],
2417 UPDATEDNSTR, sizeof( UPDATEDNSTR ) - 1 ) )
2419 struct berval updatedn = {0, NULL};
2420 val = cargv[ i ] + sizeof( UPDATEDNSTR );
2421 ber_str2bv( val, 0, 0, &updatedn );
2422 ch_free( si->si_updatedn.bv_val );
2423 dnNormalize( 0, NULL, NULL, &updatedn, &si->si_updatedn, NULL );
2424 } else if ( !strncasecmp( cargv[ i ], BINDMETHSTR,
2425 sizeof( BINDMETHSTR ) - 1 ) )
2427 val = cargv[ i ] + sizeof( BINDMETHSTR );
2428 if ( !strcasecmp( val, SIMPLESTR )) {
2429 si->si_bindmethod = LDAP_AUTH_SIMPLE;
2431 } else if ( !strcasecmp( val, SASLSTR )) {
2432 #ifdef HAVE_CYRUS_SASL
2433 si->si_bindmethod = LDAP_AUTH_SASL;
2435 #else /* HAVE_CYRUS_SASL */
2436 fprintf( stderr, "Error: parse_syncrepl_line: "
2437 "not compiled with SASL support\n" );
2439 #endif /* HAVE_CYRUS_SASL */
2441 si->si_bindmethod = -1;
2443 } else if ( !strncasecmp( cargv[ i ],
2444 BINDDNSTR, sizeof( BINDDNSTR ) - 1 ) ) {
2445 val = cargv[ i ] + sizeof( BINDDNSTR );
2446 si->si_binddn = ch_strdup( val );
2447 } else if ( !strncasecmp( cargv[ i ],
2448 CREDSTR, sizeof( CREDSTR ) - 1 ) ) {
2449 val = cargv[ i ] + sizeof( CREDSTR );
2450 si->si_passwd = ch_strdup( val );
2451 } else if ( !strncasecmp( cargv[ i ],
2452 SASLMECHSTR, sizeof( SASLMECHSTR ) - 1 ) ) {
2453 val = cargv[ i ] + sizeof( SASLMECHSTR );
2454 si->si_saslmech = ch_strdup( val );
2455 } else if ( !strncasecmp( cargv[ i ],
2456 SECPROPSSTR, sizeof( SECPROPSSTR ) - 1 ) ) {
2457 val = cargv[ i ] + sizeof( SECPROPSSTR );
2458 si->si_secprops = ch_strdup( val );
2459 } else if ( !strncasecmp( cargv[ i ],
2460 REALMSTR, sizeof( REALMSTR ) - 1 ) ) {
2461 val = cargv[ i ] + sizeof( REALMSTR );
2462 si->si_realm = ch_strdup( val );
2463 } else if ( !strncasecmp( cargv[ i ],
2464 AUTHCSTR, sizeof( AUTHCSTR ) - 1 ) ) {
2465 val = cargv[ i ] + sizeof( AUTHCSTR );
2466 if ( si->si_authcId )
2467 ch_free( si->si_authcId );
2468 si->si_authcId = ch_strdup( val );
2469 } else if ( !strncasecmp( cargv[ i ],
2470 OLDAUTHCSTR, sizeof( OLDAUTHCSTR ) - 1 ) ) {
2471 /* Old authcID is provided for some backwards compatibility */
2472 val = cargv[ i ] + sizeof( OLDAUTHCSTR );
2473 if ( si->si_authcId )
2474 ch_free( si->si_authcId );
2475 si->si_authcId = ch_strdup( val );
2476 } else if ( !strncasecmp( cargv[ i ],
2477 AUTHZSTR, sizeof( AUTHZSTR ) - 1 ) ) {
2478 val = cargv[ i ] + sizeof( AUTHZSTR );
2479 si->si_authzId = ch_strdup( val );
2480 } else if ( !strncasecmp( cargv[ i ],
2481 SCHEMASTR, sizeof( SCHEMASTR ) - 1 ) )
2483 val = cargv[ i ] + sizeof( SCHEMASTR );
2484 if ( !strncasecmp( val, "on", STRLENOF( "on" ) )) {
2485 si->si_schemachecking = 1;
2486 } else if ( !strncasecmp( val, "off", STRLENOF( "off" ) ) ) {
2487 si->si_schemachecking = 0;
2489 si->si_schemachecking = 1;
2491 } else if ( !strncasecmp( cargv[ i ],
2492 FILTERSTR, sizeof( FILTERSTR ) - 1 ) )
2494 val = cargv[ i ] + sizeof( FILTERSTR );
2495 ber_str2bv( val, 0, 1, &si->si_filterstr );
2496 } else if ( !strncasecmp( cargv[ i ],
2497 SEARCHBASESTR, sizeof( SEARCHBASESTR ) - 1 ) )
2500 val = cargv[ i ] + sizeof( SEARCHBASESTR );
2501 if ( si->si_base.bv_val ) {
2502 ch_free( si->si_base.bv_val );
2504 ber_str2bv( val, 0, 0, &bv );
2505 if ( dnNormalize( 0, NULL, NULL, &bv, &si->si_base, NULL )) {
2506 fprintf( stderr, "Invalid base DN \"%s\"\n", val );
2509 } else if ( !strncasecmp( cargv[ i ],
2510 SCOPESTR, sizeof( SCOPESTR ) - 1 ) )
2512 val = cargv[ i ] + sizeof( SCOPESTR );
2513 if ( !strncasecmp( val, "base", STRLENOF( "base" ) )) {
2514 si->si_scope = LDAP_SCOPE_BASE;
2515 } else if ( !strncasecmp( val, "one", STRLENOF( "one" ) )) {
2516 si->si_scope = LDAP_SCOPE_ONELEVEL;
2517 #ifdef LDAP_SCOPE_SUBORDINATE
2518 } else if ( !strcasecmp( val, "subordinate" ) ||
2519 !strcasecmp( val, "children" ))
2521 si->si_scope = LDAP_SCOPE_SUBORDINATE;
2523 } else if ( !strncasecmp( val, "sub", STRLENOF( "sub" ) )) {
2524 si->si_scope = LDAP_SCOPE_SUBTREE;
2526 fprintf( stderr, "Error: parse_syncrepl_line: "
2527 "unknown scope \"%s\"\n", val);
2530 } else if ( !strncasecmp( cargv[ i ],
2531 ATTRSONLYSTR, sizeof( ATTRSONLYSTR ) - 1 ) )
2533 si->si_attrsonly = 1;
2534 } else if ( !strncasecmp( cargv[ i ],
2535 ATTRSSTR, sizeof( ATTRSSTR ) - 1 ) )
2537 val = cargv[ i ] + sizeof( ATTRSSTR );
2538 str2clist( &si->si_attrs, val, "," );
2539 } else if ( !strncasecmp( cargv[ i ],
2540 EXATTRSSTR, sizeof( EXATTRSSTR ) - 1 ) )
2542 val = cargv[ i ] + sizeof( EXATTRSSTR );
2543 str2clist( &si->si_exattrs, val, "," );
2544 } else if ( !strncasecmp( cargv[ i ],
2545 TYPESTR, sizeof( TYPESTR ) - 1 ) )
2547 val = cargv[ i ] + sizeof( TYPESTR );
2548 if ( !strncasecmp( val, "refreshOnly", STRLENOF("refreshOnly") )) {
2549 si->si_type = LDAP_SYNC_REFRESH_ONLY;
2550 } else if ( !strncasecmp( val, "refreshAndPersist",
2551 STRLENOF("refreshAndPersist") ))
2553 si->si_type = LDAP_SYNC_REFRESH_AND_PERSIST;
2554 si->si_interval = 60;
2556 fprintf( stderr, "Error: parse_syncrepl_line: "
2557 "unknown sync type \"%s\"\n", val);
2560 } else if ( !strncasecmp( cargv[ i ],
2561 INTERVALSTR, sizeof( INTERVALSTR ) - 1 ) )
2563 val = cargv[ i ] + sizeof( INTERVALSTR );
2564 if ( si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ) {
2565 si->si_interval = 0;
2573 hstr = strchr( dstr, ':' );
2574 if ( hstr == NULL ) {
2575 fprintf( stderr, "Error: parse_syncrepl_line: "
2576 "invalid interval \"%s\"\n", val );
2580 mstr = strchr( hstr, ':' );
2581 if ( mstr == NULL ) {
2582 fprintf( stderr, "Error: parse_syncrepl_line: "
2583 "invalid interval \"%s\"\n", val );
2587 sstr = strchr( mstr, ':' );
2588 if ( sstr == NULL ) {
2589 fprintf( stderr, "Error: parse_syncrepl_line: "
2590 "invalid interval \"%s\"\n", val );
2599 if (( hh > 24 ) || ( hh < 0 ) ||
2600 ( mm > 60 ) || ( mm < 0 ) ||
2601 ( ss > 60 ) || ( ss < 0 ) || ( dd < 0 )) {
2602 fprintf( stderr, "Error: parse_syncrepl_line: "
2603 "invalid interval \"%s\"\n", val );
2606 si->si_interval = (( dd * 24 + hh ) * 60 + mm ) * 60 + ss;
2608 if ( si->si_interval < 0 ) {
2609 fprintf( stderr, "Error: parse_syncrepl_line: "
2610 "invalid interval \"%ld\"\n",
2611 (long) si->si_interval);
2614 } else if ( !strncasecmp( cargv[ i ],
2615 RETRYSTR, sizeof( RETRYSTR ) - 1 ) )
2621 val = cargv[ i ] + sizeof( RETRYSTR );
2622 retry_list = (char **) ch_calloc( 1, sizeof( char * ));
2623 retry_list[0] = NULL;
2625 str2clist( &retry_list, val, " ,\t" );
2627 for ( k = 0; retry_list && retry_list[k]; k++ ) ;
2631 "Error: incomplete syncrepl retry list\n" );
2632 for ( k = 0; retry_list && retry_list[k]; k++ ) {
2633 ch_free( retry_list[k] );
2635 ch_free( retry_list );
2636 exit( EXIT_FAILURE );
2638 si->si_retryinterval = (time_t *) ch_calloc( n + 1, sizeof( time_t ));
2639 si->si_retrynum = (int *) ch_calloc( n + 1, sizeof( int ));
2640 si->si_retrynum_init = (int *) ch_calloc( n + 1, sizeof( int ));
2641 for ( j = 0; j < n; j++ ) {
2642 si->si_retryinterval[j] = atoi( retry_list[j*2] );
2643 if ( *retry_list[j*2+1] == '+' ) {
2644 si->si_retrynum_init[j] = -1;
2645 si->si_retrynum[j] = -1;
2649 si->si_retrynum_init[j] = atoi( retry_list[j*2+1] );
2650 si->si_retrynum[j] = atoi( retry_list[j*2+1] );
2653 si->si_retrynum_init[j] = -2;
2654 si->si_retrynum[j] = -2;
2655 si->si_retryinterval[j] = 0;
2657 for ( k = 0; retry_list && retry_list[k]; k++ ) {
2658 ch_free( retry_list[k] );
2660 ch_free( retry_list );
2661 } else if ( !strncasecmp( cargv[ i ],
2662 MANAGEDSAITSTR, sizeof( MANAGEDSAITSTR ) - 1 ) )
2664 val = cargv[ i ] + sizeof( MANAGEDSAITSTR );
2665 si->si_manageDSAit = atoi( val );
2666 } else if ( !strncasecmp( cargv[ i ],
2667 SLIMITSTR, sizeof( SLIMITSTR ) - 1 ) )
2669 val = cargv[ i ] + sizeof( SLIMITSTR );
2670 si->si_slimit = atoi( val );
2671 } else if ( !strncasecmp( cargv[ i ],
2672 TLIMITSTR, sizeof( TLIMITSTR ) - 1 ) )
2674 val = cargv[ i ] + sizeof( TLIMITSTR );
2675 si->si_tlimit = atoi( val );
2677 fprintf( stderr, "Error: parse_syncrepl_line: "
2678 "unknown keyword \"%s\"\n", cargv[ i ] );
2682 if ( gots != GOT_ALL ) {
2684 "Error: Malformed \"syncrepl\" line in slapd config file" );
2692 str2clist( char ***out, char *in, const char *brkstr )
2701 /* find last element in list */
2702 for (i = 0; *out && *out[i]; i++);
2704 /* protect the input string from strtok */
2705 str = ch_strdup( in );
2707 if ( *str == '\0' ) {
2712 /* Count words in string */
2714 for ( s = str; *s; s++ ) {
2715 if ( strchr( brkstr, *s ) != NULL ) {
2720 *out = ch_realloc( *out, ( i + j + 1 ) * sizeof( char * ) );
2722 for ( s = ldap_pvt_strtok( str, brkstr, &lasts );
2724 s = ldap_pvt_strtok( NULL, brkstr, &lasts ) )
2726 *new = ch_strdup( s );