/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2005-2007 The OpenLDAP Foundation.
+ * Copyright 2005-2008 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
static CfBackInfo cfBackInfo;
static char *passwd_salt;
+static FILE *logfile;
static char *logfileName;
#ifdef SLAP_AUTH_REWRITE
static BerVarray authz_rewrites;
static ConfigDriver config_security;
static ConfigDriver config_referral;
static ConfigDriver config_loglevel;
-static ConfigDriver config_replica;
static ConfigDriver config_updatedn;
static ConfigDriver config_updateref;
static ConfigDriver config_include;
+static ConfigDriver config_obsolete;
#ifdef HAVE_TLS
static ConfigDriver config_tls_option;
static ConfigDriver config_tls_config;
CFG_TLS_DH_FILE,
CFG_TLS_VERIFY,
CFG_TLS_CRLCHECK,
+ CFG_TLS_CRL_FILE,
CFG_CONCUR,
CFG_THREADS,
CFG_SALT,
CFG_DIT,
CFG_ATTR,
CFG_ATOPT,
- CFG_REPLICA_ARGSFILE,
- CFG_REPLICA_PIDFILE,
- CFG_REPLICATIONINTERVAL,
- CFG_REPLOG,
CFG_ROOTDSE,
CFG_LOGFILE,
CFG_PLUGIN,
CFG_MIRRORMODE,
CFG_HIDDEN,
CFG_MONITORING,
+ CFG_SERVERID,
+ CFG_SORTVALS,
+ CFG_IX_INTLEN,
CFG_LAST
};
} OidRec;
static OidRec OidMacros[] = {
- /* OpenLDAProot:666.11.1 */
- { "OLcfg", "1.3.6.1.4.1.4203.666.11.1" },
+ /* OpenLDAProot:1.12.2 */
+ { "OLcfg", "1.3.6.1.4.1.4203.1.12.2" },
{ "OLcfgAt", "OLcfg:3" },
{ "OLcfgGlAt", "OLcfgAt:0" },
{ "OLcfgBkAt", "OLcfgAt:1" },
{ "OLcfgDbAt", "OLcfgAt:2" },
{ "OLcfgOvAt", "OLcfgAt:3" },
+ { "OLcfgCtAt", "OLcfgAt:4" }, /* contrib modules */
{ "OLcfgOc", "OLcfg:4" },
{ "OLcfgGlOc", "OLcfgOc:0" },
{ "OLcfgBkOc", "OLcfgOc:1" },
{ "OLcfgDbOc", "OLcfgOc:2" },
{ "OLcfgOvOc", "OLcfgOc:3" },
+ { "OLcfgCtOc", "OLcfgOc:4" }, /* contrib modules */
/* Syntaxes. We should just start using the standard names and
* document that they are predefined and available for users
{ "OMsBoolean", "OMsyn:7" },
{ "OMsDN", "OMsyn:12" },
{ "OMsDirectoryString", "OMsyn:15" },
+ { "OMsIA5String", "OMsyn:26" },
{ "OMsInteger", "OMsyn:27" },
{ "OMsOID", "OMsyn:38" },
{ "OMsOctetString", "OMsyn:40" },
* OLcfg{Bk|Db}{Oc|At}:1 -> back-bdb(/back-hdb)
* OLcfg{Bk|Db}{Oc|At}:2 -> back-ldif
* OLcfg{Bk|Db}{Oc|At}:3 -> back-ldap
+ * OLcfg{Bk|Db}{Oc|At}:4 -> back-monitor
+ * OLcfg{Bk|Db}{Oc|At}:5 -> back-relay
+ * OLcfg{Bk|Db}{Oc|At}:6 -> back-sql
+ * OLcfg{Bk|Db}{Oc|At}:7 -> back-sock
*/
/*
* OLcfgOv{Oc|At}:3 -> chain
* OLcfgOv{Oc|At}:4 -> accesslog
* OLcfgOv{Oc|At}:5 -> valsort
- * (FIXME: separate arc for contribware?)
- * OLcfgOv{Oc|At}:6 -> smbk5pwd
* OLcfgOv{Oc|At}:7 -> distproc
* OLcfgOv{Oc|At}:8 -> dynlist
* OLcfgOv{Oc|At}:9 -> dds
- * OLcfgOv{Oc|At}:10 -> unique
- * OLcfgOv{Oc|At}:11 -> refint
- * OLcfgOv{Oc|At}:12 -> ppolicy
- * OLcfgOv{Oc|At}:13 -> constraint
- * OLcfgOv{Oc|At}:14 -> translucent
- * OLcfgOv{Oc|At}:15 -> auditlog
+ * OLcfgOv{Oc|At}:10 -> unique
+ * OLcfgOv{Oc|At}:11 -> refint
+ * OLcfgOv{Oc|At}:12 -> ppolicy
+ * OLcfgOv{Oc|At}:13 -> constraint
+ * OLcfgOv{Oc|At}:14 -> translucent
+ * OLcfgOv{Oc|At}:15 -> auditlog
+ * OLcfgOv{Oc|At}:16 -> rwm
+ * OLcfgOv{Oc|At}:17 -> dyngroup
+ * OLcfgOv{Oc|At}:18 -> memberof
+ * OLcfgOv{Oc|At}:19 -> collect
*/
/* alphabetical ordering */
&global_idletimeout, "( OLcfgGlAt:18 NAME 'olcIdleTimeout' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "include", "file", 2, 2, 0, ARG_MAGIC,
- &config_include, NULL, NULL, NULL },
+ &config_include, "( OLcfgGlAt:19 NAME 'olcInclude' "
+ "SUP labeledURI )", NULL, NULL },
{ "index_substr_if_minlen", "min", 2, 2, 0, ARG_INT|ARG_NONZERO|ARG_MAGIC|CFG_SSTR_IF_MIN,
&config_generic, "( OLcfgGlAt:20 NAME 'olcIndexSubstrIfMinLen' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "index_substr_any_step", "step", 2, 2, 0, ARG_INT|ARG_NONZERO,
&index_substr_any_step, "( OLcfgGlAt:23 NAME 'olcIndexSubstrAnyStep' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+ { "index_intlen", "len", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_IX_INTLEN,
+ &config_generic, "( OLcfgGlAt:84 NAME 'olcIndexIntLen' "
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "lastmod", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_LASTMOD,
&config_generic, "( OLcfgDbAt:0.4 NAME 'olcLastMod' "
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ "moduleload", "file", 2, 0, 0,
#ifdef SLAPD_MODULES
- ARG_MAGIC|CFG_MODLOAD, &config_generic,
+ ARG_MAGIC|CFG_MODLOAD|ARG_NO_DELETE, &config_generic,
#else
ARG_IGNORED, NULL,
#endif
&config_referral, "( OLcfgGlAt:41 NAME 'olcReferral' "
"SUP labeledURI SINGLE-VALUE )", NULL, NULL },
{ "replica", "host or uri", 2, 0, 0, ARG_DB|ARG_MAGIC,
- &config_replica, "( OLcfgDbAt:0.7 NAME 'olcReplica' "
+ &config_obsolete, "( OLcfgDbAt:0.7 NAME 'olcReplica' "
"EQUALITY caseIgnoreMatch "
"SUP labeledURI X-ORDERED 'VALUES' )", NULL, NULL },
- { "replica-argsfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC|ARG_STRING|CFG_REPLICA_ARGSFILE,
- &config_generic, "( OLcfgGlAt:43 NAME 'olcReplicaArgsFile' "
+ { "replica-argsfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC,
+ &config_obsolete, "( OLcfgGlAt:43 NAME 'olcReplicaArgsFile' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
- { "replica-pidfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC|ARG_STRING|CFG_REPLICA_PIDFILE,
- &config_generic, "( OLcfgGlAt:44 NAME 'olcReplicaPidFile' "
+ { "replica-pidfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC,
+ &config_obsolete, "( OLcfgGlAt:44 NAME 'olcReplicaPidFile' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
- { "replicationInterval", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC|ARG_INT|CFG_REPLICATIONINTERVAL,
- &config_generic, "( OLcfgGlAt:45 NAME 'olcReplicationInterval' "
+ { "replicationInterval", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC,
+ &config_obsolete, "( OLcfgGlAt:45 NAME 'olcReplicationInterval' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
- { "replogfile", "filename", 2, 2, 0, ARG_MAY_DB|ARG_MAGIC|ARG_STRING|CFG_REPLOG,
- &config_generic, "( OLcfgGlAt:46 NAME 'olcReplogFile' "
+ { "replogfile", "filename", 2, 2, 0, ARG_MAY_DB|ARG_MAGIC,
+ &config_obsolete, "( OLcfgGlAt:46 NAME 'olcReplogFile' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "require", "features", 2, 0, 7, ARG_MAY_DB|ARG_MAGIC,
&config_requires, "( OLcfgGlAt:47 NAME 'olcRequires' "
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ "rootdn", "dn", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
&config_rootdn, "( OLcfgDbAt:0.8 NAME 'olcRootDN' "
+ "EQUALITY distinguishedNameMatch "
"SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
{ "rootDSE", "file", 2, 2, 0, ARG_MAGIC|CFG_ROOTDSE,
&config_generic, "( OLcfgGlAt:51 NAME 'olcRootDSE' "
&config_generic, NULL, NULL, NULL },
{ "sasl-host", "host", 2, 2, 0,
#ifdef HAVE_CYRUS_SASL
- ARG_STRING|ARG_UNIQUE, &global_host,
+ ARG_STRING|ARG_UNIQUE, &sasl_host,
#else
ARG_IGNORED, NULL,
#endif
&config_generic, NULL, NULL, NULL },
{ "schemadn", "dn", 2, 2, 0, ARG_MAY_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
&config_schema_dn, "( OLcfgGlAt:58 NAME 'olcSchemaDN' "
+ "EQUALITY distinguishedNameMatch "
"SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
{ "security", "factors", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
&config_security, "( OLcfgGlAt:59 NAME 'olcSecurity' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString )", NULL, NULL },
+ { "serverID", "number> <[URI]", 2, 3, 0, ARG_MAGIC|CFG_SERVERID,
+ &config_generic, "( OLcfgGlAt:81 NAME 'olcServerID' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString )", NULL, NULL },
{ "sizelimit", "limit", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
&config_sizelimit, "( OLcfgGlAt:60 NAME 'olcSizeLimit' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "sockbuf_max_incoming_auth", "max", 2, 2, 0, ARG_BER_LEN_T,
&sockbuf_max_incoming_auth, "( OLcfgGlAt:62 NAME 'olcSockbufMaxIncomingAuth' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+ { "sortvals", "attr", 2, 0, 0, ARG_MAGIC|CFG_SORTVALS,
+ &config_generic, "( OLcfgGlAt:83 NAME 'olcSortVals' "
+ "DESC 'Attributes whose values will always be sorted' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString )", NULL, NULL },
{ "subordinate", "[advertise]", 1, 2, 0, ARG_DB|ARG_MAGIC,
&config_subordinate, "( OLcfgDbAt:0.15 NAME 'olcSubordinate' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
"SYNTAX OMsDN )", NULL, NULL },
{ "syncrepl", NULL, 0, 0, 0, ARG_DB|ARG_MAGIC,
&syncrepl_config, "( OLcfgDbAt:0.11 NAME 'olcSyncrepl' "
- "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
{ "threads", "count", 2, 2, 0,
#ifdef NO_THREADS
ARG_IGNORED, NULL,
#endif
"( OLcfgGlAt:73 NAME 'olcTLSCRLCheck' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "TLSCRLFile", NULL, 0, 0, 0,
+#if defined(HAVE_GNUTLS)
+ CFG_TLS_CRL_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
+#else
+ ARG_IGNORED, NULL,
+#endif
+ "( OLcfgGlAt:82 NAME 'olcTLSCRLFile' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "TLSRandFile", NULL, 0, 0, 0,
#ifdef HAVE_TLS
CFG_TLS_RAND|ARG_STRING|ARG_MAGIC, &config_tls_option,
};
/* Routines to check if a child can be added to this type */
-static ConfigLDAPadd cfAddSchema, cfAddDatabase,
+static ConfigLDAPadd cfAddSchema, cfAddInclude, cfAddDatabase,
cfAddBackend, cfAddModule, cfAddOverlay;
/* NOTE: be careful when defining array members
#define CFOC_BACKEND cf_ocs[3]
#define CFOC_DATABASE cf_ocs[4]
#define CFOC_OVERLAY cf_ocs[5]
-#define CFOC_FRONTEND cf_ocs[6]
+#define CFOC_INCLUDE cf_ocs[6]
+#define CFOC_FRONTEND cf_ocs[7]
#ifdef SLAPD_MODULES
-#define CFOC_MODULE cf_ocs[7]
+#define CFOC_MODULE cf_ocs[8]
#endif /* SLAPD_MODULES */
static ConfigOCs cf_ocs[] = {
"olcConnMaxPending $ olcConnMaxPendingAuth $ "
"olcDisallows $ olcGentleHUP $ olcIdleTimeout $ "
"olcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ "
- "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcLocalSSF $ "
- "olcLogLevel $ "
+ "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ "
+ "olcLocalSSF $ olcLogLevel $ "
"olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ "
"olcPluginLogFile $ olcReadOnly $ olcReferral $ "
"olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
"olcRootDSE $ "
"olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
- "olcSecurity $ olcSizeLimit $ "
+ "olcSecurity $ olcServerID $ olcSizeLimit $ "
"olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ "
"olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
"olcTLSCACertificatePath $ olcTLSCertificateFile $ "
"olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
"olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
- "olcToolThreads $ "
+ "olcTLSCRLFile $ olcToolThreads $ "
"olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
"olcDitContentRules ) )", Cft_Global },
{ "( OLcfgGlOc:2 "
"DESC 'OpenLDAP Overlay-specific options' "
"SUP olcConfig STRUCTURAL "
"MUST olcOverlay )", Cft_Overlay, NULL, cfAddOverlay },
+ { "( OLcfgGlOc:6 "
+ "NAME 'olcIncludeFile' "
+ "DESC 'OpenLDAP configuration include file' "
+ "SUP olcConfig STRUCTURAL "
+ "MUST olcInclude "
+ "MAY ( cn $ olcRootDSE ) )",
+ /* Used to be Cft_Include, that def has been removed */
+ Cft_Abstract, NULL, cfAddInclude },
/* This should be STRUCTURAL like all the other database classes, but
* that would mean inheriting all of the olcDatabaseConfig attributes,
* which causes them to be merged twice in config_build_entry.
"NAME 'olcFrontendConfig' "
"DESC 'OpenLDAP frontend configuration' "
"AUXILIARY "
- "MAY olcDefaultSearchBase )",
+ "MAY ( olcDefaultSearchBase $ olcPasswordHash $ olcSortVals ) )",
Cft_Database, NULL, NULL },
#ifdef SLAPD_MODULES
{ "( OLcfgGlOc:8 "
{ NULL, 0, NULL }
};
+typedef struct ServerID {
+ struct ServerID *si_next;
+ struct berval si_url;
+ int si_num;
+} ServerID;
+
+static ServerID *sid_list;
+
+typedef struct voidList {
+ struct voidList *vl_next;
+ void *vl_ptr;
+} voidList;
+
+typedef struct ADlist {
+ struct ADlist *al_next;
+ AttributeDescription *al_desc;
+} ADlist;
+
+static ADlist *sortVals;
+
static int
config_generic(ConfigArgs *c) {
int i;
if ( c->be->be_limits ) {
char buf[4096*3];
struct berval bv;
- int i;
for ( i=0; c->be->be_limits[i]; i++ ) {
bv.bv_len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i );
}
break;
case CFG_OID: {
- ConfigFile *cf = c->private;
+ ConfigFile *cf = c->ca_private;
if ( !cf )
oidm_unparse( &c->rvalue_vals, NULL, NULL, 1 );
else if ( cf->c_om_head )
ad_unparse_options( &c->rvalue_vals );
break;
case CFG_OC: {
- ConfigFile *cf = c->private;
+ ConfigFile *cf = c->ca_private;
if ( !cf )
oc_unparse( &c->rvalue_vals, NULL, NULL, 1 );
else if ( cf->c_oc_head )
}
break;
case CFG_ATTR: {
- ConfigFile *cf = c->private;
+ ConfigFile *cf = c->ca_private;
if ( !cf )
at_unparse( &c->rvalue_vals, NULL, NULL, 1 );
else if ( cf->c_at_head )
}
break;
case CFG_DIT: {
- ConfigFile *cf = c->private;
+ ConfigFile *cf = c->ca_private;
if ( !cf )
cr_unparse( &c->rvalue_vals, NULL, NULL, 1 );
else if ( cf->c_cr_head )
AccessControl *a;
char *src, *dst, ibuf[11];
struct berval bv, abv;
- for (i=0, a=c->be->be_acl; a; i++,a=a->acl_next) {
+ AccessControl *end;
+ if ( c->be == frontendDB )
+ end = NULL;
+ else
+ end = frontendDB->be_acl;
+ for (i=0, a=c->be->be_acl; a && a != end; i++,a=a->acl_next) {
abv.bv_len = snprintf( ibuf, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i );
if ( abv.bv_len >= sizeof( ibuf ) ) {
ber_bvarray_free_x( c->rvalue_vals, NULL );
rc = (!i);
break;
}
- case CFG_REPLICA_ARGSFILE:
- if ( c->be->be_replica_argsfile )
- c->value_string = ch_strdup( c->be->be_replica_argsfile );
- break;
- case CFG_REPLICA_PIDFILE:
- if ( c->be->be_replica_pidfile )
- c->value_string = ch_strdup( c->be->be_replica_pidfile );
- break;
- case CFG_REPLICATIONINTERVAL:
- if ( c->be->be_replicationinterval > 0 ) {
- c->value_int = c->be->be_replicationinterval;
- } else {
- rc = 1;
- }
- break;
- case CFG_REPLOG:
- if ( c->be->be_replogfile )
- c->value_string = ch_strdup( c->be->be_replogfile );
- break;
case CFG_ROOTDSE: {
- ConfigFile *cf = c->private;
+ ConfigFile *cf = c->ca_private;
if ( cf->c_dseFiles ) {
value_add( &c->rvalue_vals, cf->c_dseFiles );
} else {
}
}
break;
+ case CFG_SERVERID:
+ if ( sid_list ) {
+ ServerID *si;
+ struct berval bv;
+
+ for ( si = sid_list; si; si=si->si_next ) {
+ assert( si->si_num >= 0 && si->si_num <= SLAP_SYNC_SID_MAX );
+ if ( !BER_BVISEMPTY( &si->si_url )) {
+ bv.bv_len = si->si_url.bv_len + 6;
+ bv.bv_val = ch_malloc( bv.bv_len );
+ sprintf( bv.bv_val, "%d %s", si->si_num,
+ si->si_url.bv_val );
+ ber_bvarray_add( &c->rvalue_vals, &bv );
+ } else {
+ char buf[5];
+ bv.bv_val = buf;
+ bv.bv_len = sprintf( buf, "%d", si->si_num );
+ value_add_one( &c->rvalue_vals, &bv );
+ }
+ }
+ } else {
+ rc = 1;
+ }
+ break;
case CFG_LOGFILE:
if ( logfileName )
c->value_string = ch_strdup( logfileName );
case CFG_SSTR_IF_MIN:
c->value_int = index_substr_if_minlen;
break;
+ case CFG_IX_INTLEN:
+ c->value_int = index_intlen;
+ break;
+ case CFG_SORTVALS: {
+ ADlist *sv;
+ rc = 1;
+ for ( sv = sortVals; sv; sv = sv->al_next ) {
+ value_add_one( &c->rvalue_vals, &sv->al_desc->ad_cname );
+ rc = 0;
+ }
+ } break;
#ifdef SLAPD_MODULES
case CFG_MODLOAD: {
- ModPaths *mp = c->private;
+ ModPaths *mp = c->ca_private;
if (mp->mp_loads) {
int i;
for (i=0; !BER_BVISNULL(&mp->mp_loads[i]); i++) {
}
break;
case CFG_MODPATH: {
- ModPaths *mp = c->private;
+ ModPaths *mp = c->ca_private;
if ( !BER_BVISNULL( &mp->mp_path ))
value_add_one( &c->rvalue_vals, &mp->mp_path );
passwd_salt = NULL;
break;
- case CFG_REPLICA_ARGSFILE:
- ch_free( c->be->be_replica_argsfile );
- c->be->be_replica_argsfile = NULL;
- break;
-
- case CFG_REPLICA_PIDFILE:
- ch_free( c->be->be_replica_pidfile );
- c->be->be_replica_pidfile = NULL;
- break;
-
- case CFG_REPLICATIONINTERVAL:
- c->be->be_replicationinterval = 0;
- break;
-
- case CFG_REPLOG:
- ch_free( c->be->be_replogfile );
- c->be->be_replogfile = NULL;
- break;
-
case CFG_LOGFILE:
ch_free( logfileName );
logfileName = NULL;
+ if ( logfile ) {
+ fclose( logfile );
+ logfile = NULL;
+ }
break;
+ case CFG_SERVERID: {
+ ServerID *si, **sip;
+
+ for ( i=0, si = sid_list, sip = &sid_list;
+ si; si = *sip, i++ ) {
+ if ( c->valx == -1 || i == c->valx ) {
+ *sip = si->si_next;
+ ch_free( si );
+ if ( c->valx >= 0 )
+ break;
+ } else {
+ sip = &si->si_next;
+ }
+ }
+ }
+ break;
case CFG_HIDDEN:
c->be->be_flags &= ~SLAP_DBFLAG_HIDDEN;
break;
+ case CFG_IX_INTLEN:
+ index_intlen = SLAP_INDEX_INTLEN_DEFAULT;
+ index_intlen_strlen = SLAP_INDEX_INTLEN_STRLEN(
+ SLAP_INDEX_INTLEN_DEFAULT );
+ break;
+
case CFG_ACL:
if ( c->valx < 0 ) {
AccessControl *end;
break;
case CFG_OC: {
- CfEntryInfo *ce = c->ca_entry->e_private;
- /* can't modify the hardcoded schema */
- if ( ce->ce_parent->ce_type == Cft_Global )
- return 1;
+ CfEntryInfo *ce;
+ /* Can be NULL when undoing a failed add */
+ if ( c->ca_entry ) {
+ ce = c->ca_entry->e_private;
+ /* can't modify the hardcoded schema */
+ if ( ce->ce_parent->ce_type == Cft_Global )
+ return 1;
+ }
}
- cfn = c->private;
+ cfn = c->ca_private;
if ( c->valx < 0 ) {
ObjectClass *oc;
cfn->c_oc_head = cfn->c_oc_tail = NULL;
} else {
ObjectClass *oc, *prev = NULL;
- int i;
for ( i=0, oc=cfn->c_oc_head; i<c->valx; i++) {
prev = oc;
break;
case CFG_ATTR: {
- CfEntryInfo *ce = c->ca_entry->e_private;
- /* can't modify the hardcoded schema */
- if ( ce->ce_parent->ce_type == Cft_Global )
- return 1;
+ CfEntryInfo *ce;
+ /* Can be NULL when undoing a failed add */
+ if ( c->ca_entry ) {
+ ce = c->ca_entry->e_private;
+ /* can't modify the hardcoded schema */
+ if ( ce->ce_parent->ce_type == Cft_Global )
+ return 1;
+ }
}
- cfn = c->private;
+ cfn = c->ca_private;
if ( c->valx < 0 ) {
AttributeType *at;
cfn->c_at_head = cfn->c_at_tail = NULL;
} else {
AttributeType *at, *prev = NULL;
- int i;
for ( i=0, at=cfn->c_at_head; i<c->valx; i++) {
prev = at;
}
}
break;
+ case CFG_SORTVALS:
+ if ( c->valx < 0 ) {
+ ADlist *sv;
+ for ( sv = sortVals; sv; sv = sortVals ) {
+ sortVals = sv->al_next;
+ sv->al_desc->ad_type->sat_flags &= ~SLAP_AT_SORTED_VAL;
+ ch_free( sv );
+ }
+ } else {
+ ADlist *sv, **prev;
+ int i = 0;
+
+ for ( prev = &sortVals, sv = sortVals; i < c->valx; i++ ) {
+ prev = &sv->al_next;
+ sv = sv->al_next;
+ }
+ sv->al_desc->ad_type->sat_flags &= ~SLAP_AT_SORTED_VAL;
+ *prev = sv->al_next;
+ ch_free( sv );
+ }
+ break;
case CFG_LIMITS:
/* FIXME: there is no limits_free function */
switch(c->type) {
case CFG_BACKEND:
if(!(c->bi = backend_info(c->argv[1]))) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> failed init", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> failed init", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
- c->log, c->msg, c->argv[1] );
+ c->log, c->cr_msg, c->argv[1] );
return(1);
}
break;
} else if ( !strcasecmp( c->argv[1], "frontend" )) {
c->be = frontendDB;
} else {
- c->be = backend_db_init(c->argv[1], NULL, c->valx);
+ c->be = backend_db_init(c->argv[1], NULL, c->valx, &c->reply);
if ( !c->be ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> failed init", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
- c->log, c->msg, c->argv[1] );
+ if ( c->cr_msg[0] == 0 )
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> failed init", c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n", c->log, c->cr_msg, c->argv[1] );
return(1);
}
}
case CFG_THREADS:
if ( c->value_int < 2 ) {
- snprintf( c->msg, sizeof( c->msg ),
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
"threads=%d smaller than minimum value 2",
c->value_int );
Debug(LDAP_DEBUG_ANY, "%s: %s.\n",
- c->log, c->msg, 0 );
+ c->log, c->cr_msg, 0 );
return 1;
} else if ( c->value_int > 2 * SLAP_MAX_WORKER_THREADS ) {
- snprintf( c->msg, sizeof( c->msg ),
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
"warning, threads=%d larger than twice the default (2*%d=%d); YMMV",
c->value_int, SLAP_MAX_WORKER_THREADS, 2 * SLAP_MAX_WORKER_THREADS );
Debug(LDAP_DEBUG_ANY, "%s: %s.\n",
- c->log, c->msg, 0 );
+ c->log, c->cr_msg, 0 );
}
if ( slapMode & SLAP_SERVER_MODE )
ldap_pvt_thread_pool_maxthreads(&connection_pool, c->value_int);
case CFG_AZPOLICY:
ch_free(c->value_string);
if (slap_sasl_setpolicy( c->argv[1] )) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, c->argv[1] );
+ c->log, c->cr_msg, c->argv[1] );
return(1);
}
break;
{
char *txt = slap_sasl_secprops( c->argv[1] );
if ( txt ) {
- snprintf( c->msg, sizeof(c->msg), "<%s> %s",
+ snprintf( c->cr_msg, sizeof(c->cr_msg), "<%s> %s",
c->argv[0], txt );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
+ Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->cr_msg, 0 );
return(1);
}
break;
case CFG_OID: {
OidMacro *om;
- if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
- cfn = c->private;
+ if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+ cfn = c->ca_private;
if(parse_oidm(c, 1, &om))
return(1);
if (!cfn->c_om_head) cfn->c_om_head = om;
case CFG_OC: {
ObjectClass *oc, *prev;
- if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
- cfn = c->private;
+ if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+ cfn = c->ca_private;
if ( c->valx < 0 ) {
prev = cfn->c_oc_tail;
} else {
case CFG_ATTR: {
AttributeType *at, *prev;
- if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
- cfn = c->private;
+ if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+ cfn = c->ca_private;
if ( c->valx < 0 ) {
prev = cfn->c_at_tail;
} else {
case CFG_DIT: {
ContentRule *cr;
- if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
- cfn = c->private;
+ if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+ cfn = c->ca_private;
if(parse_cr(c, &cr)) return(1);
if (!cfn->c_cr_head) cfn->c_cr_head = cr;
cfn->c_cr_tail = cr;
return(1);
break;
+ case CFG_IX_INTLEN:
+ if ( c->value_int < SLAP_INDEX_INTLEN_DEFAULT )
+ c->value_int = SLAP_INDEX_INTLEN_DEFAULT;
+ else if ( c->value_int > 255 )
+ c->value_int = 255;
+ index_intlen = c->value_int;
+ index_intlen_strlen = SLAP_INDEX_INTLEN_STRLEN(
+ index_intlen );
+ break;
+
+ case CFG_SORTVALS: {
+ ADlist *svnew = NULL, *svtail, *sv;
+
+ for ( i = 1; i < c->argc; i++ ) {
+ AttributeDescription *ad = NULL;
+ const char *text;
+ int rc;
+
+ rc = slap_str2ad( c->argv[i], &ad, &text );
+ if ( rc ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown attribute type #%d",
+ c->argv[0], i );
+sortval_reject:
+ Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+ c->log, c->cr_msg, c->argv[i] );
+ for ( sv = svnew; sv; sv = svnew ) {
+ svnew = sv->al_next;
+ ch_free( sv );
+ }
+ return 1;
+ }
+ if (( ad->ad_type->sat_flags & SLAP_AT_ORDERED ) ||
+ ad->ad_type->sat_single_value ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> inappropriate attribute type #%d",
+ c->argv[0], i );
+ goto sortval_reject;
+ }
+ sv = ch_malloc( sizeof( ADlist ));
+ sv->al_desc = ad;
+ if ( !svnew ) {
+ svnew = sv;
+ } else {
+ svtail->al_next = sv;
+ }
+ svtail = sv;
+ }
+ sv->al_next = NULL;
+ for ( sv = svnew; sv; sv = sv->al_next )
+ sv->al_desc->ad_type->sat_flags |= SLAP_AT_SORTED_VAL;
+ for ( sv = sortVals; sv && sv->al_next; sv = sv->al_next );
+ if ( sv )
+ sv->al_next = svnew;
+ else
+ sortVals = svnew;
+ }
+ break;
+
case CFG_ACL:
/* Don't append to the global ACL if we're on a specific DB */
i = c->valx;
}
break;
- case CFG_REPLICA_ARGSFILE:
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica-argsfile\" should not be used "
- "inside monitor database\n",
- c->log, 0, 0);
- /* FIXME: should this be an error? */
- return(0);
- }
-
- if ( c->be->be_replica_argsfile != NULL ) {
- /* FIXME: error? */
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica-argsfile\" already provided; "
- "replacing \"%s\" with \"%s\".\n",
- c->log, c->be->be_replica_argsfile, c->value_string );
- ch_free( c->be->be_replica_argsfile );
- }
-
- c->be->be_replica_argsfile = c->value_string;
- break;
-
- case CFG_REPLICA_PIDFILE:
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica-pidfile\" should not be used "
- "inside monitor database\n",
- c->log, 0, 0);
- /* FIXME: should this be an error? */
- return(0);
- }
-
- if ( c->be->be_replica_pidfile != NULL ) {
- /* FIXME: error? */
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica-pidfile\" already provided; "
- "replacing \"%s\" with \"%s\".\n",
- c->log, c->be->be_replica_pidfile, c->value_string );
- ch_free( c->be->be_replica_pidfile );
- }
-
- c->be->be_replica_pidfile = c->value_string;
- break;
-
- case CFG_REPLICATIONINTERVAL:
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replicationinterval\" should not be used "
- "inside monitor database\n",
- c->log, 0, 0);
- /* FIXME: should this be an error? */
- return(0);
- }
-
- c->be->be_replicationinterval = c->value_int;
- break;
-
- case CFG_REPLOG:
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replogfile\" should not be used "
- "inside monitor database\n",
- c->log, 0, 0);
- /* FIXME: should this be an error? */
- return(0);
- }
-
- if ( c->be->be_replogfile != NULL ) {
- /* FIXME: error? */
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replogfile\" already provided; "
- "replacing \"%s\" with \"%s\".\n",
- c->log, c->be->be_replogfile, c->value_string );
- ch_free( c->be->be_replogfile );
- }
-
- c->be->be_replogfile = c->value_string;
- break;
-
case CFG_ROOTDSE:
if(root_dse_read_file(c->argv[1])) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> could not read file", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> could not read file", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
- c->log, c->msg, c->argv[1] );
+ c->log, c->cr_msg, c->argv[1] );
return(1);
}
{
struct berval bv;
ber_str2bv( c->argv[1], 0, 1, &bv );
- if ( c->op == LDAP_MOD_ADD && c->private && cfn != c->private )
- cfn = c->private;
+ if ( c->op == LDAP_MOD_ADD && c->ca_private && cfn != c->ca_private )
+ cfn = c->ca_private;
ber_bvarray_add( &cfn->c_dseFiles, &bv );
}
break;
+ case CFG_SERVERID:
+ {
+ ServerID *si, **sip;
+ LDAPURLDesc *lud;
+ int num;
+ if ( lutil_atoi( &num, c->argv[1] ) ||
+ num < 0 || num > SLAP_SYNC_SID_MAX )
+ {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "<%s> illegal server ID", c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+ c->log, c->cr_msg, c->argv[1] );
+ return 1;
+ }
+ /* only one value allowed if no URL is given */
+ if ( c->argc > 2 ) {
+ int len;
+
+ if ( sid_list && BER_BVISEMPTY( &sid_list->si_url )) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "<%s> only one server ID allowed now", c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+ c->log, c->cr_msg, c->argv[1] );
+ return 1;
+ }
+
+ if ( ldap_url_parse( c->argv[2], &lud )) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "<%s> invalid URL", c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+ c->log, c->cr_msg, c->argv[2] );
+ return 1;
+ }
+ len = strlen( c->argv[2] );
+ si = ch_malloc( sizeof(ServerID) + len + 1 );
+ si->si_url.bv_val = (char *)(si+1);
+ si->si_url.bv_len = len;
+ strcpy( si->si_url.bv_val, c->argv[2] );
+ } else {
+ if ( sid_list ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "<%s> unqualified server ID not allowed now", c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+ c->log, c->cr_msg, c->argv[1] );
+ return 1;
+ }
+ si = ch_malloc( sizeof(ServerID) );
+ BER_BVZERO( &si->si_url );
+ slap_serverID = num;
+ Debug( LDAP_DEBUG_CONFIG,
+ "%s: SID=%d\n",
+ c->log, slap_serverID, 0 );
+ }
+ si->si_next = NULL;
+ si->si_num = num;
+ for ( sip = &sid_list; *sip; sip = &(*sip)->si_next );
+ *sip = si;
+
+ if (( slapMode & SLAP_SERVER_MODE ) && c->argc > 2 ) {
+ /* If hostname is empty, or is localhost, or matches
+ * our hostname, this serverID refers to this host.
+ * Compare it against listeners and ports.
+ */
+ if ( !lud->lud_host || !lud->lud_host[0] ||
+ !strncasecmp("localhost", lud->lud_host,
+ STRLENOF("localhost")) ||
+ !strcasecmp( global_host, lud->lud_host )) {
+ Listener **l = slapd_get_listeners();
+ int i;
+
+ for ( i=0; l && l[i]; i++ ) {
+ LDAPURLDesc *lu2;
+ int isMe = 0;
+ ldap_url_parse( l[i]->sl_url.bv_val, &lu2 );
+ do {
+ if ( strcasecmp( lud->lud_scheme,
+ lu2->lud_scheme ))
+ break;
+ if ( lud->lud_port != lu2->lud_port )
+ break;
+ /* Listener on ANY address */
+ if ( !lu2->lud_host || !lu2->lud_host[0] ) {
+ isMe = 1;
+ break;
+ }
+ /* URL on ANY address */
+ if ( !lud->lud_host || !lud->lud_host[0] ) {
+ isMe = 1;
+ break;
+ }
+ /* Listener has specific host, must
+ * match it
+ */
+ if ( !strcasecmp( lud->lud_host,
+ lu2->lud_host )) {
+ isMe = 1;
+ break;
+ }
+ } while(0);
+ ldap_free_urldesc( lu2 );
+ if ( isMe ) {
+ slap_serverID = si->si_num;
+ Debug( LDAP_DEBUG_CONFIG,
+ "%s: SID=%d (listener=%s)\n",
+ c->log, slap_serverID,
+ l[i]->sl_url.bv_val );
+ break;
+ }
+ }
+ }
+ }
+ if ( c->argc > 2 )
+ ldap_free_urldesc( lud );
+ }
+ break;
case CFG_LOGFILE: {
- FILE *logfile;
if ( logfileName ) ch_free( logfileName );
logfileName = c->value_string;
logfile = fopen(logfileName, "w");
case CFG_LASTMOD:
if(SLAP_NOLASTMODCMD(c->be)) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> not available for %s database",
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> not available for %s database",
c->argv[0], c->be->bd_info->bi_type );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
- c->log, c->msg, 0 );
+ c->log, c->cr_msg, 0 );
return(1);
}
if(c->value_int)
case CFG_MIRRORMODE:
if(!SLAP_SHADOW(c->be)) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> database is not a shadow",
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> database is not a shadow",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
- c->log, c->msg, 0 );
+ c->log, c->cr_msg, 0 );
return(1);
}
if(c->value_int)
case CFG_SSTR_IF_MAX:
if (c->value_int < index_substr_if_minlen) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
- c->log, c->msg, c->value_int );
+ c->log, c->cr_msg, c->value_int );
return(1);
}
index_substr_if_maxlen = c->value_int;
case CFG_SSTR_IF_MIN:
if (c->value_int > index_substr_if_maxlen) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
- c->log, c->msg, c->value_int );
+ c->log, c->cr_msg, c->value_int );
return(1);
}
index_substr_if_minlen = c->value_int;
/* If we're just adding a module on an existing modpath,
* make sure we've selected the current path.
*/
- if ( c->op == LDAP_MOD_ADD && c->private && modcur != c->private ) {
- modcur = c->private;
+ if ( c->op == LDAP_MOD_ADD && c->ca_private && modcur != c->ca_private ) {
+ modcur = c->ca_private;
/* This should never fail */
if ( module_path( modcur->mp_path.bv_val )) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> module path no longer valid",
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> module path no longer valid",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
- c->log, c->msg, modcur->mp_path.bv_val );
+ c->log, c->cr_msg, modcur->mp_path.bv_val );
return(1);
}
}
mp->mp_next = NULL;
mp->mp_loads = NULL;
modlast = mp;
- c->private = mp;
+ c->ca_private = mp;
modcur = mp;
}
static int
config_fname(ConfigArgs *c) {
if(c->op == SLAP_CONFIG_EMIT) {
- if (c->private) {
- ConfigFile *cf = c->private;
+ if (c->ca_private) {
+ ConfigFile *cf = c->ca_private;
value_add_one( &c->rvalue_vals, &cf->c_file );
return 0;
}
return(0);
}
+/* For RE23 compatibility we allow this in the global entry
+ * but we now defer it to the frontend entry to allow modules
+ * to load new hash types.
+ */
static int
config_passwd_hash(ConfigArgs *c) {
int i;
if (c->op == SLAP_CONFIG_EMIT) {
struct berval bv;
+ /* Don't generate it in the global entry */
+ if ( c->table == Cft_Global )
+ return 1;
for (i=0; default_passwd_hash && default_passwd_hash[i]; i++) {
ber_str2bv(default_passwd_hash[i], 0, 0, &bv);
value_add_one(&c->rvalue_vals, &bv);
}
return i ? 0 : 1;
} else if ( c->op == LDAP_MOD_DELETE ) {
+ /* Deleting from global is a no-op, only the frontendDB entry matters */
+ if ( c->table == Cft_Global )
+ return 0;
if ( c->valx < 0 ) {
ldap_charray_free( default_passwd_hash );
default_passwd_hash = NULL;
}
return 0;
}
- if(default_passwd_hash) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "already set default password_hash\n",
- c->log, 0, 0);
- return(1);
- }
for(i = 1; i < c->argc; i++) {
if(!lutil_passwd_scheme(c->argv[i])) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> scheme not available", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> scheme not available", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
} else {
ldap_charray_add(&default_passwd_hash, c->argv[i]);
}
- if(!default_passwd_hash) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> no valid hashes found", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n",
- c->log, c->msg, 0 );
- return(1);
- }
+ }
+ if(!default_passwd_hash) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> no valid hashes found", c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s\n",
+ c->log, c->cr_msg, 0 );
+ return(1);
}
return(0);
}
if(!strncasecmp(c->argv[i], "size", 4)) {
rc = limits_parse_one(c->argv[i], lim);
if ( rc ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return(1);
}
} else {
lim->lms_s_soft = -1;
} else {
if ( lutil_atoix( &lim->lms_s_soft, c->argv[i], 0 ) != 0 ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse limit", c->argv[0]);
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return(1);
}
}
if(!strncasecmp(c->argv[i], "time", 4)) {
rc = limits_parse_one(c->argv[i], lim);
if ( rc ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse value", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse value", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return(1);
}
} else {
lim->lms_t_soft = -1;
} else {
if ( lutil_atoix( &lim->lms_t_soft, c->argv[i], 0 ) != 0 ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse limit", c->argv[0]);
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return(1);
}
}
assert(0);
}
if(c->argv[1][0] == '-' && overlay_config(c->be, &c->argv[1][1],
- c->valx, &c->bi)) {
+ c->valx, &c->bi, &c->reply)) {
/* log error */
Debug( LDAP_DEBUG_ANY,
"%s: (optional) %s overlay \"%s\" configuration failed.\n",
c->log, c->be == frontendDB ? "global " : "", &c->argv[1][1]);
return 1;
- } else if(overlay_config(c->be, c->argv[1], c->valx, &c->bi)) {
+ } else if(overlay_config(c->be, c->argv[1], c->valx, &c->bi, &c->reply)) {
return(1);
}
return(0);
#ifdef SLAPD_MONITOR_DN
if(!strcasecmp(c->argv[1], SLAPD_MONITOR_DN)) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> DN is reserved for monitoring slapd",
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> DN is reserved for monitoring slapd",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
- c->log, c->msg, SLAPD_MONITOR_DN);
+ c->log, c->cr_msg, SLAPD_MONITOR_DN);
return(1);
}
#endif
+ if (SLAP_DB_ONE_SUFFIX( c->be ) && c->be->be_suffix ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> Only one suffix is allowed on this %s backend",
+ c->argv[0], c->be->bd_info->bi_type );
+ Debug(LDAP_DEBUG_ANY, "%s: %s\n",
+ c->log, c->cr_msg, 0);
+ return(1);
+ }
+
pdn = c->value_dn;
ndn = c->value_ndn;
+
if (SLAP_DBHIDDEN( c->be ))
tbe = NULL;
else
- tbe = select_backend(&ndn, 0, 0);
+ tbe = select_backend(&ndn, 0);
if(tbe == c->be) {
Debug( LDAP_DEBUG_ANY, "%s: suffix already served by this backend!.\n",
c->log, 0, 0);
type = oi->oi_orig->bi_type;
}
- snprintf( c->msg, sizeof( c->msg ), "<%s> namingContext \"%s\" "
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> namingContext \"%s\" "
"already served by a preceding %s database",
c->argv[0], pdn.bv_val, type );
Debug(LDAP_DEBUG_ANY, "%s: %s serving namingContext \"%s\"\n",
- c->log, c->msg, tbe->be_suffix[0].bv_val);
+ c->log, c->cr_msg, tbe->be_suffix[0].bv_val);
free(pdn.bv_val);
free(ndn.bv_val);
return(1);
return 0;
}
- tbe = select_backend(&c->be->be_rootndn, 0, 0);
+ tbe = select_backend(&c->be->be_rootndn, 0);
if(tbe != c->be) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> can only be set when rootdn is under suffix",
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> can only be set when rootdn is under suffix",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
- c->log, c->msg, 0);
+ c->log, c->cr_msg, 0);
return(1);
}
if ( !BER_BVISNULL( &c->be->be_rootpw ))
}
i = verbs_to_mask( c->argc, c->argv, restrictable_ops, &restrictops );
if ( i ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unknown operation", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown operation", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return(1);
}
if ( restrictops & SLAP_RESTRICT_OP_EXTENDED )
}
i = verbs_to_mask(c->argc, c->argv, allowable_ops, &allows);
if ( i ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown feature", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return(1);
}
global_allows |= allows;
}
i = verbs_to_mask(c->argc, c->argv, disallowable_ops, &disallows);
if ( i ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown feature", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return(1);
}
global_disallows |= disallows;
i = verbs_to_mask(argc, argv, requires_ops, &requires);
if ( i ) {
if (strcasecmp( c->argv[ i ], "none" ) == 0 ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> \"none\" (#%d) must be listed first", c->argv[0], i - 1 );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> \"none\" (#%d) must be listed first", c->argv[0], i - 1 );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
- c->log, c->msg, 0);
+ c->log, c->cr_msg, 0);
} else {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unknown feature #%d", c->argv[0], i - 1 );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown feature #%d", c->argv[0], i - 1 );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
}
return(1);
}
slap_loglevel_get( struct berval *s, int *l )
{
int rc;
- unsigned long i;
- slap_mask_t m;
+ slap_mask_t m, i;
if ( loglevel_ops == NULL ) {
loglevel_init();
m |= loglevel_ops[ i ].mask;
}
- m = ~m;
-
- for ( i = 1; i <= ( 1 << ( sizeof( int ) * 8 - 1 ) ) && !( m & i ); i <<= 1 )
+ for ( i = 1; m & i; i <<= 1 )
;
- if ( !( m & i ) ) {
+ if ( i == 0 ) {
return -1;
}
return 0;
}
- config_syslog = 0;
-
for( i=1; i < c->argc; i++ ) {
int level;
if ( isdigit((unsigned char)c->argv[i][0]) || c->argv[i][0] == '-' ) {
if( lutil_atoi( &level, c->argv[i] ) != 0 ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse level", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse level", c->argv[0] );
Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return( 1 );
}
} else {
if ( str2loglevel( c->argv[i], &level ) ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unknown level", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown level", c->argv[0] );
Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return( 1 );
}
}
- config_syslog |= level;
+ /* Explicitly setting a zero clears all the levels */
+ if ( level )
+ config_syslog |= level;
+ else
+ config_syslog = 0;
}
if ( slapMode & SLAP_SERVER_MODE ) {
ldap_syslog = config_syslog;
return 0;
}
if(validate_global_referral(c->argv[1])) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid URL", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid URL", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
- c->log, c->msg, c->argv[1]);
+ c->log, c->cr_msg, c->argv[1]);
return(1);
}
}
}
if ( !tgt ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unknown factor", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unknown factor", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return(1);
}
if ( lutil_atou( tgt, src ) != 0 ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse factor", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to parse factor", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, c->argv[i]);
+ c->log, c->cr_msg, c->argv[i]);
return(1);
}
}
return ptr;
}
-static void
-replica_unparse( struct slap_replica_info *ri, int i, struct berval *bv )
-{
- int len;
- char *ptr;
- struct berval bc = BER_BVNULL;
- char numbuf[32];
-
- assert( !BER_BVISNULL( &ri->ri_bindconf.sb_uri ) );
-
- BER_BVZERO( bv );
-
- len = snprintf(numbuf, sizeof( numbuf ), SLAP_X_ORDERED_FMT, i );
- if ( len >= sizeof( numbuf ) ) {
- /* FIXME: how can indicate error? */
- return;
- }
-
- if ( ri->ri_nsuffix ) {
- for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
- len += ri->ri_nsuffix[i].bv_len + STRLENOF(" suffix=\"\"");
- }
- }
- if ( ri->ri_attrs ) {
- len += STRLENOF(" attrs");
- if ( ri->ri_exclude ) len++;
- for (i=0; !BER_BVISNULL( &ri->ri_attrs[i].an_name ); i++) {
- len += 1 + ri->ri_attrs[i].an_name.bv_len;
- }
- }
- bindconf_unparse( &ri->ri_bindconf, &bc );
- len += bc.bv_len;
-
- bv->bv_val = ch_malloc(len + 1);
- bv->bv_len = len;
-
- ptr = lutil_strcopy( bv->bv_val, numbuf );
-
- /* start with URI from bindconf */
- assert( !BER_BVISNULL( &bc ) );
- if ( bc.bv_val ) {
- strcpy( ptr, bc.bv_val );
- ch_free( bc.bv_val );
- }
-
- if ( ri->ri_nsuffix ) {
- for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
- ptr = lutil_strcopy( ptr, " suffix=\"" );
- ptr = lutil_strcopy( ptr, ri->ri_nsuffix[i].bv_val );
- *ptr++ = '"';
- }
- }
- if ( ri->ri_attrs ) {
- ptr = lutil_strcopy( ptr, " attrs" );
- if ( ri->ri_exclude ) *ptr++ = '!';
- *ptr++ = '=';
- ptr = anlist_unparse( ri->ri_attrs, ptr, 0 );
- }
-}
-
-static int
-config_replica(ConfigArgs *c) {
- int i, nr = -1;
- char *replicahost = NULL, *replicauri = NULL;
- LDAPURLDesc *ludp;
-
- if (c->op == SLAP_CONFIG_EMIT) {
- if (c->be->be_replica) {
- struct berval bv;
- for (i=0;c->be->be_replica[i]; i++) {
- replica_unparse( c->be->be_replica[i], i, &bv );
- ber_bvarray_add( &c->rvalue_vals, &bv );
- }
- return 0;
- }
- return 1;
- } else if ( c->op == LDAP_MOD_DELETE ) {
- /* FIXME: there is no replica_free function */
- if ( c->valx < 0 ) {
- } else {
- }
- }
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica\" should not be used inside monitor database\n",
- c->log, 0, 0);
- return(0); /* FIXME: should this be an error? */
- }
-
- for(i = 1; i < c->argc; i++) {
- if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
- ber_len_t len;
-
- if ( replicauri ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
- return(1);
- }
-
- replicahost = c->argv[i] + STRLENOF("host=");
- len = strlen( replicahost ) + STRLENOF("ldap://");
- replicauri = ch_malloc( len + 1 );
- snprintf( replicauri, len + 1, "ldap://%s", replicahost );
- replicahost = replicauri + STRLENOF( "ldap://");
- nr = add_replica_info(c->be, replicauri, replicahost);
- break;
- } else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
- ber_len_t len;
-
- if ( replicauri ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
- return(1);
- }
-
- if(ldap_url_parse(c->argv[i] + STRLENOF("uri="), &ludp) != LDAP_SUCCESS) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
- return(1);
- }
- if(!ludp->lud_host) {
- ldap_free_urldesc(ludp);
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri - missing hostname",
- c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
- return(1);
- }
-
- len = strlen(ludp->lud_scheme) + strlen(ludp->lud_host) +
- STRLENOF("://") + 1;
- if (ludp->lud_port != LDAP_PORT) {
- if (ludp->lud_port < 1 || ludp->lud_port > 65535) {
- ldap_free_urldesc(ludp);
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid port",
- c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
- return(1);
- }
- len += STRLENOF(":65535");
- }
- replicauri = ch_malloc( len );
- replicahost = lutil_strcopy( replicauri, ludp->lud_scheme );
- replicahost = lutil_strcopy( replicahost, "://" );
- if (ludp->lud_port == LDAP_PORT) {
- strcpy( replicahost, ludp->lud_host );
- } else {
- sprintf( replicahost, "%s:%d",ludp->lud_host,ludp->lud_port );
- }
- ldap_free_urldesc(ludp);
- nr = add_replica_info(c->be, replicauri, replicahost);
- break;
- }
- }
- if(i == c->argc) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> missing host or uri", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
- return(1);
- } else if(nr == -1) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unable to add replica", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg,
- replicauri ? replicauri : "" );
- return(1);
- } else {
- for(i = 1; i < c->argc; i++) {
- if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
- /* dealt with separately; don't let it get to bindconf */
- ;
-
- } else if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
- /* dealt with separately; don't let it get to bindconf */
- ;
-
- } else if(!strncasecmp(c->argv[i], "suffix=", STRLENOF( "suffix="))) {
- switch(add_replica_suffix(c->be, nr, c->argv[i] + STRLENOF("suffix="))) {
- case 1:
- Debug( LDAP_DEBUG_ANY, "%s: "
- "suffix \"%s\" in \"replica\" line is not valid for backend.\n",
- c->log, c->argv[i] + STRLENOF("suffix="), 0);
- return 1;
- break;
- case 2:
- Debug( LDAP_DEBUG_ANY, "%s: "
- "unable to normalize suffix in \"replica\" line.\n",
- c->log, 0, 0);
- return 1;
- break;
- }
-
- } else if (!strncasecmp(c->argv[i], "attr", STRLENOF("attr"))
- || !strncasecmp(c->argv[i], "attrs", STRLENOF("attrs")))
- {
- int exclude = 0;
- char *arg = c->argv[i] + STRLENOF("attr");
- if (arg[0] == 's') {
- arg++;
- } else {
- Debug( LDAP_DEBUG_ANY,
- "%s: \"attr\" "
- "is deprecated (and undocumented); "
- "use \"attrs\" instead.\n",
- c->log, 0, 0 );
- }
- if(arg[0] == '!') {
- arg++;
- exclude = 1;
- }
- if(arg[0] != '=') {
- continue;
- }
- if(add_replica_attrs(c->be, nr, arg + 1, exclude)) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unknown attribute", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, arg + 1);
- return(1);
- }
- } else if ( bindconf_parse( c->argv[i],
- &c->be->be_replica[nr]->ri_bindconf ) ) {
- return(1);
- }
- }
- }
- return(0);
-}
-
static int
config_updatedn(ConfigArgs *c) {
if (c->op == SLAP_CONFIG_EMIT) {
return 0;
}
if(SLAP_SHADOW(c->be)) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> database already shadowed", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> database already shadowed", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
- c->log, c->msg, 0);
+ c->log, c->cr_msg, 0);
return(1);
}
return 0;
}
if(!SLAP_SHADOW(c->be) && !c->be->be_syncinfo) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> must appear after syncrepl or updatedn",
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> must appear after syncrepl or updatedn",
c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s\n",
- c->log, c->msg, 0);
+ c->log, c->cr_msg, 0);
return(1);
}
if(validate_global_referral(c->argv[1])) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid URL", c->argv[0] );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid URL", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)\n",
- c->log, c->msg, c->argv[1]);
+ c->log, c->cr_msg, c->argv[1]);
return(1);
}
ber_str2bv(c->argv[1], 0, 0, &val);
return(0);
}
+static int
+config_obsolete(ConfigArgs *c) {
+ if (c->op == SLAP_CONFIG_EMIT)
+ return 1;
+
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> keyword is obsolete (ignored)",
+ c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->cr_msg, 0);
+ return(0);
+}
+
static int
config_include(ConfigArgs *c) {
int savelineno = c->lineno;
ConfigFile *cfsave = cfn;
ConfigFile *cf2 = NULL;
- /* No dynamic config for include files */
+ /* Leftover from RE23. No dynamic config for include files */
+ if ( c->op == SLAP_CONFIG_EMIT || c->op == LDAP_MOD_DELETE )
+ return 1;
+
cf = ch_calloc( 1, sizeof(ConfigFile));
if ( cfn->c_kids ) {
for (cf2=cfn->c_kids; cf2 && cf2->c_sibs; cf2=cf2->c_sibs) ;
ch_free( cf->c_file.bv_val );
ch_free( cf );
} else {
- c->private = cf;
+ c->ca_private = cf;
}
return(rc);
}
case CFG_TLS_CA_PATH: flag = LDAP_OPT_X_TLS_CACERTDIR; break;
case CFG_TLS_CA_FILE: flag = LDAP_OPT_X_TLS_CACERTFILE; break;
case CFG_TLS_DH_FILE: flag = LDAP_OPT_X_TLS_DHFILE; break;
+#ifdef HAVE_GNUTLS
+ case CFG_TLS_CRL_FILE: flag = LDAP_OPT_X_TLS_CRLFILE; break;
+#endif
default: Debug(LDAP_DEBUG_ANY, "%s: "
"unknown tls_option <0x%x>\n",
c->log, c->type, 0);
rs->sr_err = config_add_internal( sc->cfb, rs->sr_entry, sc->ca, NULL, NULL, NULL );
if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, "config error processing %s: %s\n",
- rs->sr_entry->e_name.bv_val, sc->ca->msg, 0 );
+ rs->sr_entry->e_name.bv_val, sc->ca->cr_msg, 0 );
}
}
return rs->sr_err;
if ( !cfb->cb_db.bd_info )
return 0; /* FIXME: eventually this will be a fatal error */
- if ( backend_db_init( "ldif", &cfb->cb_db, -1 ) == NULL )
+ if ( backend_db_init( "ldif", &cfb->cb_db, -1, NULL ) == NULL )
return 1;
cfb->cb_db.be_suffix = be->be_suffix;
argv[1] = (char *)dir;
argv[2] = NULL;
c.argv = argv;
+ c.reply.err = 0;
+ c.reply.msg[0] = 0;
+ c.table = Cft_Database;
ct = config_find_keyword( c.be->be_cf_ocs->co_table, &c );
if ( !ct )
if ( config_add_vals( ct, &c ))
return 1;
- if ( backend_startup_one( &cfb->cb_db ))
+ if ( backend_startup_one( &cfb->cb_db, &c.reply ))
return 1;
if ( readit ) {
void *thrctx = ldap_pvt_thread_pool_context();
int prev_DN_strict;
- op = (Operation *) &opbuf;
- connection_fake_init( &conn, op, thrctx );
+ connection_fake_init( &conn, &opbuf, thrctx );
+ op = &opbuf.ob_op;
filter.f_desc = slap_schema.si_ad_objectClass;
int rc;
/* Setup the config backend */
- be = backend_db_init( "config", NULL, 0 );
+ be = backend_db_init( "config", NULL, 0, NULL );
if ( !be )
return 1;
static int
config_back_bind( Operation *op, SlapReply *rs )
{
- if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
+ if ( be_isroot_pw( op ) ) {
ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
/* frontend sends result */
return LDAP_SUCCESS;
}
static ConfigTable *
-config_find_table( ConfigOCs **colst, int nocs, AttributeDescription *ad )
+config_find_table( ConfigOCs **colst, int nocs, AttributeDescription *ad,
+ ConfigArgs *ca )
{
int i, j;
for (j=0; j<nocs; j++) {
for (i=0; colst[j]->co_table[i].name; i++)
- if ( colst[j]->co_table[i].ad == ad )
+ if ( colst[j]->co_table[i].ad == ad ) {
+ ca->table = colst[j]->co_type;
return &colst[j]->co_table[i];
+ }
}
return NULL;
}
if ( a && ( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL )) {
rc = ordered_value_sort( a, 1 );
if ( rc ) {
- snprintf(ca->msg, sizeof( ca->msg ), "ordered_value_sort failed on attr %s\n",
+ snprintf(ca->cr_msg, sizeof( ca->cr_msg ), "ordered_value_sort failed on attr %s\n",
ad->ad_cname.bv_val );
return rc;
}
op->o_callback = ≻
op->orr_newrdn = *newrdn;
op->orr_nnewrdn = *nnewrdn;
+ op->orr_newSup = NULL;
+ op->orr_nnewSup = NULL;
op->orr_deleteoldrdn = 1;
op->orr_modlist = NULL;
slap_modrdn2mods( op, rs );
{
CfEntryInfo *ce;
int index = -1, gotindex = 0, nsibs, rc = 0;
- int renumber = 0, tailindex = 0, isfrontend = 0;
+ int renumber = 0, tailindex = 0, isfrontend = 0, isconfig = 0;
char *ptr1, *ptr2 = NULL;
struct berval rdn;
/* See if the rdn has an index already */
dnRdn( &e->e_name, &rdn );
- if ( ce_type == Cft_Database && !strncmp( rdn.bv_val + rdn.bv_len -
- STRLENOF("frontend"), "frontend", STRLENOF("frontend") ))
- isfrontend = 1;
+ if ( ce_type == Cft_Database ) {
+ if ( !strncmp( rdn.bv_val + rdn.bv_len - STRLENOF("frontend"),
+ "frontend", STRLENOF("frontend") ))
+ isfrontend = 1;
+ else if ( !strncmp( rdn.bv_val + rdn.bv_len - STRLENOF("config"),
+ "config", STRLENOF("config") ))
+ isconfig = 1;
+ }
ptr1 = ber_bvchr( &e->e_name, '{' );
if ( ptr1 && ptr1 - e->e_name.bv_val < rdn.bv_len ) {
char *next;
if ( index != -1 || !isfrontend )
return LDAP_NAMING_VIOLATION;
}
+ if ( isconfig && index != 0 ){
+ return LDAP_NAMING_VIOLATION;
+ }
}
/* count related kids */
if ( ce->ce_type == ce_type ) nsibs++;
}
+ /* account for -1 frontend */
+ if ( ce_type == Cft_Database )
+ nsibs--;
+
if ( index != nsibs ) {
if ( gotindex ) {
if ( index < nsibs ) {
renumber = 1;
}
}
- if ( !isfrontend && index == -1 )
+ /* config DB is always "0" */
+ if ( isconfig && index == -1 ) {
+ index = 0;
+ }
+ if ( !isfrontend && index == -1 ) {
index = nsibs;
+ }
/* just make index = nsibs */
if ( !renumber ) {
return rc;
}
+static int
+count_oc( ObjectClass *oc, ConfigOCs ***copp, int *nocs )
+{
+ ConfigOCs co, *cop;
+ ObjectClass **sups;
+
+ co.co_name = &oc->soc_cname;
+ cop = avl_find( CfOcTree, &co, CfOc_cmp );
+ if ( cop ) {
+ int i;
+
+ /* check for duplicates */
+ for ( i = 0; i < *nocs; i++ ) {
+ if ( *copp && (*copp)[i] == cop ) {
+ break;
+ }
+ }
+
+ if ( i == *nocs ) {
+ ConfigOCs **tmp = ch_realloc( *copp, (*nocs + 1)*sizeof( ConfigOCs * ) );
+ if ( tmp == NULL ) {
+ return -1;
+ }
+ *copp = tmp;
+ (*copp)[*nocs] = cop;
+ (*nocs)++;
+ }
+ }
+
+ for ( sups = oc->soc_sups; sups && *sups; sups++ ) {
+ if ( count_oc( *sups, copp, nocs ) ) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static ConfigOCs **
count_ocs( Attribute *oc_at, int *nocs )
{
- int i, j, n;
- ConfigOCs co, *coptr, **colst;
+ int i;
+ ConfigOCs **colst = NULL;
- /* count the objectclasses */
- for ( i=0; oc_at->a_nvals[i].bv_val; i++ );
- n = i;
- colst = (ConfigOCs **)ch_malloc( n * sizeof(ConfigOCs *));
+ *nocs = 0;
- for ( i=0, j=0; i<n; i++) {
- co.co_name = &oc_at->a_nvals[i];
- coptr = avl_find( CfOcTree, &co, CfOc_cmp );
-
- /* ignore non-config objectclasses. probably should be
- * an error, general data doesn't belong here.
- */
- if ( !coptr ) continue;
+ for ( i = 0; !BER_BVISNULL( &oc_at->a_nvals[i] ); i++ )
+ /* count attrs */ ;
- /* Ignore the root objectclass, it has no implementation.
- */
- if ( coptr->co_type == Cft_Abstract ) continue;
- colst[j++] = coptr;
+ for ( ; i--; ) {
+ ObjectClass *oc = oc_bvfind( &oc_at->a_nvals[i] );
+
+ assert( oc != NULL );
+ if ( count_oc( oc, &colst, nocs ) ) {
+ ch_free( colst );
+ return NULL;
+ }
}
- *nocs = j;
+
return colst;
}
+static int
+cfAddInclude( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
+{
+ /* Leftover from RE23. Never parse this entry */
+ return LDAP_COMPARE_TRUE;
+}
+
static int
cfAddSchema( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
{
/* This entry is hardcoded, don't re-parse it */
if ( p->ce_type == Cft_Global ) {
cfn = p->ce_private;
- ca->private = cfn;
+ ca->ca_private = cfn;
return LDAP_COMPARE_TRUE;
}
if ( p->ce_type != Cft_Schema )
return LDAP_CONSTRAINT_VIOLATION;
cfn = ch_calloc( 1, sizeof(ConfigFile) );
- ca->private = cfn;
+ ca->ca_private = cfn;
cfo = p->ce_private;
cfn->c_sibs = cfo->c_kids;
cfo->c_kids = cfn;
static int
cfAddDatabase( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
{
- if ( p->ce_type != Cft_Global )
+ if ( p->ce_type != Cft_Global ) {
+ return LDAP_CONSTRAINT_VIOLATION;
+ }
+ /* config must be {0}, nothing else allowed */
+ if ( !strncmp( e->e_nname.bv_val, "olcDatabase={0}", STRLENOF("olcDatabase={0}")) &&
+ strncmp( e->e_nname.bv_val + STRLENOF("olcDatabase={0}"), "config,", STRLENOF("config,") )) {
return LDAP_CONSTRAINT_VIOLATION;
+ }
ca->be = frontendDB; /* just to get past check_vals */
return LDAP_SUCCESS;
}
static int
cfAddBackend( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
{
- if ( p->ce_type != Cft_Global )
+ if ( p->ce_type != Cft_Global ) {
return LDAP_CONSTRAINT_VIOLATION;
+ }
return LDAP_SUCCESS;
}
static int
cfAddModule( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
{
- if ( p->ce_type != Cft_Global )
+ if ( p->ce_type != Cft_Global ) {
return LDAP_CONSTRAINT_VIOLATION;
+ }
return LDAP_SUCCESS;
}
static int
cfAddOverlay( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
{
- if ( p->ce_type != Cft_Database )
+ if ( p->ce_type != Cft_Database ) {
return LDAP_CONSTRAINT_VIOLATION;
+ }
ca->be = p->ce_be;
return LDAP_SUCCESS;
}
+static void
+schema_destroy_one( ConfigArgs *ca, ConfigOCs **colst, int nocs,
+ CfEntryInfo *p )
+{
+ ConfigTable *ct;
+ ConfigFile *cfo;
+ AttributeDescription *ad;
+ const char *text;
+
+ ca->valx = -1;
+ ca->line = NULL;
+ if ( cfn->c_cr_head ) {
+ struct berval bv = BER_BVC("olcDitContentRules");
+ ad = NULL;
+ slap_bv2ad( &bv, &ad, &text );
+ ct = config_find_table( colst, nocs, ad, ca );
+ config_del_vals( ct, ca );
+ }
+ if ( cfn->c_oc_head ) {
+ struct berval bv = BER_BVC("olcObjectClasses");
+ ad = NULL;
+ slap_bv2ad( &bv, &ad, &text );
+ ct = config_find_table( colst, nocs, ad, ca );
+ config_del_vals( ct, ca );
+ }
+ if ( cfn->c_at_head ) {
+ struct berval bv = BER_BVC("olcAttributeTypes");
+ ad = NULL;
+ slap_bv2ad( &bv, &ad, &text );
+ ct = config_find_table( colst, nocs, ad, ca );
+ config_del_vals( ct, ca );
+ }
+ if ( cfn->c_om_head ) {
+ struct berval bv = BER_BVC("olcObjectIdentifier");
+ ad = NULL;
+ slap_bv2ad( &bv, &ad, &text );
+ ct = config_find_table( colst, nocs, ad, ca );
+ config_del_vals( ct, ca );
+ }
+ cfo = p->ce_private;
+ cfo->c_kids = cfn->c_sibs;
+ ch_free( cfn );
+}
+
+static int
+config_add_oc( ConfigOCs **cop, CfEntryInfo *last, Entry *e, ConfigArgs *ca )
+{
+ int rc = LDAP_CONSTRAINT_VIOLATION;
+ ObjectClass **ocp;
+
+ if ( (*cop)->co_ldadd ) {
+ rc = (*cop)->co_ldadd( last, e, ca );
+ if ( rc != LDAP_CONSTRAINT_VIOLATION ) {
+ return rc;
+ }
+ }
+
+ for ( ocp = (*cop)->co_oc->soc_sups; ocp && *ocp; ocp++ ) {
+ ConfigOCs co = { 0 };
+
+ co.co_name = &(*ocp)->soc_cname;
+ *cop = avl_find( CfOcTree, &co, CfOc_cmp );
+ if ( *cop == NULL ) {
+ return rc;
+ }
+
+ rc = config_add_oc( cop, last, e, ca );
+ if ( rc != LDAP_CONSTRAINT_VIOLATION ) {
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
/* Parse an LDAP entry into config directives */
static int
config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
int *renum, Operation *op )
{
- CfEntryInfo *ce, *last;
- ConfigOCs **colst;
- Attribute *a, *oc_at;
- int i, ibase = -1, nocs, rc = 0;
- struct berval pdn;
- ConfigTable *ct;
- char *ptr;
+ CfEntryInfo *ce, *last = NULL;
+ ConfigOCs co, *coptr, **colst;
+ Attribute *a, *oc_at, *soc_at;
+ int i, ibase = -1, nocs, rc = 0;
+ struct berval pdn;
+ ConfigTable *ct;
+ char *ptr, *log_prefix = op ? op->o_log_prefix : "";
+
+ memset( ca, 0, sizeof(ConfigArgs));
/* Make sure parent exists and entry does not. But allow
* Databases and Overlays to be inserted. Don't do any
*/
ce = config_find_base( cfb->cb_root, &e->e_nname, &last );
if ( ce ) {
- if (( op && op->o_managedsait ) ||
+ if ( ( op && op->o_managedsait ) ||
( ce->ce_type != Cft_Database && ce->ce_type != Cft_Overlay &&
- ce->ce_type != Cft_Module ))
- return LDAP_ALREADY_EXISTS;
+ ce->ce_type != Cft_Module ) )
+ {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" already exists\n",
+ log_prefix, e->e_name.bv_val, 0 );
+ return LDAP_ALREADY_EXISTS;
+ }
}
dnParent( &e->e_nname, &pdn );
/* If last is NULL, the new entry is the root/suffix entry,
* otherwise last should be the parent.
*/
- if ( last && !dn_match( &last->ce_entry->e_nname, &pdn )) {
- if ( rs )
+ if ( last && !dn_match( &last->ce_entry->e_nname, &pdn ) ) {
+ if ( rs ) {
rs->sr_matched = last->ce_entry->e_name.bv_val;
+ }
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" not child of DN=\"%s\"\n",
+ log_prefix, e->e_name.bv_val,
+ last->ce_entry->e_name.bv_val );
return LDAP_NO_SUCH_OBJECT;
}
if ( op ) {
/* No parent, must be root. This will never happen... */
- if ( !last && !be_isroot( op ) && !be_shadow_update( op ))
+ if ( !last && !be_isroot( op ) && !be_shadow_update( op ) ) {
return LDAP_NO_SUCH_OBJECT;
+ }
+
if ( last && !access_allowed( op, last->ce_entry,
- slap_schema.si_ad_children, NULL, ACL_WADD, NULL ))
+ slap_schema.si_ad_children, NULL, ACL_WADD, NULL ) )
+ {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no write access to \"children\" of parent\n",
+ log_prefix, e->e_name.bv_val, 0 );
return LDAP_INSUFFICIENT_ACCESS;
+ }
}
oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
- if ( !oc_at ) return LDAP_OBJECT_CLASS_VIOLATION;
+ if ( !oc_at ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no objectClass\n",
+ log_prefix, e->e_name.bv_val, 0 );
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
+
+ soc_at = attr_find( e->e_attrs, slap_schema.si_ad_structuralObjectClass );
+ if ( !soc_at ) {
+ ObjectClass *soc = NULL;
+ char textbuf[ SLAP_TEXT_BUFLEN ];
+ const char *text = textbuf;
+
+ /* FIXME: check result */
+ rc = structural_class( oc_at->a_nvals, &soc, NULL,
+ &text, textbuf, sizeof(textbuf), NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass (%s)\n",
+ log_prefix, e->e_name.bv_val, text );
+ return rc;
+ }
+ attr_merge_one( e, slap_schema.si_ad_structuralObjectClass, &soc->soc_cname, NULL );
+ soc_at = attr_find( e->e_attrs, slap_schema.si_ad_structuralObjectClass );
+ if ( soc_at == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass; "
+ "unable to merge computed class %s\n",
+ log_prefix, e->e_name.bv_val,
+ soc->soc_cname.bv_val );
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
- memset( ca, 0, sizeof(ConfigArgs));
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass; "
+ "computed objectClass %s merged\n",
+ log_prefix, e->e_name.bv_val,
+ soc->soc_cname.bv_val );
+ }
/* Fake the coordinates based on whether we're part of an
* LDAP Add or if reading the config dir
}
ca->ca_op = op;
- colst = count_ocs( oc_at, &nocs );
+ co.co_name = &soc_at->a_nvals[0];
+ coptr = avl_find( CfOcTree, &co, CfOc_cmp );
+ if ( coptr == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass in configuration table\n",
+ log_prefix, e->e_name.bv_val, 0 );
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
/* Only the root can be Cft_Global, everything else must
* have a parent. Only limited nesting arrangements are allowed.
*/
rc = LDAP_CONSTRAINT_VIOLATION;
- if ( colst[0]->co_type == Cft_Global && !last ) {
+ if ( coptr->co_type == Cft_Global && !last ) {
cfn = cfb->cb_config;
- ca->private = cfn;
+ ca->ca_private = cfn;
ca->be = frontendDB; /* just to get past check_vals */
rc = LDAP_SUCCESS;
}
+ colst = count_ocs( oc_at, &nocs );
+
/* Check whether the Add is allowed by its parent, and do
* any necessary arg setup
*/
if ( last ) {
- for ( i=0; i<nocs; i++ ) {
- if ( colst[i]->co_ldadd &&
- ( rc = colst[i]->co_ldadd( last, e, ca ))
- != LDAP_CONSTRAINT_VIOLATION ) {
- break;
+ rc = config_add_oc( &coptr, last, e, ca );
+ if ( rc == LDAP_CONSTRAINT_VIOLATION ) {
+ for ( i = 0; i<nocs; i++ ) {
+ /* Already checked these */
+ if ( colst[i]->co_oc->soc_kind == LDAP_SCHEMA_STRUCTURAL )
+ continue;
+ if ( colst[i]->co_ldadd &&
+ ( rc = colst[i]->co_ldadd( last, e, ca ))
+ != LDAP_CONSTRAINT_VIOLATION ) {
+ coptr = colst[i];
+ break;
+ }
}
}
+ if ( rc == LDAP_CONSTRAINT_VIOLATION ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass add function\n",
+ log_prefix, e->e_name.bv_val, 0 );
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
}
/* Add the entry but don't parse it, we already have its contents */
}
if ( rc != LDAP_SUCCESS )
- goto done;
+ goto done_noop;
/* Parse all the values and check for simple syntax errors before
* performing any set actions.
* but only the other types support auto-renumbering of siblings.
*/
{
- rc = check_name_index( last, colst[0]->co_type, e, rs, renum,
+ rc = check_name_index( last, coptr->co_type, e, rs, renum,
&ibase );
if ( rc ) {
- goto done;
+ goto done_noop;
}
- if ( renum && *renum && colst[0]->co_type != Cft_Database &&
- colst[0]->co_type != Cft_Overlay ) {
- snprintf( ca->msg, sizeof( ca->msg ),
+ if ( renum && *renum && coptr->co_type != Cft_Database &&
+ coptr->co_type != Cft_Overlay )
+ {
+ snprintf( ca->cr_msg, sizeof( ca->cr_msg ),
"operation requires sibling renumbering" );
rc = LDAP_UNWILLING_TO_PERFORM;
- goto done;
+ goto done_noop;
}
}
/* Make sure we process attrs in the required order */
sort_attrs( e, colst, nocs );
- for ( a=e->e_attrs; a; a=a->a_next ) {
+ for ( a = e->e_attrs; a; a = a->a_next ) {
if ( a == oc_at ) continue;
- ct = config_find_table( colst, nocs, a->a_desc );
+ ct = config_find_table( colst, nocs, a->a_desc, ca );
if ( !ct ) continue; /* user data? */
rc = check_vals( ct, ca, a, 1 );
- if ( rc ) goto done;
+ if ( rc ) goto done_noop;
}
/* Basic syntax checks are OK. Do the actual settings. */
for ( a=e->e_attrs; a; a=a->a_next ) {
if ( a == oc_at ) continue;
- ct = config_find_table( colst, nocs, a->a_desc );
+ ct = config_find_table( colst, nocs, a->a_desc, ca );
if ( !ct ) continue; /* user data? */
for (i=0; a->a_vals[i].bv_val; i++) {
char *iptr = NULL;
/* Newly added databases and overlays need to be started up */
if ( CONFIG_ONLINE_ADD( ca )) {
if ( colst[0]->co_type == Cft_Database ) {
- rc = backend_startup_one( ca->be );
+ rc = backend_startup_one( ca->be, &ca->reply );
} else if ( colst[0]->co_type == Cft_Overlay ) {
if ( ca->bi->bi_db_open ) {
BackendInfo *bi_orig = ca->be->bd_info;
ca->be->bd_info = ca->bi;
- rc = ca->bi->bi_db_open( ca->be );
+ rc = ca->bi->bi_db_open( ca->be, &ca->reply );
ca->be->bd_info = bi_orig;
}
+ } else if ( ca->cleanup ) {
+ rc = ca->cleanup( ca );
}
if ( rc ) {
- snprintf( ca->msg, sizeof( ca->msg ), "<%s> failed startup", ca->argv[0] );
+ if (ca->cr_msg[0] == '\0')
+ snprintf( ca->cr_msg, sizeof( ca->cr_msg ), "<%s> failed startup", ca->argv[0] );
+
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
- ca->log, ca->msg, ca->argv[1] );
+ ca->log, ca->cr_msg, ca->argv[1] );
rc = LDAP_OTHER;
goto done;
}
ce->ce_type = colst[0]->co_type;
ce->ce_be = ca->be;
ce->ce_bi = ca->bi;
- ce->ce_private = ca->private;
+ ce->ce_private = ca->ca_private;
ca->ca_entry = ce->ce_entry;
if ( !last ) {
cfb->cb_root = ce;
backend_destroy_one( ca->be, 1 );
} else if ( (colst[0]->co_type == Cft_Overlay) && ca->bi ) {
overlay_destroy_one( ca->be, (slap_overinst *)ca->bi );
+ } else if ( colst[0]->co_type == Cft_Schema ) {
+ schema_destroy_one( ca, colst, nocs, last );
}
}
+done_noop:
ch_free( ca->argv );
if ( colst ) ch_free( colst );
*/
rs->sr_err = config_add_internal( cfb, op->ora_e, &ca, rs, &renumber, op );
if ( rs->sr_err != LDAP_SUCCESS ) {
- rs->sr_text = ca.msg;
+ rs->sr_text = ca.cr_msg;
goto out2;
}
int idx[1];
} delrec;
+static int
+config_modify_add( ConfigTable *ct, ConfigArgs *ca, AttributeDescription *ad,
+ int i )
+{
+ int rc;
+
+ if (ad->ad_type->sat_flags & SLAP_AT_ORDERED &&
+ ca->line[0] == '{' )
+ {
+ char *ptr = strchr( ca->line + 1, '}' );
+ if ( ptr ) {
+ char *next;
+
+ ca->valx = strtol( ca->line + 1, &next, 0 );
+ if ( next == ca->line + 1 || next[ 0 ] != '}' ) {
+ return LDAP_OTHER;
+ }
+ ca->line = ptr+1;
+ }
+ }
+ rc = config_parse_add( ct, ca, i );
+ if ( rc ) {
+ rc = LDAP_OTHER;
+ }
+ return rc;
+}
+
static int
config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
ConfigArgs *ca )
int rc = LDAP_UNWILLING_TO_PERFORM;
Modifications *ml;
Entry *e = ce->ce_entry;
- Attribute *save_attrs = e->e_attrs, *oc_at;
+ Attribute *save_attrs = e->e_attrs, *oc_at, *s, *a;
ConfigTable *ct;
ConfigOCs **colst;
int i, nocs;
colst = count_ocs( oc_at, &nocs );
+ /* make sure add/del flags are clear; should always be true */
+ for ( s = save_attrs; s; s = s->a_next ) {
+ s->a_flags &= ~(SLAP_ATTR_IXADD|SLAP_ATTR_IXDEL);
+ }
+
e->e_attrs = attrs_dup( e->e_attrs );
init_config_argv( ca );
ca->be = ce->ce_be;
ca->bi = ce->ce_bi;
- ca->private = ce->ce_private;
+ ca->ca_private = ce->ce_private;
ca->ca_entry = e;
ca->fname = "slapd";
ca->ca_op = op;
strcpy( ca->log, "back-config" );
for (ml = op->orm_modlist; ml; ml=ml->sml_next) {
- ct = config_find_table( colst, nocs, ml->sml_desc );
+ ct = config_find_table( colst, nocs, ml->sml_desc, ca );
switch (ml->sml_op) {
case LDAP_MOD_DELETE:
case LDAP_MOD_REPLACE: {
int *idx = NULL;
if ( ct && ( ct->arg_type & ARG_NO_DELETE )) {
rc = LDAP_OTHER;
- snprintf(ca->msg, sizeof(ca->msg), "cannot delete %s",
+ snprintf(ca->cr_msg, sizeof(ca->cr_msg), "cannot delete %s",
ml->sml_desc->ad_cname.bv_val );
- goto out;
+ goto out_noop;
}
if ( ml->sml_op == LDAP_MOD_REPLACE ) {
vals = ml->sml_values;
*/
if ( ct && ml->sml_values ) {
delrec *d;
- for (i=0; ml->sml_values[i].bv_val; i++);
+ i = ml->sml_numvals;
d = ch_malloc( sizeof(delrec) + (i - 1)* sizeof(int));
d->nidx = i;
d->next = NULL;
}
rc = modify_delete_vindex(e, &ml->sml_mod,
get_permissiveModify(op),
- &rs->sr_text, ca->msg, sizeof(ca->msg), idx );
+ &rs->sr_text, ca->cr_msg, sizeof(ca->cr_msg), idx );
if ( ml->sml_op == LDAP_MOD_REPLACE ) {
ml->sml_values = vals;
ml->sml_nvalues = nvals;
if ( ct->arg_type & ARG_NO_INSERT ) {
Attribute *a = attr_find( e->e_attrs, ml->sml_desc );
if ( a ) {
- for (i = 0; a->a_vals[i].bv_val; i++ );
- navals = i;
+ navals = a->a_numvals;
}
}
for ( i=0; !BER_BVISNULL( &ml->sml_values[i] ); i++ ) {
j = strtol( val, &next, 0 );
if ( next == val || next[ 0 ] != '}' || j < navals ) {
rc = LDAP_OTHER;
- snprintf(ca->msg, sizeof(ca->msg), "cannot insert %s",
+ snprintf(ca->cr_msg, sizeof(ca->cr_msg), "cannot insert %s",
ml->sml_desc->ad_cname.bv_val );
- goto out;
+ goto out_noop;
}
}
rc = check_vals( ct, ca, ml, 0 );
- if ( rc ) goto out;
+ if ( rc ) goto out_noop;
}
}
rc = modify_add_values(e, &ml->sml_mod,
get_permissiveModify(op),
- &rs->sr_text, ca->msg, sizeof(ca->msg) );
+ &rs->sr_text, ca->cr_msg, sizeof(ca->cr_msg) );
/* If value already exists, show success here
* and ignore this operation down below.
if(rc != LDAP_SUCCESS) break;
}
- if(rc == LDAP_SUCCESS) {
+ if ( rc == LDAP_SUCCESS) {
/* check that the entry still obeys the schema */
rc = entry_schema_check(op, e, NULL, 0, 0,
- &rs->sr_text, ca->msg, sizeof(ca->msg) );
+ &rs->sr_text, ca->cr_msg, sizeof(ca->cr_msg) );
}
- if ( rc == LDAP_SUCCESS ) {
- /* Basic syntax checks are OK. Do the actual settings. */
- for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
- ct = config_find_table( colst, nocs, ml->sml_desc );
- if ( !ct ) continue;
-
- switch (ml->sml_op) {
- case LDAP_MOD_DELETE:
- case LDAP_MOD_REPLACE: {
- BerVarray vals = NULL, nvals = NULL;
- Attribute *a;
- delrec *d = NULL;
-
- a = attr_find( e->e_attrs, ml->sml_desc );
-
- if ( ml->sml_op == LDAP_MOD_REPLACE ) {
- vals = ml->sml_values;
- nvals = ml->sml_nvalues;
- ml->sml_values = NULL;
- ml->sml_nvalues = NULL;
- }
+ if ( rc ) goto out_noop;
- if ( ml->sml_values )
- d = dels;
+ /* Basic syntax checks are OK. Do the actual settings. */
+ for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
+ ct = config_find_table( colst, nocs, ml->sml_desc, ca );
+ if ( !ct ) continue;
- /* If we didn't delete the whole attribute */
- if ( ml->sml_values && a ) {
- struct berval *mvals;
- int j;
+ s = attr_find( save_attrs, ml->sml_desc );
+ a = attr_find( e->e_attrs, ml->sml_desc );
- if ( ml->sml_nvalues )
- mvals = ml->sml_nvalues;
- else
- mvals = ml->sml_values;
-
- /* use the indexes we saved up above */
- for (i=0; i < d->nidx; i++) {
- struct berval bv = *mvals++;
- if ( a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED &&
- bv.bv_val[0] == '{' ) {
- ptr = strchr( bv.bv_val, '}' ) + 1;
- bv.bv_len -= ptr - bv.bv_val;
- bv.bv_val = ptr;
- }
- ca->line = bv.bv_val;
- ca->valx = d->idx[i];
- rc = config_del_vals( ct, ca );
- if ( rc != LDAP_SUCCESS ) break;
- for (j=i+1; j < d->nidx; j++)
- if ( d->idx[j] >d->idx[i] )
- d->idx[j]--;
+ switch (ml->sml_op) {
+ case LDAP_MOD_DELETE:
+ case LDAP_MOD_REPLACE: {
+ BerVarray vals = NULL, nvals = NULL;
+ delrec *d = NULL;
+
+ if ( ml->sml_op == LDAP_MOD_REPLACE ) {
+ vals = ml->sml_values;
+ nvals = ml->sml_nvalues;
+ ml->sml_values = NULL;
+ ml->sml_nvalues = NULL;
+ }
+
+ if ( ml->sml_values )
+ d = dels;
+
+ /* If we didn't delete the whole attribute */
+ if ( ml->sml_values && a ) {
+ struct berval *mvals;
+ int j;
+
+ if ( ml->sml_nvalues )
+ mvals = ml->sml_nvalues;
+ else
+ mvals = ml->sml_values;
+
+ /* use the indexes we saved up above */
+ for (i=0; i < d->nidx; i++) {
+ struct berval bv = *mvals++;
+ if ( a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED &&
+ bv.bv_val[0] == '{' ) {
+ ptr = strchr( bv.bv_val, '}' ) + 1;
+ bv.bv_len -= ptr - bv.bv_val;
+ bv.bv_val = ptr;
}
- } else {
- ca->valx = -1;
- ca->line = NULL;
+ ca->line = bv.bv_val;
+ ca->valx = d->idx[i];
rc = config_del_vals( ct, ca );
- if ( rc ) rc = LDAP_OTHER;
- }
- if ( ml->sml_values ) {
- d = d->next;
- ch_free( dels );
- dels = d;
+ if ( rc != LDAP_SUCCESS ) break;
+ if ( s )
+ s->a_flags |= SLAP_ATTR_IXDEL;
+ for (j=i+1; j < d->nidx; j++)
+ if ( d->idx[j] >d->idx[i] )
+ d->idx[j]--;
}
- if ( ml->sml_op == LDAP_MOD_REPLACE ) {
- ml->sml_values = vals;
- ml->sml_nvalues = nvals;
- }
- if ( !vals || rc != LDAP_SUCCESS )
- break;
- }
- /* FALLTHRU: LDAP_MOD_REPLACE && vals */
+ } else {
+ ca->valx = -1;
+ ca->line = NULL;
+ rc = config_del_vals( ct, ca );
+ if ( rc ) rc = LDAP_OTHER;
+ if ( s )
+ s->a_flags |= SLAP_ATTR_IXDEL;
+ }
+ if ( ml->sml_values ) {
+ d = d->next;
+ ch_free( dels );
+ dels = d;
+ }
+ if ( ml->sml_op == LDAP_MOD_REPLACE ) {
+ ml->sml_values = vals;
+ ml->sml_nvalues = nvals;
+ }
+ if ( !vals || rc != LDAP_SUCCESS )
+ break;
+ }
+ /* FALLTHRU: LDAP_MOD_REPLACE && vals */
+
+ case LDAP_MOD_ADD:
+ for (i=0; ml->sml_values[i].bv_val; i++) {
+ ca->line = ml->sml_values[i].bv_val;
+ ca->valx = -1;
+ rc = config_modify_add( ct, ca, ml->sml_desc, i );
+ if ( rc )
+ goto out;
+ a->a_flags |= SLAP_ATTR_IXADD;
+ }
+ break;
+ }
+ }
- case LDAP_MOD_ADD:
- for (i=0; ml->sml_values[i].bv_val; i++) {
- ca->line = ml->sml_values[i].bv_val;
+out:
+ /* Undo for a failed operation */
+ if ( rc != LDAP_SUCCESS ) {
+ ConfigReply msg = ca->reply;
+ for ( s = save_attrs; s; s = s->a_next ) {
+ if ( s->a_flags & SLAP_ATTR_IXDEL ) {
+ s->a_flags &= ~(SLAP_ATTR_IXDEL|SLAP_ATTR_IXADD);
+ ct = config_find_table( colst, nocs, s->a_desc, ca );
+ a = attr_find( e->e_attrs, s->a_desc );
+ if ( a ) {
+ /* clear the flag so the add check below will skip it */
+ a->a_flags &= ~(SLAP_ATTR_IXDEL|SLAP_ATTR_IXADD);
ca->valx = -1;
- if ( ml->sml_desc->ad_type->sat_flags & SLAP_AT_ORDERED &&
- ca->line[0] == '{' )
- {
- ptr = strchr( ca->line + 1, '}' );
- if ( ptr ) {
- char *next;
-
- ca->valx = strtol( ca->line + 1, &next, 0 );
- if ( next == ca->line + 1 || next[ 0 ] != '}' ) {
- rc = LDAP_OTHER;
- goto out;
- }
- ca->line = ptr+1;
- }
- }
- rc = config_parse_add( ct, ca, i );
- if ( rc ) {
- rc = LDAP_OTHER;
- goto out;
+ ca->line = NULL;
+ config_del_vals( ct, ca );
+ }
+ for ( i=0; !BER_BVISNULL( &s->a_vals[i] ); i++ ) {
+ ca->line = s->a_vals[i].bv_val;
+ ca->valx = -1;
+ config_modify_add( ct, ca, s->a_desc, i );
+ }
+ }
+ }
+ for ( a = e->e_attrs; a; a = a->a_next ) {
+ if ( a->a_flags & SLAP_ATTR_IXADD ) {
+ ct = config_find_table( colst, nocs, a->a_desc, ca );
+ ca->valx = -1;
+ ca->line = NULL;
+ config_del_vals( ct, ca );
+ s = attr_find( save_attrs, a->a_desc );
+ if ( s ) {
+ s->a_flags &= ~(SLAP_ATTR_IXDEL|SLAP_ATTR_IXADD);
+ for ( i=0; !BER_BVISNULL( &s->a_vals[i] ); i++ ) {
+ ca->line = s->a_vals[i].bv_val;
+ ca->valx = -1;
+ config_modify_add( ct, ca, s->a_desc, i );
}
}
-
- break;
}
}
+ ca->reply = msg;
}
-out:
if ( ca->cleanup )
ca->cleanup( ca );
+out_noop:
if ( rc == LDAP_SUCCESS ) {
attrs_free( save_attrs );
} else {
struct berval rdn;
char *ptr;
AttributeDescription *rad = NULL;
+ int do_pause = 1;
cfb = (CfBackInfo *)op->o_bd->be_private;
rs->sr_text = "Use modrdn to change the entry name";
goto out;
}
+ /* Internal update of contextCSN? */
+ if ( ml->sml_desc == slap_schema.si_ad_contextCSN && op->o_conn->c_conn_idx == -1 ) {
+ do_pause = 0;
+ break;
+ }
}
slap_mods_opattrs( op, &op->orm_modlist, 1 );
- if ( !slapd_shutdown )
+ if ( do_pause )
ldap_pvt_thread_pool_pause( &connection_pool );
/* Strategy:
*/
rs->sr_err = config_modify_internal( ce, op, rs, &ca );
if ( rs->sr_err ) {
- rs->sr_text = ca.msg;
+ rs->sr_text = ca.cr_msg;
} else if ( cfb->cb_use_ldif ) {
BackendDB *be = op->o_bd;
slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
op->o_ndn = ndn;
}
- if ( !slapd_shutdown )
+ if ( do_pause )
ldap_pvt_thread_pool_resume( &connection_pool );
out:
send_ldap_result( op, rs );
static int
config_back_delete( Operation *op, SlapReply *rs )
{
- send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, NULL );
+#ifdef SLAP_CONFIG_DELETE
+ CfBackInfo *cfb;
+ CfEntryInfo *ce, *last, *ce2;
+
+ slap_mask_t mask;
+
+ cfb = (CfBackInfo *)op->o_bd->be_private;
+
+ ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
+ if ( !ce ) {
+ if ( last )
+ rs->sr_matched = last->ce_entry->e_name.bv_val;
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ } if ( ce->ce_kids ) {
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ } else if ( ce->ce_type == Cft_Overlay ){
+ char *iptr;
+ int count, ixold, rc;
+
+ ldap_pvt_thread_pool_pause( &connection_pool );
+
+ overlay_remove( ce->ce_be, (slap_overinst *)ce->ce_bi );
+
+ /* remove CfEntryInfo from the siblings list */
+ if ( ce->ce_parent->ce_kids == ce ) {
+ ce->ce_parent->ce_kids = ce->ce_sibs;
+ } else {
+ for ( ce2 = ce->ce_parent->ce_kids ; ce2; ce2 = ce2->ce_sibs ) {
+ if ( ce2->ce_sibs == ce ) {
+ ce2->ce_sibs = ce->ce_sibs;
+ break;
+ }
+ }
+ }
+
+ /* remove from underlying database */
+ if ( cfb->cb_use_ldif ) {
+ BackendDB *be = op->o_bd;
+ slap_callback sc = { NULL, slap_null_cb, NULL, NULL }, *scp;
+ struct berval dn, ndn, req_dn, req_ndn;
+
+ op->o_bd = &cfb->cb_db;
+
+ dn = op->o_dn;
+ ndn = op->o_ndn;
+ req_dn = op->o_req_dn;
+ req_ndn = op->o_req_ndn;
+
+ op->o_dn = op->o_bd->be_rootdn;
+ op->o_ndn = op->o_bd->be_rootndn;
+ op->o_req_dn = ce->ce_entry->e_name;
+ op->o_req_ndn = ce->ce_entry->e_nname;
+
+ scp = op->o_callback;
+ op->o_callback = ≻
+ op->o_bd->be_delete( op, rs );
+ op->o_bd = be;
+ op->o_callback = scp;
+ op->o_dn = dn;
+ op->o_ndn = ndn;
+ op->o_req_dn = req_dn;
+ op->o_req_ndn = req_ndn;
+ }
+
+ /* renumber siblings */
+ iptr = ber_bvchr( &op->o_req_ndn, '{' ) + 1;
+ ixold = strtol( iptr, NULL, 0 );
+ for (ce2 = ce->ce_sibs, count=0; ce2; ce2=ce2->ce_sibs) {
+ config_renumber_one( op, rs, ce2->ce_parent, ce2->ce_entry,
+ count+ixold, 0, cfb->cb_use_ldif );
+ count++;
+ }
+
+ ce->ce_entry->e_private=NULL;
+ entry_free(ce->ce_entry);
+ ch_free(ce);
+ ldap_pvt_thread_pool_resume( &connection_pool );
+ } else {
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ }
+#else
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+#endif /* SLAP_CONFIG_DELETE */
+ send_ldap_result( op, rs );
return rs->sr_err;
}
Entry *e,
int rw )
{
+ if ( !e->e_private ) {
+ entry_free( e );
+ }
return LDAP_SUCCESS;
}
{
CfBackInfo *cfb;
CfEntryInfo *ce, *last;
+ int rc = LDAP_NO_SUCH_OBJECT;
cfb = (CfBackInfo *)op->o_bd->be_private;
ce = config_find_base( cfb->cb_root, ndn, &last );
if ( ce ) {
*ent = ce->ce_entry;
- if ( *ent && oc && !is_entry_objectclass_or_sub( *ent, oc ) ) {
- *ent = NULL;
+ if ( *ent ) {
+ rc = LDAP_SUCCESS;
+ if ( oc && !is_entry_objectclass_or_sub( *ent, oc ) ) {
+ rc = LDAP_NO_SUCH_ATTRIBUTE;
+ *ent = NULL;
+ }
}
}
- return ( *ent == NULL ? 1 : 0 );
+ return rc;
}
static void
ce->ce_parent = parent;
if ( parent ) {
pdn = parent->ce_entry->e_nname;
- if ( parent->ce_kids && parent->ce_kids->ce_type < ce->ce_type )
+ if ( parent->ce_kids && parent->ce_kids->ce_type <= ce->ce_type )
for ( ceprev = parent->ce_kids; ceprev->ce_sibs &&
- ceprev->ce_type < ce->ce_type;
+ ceprev->ce_type <= ce->ce_type;
ceprev = ceprev->ce_sibs );
} else {
BER_BVZERO( &pdn );
}
- ce->ce_private = c->private;
+ ce->ce_private = c->ca_private;
ce->ce_be = c->be;
ce->ce_bi = c->bi;
attr_merge_normalize_one(e, ad, &val, NULL );
oc = main->co_oc;
+ c->table = main->co_type;
if ( oc->soc_required )
config_build_attrs( e, oc->soc_required, ad, main->co_table, c );
if ( extra ) {
oc = extra->co_oc;
+ c->table = extra->co_type;
if ( oc->soc_required )
config_build_attrs( e, oc->soc_required, ad, extra->co_table, c );
}
oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
- rc = structural_class(oc_at->a_vals, &oc, NULL, &text, c->msg,
- sizeof(c->msg), op ? op->o_tmpmemctx : NULL );
+ rc = structural_class(oc_at->a_vals, &oc, NULL, &text, c->cr_msg,
+ sizeof(c->cr_msg), op ? op->o_tmpmemctx : NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_ANY,
+ "config_build_entry: build \"%s\" failed: \"%s\"\n",
+ rdn->bv_val, text, 0);
+ return NULL;
+ }
attr_merge_normalize_one(e, slap_schema.si_ad_structuralObjectClass, &oc->soc_cname, NULL );
- if ( op && !op->o_noop ) {
+ if ( op ) {
op->ora_e = e;
op->ora_modlist = NULL;
- op->o_bd->be_add( op, rs );
- if ( ( rs->sr_err != LDAP_SUCCESS )
- && (rs->sr_err != LDAP_ALREADY_EXISTS) ) {
- return NULL;
+ slap_add_opattrs( op, NULL, NULL, 0, 0 );
+ if ( !op->o_noop ) {
+ op->o_bd->be_add( op, rs );
+ if ( ( rs->sr_err != LDAP_SUCCESS )
+ && (rs->sr_err != LDAP_ALREADY_EXISTS) ) {
+ return NULL;
+ }
}
}
if ( ceprev ) {
Operation *op, SlapReply *rs )
{
Entry *e;
- ConfigFile *cf = c->private;
+ ConfigFile *cf = c->ca_private;
char *ptr;
struct berval bv;
for (; cf; cf=cf->c_sibs, c->depth++) {
+ if ( !cf->c_at_head && !cf->c_cr_head && !cf->c_oc_head &&
+ !cf->c_om_head ) continue;
c->value_dn.bv_val = c->log;
+ LUTIL_SLASHPATH( cf->c_file.bv_val );
bv.bv_val = strrchr(cf->c_file.bv_val, LDAP_DIRSEP[0]);
if ( !bv.bv_val ) {
bv = cf->c_file;
c->value_dn.bv_len += bv.bv_len;
c->value_dn.bv_val[c->value_dn.bv_len] ='\0';
- c->private = cf;
+ c->ca_private = cf;
e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
&CFOC_SCHEMA, NULL );
if ( !e ) {
return -1;
} else if ( e && cf->c_kids ) {
- c->private = cf->c_kids;
+ c->ca_private = cf->c_kids;
config_build_schema_inc( c, e->e_private, op, rs );
}
}
/* FIXME: how can indicate error? */
return -1;
}
- c->private = mp;
+ c->ca_private = mp;
if ( ! config_build_entry( op, rs, ceparent, c, &c->value_dn, &CFOC_MODULE, NULL )) {
return -1;
}
ber_bvarray_free( a->a_vals );
a->a_vals = NULL;
a->a_nvals = NULL;
+ a->a_numvals = 0;
}
oidm_unparse( &bv, NULL, NULL, 1 );
attr_merge_normalize( e, cfAd_om, bv, NULL );
ber_bvarray_free( a->a_vals );
a->a_vals = NULL;
a->a_nvals = NULL;
+ a->a_numvals = 0;
}
at_unparse( &bv, NULL, NULL, 1 );
attr_merge_normalize( e, cfAd_attr, bv, NULL );
ber_bvarray_free( a->a_vals );
a->a_vals = NULL;
a->a_nvals = NULL;
+ a->a_numvals = 0;
}
oc_unparse( &bv, NULL, NULL, 1 );
attr_merge_normalize( e, cfAd_oc, bv, NULL );
}
} else {
SlapReply rs = {REP_RESULT};
- c.private = NULL;
+ c.ca_private = NULL;
e = config_build_entry( op, &rs, cfb->cb_root, &c, &schema_rdn,
&CFOC_SCHEMA, NULL );
if ( !e ) {
};
static int
-config_back_db_open( BackendDB *be )
+config_back_db_open( BackendDB *be, ConfigReply *cr )
{
CfBackInfo *cfb = be->be_private;
struct berval rdn;
}
thrctx = ldap_pvt_thread_pool_context();
- op = (Operation *) &opbuf;
- connection_fake_init( &conn, op, thrctx );
+ connection_fake_init( &conn, &opbuf, thrctx );
+ op = &opbuf.ob_op;
op->o_tag = LDAP_REQ_ADD;
op->o_callback = &cb;
/* create root of tree */
rdn = config_rdn;
- c.private = cfb->cb_config;
+ c.ca_private = cfb->cb_config;
c.be = frontendDB;
e = config_build_entry( op, &rs, NULL, &c, &rdn, &CFOC_GLOBAL, NULL );
if ( !e ) {
* files.
*/
rdn = schema_rdn;
- c.private = NULL;
+ c.ca_private = NULL;
e = config_build_entry( op, &rs, ceparent, &c, &rdn, &CFOC_SCHEMA, NULL );
if ( !e ) {
return -1;
/* Create schema nodes for included schema... */
if ( cfb->cb_config->c_kids ) {
c.depth = 0;
- c.private = cfb->cb_config->c_kids;
+ c.ca_private = cfb->cb_config->c_kids;
if (config_build_schema_inc( &c, ce, op, &rs )) {
return -1;
}
slap_overinst *on;
Entry *oe;
int j;
-
- for (j=0,on=oi->oi_list; on; j++,on=on->on_next) {
+ voidList *vl, *v0 = NULL;
+
+ /* overlays are in LIFO order, must reverse stack */
+ for (on=oi->oi_list; on; on=on->on_next) {
+ vl = ch_malloc( sizeof( voidList ));
+ vl->vl_next = v0;
+ v0 = vl;
+ vl->vl_ptr = on;
+ }
+ for (j=0; vl; j++,vl=v0) {
+ on = vl->vl_ptr;
+ v0 = vl->vl_next;
+ ch_free( vl );
if ( on->on_bi.bi_db_config && !on->on_bi.bi_cf_ocs ) {
Debug( LDAP_DEBUG_ANY,
"WARNING: No dynamic config support for overlay %s.\n",
}
static int
-config_back_db_close( BackendDB *be )
+config_back_db_close( BackendDB *be, ConfigReply *cr )
{
CfBackInfo *cfb = be->be_private;
}
static int
-config_back_db_destroy( BackendDB *be )
+config_back_db_destroy( BackendDB *be, ConfigReply *cr )
{
CfBackInfo *cfb = be->be_private;
}
static int
-config_back_db_init( BackendDB *be )
+config_back_db_init( BackendDB *be, ConfigReply* cr )
{
struct berval dn;
CfBackInfo *cfb;
return NULL;
}
+static int entry_put_got_frontend=0;
+static int entry_put_got_config=0;
static ID
config_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
{
CfBackInfo *cfb = be->be_private;
BackendInfo *bi = cfb->cb_db.bd_info;
+ int rc;
+ struct berval rdn, vals[ 2 ];
ConfigArgs ca;
+ OperationBuffer opbuf;
+ Entry *ce;
+ Connection conn = {0};
+ Operation *op = NULL;
+ void *thrctx;
+ int isFrontend = 0;
+
+ /* Create entry for frontend database if it does not exist already */
+ if ( !entry_put_got_frontend ) {
+ if ( !strncmp( e->e_nname.bv_val, "olcDatabase",
+ STRLENOF( "olcDatabase" ))) {
+ if ( strncmp( e->e_nname.bv_val +
+ STRLENOF( "olcDatabase" ), "={-1}frontend",
+ STRLENOF( "={-1}frontend" )) &&
+ strncmp( e->e_nname.bv_val +
+ STRLENOF( "olcDatabase" ), "=frontend",
+ STRLENOF( "=frontend" ))) {
+ vals[1].bv_len = 0;
+ vals[1].bv_val = NULL;
+ memset( &ca, 0, sizeof(ConfigArgs));
+ ca.be = frontendDB;
+ ca.bi = frontendDB->bd_info;
+ ca.be->be_cf_ocs = &CFOC_FRONTEND;
+ rdn.bv_val = ca.log;
+ rdn.bv_len = snprintf(rdn.bv_val, sizeof( ca.log ),
+ "%s=" SLAP_X_ORDERED_FMT "%s",
+ cfAd_database->ad_cname.bv_val, -1,
+ ca.bi->bi_type);
+ ce = config_build_entry( NULL, NULL, cfb->cb_root, &ca, &rdn,
+ &CFOC_DATABASE, ca.be->be_cf_ocs );
+ thrctx = ldap_pvt_thread_pool_context();
+ connection_fake_init2( &conn, &opbuf, thrctx,0 );
+ op = &opbuf.ob_op;
+ op->o_bd = &cfb->cb_db;
+ op->o_tag = LDAP_REQ_ADD;
+ op->ora_e = ce;
+ op->o_dn = be->be_rootdn;
+ op->o_ndn = be->be_rootndn;
+ rc = slap_add_opattrs(op, NULL, NULL, 0, 0);
+ if ( rc != LDAP_SUCCESS ) {
+ text->bv_val = "autocreation of \"olcDatabase={-1}frontend\" failed";
+ text->bv_len = STRLENOF("autocreation of \"olcDatabase={-1}frontend\" failed");
+ return NOID;
+ }
+ if ( ce && bi && bi->bi_tool_entry_put &&
+ bi->bi_tool_entry_put( &cfb->cb_db, ce, text ) != NOID ) {
+ entry_put_got_frontend++;
+ } else {
+ text->bv_val = "autocreation of \"olcDatabase={-1}frontend\" failed";
+ text->bv_len = STRLENOF("autocreation of \"olcDatabase={-1}frontend\" failed");
+ return NOID;
+ }
+ } else {
+ entry_put_got_frontend++;
+ isFrontend = 1;
+ }
+ }
+ }
+ /* Create entry for config database if it does not exist already */
+ if ( !entry_put_got_config && !isFrontend ) {
+ if ( !strncmp( e->e_nname.bv_val, "olcDatabase",
+ STRLENOF( "olcDatabase" ))) {
+ if ( strncmp( e->e_nname.bv_val +
+ STRLENOF( "olcDatabase" ), "={0}config",
+ STRLENOF( "={0}config" )) &&
+ strncmp( e->e_nname.bv_val +
+ STRLENOF( "olcDatabase" ), "=config",
+ STRLENOF( "=config" )) ) {
+ vals[1].bv_len = 0;
+ vals[1].bv_val = NULL;
+ memset( &ca, 0, sizeof(ConfigArgs));
+ ca.be = LDAP_STAILQ_FIRST( &backendDB );
+ ca.bi = ca.be->bd_info;
+ rdn.bv_val = ca.log;
+ rdn.bv_len = snprintf(rdn.bv_val, sizeof( ca.log ),
+ "%s=" SLAP_X_ORDERED_FMT "%s",
+ cfAd_database->ad_cname.bv_val, 0,
+ ca.bi->bi_type);
+ ce = config_build_entry( NULL, NULL, cfb->cb_root, &ca, &rdn, &CFOC_DATABASE,
+ ca.be->be_cf_ocs );
+ if ( ! op ) {
+ thrctx = ldap_pvt_thread_pool_context();
+ connection_fake_init2( &conn, &opbuf, thrctx,0 );
+ op = &opbuf.ob_op;
+ op->o_bd = &cfb->cb_db;
+ op->o_tag = LDAP_REQ_ADD;
+ op->o_dn = be->be_rootdn;
+ op->o_ndn = be->be_rootndn;
+ }
+ op->ora_e = ce;
+ rc = slap_add_opattrs(op, NULL, NULL, 0, 0);
+ if ( rc != LDAP_SUCCESS ) {
+ text->bv_val = "autocreation of \"olcDatabase={0}config\" failed";
+ text->bv_len = STRLENOF("autocreation of \"olcDatabase={0}config\" failed");
+ return NOID;
+ }
+ if (ce && bi && bi->bi_tool_entry_put &&
+ bi->bi_tool_entry_put( &cfb->cb_db, ce, text ) != NOID ) {
+ entry_put_got_config++;
+ } else {
+ text->bv_val = "autocreation of \"olcDatabase={0}config\" failed";
+ text->bv_len = STRLENOF("autocreation of \"olcDatabase={0}config\" failed");
+ return NOID;
+ }
+ } else {
+ entry_put_got_config++;
+ }
+ }
+ }
if ( bi && bi->bi_tool_entry_put &&
config_add_internal( cfb, e, &ca, NULL, NULL, NULL ) == 0 )
return bi->bi_tool_entry_put( &cfb->cb_db, e, text );