/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2005-2014 The OpenLDAP Foundation.
+ * Copyright 2005-2017 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
CFG_DISABLED,
CFG_THREADQS,
CFG_TLS_ECNAME,
+ CFG_TLS_CACERT,
+ CFG_TLS_CERT,
+ CFG_TLS_KEY,
CFG_LAST
};
{ "timelimit", "limit", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
&config_timelimit, "( OLcfgGlAt:67 NAME 'olcTimeLimit' "
"SYNTAX OMsDirectoryString )", NULL, NULL },
+ { "TLSCACertificate", NULL, 2, 2, 0,
+#ifdef HAVE_TLS
+ CFG_TLS_CACERT|ARG_BINARY|ARG_MAGIC, &config_tls_option,
+#else
+ ARG_IGNORED, NULL,
+#endif
+ "( OLcfgGlAt:97 NAME 'olcTLSCACertificate' "
+ "DESC 'X.509 certificate, must use ;binary' "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 SINGLE-VALUE )", NULL, NULL },
{ "TLSCACertificateFile", NULL, 2, 2, 0,
#ifdef HAVE_TLS
CFG_TLS_CA_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
#endif
"( OLcfgGlAt:69 NAME 'olcTLSCACertificatePath' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "TLSCertificate", NULL, 2, 2, 0,
+#ifdef HAVE_TLS
+ CFG_TLS_CERT|ARG_BINARY|ARG_MAGIC, &config_tls_option,
+#else
+ ARG_IGNORED, NULL,
+#endif
+ "( OLcfgGlAt:98 NAME 'olcTLSCertificate' "
+ "DESC 'X.509 certificate, must use ;binary' "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 SINGLE-VALUE )", NULL, NULL },
{ "TLSCertificateFile", NULL, 2, 2, 0,
#ifdef HAVE_TLS
CFG_TLS_CERT_FILE|ARG_STRING|ARG_MAGIC, &config_tls_option,
#endif
"( OLcfgGlAt:70 NAME 'olcTLSCertificateFile' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "TLSCertificateKey", NULL, 2, 2, 0,
+#ifdef HAVE_TLS
+ CFG_TLS_KEY|ARG_BINARY|ARG_MAGIC, &config_tls_option,
+#else
+ ARG_IGNORED, NULL,
+#endif
+ "( OLcfgGlAt:99 NAME 'olcTLSCertificateKey' "
+ "DESC 'X.509 privateKey, must use ;binary' "
+ "SYNTAX 1.3.6.1.4.1.4203.666.2.13 SINGLE-VALUE )", NULL, NULL },
{ "TLSCertificateKeyFile", NULL, 2, 2, 0,
#ifdef HAVE_TLS
CFG_TLS_CERT_KEY|ARG_STRING|ARG_MAGIC, &config_tls_option,
"olcTimeLimit $ olcTLSCACertificateFile $ "
"olcTLSCACertificatePath $ olcTLSCertificateFile $ "
"olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
+ "olcTLSCACertificate $ olcTLSCertificate $ olcTLSCertificateKey $ "
"olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ olcTLSECName $ "
"olcTLSCRLFile $ olcTLSProtocolMin $ olcToolThreads $ olcWriteTimeout $ "
"olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
if(tbe == c->be) {
Debug( LDAP_DEBUG_ANY, "%s: suffix already served by this backend!.\n",
c->log, 0, 0);
- return 1;
free(pdn.bv_val);
free(ndn.bv_val);
+ return 1;
} else if(tbe) {
BackendDB *b2 = tbe;
}
tbe = select_backend(&c->be->be_rootndn, 0);
- if(tbe != c->be) {
+ if(tbe != c->be && !SLAP_DBHIDDEN( c->be )) {
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",
static int
config_tls_option(ConfigArgs *c) {
- int flag;
+ int flag, rc;
+ int berval = 0;
LDAP *ld = slap_tls_ld;
switch(c->type) {
case CFG_TLS_RAND: flag = LDAP_OPT_X_TLS_RANDOM_FILE; ld = NULL; break;
#ifdef HAVE_GNUTLS
case CFG_TLS_CRL_FILE: flag = LDAP_OPT_X_TLS_CRLFILE; break;
#endif
+ case CFG_TLS_CACERT: flag = LDAP_OPT_X_TLS_CACERT; berval = 1; break;
+ case CFG_TLS_CERT: flag = LDAP_OPT_X_TLS_CERT; berval = 1; break;
+ case CFG_TLS_KEY: flag = LDAP_OPT_X_TLS_KEY; berval = 1; break;
default: Debug(LDAP_DEBUG_ANY, "%s: "
"unknown tls_option <0x%x>\n",
c->log, c->type, 0);
return 1;
}
if (c->op == SLAP_CONFIG_EMIT) {
- return ldap_pvt_tls_get_option( ld, flag, &c->value_string );
+ return ldap_pvt_tls_get_option( ld, flag, berval ? (void *)&c->value_bv : (void *)&c->value_string );
} else if ( c->op == LDAP_MOD_DELETE ) {
c->cleanup = config_tls_cleanup;
return ldap_pvt_tls_set_option( ld, flag, NULL );
}
- ch_free(c->value_string);
+ if ( !berval ) ch_free(c->value_string);
c->cleanup = config_tls_cleanup;
- return(ldap_pvt_tls_set_option(ld, flag, c->argv[1]));
+ rc = ldap_pvt_tls_set_option(ld, flag, berval ? (void *)&c->value_bv : (void *)c->argv[1]);
+ if ( berval ) ch_free(c->value_bv.bv_val);
+ return rc;
}
/* FIXME: this ought to be provided by libldap */
ConfigArgs *ca )
{
int i, j;
+ if (ad->ad_flags & SLAP_DESC_BINARY)
+ ad = ad->ad_type->sat_ad;
for (j=0; j<nocs; j++) {
for (i=0; colst[j]->co_table[i].name; i++)
}
for ( i=0; vals[i].bv_val; i++ ) {
ca->line = vals[i].bv_val;
+ ca->linelen = vals[i].bv_len;
if (( ad->ad_type->sat_flags & SLAP_AT_ORDERED_VAL ) &&
ca->line[0] == '{' ) {
char *idx = strchr( ca->line, '}' );
- if ( idx ) ca->line = idx+1;
+ if ( idx ) {
+ ca->linelen -= (idx+1) - ca->line;
+ ca->line = idx+1;
+ }
}
rc = config_parse_vals( ct, ca, i );
if ( rc ) {
struct berval *nnewrdn, int use_ldif )
{
char *ptr1;
- int rc = 0;
+ int cnt, rc = 0;
struct berval odn, ondn;
+ const char *text = "";
+ LDAPRDN rDN;
odn = e->e_name;
ondn = e->e_nname;
build_new_dn( &e->e_nname, &parent->ce_entry->e_nname, nnewrdn, NULL );
/* Replace attr */
- free( a->a_vals[0].bv_val );
- ptr1 = strchr( newrdn->bv_val, '=' ) + 1;
- a->a_vals[0].bv_len = newrdn->bv_len - (ptr1 - newrdn->bv_val);
- a->a_vals[0].bv_val = ch_malloc( a->a_vals[0].bv_len + 1 );
- strcpy( a->a_vals[0].bv_val, ptr1 );
-
- if ( a->a_nvals != a->a_vals ) {
- free( a->a_nvals[0].bv_val );
- ptr1 = strchr( nnewrdn->bv_val, '=' ) + 1;
- a->a_nvals[0].bv_len = nnewrdn->bv_len - (ptr1 - nnewrdn->bv_val);
- a->a_nvals[0].bv_val = ch_malloc( a->a_nvals[0].bv_len + 1 );
- strcpy( a->a_nvals[0].bv_val, ptr1 );
+ rc = ldap_bv2rdn( &e->e_name, &rDN, (char **)&text, LDAP_DN_FORMAT_LDAP );
+ if ( rc ) {
+ return rc;
+ }
+ for ( cnt = 0; rDN[cnt]; cnt++ ) {
+ AttributeDescription *ad = NULL;
+ LDAPAVA *ava = rDN[cnt];
+
+ rc = slap_bv2ad( &ava->la_attr, &ad, &text );
+ if ( rc ) {
+ break;
+ }
+
+ if ( ad != a->a_desc ) continue;
+
+ free( a->a_vals[0].bv_val );
+ ber_dupbv( &a->a_vals[0], &ava->la_value );
+ if ( a->a_nvals != a->a_vals ) {
+ free( a->a_nvals[0].bv_val );
+ rc = attr_normalize_one( ad, &ava->la_value, &a->a_nvals[0], NULL );
+ if ( rc ) {
+ break;
+ }
+ }
+
+ /* attributes with X-ORDERED 'SIBLINGS' are single-valued, we're done */
+ break;
}
+ /* the attribute must be present in rDN */
+ assert( rDN[cnt] );
+ ldap_rdnfree( rDN );
+ if ( rc ) {
+ return rc;
+ }
+
if ( use_ldif ) {
CfBackInfo *cfb = (CfBackInfo *)op->o_bd->be_private;
BackendDB *be = op->o_bd;
if ( ce_type == Cft_Database )
nsibs--;
- if ( index != nsibs ) {
+ if ( index != nsibs || isfrontend ) {
if ( gotindex ) {
if ( index < nsibs ) {
if ( tailindex ) return LDAP_NAMING_VIOLATION;
char *iptr = NULL;
ca->valx = -1;
ca->line = a->a_vals[i].bv_val;
+ ca->linelen = a->a_vals[i].bv_len;
if ( a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED ) {
ptr = strchr( ca->line, '}' );
if ( ptr ) {
iptr = strchr( ca->line, '{' );
+ ca->linelen -= (ptr+1) - ca->line;
ca->line = ptr+1;
}
}
config_back_add( Operation *op, SlapReply *rs )
{
CfBackInfo *cfb;
- int renumber;
+ int renumber, dopause = 1;
ConfigArgs ca;
if ( !access_allowed( op, op->ora_e, slap_schema.si_ad_entry,
rs->sr_err = SLAPD_ABANDON;
goto out;
}
- ldap_pvt_thread_pool_pause( &connection_pool );
+ if ( ldap_pvt_thread_pool_pause( &connection_pool ) < 0 )
+ dopause = 0;
/* Strategy:
* 1) check for existence of entry
}
out2:;
- ldap_pvt_thread_pool_resume( &connection_pool );
+ if ( dopause )
+ ldap_pvt_thread_pool_resume( &connection_pool );
out:;
{ int repl = op->o_dont_replicate;
if ( next == ca->line + 1 || next[ 0 ] != '}' ) {
return LDAP_OTHER;
}
+ ca->linelen -= (ptr+1) - ca->line;
ca->line = ptr+1;
}
}
bv.bv_val = ptr;
}
ca->line = bv.bv_val;
+ ca->linelen = bv.bv_len;
ca->valx = d->idx[i];
config_parse_vals(ct, ca, d->idx[i] );
rc = config_del_vals( ct, ca );
break;
for (i=0; ml->sml_values[i].bv_val; i++) {
ca->line = ml->sml_values[i].bv_val;
+ ca->linelen = ml->sml_values[i].bv_len;
ca->valx = -1;
rc = config_modify_add( ct, ca, ml->sml_desc, i );
if ( rc )
}
for ( i=0; !BER_BVISNULL( &s->a_vals[i] ); i++ ) {
ca->line = s->a_vals[i].bv_val;
+ ca->linelen = s->a_vals[i].bv_len;
ca->valx = -1;
config_modify_add( ct, ca, s->a_desc, i );
}
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->linelen = s->a_vals[i].bv_len;
ca->valx = -1;
config_modify_add( ct, ca, s->a_desc, i );
}
rs->sr_err = SLAPD_ABANDON;
goto out;
}
- ldap_pvt_thread_pool_pause( &connection_pool );
+ if ( ldap_pvt_thread_pool_pause( &connection_pool ) < 0 )
+ do_pause = 0;
}
/* Strategy:
CfBackInfo *cfb;
CfEntryInfo *ce, *last;
struct berval rdn;
- int ixold, ixnew;
+ int ixold, ixnew, dopause = 1;
cfb = (CfBackInfo *)op->o_bd->be_private;
rs->sr_err = SLAPD_ABANDON;
goto out;
}
- ldap_pvt_thread_pool_pause( &connection_pool );
+ if ( ldap_pvt_thread_pool_pause( &connection_pool ) < 0 )
+ dopause = 0;
if ( ce->ce_type == Cft_Schema ) {
req_modrdn_s modr = op->oq_modrdn;
op->oq_modrdn = modr;
}
- ldap_pvt_thread_pool_resume( &connection_pool );
+ if ( dopause )
+ ldap_pvt_thread_pool_resume( &connection_pool );
out:
send_ldap_result( op, rs );
return rs->sr_err;
#ifdef SLAP_CONFIG_DELETE
CfBackInfo *cfb;
CfEntryInfo *ce, *last, *ce2;
+ int dopause = 1;
cfb = (CfBackInfo *)op->o_bd->be_private;
char *iptr;
int count, ixold;
- ldap_pvt_thread_pool_pause( &connection_pool );
+ if ( ldap_pvt_thread_pool_pause( &connection_pool ) < 0 )
+ dopause = 0;
if ( ce->ce_type == Cft_Overlay ){
overlay_remove( ce->ce_be, (slap_overinst *)ce->ce_bi, op );
if ( !oc_at ) {
rs->sr_err = LDAP_OTHER;
rs->sr_text = "objectclass not found";
- ldap_pvt_thread_pool_resume( &connection_pool );
+ if ( dopause ) ldap_pvt_thread_pool_resume( &connection_pool );
goto out;
}
for ( i=0; !BER_BVISNULL(&oc_at->a_nvals[i]); i++ ) {
/* FIXME: We should return a helpful error message
* here */
}
- ldap_pvt_thread_pool_resume( &connection_pool );
+ if ( dopause ) ldap_pvt_thread_pool_resume( &connection_pool );
goto out;
}
break;
if ( ce->ce_be == frontendDB || ce->ce_be == op->o_bd ){
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
rs->sr_text = "Cannot delete config or frontend database";
- ldap_pvt_thread_pool_resume( &connection_pool );
+ if ( dopause ) ldap_pvt_thread_pool_resume( &connection_pool );
goto out;
}
if ( ce->ce_be->bd_info->bi_db_close ) {
ce->ce_entry->e_private=NULL;
entry_free(ce->ce_entry);
ch_free(ce);
- ldap_pvt_thread_pool_resume( &connection_pool );
+ if ( dopause ) ldap_pvt_thread_pool_resume( &connection_pool );
} else {
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
}
struct berval val;
struct berval ad_name;
AttributeDescription *ad = NULL;
- int rc;
+ int cnt, rc;
char *ptr;
const char *text = "";
Attribute *oc_at;
struct berval pdn;
ObjectClass *oc;
CfEntryInfo *ceprev = NULL;
+ LDAPRDN rDN;
Debug( LDAP_DEBUG_TRACE, "config_build_entry: \"%s\"\n", rdn->bv_val, 0, 0);
e->e_private = ce;
if ( extra )
attr_merge_normalize_one(e, slap_schema.si_ad_objectClass,
extra->co_name, NULL );
- ptr = strchr(rdn->bv_val, '=');
- ad_name.bv_val = rdn->bv_val;
- ad_name.bv_len = ptr - rdn->bv_val;
- rc = slap_bv2ad( &ad_name, &ad, &text );
+
+ rc = ldap_bv2rdn( rdn, &rDN, (char **)&text, LDAP_DN_FORMAT_LDAP );
+ if ( rc ) {
+ goto fail;
+ }
+ for ( cnt = 0; rDN[cnt]; cnt++ ) {
+ LDAPAVA *ava = rDN[cnt];
+
+ ad = NULL;
+ rc = slap_bv2ad( &ava->la_attr, &ad, &text );
+ if ( rc ) {
+ break;
+ }
+ if ( !ad->ad_type->sat_equality ) {
+ rc = LDAP_CONSTRAINT_VIOLATION;
+ text = "attribute has no equality matching rule";
+ break;
+ }
+ if ( !ad->ad_type->sat_equality->smr_match ) {
+ rc = LDAP_CONSTRAINT_VIOLATION;
+ text = "attribute has unsupported equality matching rule";
+ break;
+ }
+ attr_merge_normalize_one(e, ad, &ava->la_value, NULL );
+ }
+ ldap_rdnfree( rDN );
if ( rc ) {
goto fail;
}
- val.bv_val = ptr+1;
- val.bv_len = rdn->bv_len - (val.bv_val - rdn->bv_val);
- attr_merge_normalize_one(e, ad, &val, NULL );
oc = main->co_oc;
c->table = main->co_type;
return NOID;
}
} else {
- if ( !strncmp( e->e_nname.bv_val +
- STRLENOF( "olcDatabase" ), "=frontend",
- STRLENOF( "=frontend" ) ) )
- {
- struct berval rdn, pdn, ndn;
- dnParent( &e->e_nname, &pdn );
- 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,
- frontendDB->bd_info->bi_type );
- build_new_dn( &ndn, &pdn, &rdn, NULL );
- ber_memfree( e->e_name.bv_val );
- e->e_name = ndn;
- ber_bvreplace( &e->e_nname, &e->e_name );
- }
entry_put_got_frontend++;
isFrontend = 1;
}
return NOID;
}
+static int
+config_tool_entry_delete( BackendDB *be, struct berval *ndn, struct berval *text )
+{
+ CfBackInfo *cfb = be->be_private;
+ BackendInfo *bi = cfb->cb_db.bd_info;
+ CfEntryInfo *ce, *last;
+ ConfigArgs ca = {0};
+
+ ce = config_find_base( cfb->cb_root, ndn, &last );
+
+ if ( ce && bi && bi->bi_tool_entry_delete )
+ return bi->bi_tool_entry_delete( &cfb->cb_db, ndn, text );
+
+ return LDAP_OTHER;
+}
+
static struct {
char *name;
AttributeDescription **desc;
bi->bi_tool_entry_get = config_tool_entry_get;
bi->bi_tool_entry_put = config_tool_entry_put;
bi->bi_tool_entry_modify = config_tool_entry_modify;
+ bi->bi_tool_entry_delete = config_tool_entry_delete;
ca.argv = argv;
argv[ 0 ] = "slapd";