ITS#8574 - Deal with rDN correctly

This fixes issues with values that need escaping in the rDN when an
incorrect value would be passed to the handler and back-ldif.
This commit is contained in:
Ondřej Kuzník 2017-02-22 18:24:48 +00:00 committed by Quanah Gibson-Mount
parent 4962dd6083
commit 53c6c9d16b

View File

@ -4720,8 +4720,10 @@ config_rename_one( Operation *op, SlapReply *rs, Entry *e,
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;
@ -4729,19 +4731,41 @@ config_rename_one( Operation *op, SlapReply *rs, Entry *e,
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, &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;
@ -6696,13 +6720,14 @@ config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
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;
@ -6731,16 +6756,35 @@ config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
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, &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;