1 /* bconfig.c - the config backend */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2005 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>.
17 * This work was originally developed by Howard Chu for inclusion
18 * in OpenLDAP Software.
24 #include <ac/string.h>
31 #include "slapi/slapi.h"
38 static struct berval config_rdn = BER_BVC("cn=config");
39 static struct berval access_rdn = BER_BVC("cn=access");
42 typedef struct modpath_s {
43 struct modpath_s *mp_next;
44 struct berval mp_path;
49 typedef struct ConfigFile {
50 struct ConfigFile *c_sibs;
51 struct ConfigFile *c_kids;
60 typedef struct CfEntryInfo {
61 struct CfEntryInfo *ce_sibs;
62 struct CfEntryInfo *ce_kids;
69 ConfigFile *cb_config;
73 /* These do nothing in slapd, they're kept only to make them
76 static char *replica_pidFile, *replica_argsFile;
77 static int replicationInterval;
79 static char *passwd_salt;
80 static char *logfileName;
81 static BerVarray authz_rewrites;
83 static AttributeDescription *cfAd_backend, *cfAd_database, *cfAd_overlay,
86 static ObjectClass *cfOc_global, *cfOc_backend, *cfOc_database,
87 *cfOc_include, *cfOc_overlay, *cfOc_access;
89 static ConfigFile cf_prv, *cfn = &cf_prv;
91 static int add_syncrepl LDAP_P(( Backend *, char **, int ));
92 static int parse_syncrepl_line LDAP_P(( char **, int, syncinfo_t *));
93 static void syncrepl_unparse LDAP_P (( syncinfo_t *, struct berval *));
95 static ConfigDriver config_fname;
96 static ConfigDriver config_generic;
97 static ConfigDriver config_search_base;
98 static ConfigDriver config_passwd_hash;
99 static ConfigDriver config_schema_dn;
100 static ConfigDriver config_sizelimit;
101 static ConfigDriver config_timelimit;
102 static ConfigDriver config_limits;
103 static ConfigDriver config_overlay;
104 static ConfigDriver config_suffix;
105 static ConfigDriver config_deref_depth;
106 static ConfigDriver config_rootdn;
107 static ConfigDriver config_rootpw;
108 static ConfigDriver config_restrict;
109 static ConfigDriver config_allows;
110 static ConfigDriver config_disallows;
111 static ConfigDriver config_requires;
112 static ConfigDriver config_security;
113 static ConfigDriver config_referral;
114 static ConfigDriver config_loglevel;
115 static ConfigDriver config_syncrepl;
116 static ConfigDriver config_replica;
117 static ConfigDriver config_updatedn;
118 static ConfigDriver config_updateref;
119 static ConfigDriver config_include;
121 static ConfigDriver config_tls_option;
122 static ConfigDriver config_tls_config;
171 static OidRec OidMacros[] = {
172 /* OpenLDAProot:666.11.1 */
173 { "OLcfg", "1.3.6.1.4.1.4203.666.11.1" },
174 { "OLcfgAt", "OLcfg:3" },
175 { "OLcfgOc", "OLcfg:4" },
176 { "OMsyn", "1.3.6.1.4.1.1466.115.121.1" },
177 { "OMsInteger", "OMsyn:2" },
178 { "OMsBoolean", "OMsyn:7" },
179 { "OMsDN", "OMsyn:12" },
180 { "OMsDirectoryString", "OMsyn:15" },
181 { "OMsOctetString", "OMsyn:40" },
185 /* alphabetical ordering */
187 ConfigTable config_back_cf_table[] = {
188 /* This attr is read-only */
189 { "", "", 0, 0, 0, ARG_MAGIC,
190 &config_fname, "( OLcfgAt:78 NAME 'olcConfigFile' "
191 "DESC 'File for slapd configuration directives' "
192 "EQUALITY caseIgnoreMatch "
193 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
194 { "access", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC|CFG_ACL,
195 &config_generic, "( OLcfgAt:1 NAME 'olcAccess' "
196 "DESC 'Access Control List' "
197 "EQUALITY caseIgnoreMatch "
198 "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
199 { "allows", "features", 2, 0, 5, ARG_PRE_DB|ARG_MAGIC,
200 &config_allows, "( OLcfgAt:2 NAME 'olcAllows' "
201 "DESC 'Allowed set of deprecated features' "
202 "EQUALITY caseIgnoreMatch "
203 "SYNTAX OMsDirectoryString )", NULL, NULL },
204 { "argsfile", "file", 2, 2, 0, ARG_STRING,
205 &slapd_args_file, "( OLcfgAt:3 NAME 'olcArgsFile' "
206 "DESC 'File for slapd command line options' "
207 "EQUALITY caseIgnoreMatch "
208 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
209 /* Use standard 'attributeTypes' attr */
210 { "attribute", "attribute", 2, 0, 9, ARG_PAREN|ARG_MAGIC|CFG_ATTR,
211 &config_generic, NULL, NULL, NULL },
212 { "attributeoptions", NULL, 0, 0, 0, ARG_MAGIC|CFG_ATOPT,
213 &config_generic, "( OLcfgAt:5 NAME 'olcAttributeOptions' "
214 "EQUALITY caseIgnoreMatch "
215 "SYNTAX OMsDirectoryString )", NULL, NULL },
216 { "authid-rewrite", NULL, 2, 0, 0,
217 #ifdef SLAP_AUTH_REWRITE
218 ARG_MAGIC|CFG_REWRITE, &config_generic,
222 "( OLcfgAt:6 NAME 'olcAuthIDRewrite' "
223 "EQUALITY caseIgnoreMatch "
224 "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
225 { "authz-policy", "policy", 2, 2, 0, ARG_STRING|ARG_MAGIC|CFG_AZPOLICY,
226 &config_generic, "( OLcfgAt:7 NAME 'olcAuthzPolicy' "
227 "EQUALITY caseIgnoreMatch "
228 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
229 { "authz-regexp", NULL, 3, 3, 0, ARG_MAGIC|CFG_AZREGEXP,
230 &config_generic, "( OLcfgAt:8 NAME 'olcAuthzRegexp' "
231 "EQUALITY caseIgnoreMatch "
232 "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
233 { "backend", "type", 2, 2, 0, ARG_PRE_DB|ARG_MAGIC|CFG_BACKEND,
234 &config_generic, "( OLcfgAt:9 NAME 'olcBackend' "
235 "DESC 'A type of backend' "
236 "EQUALITY caseIgnoreMatch "
237 "SYNTAX OMsDirectoryString )", NULL, NULL },
238 { "concurrency", "level", 2, 2, 0, ARG_INT|ARG_NONZERO|ARG_MAGIC|CFG_CONCUR,
239 &config_generic, "( OLcfgAt:10 NAME 'olcConcurrency' "
240 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
241 { "conn_max_pending", "max", 2, 2, 0, ARG_LONG,
242 &slap_conn_max_pending, "( OLcfgAt:11 NAME 'olcConnMaxPending' "
243 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
244 { "conn_max_pending_auth", "max", 2, 2, 0, ARG_LONG,
245 &slap_conn_max_pending_auth, "( OLcfgAt:12 NAME 'olcConnMaxPendingAuth' "
246 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
247 { "database", "type", 2, 2, 0, ARG_MAGIC|CFG_DATABASE,
248 &config_generic, "( OLcfgAt:13 NAME 'olcDatabase' "
249 "DESC 'The backend type for a database instance' "
250 "SUP olcBackend )", NULL, NULL },
251 { "defaultSearchBase", "dn", 2, 2, 0, ARG_PRE_BI|ARG_PRE_DB|ARG_DN|ARG_MAGIC,
252 &config_search_base, "( OLcfgAt:14 NAME 'olcDefaultSearchBase' "
253 "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
254 { "disallows", "features", 2, 0, 8, ARG_PRE_DB|ARG_MAGIC,
255 &config_disallows, "( OLcfgAt:15 NAME 'olcDisallows' "
256 "EQUALITY caseIgnoreMatch "
257 "SYNTAX OMsDirectoryString )", NULL, NULL },
258 /* use standard schema */
259 { "ditcontentrule", NULL, 0, 0, 0, ARG_MAGIC|CFG_DIT,
260 &config_generic, NULL, NULL, NULL },
261 { "gentlehup", "on|off", 2, 2, 0,
263 ARG_ON_OFF, &global_gentlehup,
267 "( OLcfgAt:17 NAME 'olcGentleHUP' "
268 "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
269 { "idletimeout", "timeout", 2, 2, 0, ARG_INT,
270 &global_idletimeout, "( OLcfgAt:18 NAME 'olcIdleTimeout' "
271 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
272 /* XXX -- special case? */
273 { "include", "file", 2, 2, 0, ARG_MAGIC,
274 &config_include, "( OLcfgAt:19 NAME 'olcInclude' "
275 "SUP labeledURI )", NULL, NULL },
276 { "index_substr_if_minlen", "min", 2, 2, 0, ARG_INT|ARG_NONZERO|ARG_MAGIC|CFG_SSTR_IF_MIN,
277 &config_generic, "( OLcfgAt:20 NAME 'olcIndexSubstrIfMinLen' "
278 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
279 { "index_substr_if_maxlen", "max", 2, 2, 0, ARG_INT|ARG_NONZERO|ARG_MAGIC|CFG_SSTR_IF_MAX,
280 &config_generic, "( OLcfgAt:21 NAME 'olcIndexSubstrIfMaxLen' "
281 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
282 { "index_substr_any_len", "len", 2, 2, 0, ARG_INT|ARG_NONZERO,
283 &index_substr_any_len, "( OLcfgAt:22 NAME 'olcIndexSubstrAnyLen' "
284 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
285 { "index_substr_step", "step", 2, 2, 0, ARG_INT|ARG_NONZERO,
286 &index_substr_any_step, "( OLcfgAt:23 NAME 'olcIndexSubstrAnyStep' "
287 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
288 { "lastmod", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_LASTMOD,
289 &config_generic, "( OLcfgAt:24 NAME 'olcLastMod' "
290 "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
291 { "limits", "limits", 2, 0, 0, ARG_DB|ARG_MAGIC|CFG_LIMITS,
292 &config_generic, "( OLcfgAt:25 NAME 'olcLimits' "
293 "SYNTAX OMsDirectoryString )", NULL, NULL },
294 { "localSSF", "ssf", 2, 2, 0, ARG_LONG,
295 &local_ssf, "( OLcfgAt:26 NAME 'olcLocalSSF' "
296 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
297 { "logfile", "file", 2, 2, 0, ARG_STRING|ARG_MAGIC|CFG_LOGFILE,
298 &config_generic, "( OLcfgAt:27 NAME 'olcLogFile' "
299 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
300 { "loglevel", "level", 2, 0, 0, ARG_MAGIC,
301 &config_loglevel, "( OLcfgAt:28 NAME 'olcLogLevel' "
302 "SYNTAX OMsDirectoryString )", NULL, NULL },
303 { "maxDerefDepth", "depth", 2, 2, 0, ARG_DB|ARG_INT|ARG_MAGIC|CFG_DEPTH,
304 &config_generic, "( OLcfgAt:29 NAME 'olcMaxDerefDepth' "
305 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
306 { "moduleload", "file", 2, 0, 0,
308 ARG_MAGIC|CFG_MODLOAD, &config_generic,
312 "( OLcfgAt:30 NAME 'olcModuleLoad' "
313 "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
314 { "modulepath", "path", 2, 2, 0,
316 ARG_MAGIC|CFG_MODPATH, &config_generic,
320 "( OLcfgAt:31 NAME 'olcModulePath' "
321 "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
322 /* use standard schema */
323 { "objectclass", "objectclass", 2, 0, 0, ARG_PAREN|ARG_MAGIC|CFG_OC,
324 &config_generic, NULL, NULL, NULL },
325 { "objectidentifier", NULL, 0, 0, 0, ARG_MAGIC|CFG_OID,
326 &config_generic, "( OLcfgAt:33 NAME 'olcObjectIdentifier' "
327 "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
328 { "overlay", "overlay", 2, 2, 0, ARG_MAGIC,
329 &config_overlay, "( OLcfgAt:34 NAME 'olcOverlay' "
330 "SUP olcDatabase )", NULL, NULL },
331 { "password-crypt-salt-format", "salt", 2, 2, 0, ARG_STRING|ARG_MAGIC|CFG_SALT,
332 &config_generic, "( OLcfgAt:35 NAME 'olcPasswordCryptSaltFormat' "
333 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
334 { "password-hash", "hash", 2, 2, 0, ARG_MAGIC,
335 &config_passwd_hash, "( OLcfgAt:36 NAME 'olcPasswordHash' "
336 "SYNTAX OMsDirectoryString )", NULL, NULL },
337 { "pidfile", "file", 2, 2, 0, ARG_STRING,
338 &slapd_pid_file, "( OLcfgAt:37 NAME 'olcPidFile' "
339 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
340 { "plugin", NULL, 0, 0, 0,
342 ARG_MAGIC|CFG_PLUGIN, &config_generic,
346 "( OLcfgAt:38 NAME 'olcPlugin' "
347 "SYNTAX OMsDirectoryString )", NULL, NULL },
348 { "pluginlog", "filename", 2, 2, 0,
350 ARG_STRING, &slapi_log_file,
354 "( OLcfgAt:39 NAME 'olcPluginLogFile' "
355 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
356 { "readonly", "on|off", 2, 2, 0, ARG_MAY_DB|ARG_ON_OFF|ARG_MAGIC|CFG_RO,
357 &config_generic, "( OLcfgAt:40 NAME 'olcReadOnly' "
358 "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
359 { "referral", "url", 2, 2, 0, ARG_MAGIC,
360 &config_referral, "( OLcfgAt:41 NAME 'olcReferral' "
361 "SUP labeledURI SINGLE-VALUE )", NULL, NULL },
362 { "replica", "host or uri", 2, 0, 0, ARG_DB|ARG_MAGIC,
363 &config_replica, "( OLcfgAt:42 NAME 'olcReplica' "
364 "SUP labeledURI )", NULL, NULL },
365 { "replica-argsfile", NULL, 0, 0, 0, ARG_STRING,
366 &replica_argsFile, "( OLcfgAt:43 NAME 'olcReplicaArgsFile' "
367 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
368 { "replica-pidfile", NULL, 0, 0, 0, ARG_STRING,
369 &replica_pidFile, "( OLcfgAt:44 NAME 'olcReplicaPidFile' "
370 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
371 { "replicationInterval", NULL, 0, 0, 0, ARG_INT,
372 &replicationInterval, "( OLcfgAt:45 NAME 'olcReplicationInterval' "
373 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
374 { "replogfile", "filename", 2, 2, 0, ARG_MAY_DB|ARG_MAGIC|ARG_STRING|CFG_REPLOG,
375 &config_generic, "( OLcfgAt:46 NAME 'olcReplogFile' "
376 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
377 { "require", "features", 2, 0, 7, ARG_MAY_DB|ARG_MAGIC,
378 &config_requires, "( OLcfgAt:47 NAME 'olcRequires' "
379 "SYNTAX OMsDirectoryString )", NULL, NULL },
380 { "restrict", "op_list", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
381 &config_restrict, "( OLcfgAt:48 NAME 'olcRestrict' "
382 "SYNTAX OMsDirectoryString )", NULL, NULL },
383 { "reverse-lookup", "on|off", 2, 2, 0,
384 #ifdef SLAPD_RLOOKUPS
385 ARG_ON_OFF, &use_reverse_lookup,
389 "( OLcfgAt:49 NAME 'olcReverseLookup' "
390 "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
391 { "rootdn", "dn", 2, 2, 0, ARG_DB|ARG_DN|ARG_MAGIC,
392 &config_rootdn, "( OLcfgAt:50 NAME 'olcRootDN' "
393 "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
394 { "rootDSE", "file", 2, 2, 0, ARG_MAGIC|CFG_ROOTDSE,
395 &config_generic, "( OLcfgAt:51 NAME 'olcRootDSE' "
396 "SYNTAX OMsDirectoryString )", NULL, NULL },
397 { "rootpw", "password", 2, 2, 0, ARG_STRING|ARG_DB|ARG_MAGIC,
398 &config_rootpw, "( OLcfgAt:52 NAME 'olcRootPW' "
399 "SYNTAX OMsOctetString SINGLE-VALUE )", NULL, NULL },
400 { "sasl-authz-policy", NULL, 2, 2, 0, ARG_MAGIC|CFG_AZPOLICY,
401 &config_generic, NULL, NULL, NULL },
402 { "sasl-host", "host", 2, 2, 0,
403 #ifdef HAVE_CYRUS_SASL
404 ARG_STRING|ARG_UNIQUE, &global_host,
408 "( OLcfgAt:53 NAME 'olcSaslHost' "
409 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
410 { "sasl-realm", "realm", 2, 2, 0,
411 #ifdef HAVE_CYRUS_SASL
412 ARG_STRING|ARG_UNIQUE, &global_realm,
416 "( OLcfgAt:54 NAME 'olcSaslRealm' "
417 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
418 { "sasl-regexp", NULL, 3, 3, 0, ARG_MAGIC|CFG_AZREGEXP,
419 &config_generic, NULL, NULL, NULL },
420 { "sasl-secprops", "properties", 2, 2, 0,
421 #ifdef HAVE_CYRUS_SASL
422 ARG_MAGIC|CFG_SASLSECP, &config_generic,
426 "( OLcfgAt:56 NAME 'olcSaslSecProps' "
427 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
428 { "saslRegexp", NULL, 3, 3, 0, ARG_MAGIC|CFG_AZREGEXP,
429 &config_generic, NULL, NULL, NULL },
430 { "schemacheck", "on|off", 2, 2, 0, ARG_ON_OFF|ARG_MAGIC|CFG_CHECK,
431 &config_generic, "( OLcfgAt:57 NAME 'olcSchemaCheck' "
432 "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
433 { "schemadn", "dn", 2, 2, 0, ARG_MAY_DB|ARG_DN|ARG_MAGIC,
434 &config_schema_dn, "( OLcfgAt:58 NAME 'olcSchemaDN' "
435 "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
436 { "security", "factors", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
437 &config_security, "( OLcfgAt:59 NAME 'olcSecurity' "
438 "SYNTAX OMsDirectoryString )", NULL, NULL },
439 { "sizelimit", "limit", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC|CFG_SIZE,
440 &config_sizelimit, "( OLcfgAt:60 NAME 'olcSizeLimit' "
441 "SYNTAX OMsInteger )", NULL, NULL },
442 { "sockbuf_max_incoming", "max", 2, 2, 0, ARG_LONG,
443 &sockbuf_max_incoming, "( OLcfgAt:61 NAME 'olcSockbufMaxIncoming' "
444 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
445 { "sockbuf_max_incoming_auth", "max", 2, 2, 0, ARG_LONG,
446 &sockbuf_max_incoming_auth, "( OLcfgAt:62 NAME 'olcSockbufMaxIncomingAuth' "
447 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
448 { "srvtab", "file", 2, 2, 0,
449 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
450 ARG_STRING, &ldap_srvtab,
454 "( OLcfgAt:63 NAME 'olcSrvtab' "
455 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
456 { "suffix", "suffix", 2, 2, 0, ARG_DB|ARG_DN|ARG_MAGIC,
457 &config_suffix, "( OLcfgAt:64 NAME 'olcSuffix' "
458 "SYNTAX OMsDN )", NULL, NULL },
459 { "syncrepl", NULL, 0, 0, 0, ARG_DB|ARG_MAGIC,
460 &config_syncrepl, "( OLcfgAt:65 NAME 'olcSyncrepl' "
461 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
462 { "threads", "count", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_THREADS,
463 &config_generic, "( OLcfgAt:66 NAME 'olcThreads' "
464 "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
465 { "timelimit", "limit", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC|CFG_TIME,
466 &config_timelimit, "( OLcfgAt:67 NAME 'olcTimeLimit' "
467 "SYNTAX OMsInteger )", NULL, NULL },
468 { "TLSCACertificateFile", NULL, 0, 0, 0,
470 CFG_TLS_CA_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
474 "( OLcfgAt:68 NAME 'olcTLSCACertificateFile' "
475 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
476 { "TLSCACertificatePath", NULL, 0, 0, 0,
478 CFG_TLS_CA_PATH|ARG_STRING|ARG_MAGIC, &config_tls_option,
482 "( OLcfgAt:69 NAME 'olcTLSCACertificatePath' "
483 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
484 { "TLSCertificateFile", NULL, 0, 0, 0,
486 CFG_TLS_CERT_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
490 "( OLcfgAt:70 NAME 'olcTLSCertificateFile' "
491 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
492 { "TLSCertificateKeyFile", NULL, 0, 0, 0,
494 CFG_TLS_CERT_KEY|ARG_STRING|ARG_MAGIC, &config_tls_option,
498 "( OLcfgAt:71 NAME 'olcTLSCertificateKeyFile' "
499 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
500 { "TLSCipherSuite", NULL, 0, 0, 0,
502 CFG_TLS_CIPHER|ARG_STRING|ARG_MAGIC, &config_tls_option,
506 "( OLcfgAt:72 NAME 'olcTLSCipherSuite' "
507 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
508 { "TLSCRLCheck", NULL, 0, 0, 0,
510 CFG_TLS_CRLCHECK|ARG_STRING|ARG_MAGIC, &config_tls_config,
514 "( OLcfgAt:73 NAME 'olcTLSCRLCheck' "
515 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
516 { "TLSRandFile", NULL, 0, 0, 0,
518 CFG_TLS_RAND|ARG_STRING|ARG_MAGIC, &config_tls_option,
522 "( OLcfgAt:74 NAME 'olcTLSRandFile' "
523 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
524 { "TLSVerifyClient", NULL, 0, 0, 0,
526 CFG_TLS_VERIFY|ARG_STRING|ARG_MAGIC, &config_tls_config,
530 "( OLcfgAt:75 NAME 'olcTLSVerifyClient' "
531 "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
532 { "ucdata-path", "path", 2, 2, 0, ARG_IGNORED,
533 NULL, NULL, NULL, NULL },
534 { "updatedn", "dn", 2, 2, 0, ARG_DB|ARG_MAGIC,
535 &config_updatedn, "( OLcfgAt:76 NAME 'olcUpdateDN' "
536 "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
537 { "updateref", "url", 2, 2, 0, ARG_DB|ARG_MAGIC,
538 &config_updateref, "( OLcfgAt:77 NAME 'olcUpdateRef' "
539 "SUP labeledURI )", NULL, NULL },
540 { NULL, NULL, 0, 0, 0, ARG_IGNORED,
541 NULL, NULL, NULL, NULL }
544 static ConfigOCs cf_ocs[] = {
547 "DESC 'OpenLDAP configuration object' "
549 "MAY ( cn $ olcConfigFile ) )", NULL },
552 "DESC 'OpenLDAP Global configuration options' "
553 "SUP olcConfig STRUCTURAL "
554 "MAY ( olcAllows $ olcArgsFile $ olcAttributeOptions $ "
555 "olcAuthIDRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ "
556 "olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ "
557 "olcDefaultSearchBase $ olcDisallows $ olcGentleHUP $ "
558 "olcIdleTimeout $ olcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ "
559 "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcLocalSSF $ "
560 "olcLogLevel $ olcModuleLoad $ olcModulePath $ olcObjectIdentifier $ "
561 "olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ "
562 "olcPlugin $ olcPluginLogFile $ olcReadOnly $ olcReferral $ "
563 "olcReplicaPidFile $ olcReplicaArgsFile $ olcReplicationInterval $ "
564 "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
565 "olcRootDSE $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
566 "olcSchemaCheck $ olcSchemaDN $ olcSecurity $ olcSizeLimit $ "
567 "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcSrvtab $ "
568 "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
569 "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
570 "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
571 "olcTLSRandFile $ olcTLSVerifyClient ) )", &cfOc_global },
573 "NAME 'olcBackendConfig' "
574 "DESC 'OpenLDAP Backend-specific options' "
575 "SUP olcConfig STRUCTURAL "
576 "MAY ( olcBackend ) )", &cfOc_backend },
578 "NAME 'olcDatabaseConfig' "
579 "DESC 'OpenLDAP Database-specific options' "
580 "SUP olcConfig STRUCTURAL "
581 "MAY ( olcDatabase $ olcAccess $ olcLastMod $ olcLimits $ "
582 "olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ "
583 "olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
584 "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSuffix $ olcSyncrepl $ "
585 "olcTimeLimit $ olcUpdateDN $ olcUpdateRef ) )", &cfOc_database },
587 "NAME 'olcIncludeFile' "
588 "DESC 'OpenLDAP configuration include file' "
589 "SUP olcConfig STRUCTURAL "
590 "MAY ( olcInclude $ olcModuleLoad $ olcModulePath $ olcRootDSE ) )",
593 "NAME 'olcOverlayConfig' "
594 "DESC 'OpenLDAP Overlay-specific options' "
595 "SUP olcConfig STRUCTURAL "
596 "MAY ( olcOverlay ) )", &cfOc_overlay },
599 "DESC 'OpenLDAP Access Control List' "
600 "SUP olcConfig STRUCTURAL "
601 "MUST ( olcAccess ) )", &cfOc_access },
606 config_generic(ConfigArgs *c) {
614 c->value_int = ldap_pvt_thread_get_concurrency();
617 c->value_int = connection_pool_max;
621 c->value_string = ch_strdup( passwd_salt );
626 if ( c->be->be_limits ) {
631 for ( i=0; c->be->be_limits[i]; i++ ) {
632 bv.bv_len = sprintf( buf, "{%d}", i );
633 bv.bv_val = buf+bv.bv_len;
634 limits_unparse( c->be->be_limits[i], &bv );
635 bv.bv_len += bv.bv_val - buf;
637 value_add_one( &c->rvalue_vals, &bv );
640 if ( !c->rvalue_vals ) rc = 1;
643 c->value_int = (c->be->be_restrictops & SLAP_RESTRICT_OP_WRITES) != 0;
646 c->value_string = ch_strdup( slap_sasl_getpolicy());
649 slap_sasl_regexp_unparse( &c->rvalue_vals );
650 if ( !c->rvalue_vals ) rc = 1;
652 #ifdef HAVE_CYRUS_SASL
654 struct berval bv = BER_BVNULL;
655 slap_sasl_secprops_unparse( &bv );
656 if ( !BER_BVISNULL( &bv )) {
657 ber_bvarray_add( &c->rvalue_vals, &bv );
665 c->value_int = c->be->be_max_deref_depth;
668 oidm_unparse( &c->rvalue_vals );
669 if ( !c->rvalue_vals )
673 c->value_int = global_schemacheck;
677 char *src, *dst, ibuf[11];
678 struct berval bv, abv;
679 for (i=0, a=c->be->be_acl; a; i++,a=a->acl_next) {
680 abv.bv_len = sprintf( ibuf, "{%x}", i );
681 acl_unparse( a, &bv );
682 abv.bv_val = ch_malloc( abv.bv_len + bv.bv_len + 1 );
683 AC_MEMCPY( abv.bv_val, ibuf, abv.bv_len );
684 /* Turn TAB / EOL into plain space */
685 for (src=bv.bv_val,dst=abv.bv_val+abv.bv_len; *src; src++) {
686 if (isspace(*src)) *dst++ = ' ';
690 if (dst[-1] == ' ') {
694 abv.bv_len = dst - abv.bv_val;
695 ber_bvarray_add( &c->rvalue_vals, &abv );
701 if ( c->be->be_replogfile )
702 c->value_string = ch_strdup( c->be->be_replogfile );
705 ConfigFile *cf = (ConfigFile *)c->line;
706 if ( cf->c_dseFiles ) {
707 value_add( &c->rvalue_vals, cf->c_dseFiles );
715 c->value_string = ch_strdup( logfileName );
720 c->value_int = (SLAP_NOLASTMOD(c->be) == 0);
722 case CFG_SSTR_IF_MAX:
723 c->value_int = index_substr_if_maxlen;
725 case CFG_SSTR_IF_MIN:
726 c->value_int = index_substr_if_minlen;
730 ConfigFile *cf = (ConfigFile *)c->line;
732 for (i=0, mp=&cf->c_modpaths; mp; mp=mp->mp_next, i++) {
734 if (!mp->mp_loads) continue;
735 for (j=0; !BER_BVISNULL(&mp->mp_loads[j]); j++) {
738 bv.bv_len = sprintf( bv.bv_val, "{%d}{%d}%s", i, j,
739 mp->mp_loads[j].bv_val );
740 value_add_one( &c->rvalue_vals, &bv );
743 rc = c->rvalue_vals ? 0 : 1;
747 ConfigFile *cf = (ConfigFile *)c->line;
749 for (i=0, mp=&cf->c_modpaths; mp; mp=mp->mp_next, i++) {
751 if ( BER_BVISNULL( &mp->mp_path ) && !mp->mp_loads )
754 bv.bv_len = sprintf( bv.bv_val, "{%d}%s", i,
755 mp->mp_path.bv_val );
756 value_add_one( &c->rvalue_vals, &bv );
758 rc = c->rvalue_vals ? 0 : 1;
764 slapi_int_plugin_unparse( c->be, &c->rvalue_vals );
765 if ( !c->rvalue_vals ) rc = 1;
768 #ifdef SLAP_AUTH_REWRITE
770 if ( authz_rewrites ) {
771 struct berval bv, idx;
776 for ( i=0; !BER_BVISNULL( &authz_rewrites[i] ); i++ ) {
777 idx.bv_len = sprintf( idx.bv_val, "{%d}", i );
778 bv.bv_len = idx.bv_len + authz_rewrites[i].bv_len;
779 bv.bv_val = ch_malloc( bv.bv_len + 1 );
780 strcpy( bv.bv_val, idx.bv_val );
781 strcpy( bv.bv_val+idx.bv_len, authz_rewrites[i].bv_val );
782 ber_bvarray_add( &c->rvalue_vals, &bv );
785 if ( !c->rvalue_vals ) rc = 1;
794 p = strchr(c->line,'(' /*')'*/);
797 if(!(c->bi = backend_info(c->argv[1]))) {
798 Debug(LDAP_DEBUG_ANY, "%s: "
799 "backend %s failed init!\n", c->log, c->argv[1], 0);
806 /* NOTE: config is always the first backend!
808 if ( !strcasecmp( c->argv[1], "config" )) {
810 } else if(!(c->be = backend_db_init(c->argv[1]))) {
811 Debug(LDAP_DEBUG_ANY, "%s: "
812 "database %s failed init!\n", c->log, c->argv[1], 0);
818 ldap_pvt_thread_set_concurrency(c->value_int);
822 ldap_pvt_thread_pool_maxthreads(&connection_pool, c->value_int);
823 connection_pool_max = c->value_int; /* save for reference */
827 if ( passwd_salt ) ch_free( passwd_salt );
828 passwd_salt = c->value_string;
829 lutil_salt_format(passwd_salt);
833 if(limits_parse(c->be, c->fname, c->lineno, c->argc, c->argv))
839 c->be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
841 c->be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
845 ch_free(c->value_string);
846 if (slap_sasl_setpolicy( c->argv[1] )) {
847 Debug(LDAP_DEBUG_ANY, "%s: unable to parse value \"%s\" in"
848 " \"authz-policy <policy>\"\n",
849 c->log, c->argv[1], 0 );
855 if (slap_sasl_regexp_config( c->argv[1], c->argv[2] ))
859 #ifdef HAVE_CYRUS_SASL
862 char *txt = slap_sasl_secprops( c->argv[1] );
864 Debug(LDAP_DEBUG_ANY, "%s: sasl-secprops: %s\n",
873 c->be->be_max_deref_depth = c->value_int;
877 if(parse_oidm(c->fname, c->lineno, c->argc, c->argv)) return(1);
881 if(parse_oc(c->fname, c->lineno, p, c->argv)) return(1);
885 if(parse_cr(c->fname, c->lineno, p, c->argv)) return(1);
889 if(parse_at(c->fname, c->lineno, p, c->argv)) return(1);
893 ad_define_option(NULL, NULL, 0);
894 for(i = 1; i < c->argc; i++)
895 if(ad_define_option(c->argv[i], c->fname, c->lineno))
900 global_schemacheck = c->value_int;
901 if(!global_schemacheck) Debug(LDAP_DEBUG_ANY, "%s: "
902 "schema checking disabled! your mileage may vary!\n",
907 parse_acl(c->be, c->fname, c->lineno, c->argc, c->argv);
911 if(SLAP_MONITOR(c->be)) {
912 Debug(LDAP_DEBUG_ANY, "%s: "
913 "\"replogfile\" should not be used "
914 "inside monitor database\n",
916 return(0); /* FIXME: should this be an error? */
919 c->be->be_replogfile = c->value_string;
923 if(read_root_dse_file(c->argv[1])) {
924 Debug(LDAP_DEBUG_ANY, "%s: "
925 "could not read \"rootDSE <filename>\" line\n",
931 ber_str2bv( c->argv[1], 0, 1, &bv );
932 ber_bvarray_add( &cfn->c_dseFiles, &bv );
938 if ( logfileName ) ch_free( logfileName );
939 logfileName = c->value_string;
940 logfile = fopen(logfileName, "w");
941 if(logfile) lutil_debug_file(logfile);
945 if(SLAP_NOLASTMODCMD(c->be)) {
946 Debug(LDAP_DEBUG_ANY, "%s: "
947 "lastmod not available for %s databases\n",
948 c->log, c->be->bd_info->bi_type, 0);
952 SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_NOLASTMOD;
954 SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_NOLASTMOD;
957 case CFG_SSTR_IF_MAX:
958 if (c->value_int < index_substr_if_minlen) {
959 Debug(LDAP_DEBUG_ANY, "%s: "
960 "invalid max value (%d)\n",
961 c->log, c->value_int, 0 );
964 index_substr_if_maxlen = c->value_int;
967 case CFG_SSTR_IF_MIN:
968 if (c->value_int > index_substr_if_maxlen) {
969 Debug(LDAP_DEBUG_ANY, "%s: "
970 "invalid min value (%d)\n",
971 c->log, c->value_int, 0 );
974 index_substr_if_minlen = c->value_int;
979 if(module_load(c->argv[1], c->argc - 2, (c->argc > 2) ? c->argv + 2 : NULL))
981 /* Record this load on the current path */
984 ber_str2bv(c->line, 0, 1, &bv);
985 ber_bvarray_add( &cfn->c_modlast->mp_loads, &bv );
990 if(module_path(c->argv[1])) return(1);
991 /* Record which path was used with each module */
995 if (!cfn->c_modpaths.mp_loads) {
996 mp = &cfn->c_modpaths;
998 mp = ch_malloc( sizeof( ModPaths ));
999 cfn->c_modlast->mp_next = mp;
1001 ber_str2bv(c->argv[1], 0, 1, &mp->mp_path);
1003 mp->mp_loads = NULL;
1004 cfn->c_modlast = mp;
1012 if(slapi_int_read_config(c->be, c->fname, c->lineno, c->argc, c->argv) != LDAP_SUCCESS)
1014 slapi_plugins_used++;
1018 #ifdef SLAP_AUTH_REWRITE
1021 if(slap_sasl_rewrite_config(c->fname, c->lineno, c->argc, c->argv))
1023 ber_str2bv( c->line, 0, 1, &bv );
1024 ber_bvarray_add( &authz_rewrites, &bv );
1031 Debug(LDAP_DEBUG_ANY, "%s: unknown CFG_TYPE %d"
1032 "(ignored)\n", c->log, c->type, 0);
1040 config_fname(ConfigArgs *c) {
1041 if(c->emit && c->line) {
1042 ConfigFile *cf = (ConfigFile *)c->line;
1043 value_add_one( &c->rvalue_vals, &cf->c_file );
1050 config_search_base(ConfigArgs *c) {
1055 if (!BER_BVISEMPTY(&default_search_base)) {
1056 value_add_one(&c->rvalue_vals, &default_search_base);
1057 value_add_one(&c->rvalue_nvals, &default_search_nbase);
1063 if(c->bi || c->be != frontendDB) {
1064 Debug(LDAP_DEBUG_ANY, "%s: defaultSearchBase line must appear "
1065 "prior to any backend or database definition\n",
1070 if(default_search_nbase.bv_len) {
1071 Debug(LDAP_DEBUG_ANY, "%s: "
1072 "default search base \"%s\" already defined "
1073 "(discarding old)\n",
1074 c->log, default_search_base.bv_val, 0);
1075 free(default_search_base.bv_val);
1076 free(default_search_nbase.bv_val);
1079 default_search_base = c->value_dn;
1080 default_search_nbase = c->value_ndn;
1085 config_passwd_hash(ConfigArgs *c) {
1089 for (i=0; default_passwd_hash && default_passwd_hash[i]; i++) {
1090 ber_str2bv(default_passwd_hash[i], 0, 0, &bv);
1091 value_add_one(&c->rvalue_vals, &bv);
1095 if(default_passwd_hash) {
1096 Debug(LDAP_DEBUG_ANY, "%s: "
1097 "already set default password_hash\n",
1101 for(i = 1; i < c->argc; i++) {
1102 if(!lutil_passwd_scheme(c->argv[i])) {
1103 Debug(LDAP_DEBUG_ANY, "%s: "
1104 "password scheme \"%s\" not available\n",
1105 c->log, c->argv[i], 0);
1107 ldap_charray_add(&default_passwd_hash, c->argv[i]);
1109 if(!default_passwd_hash) {
1110 Debug(LDAP_DEBUG_ANY, "%s: no valid hashes found\n",
1119 config_schema_dn(ConfigArgs *c) {
1123 value_add_one(&c->rvalue_vals, &c->be->be_schemadn);
1124 value_add_one(&c->rvalue_nvals, &c->be->be_schemandn);
1127 c->be->be_schemadn = c->value_dn;
1128 c->be->be_schemandn = c->value_ndn;
1133 config_sizelimit(ConfigArgs *c) {
1136 struct slap_limits_set *lim = &c->be->be_def_limit;
1142 limits_unparse_one( lim, SLAP_LIMIT_SIZE, &bv );
1143 if ( !BER_BVISEMPTY( &bv ))
1144 value_add_one( &c->rvalue_vals, &bv );
1149 for(i = 1; i < c->argc; i++) {
1150 if(!strncasecmp(c->argv[i], "size", 4)) {
1151 rc = limits_parse_one(c->argv[i], lim);
1153 Debug(LDAP_DEBUG_ANY, "%s: "
1154 "unable to parse value \"%s\" in \"sizelimit <limit>\" line\n",
1155 c->log, c->argv[i], 0);
1159 if(!strcasecmp(c->argv[i], "unlimited")) {
1160 lim->lms_s_soft = -1;
1162 lim->lms_s_soft = strtol(c->argv[i], &next, 0);
1163 if(next == c->argv[i]) {
1164 Debug(LDAP_DEBUG_ANY, "%s: "
1165 "unable to parse limit \"%s\" in \"sizelimit <limit>\" line\n",
1166 c->log, c->argv[i], 0);
1168 } else if(next[0] != '\0') {
1169 Debug(LDAP_DEBUG_ANY, "%s: "
1170 "trailing chars \"%s\" in \"sizelimit <limit>\" line (ignored)\n",
1174 lim->lms_s_hard = 0;
1181 config_timelimit(ConfigArgs *c) {
1184 struct slap_limits_set *lim = &c->be->be_def_limit;
1190 limits_unparse_one( lim, SLAP_LIMIT_TIME, &bv );
1191 if ( !BER_BVISEMPTY( &bv ))
1192 value_add_one( &c->rvalue_vals, &bv );
1197 for(i = 1; i < c->argc; i++) {
1198 if(!strncasecmp(c->argv[i], "time", 4)) {
1199 rc = limits_parse_one(c->argv[i], lim);
1201 Debug(LDAP_DEBUG_ANY, "%s: "
1202 "unable to parse value \"%s\" in \"timelimit <limit>\" line\n",
1203 c->log, c->argv[i], 0);
1207 if(!strcasecmp(c->argv[i], "unlimited")) {
1208 lim->lms_t_soft = -1;
1210 lim->lms_t_soft = strtol(c->argv[i], &next, 0);
1211 if(next == c->argv[i]) {
1212 Debug(LDAP_DEBUG_ANY, "%s: "
1213 "unable to parse limit \"%s\" in \"timelimit <limit>\" line\n",
1214 c->log, c->argv[i], 0);
1216 } else if(next[0] != '\0') {
1217 Debug(LDAP_DEBUG_ANY, "%s: "
1218 "trailing chars \"%s\" in \"timelimit <limit>\" line (ignored)\n",
1222 lim->lms_t_hard = 0;
1229 config_overlay(ConfigArgs *c) {
1233 if(c->argv[1][0] == '-' && overlay_config(c->be, &c->argv[1][1])) {
1235 Debug(LDAP_DEBUG_ANY, "%s: (optional) %s overlay \"%s\" configuration failed (ignored)\n",
1236 c->log, c->be == frontendDB ? "global " : "", c->argv[1][1]);
1237 } else if(overlay_config(c->be, c->argv[1])) {
1244 config_suffix(ConfigArgs *c) {
1246 struct berval pdn, ndn;
1249 if ( !BER_BVISNULL( &c->be->be_suffix[0] )) {
1250 value_add( &c->rvalue_vals, c->be->be_suffix );
1251 value_add( &c->rvalue_nvals, c->be->be_nsuffix );
1257 #ifdef SLAPD_MONITOR_DN
1258 if(!strcasecmp(c->argv[1], SLAPD_MONITOR_DN)) {
1259 Debug(LDAP_DEBUG_ANY, "%s: "
1260 "\"%s\" is reserved for monitoring slapd\n",
1261 c->log, SLAPD_MONITOR_DN, 0);
1268 tbe = select_backend(&ndn, 0, 0);
1270 Debug(LDAP_DEBUG_ANY, "%s: suffix already served by this backend! (ignored)\n",
1275 Debug(LDAP_DEBUG_ANY, "%s: suffix already served by a preceding backend \"%s\"\n",
1276 c->log, tbe->be_suffix[0].bv_val, 0);
1280 } else if(pdn.bv_len == 0 && default_search_nbase.bv_len) {
1281 Debug(LDAP_DEBUG_ANY, "%s: suffix DN empty and default search "
1282 "base provided \"%s\" (assuming okay)\n",
1283 c->log, default_search_base.bv_val, 0);
1285 ber_bvarray_add(&c->be->be_suffix, &pdn);
1286 ber_bvarray_add(&c->be->be_nsuffix, &ndn);
1291 config_rootdn(ConfigArgs *c) {
1293 if ( !BER_BVISNULL( &c->be->be_rootdn )) {
1294 value_add_one(&c->rvalue_vals, &c->be->be_rootdn);
1295 value_add_one(&c->rvalue_nvals, &c->be->be_rootndn);
1301 c->be->be_rootdn = c->value_dn;
1302 c->be->be_rootndn = c->value_ndn;
1307 config_rootpw(ConfigArgs *c) {
1310 if (!BER_BVISEMPTY(&c->be->be_rootpw)) {
1311 c->value_string=ch_strdup("*");
1317 tbe = select_backend(&c->be->be_rootndn, 0, 0);
1319 Debug(LDAP_DEBUG_ANY, "%s: "
1320 "rootpw can only be set when rootdn is under suffix\n",
1324 ber_str2bv(c->value_string, 0, 0, &c->be->be_rootpw);
1329 config_restrict(ConfigArgs *c) {
1330 slap_mask_t restrictops = 0;
1332 slap_verbmasks restrictable_ops[] = {
1333 { BER_BVC("bind"), SLAP_RESTRICT_OP_BIND },
1334 { BER_BVC("add"), SLAP_RESTRICT_OP_ADD },
1335 { BER_BVC("modify"), SLAP_RESTRICT_OP_MODIFY },
1336 { BER_BVC("rename"), SLAP_RESTRICT_OP_RENAME },
1337 { BER_BVC("modrdn"), 0 },
1338 { BER_BVC("delete"), SLAP_RESTRICT_OP_DELETE },
1339 { BER_BVC("search"), SLAP_RESTRICT_OP_SEARCH },
1340 { BER_BVC("compare"), SLAP_RESTRICT_OP_COMPARE },
1341 { BER_BVC("read"), SLAP_RESTRICT_OP_READS },
1342 { BER_BVC("write"), SLAP_RESTRICT_OP_WRITES },
1343 { BER_BVC("extended"), SLAP_RESTRICT_OP_EXTENDED },
1344 { BER_BVC("extended=" LDAP_EXOP_START_TLS ), SLAP_RESTRICT_EXOP_START_TLS },
1345 { BER_BVC("extended=" LDAP_EXOP_MODIFY_PASSWD ), SLAP_RESTRICT_EXOP_MODIFY_PASSWD },
1346 { BER_BVC("extended=" LDAP_EXOP_X_WHO_AM_I ), SLAP_RESTRICT_EXOP_WHOAMI },
1347 { BER_BVC("extended=" LDAP_EXOP_X_CANCEL ), SLAP_RESTRICT_EXOP_CANCEL },
1352 return mask_to_verbs( restrictable_ops, c->be->be_restrictops,
1355 i = verbs_to_mask( c->argc, c->argv, restrictable_ops, &restrictops );
1357 Debug(LDAP_DEBUG_ANY, "%s: "
1358 "unknown operation %s in \"restrict <features>\" line\n",
1359 c->log, c->argv[i], 0);
1362 if ( restrictops & SLAP_RESTRICT_OP_EXTENDED )
1363 restrictops &= ~SLAP_RESTRICT_EXOP_MASK;
1364 c->be->be_restrictops |= restrictops;
1369 config_allows(ConfigArgs *c) {
1370 slap_mask_t allows = 0;
1372 slap_verbmasks allowable_ops[] = {
1373 { BER_BVC("bind_v2"), SLAP_ALLOW_BIND_V2 },
1374 { BER_BVC("bind_anon_cred"), SLAP_ALLOW_BIND_ANON_CRED },
1375 { BER_BVC("bind_anon_dn"), SLAP_ALLOW_BIND_ANON_DN },
1376 { BER_BVC("update_anon"), SLAP_ALLOW_UPDATE_ANON },
1380 return mask_to_verbs( allowable_ops, global_allows, &c->rvalue_vals );
1382 i = verbs_to_mask(c->argc, c->argv, allowable_ops, &allows);
1384 Debug(LDAP_DEBUG_ANY, "%s: "
1385 "unknown feature %s in \"allow <features>\" line\n",
1386 c->log, c->argv[i], 0);
1389 global_allows |= allows;
1394 config_disallows(ConfigArgs *c) {
1395 slap_mask_t disallows = 0;
1397 slap_verbmasks disallowable_ops[] = {
1398 { BER_BVC("bind_anon"), SLAP_DISALLOW_BIND_ANON },
1399 { BER_BVC("bind_simple"), SLAP_DISALLOW_BIND_SIMPLE },
1400 { BER_BVC("bind_krb4"), SLAP_DISALLOW_BIND_KRBV4 },
1401 { BER_BVC("tls_2_anon"), SLAP_DISALLOW_TLS_2_ANON },
1402 { BER_BVC("tls_authc"), SLAP_DISALLOW_TLS_AUTHC },
1406 return mask_to_verbs( disallowable_ops, global_disallows, &c->rvalue_vals );
1408 i = verbs_to_mask(c->argc, c->argv, disallowable_ops, &disallows);
1410 Debug(LDAP_DEBUG_ANY, "%s: "
1411 "unknown feature %s in \"disallow <features>\" line\n",
1412 c->log, c->argv[i], 0);
1415 global_disallows |= disallows;
1420 config_requires(ConfigArgs *c) {
1421 slap_mask_t requires = 0;
1423 slap_verbmasks requires_ops[] = {
1424 { BER_BVC("bind"), SLAP_REQUIRE_BIND },
1425 { BER_BVC("LDAPv3"), SLAP_REQUIRE_LDAP_V3 },
1426 { BER_BVC("authc"), SLAP_REQUIRE_AUTHC },
1427 { BER_BVC("sasl"), SLAP_REQUIRE_SASL },
1428 { BER_BVC("strong"), SLAP_REQUIRE_STRONG },
1432 return mask_to_verbs( requires_ops, c->be->be_requires, &c->rvalue_vals );
1434 i = verbs_to_mask(c->argc, c->argv, requires_ops, &requires);
1436 Debug(LDAP_DEBUG_ANY, "%s: "
1437 "unknown feature %s in \"require <features>\" line\n",
1438 c->log, c->argv[i], 0);
1441 c->be->be_requires = requires;
1446 config_loglevel(ConfigArgs *c) {
1449 slap_verbmasks loglevel_ops[] = {
1450 { BER_BVC("Trace"), LDAP_DEBUG_TRACE },
1451 { BER_BVC("Packets"), LDAP_DEBUG_PACKETS },
1452 { BER_BVC("Args"), LDAP_DEBUG_ARGS },
1453 { BER_BVC("Conns"), LDAP_DEBUG_CONNS },
1454 { BER_BVC("BER"), LDAP_DEBUG_BER },
1455 { BER_BVC("Filter"), LDAP_DEBUG_FILTER },
1456 { BER_BVC("Config"), LDAP_DEBUG_CONFIG },
1457 { BER_BVC("ACL"), LDAP_DEBUG_ACL },
1458 { BER_BVC("Stats"), LDAP_DEBUG_STATS },
1459 { BER_BVC("Stats2"), LDAP_DEBUG_STATS2 },
1460 { BER_BVC("Shell"), LDAP_DEBUG_SHELL },
1461 { BER_BVC("Parse"), LDAP_DEBUG_PARSE },
1462 { BER_BVC("Cache"), LDAP_DEBUG_CACHE },
1463 { BER_BVC("Index"), LDAP_DEBUG_INDEX },
1464 { BER_BVC("Any"), -1 },
1469 return mask_to_verbs( loglevel_ops, ldap_syslog, &c->rvalue_vals );
1474 for( i=1; i < c->argc; i++ ) {
1477 if ( isdigit( c->argv[i][0] ) ) {
1478 level = strtol( c->argv[i], &next, 10 );
1479 if ( next == NULL || next[0] != '\0' ) {
1480 Debug( LDAP_DEBUG_ANY,
1481 "%s: unable to parse level \"%s\" "
1482 "in \"loglevel <level> [...]\" line.\n",
1483 c->log, c->argv[i], 0);
1487 int j = verb_to_mask(c->argv[i], loglevel_ops);
1488 if(BER_BVISNULL(&loglevel_ops[j].word)) {
1489 Debug( LDAP_DEBUG_ANY,
1490 "%s: unknown level \"%s\" "
1491 "in \"loglevel <level> [...]\" line.\n",
1492 c->log, c->argv[i], 0);
1495 level = loglevel_ops[j].mask;
1497 ldap_syslog |= level;
1503 config_syncrepl(ConfigArgs *c) {
1505 if ( c->be->be_syncinfo ) {
1507 syncrepl_unparse( c->be->be_syncinfo, &bv );
1508 ber_bvarray_add( &c->rvalue_vals, &bv );
1513 if(SLAP_SHADOW(c->be)) {
1514 Debug(LDAP_DEBUG_ANY, "%s: "
1515 "syncrepl: database already shadowed.\n",
1518 } else if(add_syncrepl(c->be, c->argv, c->argc)) {
1521 SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SYNC_SHADOW);
1526 config_referral(ConfigArgs *c) {
1527 struct berval vals[2];
1529 if ( default_referral ) {
1530 value_add( &c->rvalue_vals, default_referral );
1536 if(validate_global_referral(c->argv[1])) {
1537 Debug(LDAP_DEBUG_ANY, "%s: "
1538 "invalid URL (%s) in \"referral\" line.\n",
1539 c->log, c->argv[1], 0);
1543 ber_str2bv(c->argv[1], 0, 0, &vals[0]);
1544 vals[1].bv_val = NULL; vals[1].bv_len = 0;
1545 if(value_add(&default_referral, vals)) return(LDAP_OTHER);
1553 { BER_BVC("ssf="), offsetof(slap_ssf_set_t, sss_ssf) },
1554 { BER_BVC("transport="), offsetof(slap_ssf_set_t, sss_transport) },
1555 { BER_BVC("tls="), offsetof(slap_ssf_set_t, sss_tls) },
1556 { BER_BVC("sasl="), offsetof(slap_ssf_set_t, sss_sasl) },
1557 { BER_BVC("update_ssf="), offsetof(slap_ssf_set_t, sss_update_ssf) },
1558 { BER_BVC("update_transport="), offsetof(slap_ssf_set_t, sss_update_transport) },
1559 { BER_BVC("update_tls="), offsetof(slap_ssf_set_t, sss_update_tls) },
1560 { BER_BVC("update_sasl="), offsetof(slap_ssf_set_t, sss_update_sasl) },
1561 { BER_BVC("simple_bind="), offsetof(slap_ssf_set_t, sss_simple_bind) },
1566 config_security(ConfigArgs *c) {
1567 slap_ssf_set_t *set = &c->be->be_ssf_set;
1576 for (i=0; !BER_BVISNULL( &sec_keys[i].key ); i++) {
1577 tgt = (slap_ssf_t *)((char *)set + sec_keys[i].off);
1580 bv.bv_len = sprintf( numbuf, "%u", *tgt );
1581 bv.bv_len += sec_keys[i].key.bv_len;
1582 bv.bv_val = ch_malloc( bv.bv_len + 1);
1583 next = lutil_strcopy( bv.bv_val, sec_keys[i].key.bv_val );
1584 strcpy( next, numbuf );
1585 ber_bvarray_add( &c->rvalue_vals, &bv );
1590 for(i = 1; i < c->argc; i++) {
1591 slap_ssf_t *tgt = NULL;
1593 for ( j=0; !BER_BVISNULL( &sec_keys[j].key ); j++ ) {
1594 if(!strncasecmp(c->argv[i], sec_keys[j].key.bv_val,
1595 sec_keys[j].key.bv_len)) {
1596 src = c->argv[i] + sec_keys[j].key.bv_len;
1597 tgt = (slap_ssf_t *)((char *)set + sec_keys[j].off);
1602 Debug(LDAP_DEBUG_ANY, "%s: "
1603 "unknown factor %s in \"security <factors>\" line\n",
1604 c->log, c->argv[i], 0);
1608 *tgt = strtol(src, &next, 10);
1609 if(next == NULL || next[0] != '\0' ) {
1610 Debug(LDAP_DEBUG_ANY, "%s: "
1611 "unable to parse factor \"%s\" in \"security <factors>\" line\n",
1612 c->log, c->argv[i], 0);
1620 anlist_unparse( AttributeName *an, char *ptr ) {
1623 for (; !BER_BVISNULL( &an->an_name ); an++) {
1624 if ( comma ) *ptr++ = ',';
1625 ptr = lutil_strcopy( ptr, an->an_name.bv_val );
1632 replica_unparse( struct slap_replica_info *ri, int i, struct berval *bv )
1636 struct berval bc = {0};
1639 len = sprintf(numbuf, "{%d}", i );
1641 len += strlen( ri->ri_uri ) + STRLENOF("uri=");
1642 if ( ri->ri_nsuffix ) {
1643 for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
1644 len += ri->ri_nsuffix[i].bv_len + STRLENOF(" suffix=\"\"");
1647 if ( ri->ri_attrs ) {
1648 len += STRLENOF("attr");
1649 if ( ri->ri_exclude ) len++;
1650 for (i=0; !BER_BVISNULL( &ri->ri_attrs[i].an_name ); i++) {
1651 len += 1 + ri->ri_attrs[i].an_name.bv_len;
1654 bindconf_unparse( &ri->ri_bindconf, &bc );
1657 bv->bv_val = ch_malloc(len + 1);
1660 ptr = lutil_strcopy( bv->bv_val, numbuf );
1661 ptr = lutil_strcopy( ptr, "uri=" );
1662 ptr = lutil_strcopy( ptr, ri->ri_uri );
1664 if ( ri->ri_nsuffix ) {
1665 for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
1666 ptr = lutil_strcopy( ptr, " suffix=\"" );
1667 ptr = lutil_strcopy( ptr, ri->ri_nsuffix[i].bv_val );
1671 if ( ri->ri_attrs ) {
1672 ptr = lutil_strcopy( ptr, "attr" );
1673 if ( ri->ri_exclude ) *ptr++ = '!';
1675 ptr = anlist_unparse( ri->ri_attrs, ptr );
1678 strcpy( ptr, bc.bv_val );
1679 ch_free( bc.bv_val );
1684 config_replica(ConfigArgs *c) {
1685 int i, nr = -1, len;
1686 char *replicahost, *replicauri;
1690 if (c->be->be_replica) {
1692 for (i=0;c->be->be_replica[i]; i++) {
1693 replica_unparse( c->be->be_replica[i], i, &bv );
1694 ber_bvarray_add( &c->rvalue_vals, &bv );
1700 if(SLAP_MONITOR(c->be)) {
1701 Debug(LDAP_DEBUG_ANY, "%s: "
1702 "\"replica\" should not be used inside monitor database\n",
1704 return(0); /* FIXME: should this be an error? */
1707 for(i = 1; i < c->argc; i++) {
1708 if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
1709 replicahost = c->argv[i] + STRLENOF("host=");
1710 len = strlen( replicahost );
1711 replicauri = ch_malloc( len + STRLENOF("ldap://") + 1 );
1712 sprintf( replicauri, "ldap://%s", replicahost );
1713 replicahost = replicauri + STRLENOF( "ldap://");
1714 nr = add_replica_info(c->be, replicauri, replicahost);
1716 } else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
1717 if(ldap_url_parse(c->argv[i] + STRLENOF("uri="), &ludp) != LDAP_SUCCESS) {
1718 Debug(LDAP_DEBUG_ANY, "%s: "
1719 "replica line contains invalid "
1720 "uri definition.\n", c->log, 0, 0);
1723 if(!ludp->lud_host) {
1724 Debug(LDAP_DEBUG_ANY, "%s: "
1725 "replica line contains invalid "
1726 "uri definition - missing hostname.\n",
1730 ldap_free_urldesc(ludp);
1731 replicauri = c->argv[i] + STRLENOF("uri=");
1732 replicauri = ch_strdup( replicauri );
1733 replicahost = strchr( replicauri, '/' );
1735 nr = add_replica_info(c->be, replicauri, replicahost);
1740 Debug(LDAP_DEBUG_ANY, "%s: "
1741 "missing host or uri in \"replica\" line\n",
1744 } else if(nr == -1) {
1745 Debug(LDAP_DEBUG_ANY, "%s: "
1746 "unable to add replica \"%s\"\n",
1747 c->log, replicauri, 0);
1750 for(i = 1; i < c->argc; i++) {
1751 if(!strncasecmp(c->argv[i], "suffix=", STRLENOF( "suffix="))) {
1752 switch(add_replica_suffix(c->be, nr, c->argv[i] + STRLENOF("suffix="))) {
1754 Debug(LDAP_DEBUG_ANY, "%s: "
1755 "suffix \"%s\" in \"replica\" line is not valid for backend (ignored)\n",
1756 c->log, c->argv[i] + STRLENOF("suffix="), 0);
1759 Debug(LDAP_DEBUG_ANY, "%s: "
1760 "unable to normalize suffix in \"replica\" line (ignored)\n",
1765 } else if(!strncasecmp(c->argv[i], "attr", STRLENOF("attr"))) {
1767 char *arg = c->argv[i] + STRLENOF("attr");
1775 if(add_replica_attrs(c->be, nr, arg + 1, exclude)) {
1776 Debug(LDAP_DEBUG_ANY, "%s: "
1777 "attribute \"%s\" in \"replica\" line is unknown\n",
1778 c->log, arg + 1, 0);
1781 } else if ( bindconf_parse( c->argv[i],
1782 &c->be->be_replica[nr]->ri_bindconf ) ) {
1791 config_updatedn(ConfigArgs *c) {
1795 if (!BER_BVISEMPTY(&c->be->be_update_ndn)) {
1796 value_add_one(&c->rvalue_vals, &c->be->be_update_ndn);
1797 value_add_one(&c->rvalue_nvals, &c->be->be_update_ndn);
1802 if(SLAP_SHADOW(c->be)) {
1803 Debug(LDAP_DEBUG_ANY, "%s: "
1804 "updatedn: database already shadowed.\n",
1809 ber_str2bv(c->argv[1], 0, 0, &dn);
1811 rc = dnNormalize(0, NULL, NULL, &dn, &c->be->be_update_ndn, NULL);
1813 if(rc != LDAP_SUCCESS) {
1814 Debug(LDAP_DEBUG_ANY, "%s: "
1815 "updatedn DN is invalid: %d (%s)\n",
1816 c->log, rc, ldap_err2string( rc ));
1820 SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SLURP_SHADOW);
1825 config_updateref(ConfigArgs *c) {
1826 struct berval vals[2];
1828 if ( c->be->be_update_refs ) {
1829 value_add( &c->rvalue_vals, c->be->be_update_refs );
1835 if(!SLAP_SHADOW(c->be)) {
1836 Debug(LDAP_DEBUG_ANY, "%s: "
1837 "updateref line must come after syncrepl or updatedn.\n",
1842 if(validate_global_referral(c->argv[1])) {
1843 Debug(LDAP_DEBUG_ANY, "%s: "
1844 "invalid URL (%s) in \"updateref\" line.\n",
1845 c->log, c->argv[1], 0);
1848 ber_str2bv(c->argv[1], 0, 0, &vals[0]);
1849 vals[1].bv_val = NULL;
1850 if(value_add(&c->be->be_update_refs, vals)) return(LDAP_OTHER);
1855 config_include(ConfigArgs *c) {
1856 unsigned long savelineno = c->lineno;
1859 ConfigFile *cfsave = cfn;
1860 ConfigFile *cf2 = NULL;
1864 cf = ch_calloc( 1, sizeof(ConfigFile));
1865 #ifdef SLAPD_MODULES
1866 cf->c_modlast = &cf->c_modpaths;
1868 if ( cfn->c_kids ) {
1869 for (cf2=cfn->c_kids; cf2 && cf2->c_sibs; cf2=cf2->c_sibs) ;
1875 rc = read_config_file(c->argv[1], c->depth + 1, c);
1876 c->lineno = savelineno - 1;
1879 if ( cf2 ) cf2->c_sibs = NULL;
1880 else cfn->c_kids = NULL;
1883 ber_str2bv( c->argv[1], 0, 1, &cf->c_file );
1890 config_tls_option(ConfigArgs *c) {
1893 case CFG_TLS_RAND: flag = LDAP_OPT_X_TLS_RANDOM_FILE; break;
1894 case CFG_TLS_CIPHER: flag = LDAP_OPT_X_TLS_CIPHER_SUITE; break;
1895 case CFG_TLS_CERT_FILE: flag = LDAP_OPT_X_TLS_CERTFILE; break;
1896 case CFG_TLS_CERT_KEY: flag = LDAP_OPT_X_TLS_KEYFILE; break;
1897 case CFG_TLS_CA_PATH: flag = LDAP_OPT_X_TLS_CACERTDIR; break;
1898 case CFG_TLS_CA_FILE: flag = LDAP_OPT_X_TLS_CACERTFILE; break;
1899 default: Debug(LDAP_DEBUG_ANY, "%s: "
1900 "unknown tls_option <%x>\n",
1901 c->log, c->type, 0);
1904 return ldap_pvt_tls_get_option( NULL, flag, &c->value_string );
1906 ch_free(c->value_string);
1907 return(ldap_pvt_tls_set_option(NULL, flag, c->argv[1]));
1910 /* FIXME: this ought to be provided by libldap */
1912 config_tls_config(ConfigArgs *c) {
1914 slap_verbmasks crlkeys[] = {
1915 { BER_BVC("none"), LDAP_OPT_X_TLS_CRL_NONE },
1916 { BER_BVC("peer"), LDAP_OPT_X_TLS_CRL_PEER },
1917 { BER_BVC("all"), LDAP_OPT_X_TLS_CRL_ALL },
1920 slap_verbmasks vfykeys[] = {
1921 { BER_BVC("never"), LDAP_OPT_X_TLS_NEVER },
1922 { BER_BVC("demand"), LDAP_OPT_X_TLS_DEMAND },
1923 { BER_BVC("try"), LDAP_OPT_X_TLS_TRY },
1924 { BER_BVC("hard"), LDAP_OPT_X_TLS_HARD },
1928 #ifdef HAVE_OPENSSL_CRL
1929 case CFG_TLS_CRLCHECK: flag = LDAP_OPT_X_TLS_CRLCHECK; keys = crlkeys;
1932 case CFG_TLS_VERIFY: flag = LDAP_OPT_X_TLS_REQUIRE_CERT; keys = vfykeys;
1934 default: Debug(LDAP_DEBUG_ANY, "%s: "
1935 "unknown tls_option <%x>\n",
1936 c->log, c->type, 0);
1939 ldap_pvt_tls_get_option( NULL, flag, &c->value_int );
1940 for (i=0; !BER_BVISNULL(&keys[i].word); i++) {
1941 if (keys[i].mask == c->value_int) {
1942 c->value_string = ch_strdup( keys[i].word.bv_val );
1948 ch_free( c->value_string );
1949 if(isdigit((unsigned char)c->argv[1][0])) {
1950 i = atoi(c->argv[1]);
1951 return(ldap_pvt_tls_set_option(NULL, flag, &i));
1953 return(ldap_int_tls_config(NULL, flag, c->argv[1]));
1968 si = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );
1971 Debug( LDAP_DEBUG_ANY, "out of memory in add_syncrepl\n", 0, 0, 0 );
1975 si->si_bindconf.sb_tls = SB_TLS_OFF;
1976 si->si_bindconf.sb_method = LDAP_AUTH_SIMPLE;
1977 si->si_schemachecking = 0;
1978 ber_str2bv( "(objectclass=*)", STRLENOF("(objectclass=*)"), 1,
1979 &si->si_filterstr );
1980 si->si_base.bv_val = NULL;
1981 si->si_scope = LDAP_SCOPE_SUBTREE;
1982 si->si_attrsonly = 0;
1983 si->si_anlist = (AttributeName *) ch_calloc( 1, sizeof( AttributeName ));
1984 si->si_exanlist = (AttributeName *) ch_calloc( 1, sizeof( AttributeName ));
1985 si->si_attrs = NULL;
1986 si->si_allattrs = 0;
1987 si->si_allopattrs = 0;
1988 si->si_exattrs = NULL;
1989 si->si_type = LDAP_SYNC_REFRESH_ONLY;
1990 si->si_interval = 86400;
1991 si->si_retryinterval = NULL;
1992 si->si_retrynum_init = NULL;
1993 si->si_retrynum = NULL;
1994 si->si_manageDSAit = 0;
1998 si->si_presentlist = NULL;
1999 LDAP_LIST_INIT( &si->si_nonpresentlist );
2000 ldap_pvt_thread_mutex_init( &si->si_mutex );
2002 rc = parse_syncrepl_line( cargv, cargc, si );
2005 Debug( LDAP_DEBUG_ANY, "failed to add syncinfo\n", 0, 0, 0 );
2006 syncinfo_free( si );
2009 Debug( LDAP_DEBUG_CONFIG,
2010 "Config: ** successfully added syncrepl \"%s\"\n",
2011 BER_BVISNULL( &si->si_provideruri ) ?
2012 "(null)" : si->si_provideruri.bv_val, 0, 0 );
2013 if ( !si->si_schemachecking ) {
2014 SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK;
2017 be->be_syncinfo = si;
2022 /* NOTE: used & documented in slapd.conf(5) */
2024 #define PROVIDERSTR "provider"
2025 #define TYPESTR "type"
2026 #define INTERVALSTR "interval"
2027 #define SEARCHBASESTR "searchbase"
2028 #define FILTERSTR "filter"
2029 #define SCOPESTR "scope"
2030 #define ATTRSSTR "attrs"
2031 #define ATTRSONLYSTR "attrsonly"
2032 #define SLIMITSTR "sizelimit"
2033 #define TLIMITSTR "timelimit"
2034 #define SCHEMASTR "schemachecking"
2036 /* FIXME: undocumented */
2037 #define OLDAUTHCSTR "bindprincipal"
2038 #define EXATTRSSTR "exattrs"
2039 #define RETRYSTR "retry"
2042 #define LASTMODSTR "lastmod"
2043 #define LMGENSTR "gen"
2044 #define LMNOSTR "no"
2045 #define LMREQSTR "req"
2046 #define SRVTABSTR "srvtab"
2047 #define SUFFIXSTR "suffix"
2048 #define MANAGEDSAITSTR "manageDSAit"
2051 #define GOT_ID 0x0001
2052 #define GOT_PROVIDER 0x0002
2055 #define GOT_ALL (GOT_ID|GOT_PROVIDER)
2061 { BER_BVC("base"), LDAP_SCOPE_BASE },
2062 { BER_BVC("one"), LDAP_SCOPE_ONELEVEL },
2063 #ifdef LDAP_SCOPE_SUBORDINATE
2064 { BER_BVC("children"), LDAP_SCOPE_SUBORDINATE },
2065 { BER_BVC("subordinate"), 0 },
2067 { BER_BVC("sub"), LDAP_SCOPE_SUBTREE },
2072 parse_syncrepl_line(
2082 for ( i = 1; i < cargc; i++ ) {
2083 if ( !strncasecmp( cargv[ i ], IDSTR "=",
2084 STRLENOF( IDSTR "=" ) ) )
2087 /* '\0' string terminator accounts for '=' */
2088 val = cargv[ i ] + STRLENOF( IDSTR "=" );
2090 if ( tmp >= 1000 || tmp < 0 ) {
2091 fprintf( stderr, "Error: parse_syncrepl_line: "
2092 "syncrepl id %d is out of range [0..999]\n", tmp );
2097 } else if ( !strncasecmp( cargv[ i ], PROVIDERSTR "=",
2098 STRLENOF( PROVIDERSTR "=" ) ) )
2100 val = cargv[ i ] + STRLENOF( PROVIDERSTR "=" );
2101 ber_str2bv( val, 0, 1, &si->si_provideruri );
2102 gots |= GOT_PROVIDER;
2103 } else if ( !strncasecmp( cargv[ i ], SCHEMASTR "=",
2104 STRLENOF( SCHEMASTR "=" ) ) )
2106 val = cargv[ i ] + STRLENOF( SCHEMASTR "=" );
2107 if ( !strncasecmp( val, "on", STRLENOF( "on" ) )) {
2108 si->si_schemachecking = 1;
2109 } else if ( !strncasecmp( val, "off", STRLENOF( "off" ) ) ) {
2110 si->si_schemachecking = 0;
2112 si->si_schemachecking = 1;
2114 } else if ( !strncasecmp( cargv[ i ], FILTERSTR "=",
2115 STRLENOF( FILTERSTR "=" ) ) )
2117 val = cargv[ i ] + STRLENOF( FILTERSTR "=" );
2118 ber_str2bv( val, 0, 1, &si->si_filterstr );
2119 } else if ( !strncasecmp( cargv[ i ], SEARCHBASESTR "=",
2120 STRLENOF( SEARCHBASESTR "=" ) ) )
2125 val = cargv[ i ] + STRLENOF( SEARCHBASESTR "=" );
2126 if ( si->si_base.bv_val ) {
2127 ch_free( si->si_base.bv_val );
2129 ber_str2bv( val, 0, 0, &bv );
2130 rc = dnNormalize( 0, NULL, NULL, &bv, &si->si_base, NULL );
2131 if ( rc != LDAP_SUCCESS ) {
2132 fprintf( stderr, "Invalid base DN \"%s\": %d (%s)\n",
2133 val, rc, ldap_err2string( rc ) );
2136 } else if ( !strncasecmp( cargv[ i ], SCOPESTR "=",
2137 STRLENOF( SCOPESTR "=" ) ) )
2140 val = cargv[ i ] + STRLENOF( SCOPESTR "=" );
2141 for ( j=0; !BER_BVISNULL(&scopes[j].key); j++ ) {
2142 if (!strncasecmp( val, scopes[j].key.bv_val,
2143 scopes[j].key.bv_len )) {
2144 while (!scopes[j].val) j--;
2145 si->si_scope = scopes[j].val;
2149 if ( BER_BVISNULL(&scopes[j].key) ) {
2150 fprintf( stderr, "Error: parse_syncrepl_line: "
2151 "unknown scope \"%s\"\n", val);
2154 } else if ( !strncasecmp( cargv[ i ], ATTRSONLYSTR "=",
2155 STRLENOF( ATTRSONLYSTR "=" ) ) )
2157 si->si_attrsonly = 1;
2158 } else if ( !strncasecmp( cargv[ i ], ATTRSSTR "=",
2159 STRLENOF( ATTRSSTR "=" ) ) )
2161 val = cargv[ i ] + STRLENOF( ATTRSSTR "=" );
2162 if ( !strncasecmp( val, ":include:", STRLENOF(":include:") ) ) {
2164 attr_fname = ch_strdup( val + STRLENOF(":include:") );
2165 si->si_anlist = file2anlist( si->si_anlist, attr_fname, " ,\t" );
2166 if ( si->si_anlist == NULL ) {
2167 ch_free( attr_fname );
2170 si->si_anfile = attr_fname;
2172 char *str, *s, *next;
2173 char delimstr[] = " ,\t";
2174 str = ch_strdup( val );
2175 for ( s = ldap_pvt_strtok( str, delimstr, &next );
2177 s = ldap_pvt_strtok( NULL, delimstr, &next ) )
2179 if ( strlen(s) == 1 && *s == '*' ) {
2180 si->si_allattrs = 1;
2181 *(val + ( s - str )) = delimstr[0];
2183 if ( strlen(s) == 1 && *s == '+' ) {
2184 si->si_allopattrs = 1;
2185 *(val + ( s - str )) = delimstr[0];
2189 si->si_anlist = str2anlist( si->si_anlist, val, " ,\t" );
2190 if ( si->si_anlist == NULL ) {
2194 } else if ( !strncasecmp( cargv[ i ], EXATTRSSTR "=",
2195 STRLENOF( EXATTRSSTR "=" ) ) )
2197 val = cargv[ i ] + STRLENOF( EXATTRSSTR "=" );
2198 if ( !strncasecmp( val, ":include:", STRLENOF(":include:") )) {
2200 attr_fname = ch_strdup( val + STRLENOF(":include:") );
2201 si->si_exanlist = file2anlist(
2202 si->si_exanlist, attr_fname, " ,\t" );
2203 if ( si->si_exanlist == NULL ) {
2204 ch_free( attr_fname );
2207 ch_free( attr_fname );
2209 si->si_exanlist = str2anlist( si->si_exanlist, val, " ,\t" );
2210 if ( si->si_exanlist == NULL ) {
2214 } else if ( !strncasecmp( cargv[ i ], TYPESTR "=",
2215 STRLENOF( TYPESTR "=" ) ) )
2217 val = cargv[ i ] + STRLENOF( TYPESTR "=" );
2218 if ( !strncasecmp( val, "refreshOnly",
2219 STRLENOF("refreshOnly") ))
2221 si->si_type = LDAP_SYNC_REFRESH_ONLY;
2222 } else if ( !strncasecmp( val, "refreshAndPersist",
2223 STRLENOF("refreshAndPersist") ))
2225 si->si_type = LDAP_SYNC_REFRESH_AND_PERSIST;
2226 si->si_interval = 60;
2228 fprintf( stderr, "Error: parse_syncrepl_line: "
2229 "unknown sync type \"%s\"\n", val);
2232 } else if ( !strncasecmp( cargv[ i ], INTERVALSTR "=",
2233 STRLENOF( INTERVALSTR "=" ) ) )
2235 val = cargv[ i ] + STRLENOF( INTERVALSTR "=" );
2236 if ( si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ) {
2237 si->si_interval = 0;
2245 hstr = strchr( dstr, ':' );
2246 if ( hstr == NULL ) {
2247 fprintf( stderr, "Error: parse_syncrepl_line: "
2248 "invalid interval \"%s\"\n", val );
2252 mstr = strchr( hstr, ':' );
2253 if ( mstr == NULL ) {
2254 fprintf( stderr, "Error: parse_syncrepl_line: "
2255 "invalid interval \"%s\"\n", val );
2259 sstr = strchr( mstr, ':' );
2260 if ( sstr == NULL ) {
2261 fprintf( stderr, "Error: parse_syncrepl_line: "
2262 "invalid interval \"%s\"\n", val );
2271 if (( hh > 24 ) || ( hh < 0 ) ||
2272 ( mm > 60 ) || ( mm < 0 ) ||
2273 ( ss > 60 ) || ( ss < 0 ) || ( dd < 0 )) {
2274 fprintf( stderr, "Error: parse_syncrepl_line: "
2275 "invalid interval \"%s\"\n", val );
2278 si->si_interval = (( dd * 24 + hh ) * 60 + mm ) * 60 + ss;
2280 if ( si->si_interval < 0 ) {
2281 fprintf( stderr, "Error: parse_syncrepl_line: "
2282 "invalid interval \"%ld\"\n",
2283 (long) si->si_interval);
2286 } else if ( !strncasecmp( cargv[ i ], RETRYSTR "=",
2287 STRLENOF( RETRYSTR "=" ) ) )
2292 val = cargv[ i ] + STRLENOF( RETRYSTR "=" );
2293 retry_list = (char **) ch_calloc( 1, sizeof( char * ));
2294 retry_list[0] = NULL;
2296 slap_str2clist( &retry_list, val, " ,\t" );
2298 for ( k = 0; retry_list && retry_list[k]; k++ ) ;
2302 "Error: incomplete syncrepl retry list\n" );
2303 for ( k = 0; retry_list && retry_list[k]; k++ ) {
2304 ch_free( retry_list[k] );
2306 ch_free( retry_list );
2307 exit( EXIT_FAILURE );
2309 si->si_retryinterval = (time_t *) ch_calloc( n + 1, sizeof( time_t ));
2310 si->si_retrynum = (int *) ch_calloc( n + 1, sizeof( int ));
2311 si->si_retrynum_init = (int *) ch_calloc( n + 1, sizeof( int ));
2312 for ( j = 0; j < n; j++ ) {
2313 si->si_retryinterval[j] = atoi( retry_list[j*2] );
2314 if ( *retry_list[j*2+1] == '+' ) {
2315 si->si_retrynum_init[j] = -1;
2316 si->si_retrynum[j] = -1;
2320 si->si_retrynum_init[j] = atoi( retry_list[j*2+1] );
2321 si->si_retrynum[j] = atoi( retry_list[j*2+1] );
2324 si->si_retrynum_init[j] = -2;
2325 si->si_retrynum[j] = -2;
2326 si->si_retryinterval[j] = 0;
2328 for ( k = 0; retry_list && retry_list[k]; k++ ) {
2329 ch_free( retry_list[k] );
2331 ch_free( retry_list );
2332 } else if ( !strncasecmp( cargv[ i ], MANAGEDSAITSTR "=",
2333 STRLENOF( MANAGEDSAITSTR "=" ) ) )
2335 val = cargv[ i ] + STRLENOF( MANAGEDSAITSTR "=" );
2336 si->si_manageDSAit = atoi( val );
2337 } else if ( !strncasecmp( cargv[ i ], SLIMITSTR "=",
2338 STRLENOF( SLIMITSTR "=") ) )
2340 val = cargv[ i ] + STRLENOF( SLIMITSTR "=" );
2341 si->si_slimit = atoi( val );
2342 } else if ( !strncasecmp( cargv[ i ], TLIMITSTR "=",
2343 STRLENOF( TLIMITSTR "=" ) ) )
2345 val = cargv[ i ] + STRLENOF( TLIMITSTR "=" );
2346 si->si_tlimit = atoi( val );
2347 } else if ( bindconf_parse( cargv[i], &si->si_bindconf )) {
2348 fprintf( stderr, "Error: parse_syncrepl_line: "
2349 "unknown keyword \"%s\"\n", cargv[ i ] );
2354 if ( gots != GOT_ALL ) {
2356 "Error: Malformed \"syncrepl\" line in slapd config file" );
2364 syncrepl_unparse( syncinfo_t *si, struct berval *bv )
2367 char buf[BUFSIZ*2], *ptr;
2370 bindconf_unparse( &si->si_bindconf, &bc );
2372 ptr += sprintf( ptr, IDSTR "=%03d " PROVIDERSTR "=%s",
2373 si->si_rid, si->si_provideruri.bv_val );
2374 if ( !BER_BVISNULL( &bc )) {
2375 ptr = lutil_strcopy( ptr, bc.bv_val );
2378 if ( !BER_BVISEMPTY( &si->si_filterstr )) {
2379 ptr = lutil_strcopy( ptr, " " FILTERSTR "=\"" );
2380 ptr = lutil_strcopy( ptr, si->si_filterstr.bv_val );
2383 if ( !BER_BVISNULL( &si->si_base )) {
2384 ptr = lutil_strcopy( ptr, " " SEARCHBASESTR "=\"" );
2385 ptr = lutil_strcopy( ptr, si->si_base.bv_val );
2388 for (i=0; !BER_BVISNULL(&scopes[i].key);i++) {
2389 if ( si->si_scope == scopes[i].val ) {
2390 ptr = lutil_strcopy( ptr, " " SCOPESTR "=" );
2391 ptr = lutil_strcopy( ptr, scopes[i].key.bv_val );
2395 if ( si->si_attrsonly ) {
2396 ptr = lutil_strcopy( ptr, " " ATTRSONLYSTR "=yes" );
2398 if ( si->si_anfile ) {
2399 ptr = lutil_strcopy( ptr, " " ATTRSSTR "=:include:" );
2400 ptr = lutil_strcopy( ptr, si->si_anfile );
2401 } else if ( si->si_allattrs || si->si_allopattrs ||
2402 ( si->si_anlist && !BER_BVISNULL(&si->si_anlist[0].an_name) )) {
2404 ptr = lutil_strcopy( ptr, " " ATTRSSTR "=\"" );
2406 ptr = anlist_unparse( si->si_anlist, ptr );
2407 if ( si->si_allattrs ) {
2408 if ( old != ptr ) *ptr++ = ',';
2411 if ( si->si_allopattrs ) {
2412 if ( old != ptr ) *ptr++ = ',';
2417 if ( si->si_exanlist && !BER_BVISNULL(&si->si_exanlist[0].an_name) ) {
2418 ptr = lutil_strcopy( ptr, " " EXATTRSSTR "=" );
2419 ptr = anlist_unparse( si->si_exanlist, ptr );
2421 ptr = lutil_strcopy( ptr, " " SCHEMASTR "=" );
2422 ptr = lutil_strcopy( ptr, si->si_schemachecking ? "on" : "off" );
2424 ptr = lutil_strcopy( ptr, " " TYPESTR "=" );
2425 ptr = lutil_strcopy( ptr, si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ?
2426 "refreshAndPersist" : "refreshOnly" );
2428 if ( si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
2431 dd = si->si_interval;
2438 ptr = lutil_strcopy( ptr, " " INTERVALSTR "=" );
2439 ptr += sprintf( ptr, "%02d:%02d:%02d:%02d", dd, hh, mm, ss );
2440 } else if ( si->si_retryinterval ) {
2442 ptr = lutil_strcopy( ptr, " " RETRYSTR "=\"" );
2443 for (i=0; si->si_retryinterval[i]; i++) {
2444 if ( space ) *ptr++ = ' ';
2446 ptr += sprintf( ptr, "%d", si->si_retryinterval[i] );
2447 if ( si->si_retrynum_init[i] == -1 )
2450 ptr += sprintf( ptr, "%d", si->si_retrynum_init );
2455 #if 0 /* FIXME: unused in syncrepl.c, should remove it */
2456 ptr = lutil_strcopy( ptr, " " MANAGEDSAITSTR "=" );
2457 ptr += sprintf( ptr, "%d", si->si_manageDSAit );
2460 if ( si->si_slimit ) {
2461 ptr = lutil_strcopy( ptr, " " SLIMITSTR "=" );
2462 ptr += sprintf( ptr, "%d", si->si_slimit );
2465 if ( si->si_tlimit ) {
2466 ptr = lutil_strcopy( ptr, " " TLIMITSTR "=" );
2467 ptr += sprintf( ptr, "%d", si->si_tlimit );
2469 bc.bv_len = ptr - buf;
2471 ber_dupbv( bv, &bc );
2476 read_config(const char *fname, int depth) {
2478 if ( !backend_db_init( "config" ))
2481 ber_str2bv( fname, 0, 1, &cf_prv.c_file );
2482 return read_config_file(fname, depth, NULL);
2486 config_back_bind( Operation *op, SlapReply *rs )
2488 if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
2489 ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
2490 /* frontend sends result */
2491 return LDAP_SUCCESS;
2494 rs->sr_err = LDAP_INVALID_CREDENTIALS;
2495 send_ldap_result( op, rs );
2500 static CfEntryInfo *
2501 config_find_base( CfEntryInfo *root, struct berval *dn, CfEntryInfo **last )
2506 if ( dn_match( &root->ce_entry->e_nname, dn ))
2509 c = dn->bv_val+dn->bv_len;
2510 for (;*c != ',';c--);
2514 for (--c;c>dn->bv_val && *c != ',';c--);
2518 cdn.bv_len = dn->bv_len - (c-dn->bv_val);
2520 root = root->ce_kids;
2522 for (;root;root=root->ce_sibs) {
2523 if ( dn_match( &root->ce_entry->e_nname, &cdn )) {
2524 if ( cdn.bv_val == dn->bv_val ) {
2535 config_send( Operation *op, SlapReply *rs, CfEntryInfo *ce, int depth )
2539 if ( test_filter( op, ce->ce_entry, op->ors_filter ) == LDAP_COMPARE_TRUE )
2541 rs->sr_attrs = op->ors_attrs;
2542 rs->sr_entry = ce->ce_entry;
2543 rc = send_search_entry( op, rs );
2545 if ( op->ors_scope == LDAP_SCOPE_SUBTREE ) {
2546 if ( ce->ce_kids ) {
2547 rc = config_send( op, rs, ce->ce_kids, 1 );
2548 if ( rc ) return rc;
2551 for (ce=ce->ce_sibs; ce; ce=ce->ce_sibs) {
2552 rc = config_send( op, rs, ce, 0 );
2561 config_back_modify( Operation *op, SlapReply *rs )
2564 CfEntryInfo *ce, *last;
2566 if ( !be_isroot( op ) ) {
2567 rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
2568 send_ldap_result( op, rs );
2571 cfb = (CfBackInfo *)op->o_bd->be_private;
2573 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
2576 rs->sr_matched = last->ce_entry->e_name.bv_val;
2577 rs->sr_err = LDAP_NO_SUCH_OBJECT;
2580 ldap_pvt_thread_pool_pause( &connection_pool );
2581 ldap_pvt_thread_pool_resume( &connection_pool );
2583 send_ldap_result( op, rs );
2588 config_back_search( Operation *op, SlapReply *rs )
2591 CfEntryInfo *ce, *last;
2594 if ( !be_isroot( op ) ) {
2595 rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
2596 send_ldap_result( op, rs );
2599 cfb = (CfBackInfo *)op->o_bd->be_private;
2601 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
2604 rs->sr_matched = last->ce_entry->e_name.bv_val;
2605 rs->sr_err = LDAP_NO_SUCH_OBJECT;
2608 switch ( op->ors_scope ) {
2609 case LDAP_SCOPE_BASE:
2610 case LDAP_SCOPE_SUBTREE:
2611 config_send( op, rs, ce, 0 );
2614 case LDAP_SCOPE_ONELEVEL:
2615 for (ce = ce->ce_kids; ce; ce=ce->ce_sibs) {
2616 config_send( op, rs, ce, 1 );
2621 rs->sr_err = LDAP_SUCCESS;
2623 send_ldap_result( op, rs );
2628 config_alloc_entry( struct berval *pdn, struct berval *rdn )
2630 Entry *e = ch_calloc( 1, sizeof(Entry) );
2631 CfEntryInfo *ce = ch_calloc( 1, sizeof(CfEntryInfo) );
2634 build_new_dn( &e->e_name, pdn, rdn, NULL );
2635 ber_dupbv( &e->e_nname, &e->e_name );
2644 config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc,
2645 struct berval *rdn, ConfigTable *ct, int table )
2647 struct berval vals[2];
2648 struct berval ad_name;
2649 AttributeDescription *ad = NULL;
2655 BER_BVZERO( &vals[1] );
2657 vals[0] = oc->soc_cname;
2658 attr_merge(e, slap_schema.si_ad_objectClass, vals, NULL );
2659 ptr = strchr(rdn->bv_val, '=');
2660 ad_name.bv_val = rdn->bv_val;
2661 ad_name.bv_len = ptr - rdn->bv_val;
2662 rc = slap_bv2ad( &ad_name, &ad, &text );
2666 vals[0].bv_val = ptr+1;
2667 vals[0].bv_len = rdn->bv_len - (vals[0].bv_val - rdn->bv_val);
2668 attr_merge(e, ad, vals, NULL );
2670 for (at=oc->soc_required; at && *at; at++) {
2671 /* Skip the naming attr */
2672 if ((*at)->sat_ad == ad || (*at)->sat_ad == slap_schema.si_ad_cn )
2674 for (i=0;ct[i].name;i++) {
2675 if (ct[i].ad == (*at)->sat_ad)
2678 rc = config_get_vals(&ct[i], c);
2679 if (rc == LDAP_SUCCESS) {
2680 attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
2681 ber_bvarray_free( c->rvalue_nvals );
2682 ber_bvarray_free( c->rvalue_vals );
2686 for (at=oc->soc_allowed; at && *at; at++) {
2687 /* Skip the naming attr */
2688 if ((*at)->sat_ad == ad || (*at)->sat_ad == slap_schema.si_ad_cn )
2690 for (i=0;ct[i].name;i++) {
2691 if (ct[i].ad == (*at)->sat_ad)
2694 rc = config_get_vals(&ct[i], c);
2695 if (rc == LDAP_SUCCESS) {
2696 attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
2697 ber_bvarray_free( c->rvalue_nvals );
2698 ber_bvarray_free( c->rvalue_vals );
2703 if ( table == BI_TABLE )
2704 ct = c->bi->bi_cf_table;
2706 ct = c->be->be_cf_table;
2707 for (;ct && ct->name;ct++) {
2708 if (!ct->ad) continue;
2709 rc = config_get_vals(ct, c);
2710 if (rc == LDAP_SUCCESS) {
2711 attr_merge(e, ct->ad, c->rvalue_vals, c->rvalue_nvals);
2719 static CfEntryInfo *
2720 config_build_includes( ConfigArgs *c, Entry *parent )
2724 ConfigFile *cf = (ConfigFile *)c->line;
2725 CfEntryInfo *ce, *ceparent, *ceprev;
2727 ceparent = parent->e_private;
2729 for (i=0; cf; cf=cf->c_sibs, i++) {
2730 c->value_dn.bv_val = c->log;
2731 c->value_dn.bv_len = sprintf(c->value_dn.bv_val, "cn=include{%d}", i);
2732 e = config_alloc_entry( &parent->e_nname, &c->value_dn );
2733 c->line = (char *)cf;
2734 config_build_entry( c, e, cfOc_include, &c->value_dn,
2735 c->bi->bi_cf_table, NO_TABLE );
2737 if ( !ceparent->ce_kids ) {
2738 ceparent->ce_kids = ce;
2740 ceprev->ce_sibs = ce;
2744 c->line = (char *)cf->c_kids;
2745 config_build_includes( c, e );
2752 config_back_db_open( BackendDB *be )
2754 CfBackInfo *cfb = be->be_private;
2757 CfEntryInfo *ce, *ceparent, *ceprev;
2764 /* create root of tree */
2766 e = config_alloc_entry( NULL, &rdn );
2771 c.line = (char *)cfb->cb_config;
2772 ct = c.bi->bi_cf_table;
2773 config_build_entry( &c, e, cfOc_global, &rdn, ct, NO_TABLE );
2778 /* Create includeFile nodes... */
2779 if ( cfb->cb_config->c_kids ) {
2780 c.line = (char *)cfb->cb_config->c_kids;
2781 ceprev = config_build_includes( &c, parent );
2784 /* Create backend nodes. Skip if they don't provide a cf_table.
2785 * There usually aren't any of these.
2790 for (i=0; i<nBackendInfo; i++, bi++) {
2791 if (!bi->bi_cf_table) continue;
2792 if (!bi->bi_private) continue;
2795 rdn.bv_len = sprintf(rdn.bv_val, "%s=%s", cfAd_backend->ad_cname.bv_val, bi->bi_type);
2796 e = config_alloc_entry( &parent->e_nname, &rdn );
2800 config_build_entry( &c, e, cfOc_backend, &rdn, ct, BI_TABLE );
2801 if ( !ceparent->ce_kids ) {
2802 ceparent->ce_kids = ce;
2804 ceprev->ce_sibs = ce;
2809 /* Create database nodes... */
2810 for (i=0; i<nBackendDB; i++) {
2811 slap_overinfo *oi = NULL;
2815 bptr = &backendDB[i];
2817 if ( overlay_is_over( bptr )) {
2818 oi = bptr->bd_info->bi_private;
2824 rdn.bv_len = sprintf(rdn.bv_val, "%s={%0x}%s", cfAd_database->ad_cname.bv_val,
2826 e = config_alloc_entry( &parent->e_nname, &rdn );
2832 config_build_entry( &c, e, cfOc_database, &rdn, ct, BE_TABLE );
2833 if ( !ceparent->ce_kids ) {
2834 ceparent->ce_kids = ce;
2836 ceprev->ce_sibs = ce;
2839 /* Iterate through overlays */
2843 CfEntryInfo *opar = ce, *oprev = NULL;
2846 for (j=0,on=oi->oi_list; on; j++,on=on->on_next) {
2848 rdn.bv_len = sprintf(rdn.bv_val, "%s={%0x}%s",
2849 cfAd_overlay->ad_cname.bv_val, j, on->on_bi.bi_type );
2850 oe = config_alloc_entry( &e->e_nname, &rdn );
2856 config_build_entry( &c, oe, cfOc_overlay, &rdn, ct, BI_TABLE );
2857 if ( !opar->ce_kids ) {
2860 oprev->ce_sibs = ce;
2867 if ( bptr->be_acl ) {
2869 CfEntryInfo *opar = ce;
2871 ae = config_alloc_entry( &e->e_nname, &access_rdn );
2877 config_build_entry( &c, ae, cfOc_access, &access_rdn, ct,
2879 if ( opar->ce_kids ) {
2880 ce->ce_sibs = opar->ce_kids;
2891 config_back_db_destroy( Backend *be )
2893 free( be->be_private );
2898 config_back_db_init( Backend *be )
2903 cfb = ch_calloc( 1, sizeof(CfBackInfo));
2904 cfb->cb_config = &cf_prv;
2905 be->be_private = cfb;
2907 ber_dupbv( &be->be_rootdn, &config_rdn );
2908 ber_dupbv( &be->be_rootndn, &be->be_rootdn );
2909 ber_dupbv( &dn, &be->be_rootdn );
2910 ber_bvarray_add( &be->be_suffix, &dn );
2911 ber_dupbv( &dn, &be->be_rootdn );
2912 ber_bvarray_add( &be->be_nsuffix, &dn );
2914 /* Hide from namingContexts */
2915 SLAP_BFLAGS(be) |= SLAP_BFLAG_CONFIG;
2922 AttributeDescription **desc;
2923 AttributeDescription *sub;
2925 { "attribute", NULL, NULL },
2926 { "backend", &cfAd_backend, NULL },
2927 { "database", &cfAd_database, NULL },
2928 { "ditcontentrule", NULL, NULL },
2929 { "include", &cfAd_include, NULL },
2930 { "objectclass", NULL, NULL },
2931 { "overlay", &cfAd_overlay, NULL },
2932 { NULL, NULL, NULL }
2936 config_back_initialize( BackendInfo *bi )
2938 ConfigTable *ct = config_back_cf_table;
2947 bi->bi_db_init = config_back_db_init;
2948 bi->bi_db_config = 0;
2949 bi->bi_db_open = config_back_db_open;
2950 bi->bi_db_close = 0;
2951 bi->bi_db_destroy = config_back_db_destroy;
2953 bi->bi_op_bind = config_back_bind;
2954 bi->bi_op_unbind = 0;
2955 bi->bi_op_search = config_back_search;
2956 bi->bi_op_compare = 0;
2957 bi->bi_op_modify = config_back_modify;
2958 bi->bi_op_modrdn = 0;
2960 bi->bi_op_delete = 0;
2961 bi->bi_op_abandon = 0;
2963 bi->bi_extended = 0;
2965 bi->bi_chk_referrals = 0;
2967 bi->bi_connection_init = 0;
2968 bi->bi_connection_destroy = 0;
2971 for (i=0; OidMacros[i].name; i++ ) {
2972 argv[1] = OidMacros[i].name;
2973 argv[2] = OidMacros[i].oid;
2974 parse_oidm( "slapd", i, 3, argv );
2977 i = init_config_attrs( ct );
2980 /* set up the notable AttributeDescriptions */
2981 ads[0].sub = slap_schema.si_ad_attributeTypes;
2982 ads[3].sub = slap_schema.si_ad_ditContentRules;
2983 ads[5].sub = slap_schema.si_ad_objectClasses;
2985 bi->bi_cf_table = ct;
2988 for (;ct->name;ct++) {
2989 if (strcmp(ct->name, ads[i].name)) continue;
2991 ct->ad = ads[i].sub;
2993 *ads[i].desc = ct->ad;
2996 if (!ads[i].name) break;
2999 /* set up the objectclasses */
3000 i = init_config_ocs( cf_ocs );