From 21fee6a7f1291cafa1468473a1924751d594d667 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Thu, 20 Jan 2005 23:43:28 +0000 Subject: [PATCH] more fixes related to ITS#3499 --- CHANGES | 1 + servers/slapd/back-ldap/add.c | 7 ++- servers/slapd/back-ldap/back-ldap.h | 2 + servers/slapd/back-ldap/modify.c | 6 ++ servers/slapd/back-meta/add.c | 87 ++++++++++++++++++++++------- servers/slapd/back-meta/bind.c | 67 ++++++++++++++++++++-- servers/slapd/back-meta/modify.c | 26 +++++++-- 7 files changed, 162 insertions(+), 34 deletions(-) diff --git a/CHANGES b/CHANGES index 2bb208ac2d..a24edc7860 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,7 @@ OpenLDAP 2.2.21 Release Fixed back-bdb retcode on referral (ITS#3475) Fixed back-bdb detecting deadlock in indexer (ITS#3481) Fixed back-bdb cache deadlock (ITS#3494) + Fixed back-ldap/meta objectClass mapping in updates (ITS#3499) Fixed back-meta DN-valued attribute delete (ITS#3498) Fixed back-sql access checking on search (ITS#3488) Build Environment diff --git a/servers/slapd/back-ldap/add.c b/servers/slapd/back-ldap/add.c index 5b958a2921..76820e95b4 100644 --- a/servers/slapd/back-ldap/add.c +++ b/servers/slapd/back-ldap/add.c @@ -146,6 +146,12 @@ ldap_back_add( } j++; } + + if ( j == 0 ) { + ch_free( attrs[ i ]->mod_bvalues ); + continue; + } + attrs[ i ]->mod_bvalues[ j ] = NULL; } else { @@ -158,7 +164,6 @@ ldap_back_add( */ (void)ldap_dnattr_rewrite( &dc, a->a_vals ); if ( a->a_vals == NULL || BER_BVISNULL( &a->a_vals[0] ) ) { - ch_free( attrs ); continue; } } diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index cfdc054c18..aedbe4246c 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -139,6 +139,8 @@ int mapping_cmp (const void *, const void *); int mapping_dup (void *, void *); void ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping ** ); +int ldap_back_mapping ( struct ldapmap *map, struct berval *s, struct ldapmapping **m, + int remap ); void ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *m, int remap ); #define BACKLDAP_MAP 0 diff --git a/servers/slapd/back-ldap/modify.c b/servers/slapd/back-ldap/modify.c index ecce4e8fcd..a4abf40f6a 100644 --- a/servers/slapd/back-ldap/modify.c +++ b/servers/slapd/back-ldap/modify.c @@ -141,6 +141,12 @@ ldap_back_modify( } j++; } + + if ( j == 0 ) { + ch_free( mods[i].mod_bvalues ); + continue; + } + mods[i].mod_bvalues[j] = NULL; } else { diff --git a/servers/slapd/back-meta/add.c b/servers/slapd/back-meta/add.c index d1e4069b1b..e49ea11130 100644 --- a/servers/slapd/back-meta/add.c +++ b/servers/slapd/back-meta/add.c @@ -87,16 +87,24 @@ meta_back_add( Operation *op, SlapReply *rs ) attrs = ch_malloc( sizeof( LDAPMod * )*i ); for ( i = 0, a = op->oq_add.rs_e->e_attrs; a; a = a->a_next ) { - int j; + int j, is_oc = 0; if ( a->a_desc->ad_type->sat_no_user_mod ) { continue; } - ldap_back_map( &li->targets[ candidate ]->rwmap.rwm_at, - &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP ); - if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) { - continue; + if ( a->a_desc == slap_schema.si_ad_objectClass + || a->a_desc == slap_schema.si_ad_structuralObjectClass ) + { + is_oc = 1; + mapped = a->a_desc->ad_cname; + + } else { + ldap_back_map( &li->targets[ candidate ]->rwmap.rwm_at, + &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP ); + if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) { + continue; + } } attrs[ i ] = ch_malloc( sizeof( LDAPMod ) ); @@ -106,29 +114,66 @@ meta_back_add( Operation *op, SlapReply *rs ) attrs[ i ]->mod_op = LDAP_MOD_BVALUES; attrs[ i ]->mod_type = mapped.bv_val; - /* - * FIXME: dn-valued attrs should be rewritten - * to allow their use in ACLs at the back-ldap - * level. - */ - if ( strcmp( a->a_desc->ad_type->sat_syntax->ssyn_oid, - SLAPD_DN_SYNTAX ) == 0 ) { - (void)ldap_dnattr_rewrite( &dc, a->a_vals ); - } - - for ( j = 0; a->a_vals[ j ].bv_val; j++ ); - attrs[ i ]->mod_vals.modv_bvals = ch_malloc((j+1)*sizeof(struct berval *)); - for ( j = 0; a->a_vals[ j ].bv_val; j++ ) { - attrs[ i ]->mod_vals.modv_bvals[ j ] = &a->a_vals[ j ]; + if ( is_oc ) { + for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) + ; + + attrs[ i ]->mod_bvalues = + (struct berval **)ch_malloc( ( j + 1 ) * + sizeof( struct berval * ) ); + + for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); ) { + struct ldapmapping *mapping; + + ldap_back_mapping( &li->targets[ candidate ]->rwmap.rwm_oc, + &a->a_vals[ j ], &mapping, BACKLDAP_MAP ); + + if ( mapping == NULL ) { + if ( li->targets[ candidate ]->rwmap.rwm_oc.drop_missing ) { + continue; + } + attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ]; + + } else { + attrs[ i ]->mod_bvalues[ j ] = &mapping->dst; + } + j++; + } + + if ( j == 0 ) { + ch_free( attrs[ i ]->mod_bvalues ); + continue; + } + + attrs[ i ]->mod_bvalues[ j ] = NULL; + + } else { + /* + * FIXME: dn-valued attrs should be rewritten + * to allow their use in ACLs at the back-ldap + * level. + */ + if ( a->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) { + (void)ldap_dnattr_rewrite( &dc, a->a_vals ); + if ( a->a_vals == NULL ) { + continue; + } + } + + for ( j = 0; a->a_vals[ j ].bv_val; j++ ); + attrs[ i ]->mod_bvalues = ch_malloc((j+1)*sizeof(struct berval *)); + for ( j = 0; a->a_vals[ j ].bv_val; j++ ) { + attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ]; + } + attrs[ i ]->mod_bvalues[ j ] = NULL; } - attrs[ i ]->mod_vals.modv_bvals[ j ] = NULL; i++; } attrs[ i ] = NULL; ldap_add_s( lc->conns[ candidate ].ld, mdn.bv_val, attrs ); for ( --i; i >= 0; --i ) { - free( attrs[ i ]->mod_vals.modv_bvals ); + free( attrs[ i ]->mod_bvalues ); free( attrs[ i ] ); } free( attrs ); diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index e53b231fb1..f068b10779 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -195,7 +195,6 @@ meta_back_do_single_bind( ber_int_t msgid; dncookie dc; struct metasingleconn *lsc = &lc->conns[ candidate ]; - LDAPMessage *res; /* * Rewrite the bind dn if needed @@ -222,9 +221,37 @@ meta_back_do_single_bind( /* FIXME: this fixes the bind problem right now; we need * to use the asynchronous version to get the "matched" * and more in case of failure ... */ - rs->sr_err = ldap_sasl_bind_s(lsc->ld, mdn.bv_val, + rs->sr_err = ldap_sasl_bind( lsc->ld, mdn.bv_val, LDAP_SASL_SIMPLE, &op->oq_bind.rb_cred, - op->o_ctrls, NULL, NULL); + op->o_ctrls, NULL, &msgid ); + if ( rs->sr_err == LDAP_SUCCESS ) { + LDAPMessage *res; + struct timeval tv = { 0, 0 }; + int rc; + +retry:; + switch ( ldap_result( lsc->ld, msgid, 0, &tv, &res ) ) { + case 0: + tv.tv_sec = 0; + tv.tv_usec = 1000; /* 0.001 s */ + ldap_pvt_thread_yield(); + goto retry; + + case -1: + ldap_get_option( lsc->ld, LDAP_OPT_ERROR_NUMBER, + &rs->sr_err ); + break; + + default: + rc = ldap_parse_result( lsc->ld, res, &rs->sr_err, + NULL, NULL, NULL, NULL, 1 ); + if ( rc != LDAP_SUCCESS ) { + rs->sr_err = rc; + } + break; + } + } + if ( rs->sr_err != LDAP_SUCCESS ) { rs->sr_err = slap_map_api2result( rs ); goto return_results; @@ -283,6 +310,7 @@ meta_back_dobind( struct metaconn *lc, Operation *op ) for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) { int rc; struct berval cred = BER_BVC(""); + int msgid; /* * Not a candidate or something wrong with this target ... @@ -329,10 +357,37 @@ meta_back_dobind( struct metaconn *lc, Operation *op ) lsc->cred.bv_len = 0; } - rc = ldap_sasl_bind_s(lsc->ld, "", LDAP_SASL_SIMPLE, &cred, - op->o_ctrls, NULL, NULL); + rc = ldap_sasl_bind( lsc->ld, "", LDAP_SASL_SIMPLE, &cred, + op->o_ctrls, NULL, &msgid ); + if ( rc == LDAP_SUCCESS ) { + LDAPMessage *res; + struct timeval tv = { 0, 0 }; + int err; + +retry:; + switch ( ldap_result( lsc->ld, msgid, 0, &tv, &res ) ) { + case 0: + tv.tv_sec = 0; + tv.tv_usec = 1000; /* 0.001 s */ + ldap_pvt_thread_yield(); + goto retry; + + case -1: + ldap_get_option( lsc->ld, LDAP_OPT_ERROR_NUMBER, + &rc ); + break; + + default: + rc = ldap_parse_result( lsc->ld, res, &err, + NULL, NULL, NULL, NULL, 1 ); + if ( rc == LDAP_SUCCESS ) { + rc = err; + } + break; + } + } + if ( rc != LDAP_SUCCESS ) { - #ifdef NEW_LOGGING LDAP_LOG( BACK_META, WARNING, "meta_back_dobind: (anonymous)" diff --git a/servers/slapd/back-meta/modify.c b/servers/slapd/back-meta/modify.c index 92d1b1e7f9..27da0b3fb1 100644 --- a/servers/slapd/back-meta/modify.c +++ b/servers/slapd/back-meta/modify.c @@ -126,15 +126,29 @@ meta_back_modify( Operation *op, SlapReply *rs ) for (j = 0; ml->sml_values[j].bv_val; j++); mods[i].mod_bvalues = (struct berval **)ch_malloc((j+1) * sizeof(struct berval *)); - for (j = 0; ml->sml_values[j].bv_val; j++) { - ldap_back_map(&li->targets[ candidate ]->rwmap.rwm_oc, + for (j = 0; ml->sml_values[j].bv_val; ) { + struct ldapmapping *mapping = NULL; + + ldap_back_mapping(&li->targets[ candidate ]->rwmap.rwm_oc, &ml->sml_values[j], - &mapped, BACKLDAP_MAP); - if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') { - continue; + &mapping, BACKLDAP_MAP); + if ( mapping == NULL ) { + if ( li->targets[ candidate ]->rwmap.rwm_oc.drop_missing ) { + continue; + } + mods[i].mod_bvalues[j] = &ml->sml_values[j]; + + } else { + mods[i].mod_bvalues[j] = &mapping->dst; } - mods[i].mod_bvalues[j] = &mapped; + j++; + } + + if ( j == 0 ) { + ch_free( mods[i].mod_bvalues ); + continue; } + mods[i].mod_bvalues[j] = NULL; } else { -- 2.39.5