struct ldaprwmap *rwmap =
(struct ldaprwmap *)on->on_bi.bi_private;
- struct berval dn, ndn, mdn = BER_BVNULL;
+ struct berval dn = BER_BVNULL,
+ ndn = BER_BVNULL;
int rc = 0;
dncookie dc;
dc.normalized = 0;
#endif
- rc = rwm_dn_massage( &dc, &op->o_req_dn, &mdn );
+ rc = rwm_dn_massage( &dc, &op->o_req_dn, &dn, &ndn );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
- if ( mdn.bv_val == op->o_req_dn.bv_val ) {
+ if ( dn.bv_val == op->o_req_dn.bv_val ) {
return LDAP_SUCCESS;
}
- rc = dnPrettyNormal( NULL, &mdn, &dn, &ndn, op->o_tmpmemctx );
- if ( rc != LDAP_SUCCESS ) {
- return rc;
- }
-
- if ( mdn.bv_val != dn.bv_val ) {
- ch_free( mdn.bv_val );
- }
-
op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
rwm_map( &rwmap->rwm_at, &(*ap)->a_desc->ad_cname,
&mapped, RWM_MAP );
- if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
+ if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
goto cleanup_attr;
}
* the operation should give up, right?
*/
#ifdef ENABLE_REWRITE
- rc = rwm_dnattr_rewrite( op, rs, "addDn",
- (*ap)->a_vals );
+ rc = rwm_dnattr_rewrite( op, rs, "addDn", (*ap)->a_vals, NULL );
#else
rc = 1;
- rc = rwm_dnattr_rewrite( op, rs, &rc,
- (*ap)->a_vals );
+ rc = rwm_dnattr_rewrite( op, rs, &rc, (*ap)->a_vals, NULL );
#endif
if ( rc ) {
goto cleanup_attr;
a = *ap;
*ap = (*ap)->a_next;
- ber_bvarray_free( a->a_vals );
- ber_bvarray_free( a->a_nvals );
- ch_free( a );
+ attr_free( a );
}
-
/* TODO: map attribute types, values of DN-valued attributes ... */
return SLAP_CB_CONTINUE;
}
int rc;
#ifdef ENABLE_REWRITE
+ ( void )rewrite_session_delete( rwmap->rwm_rw, op->o_conn );
( void )rewrite_session_init( rwmap->rwm_rw, op->o_conn );
rc = rwm_op_dn_massage( op, rs, "bindDn" );
{
rwm_map( &rwmap->rwm_oc, &op->orc_ava->aa_value,
&mapped_vals[0], RWM_MAP );
- if ( mapped_vals[0].bv_val == NULL
- || mapped_vals[0].bv_val[0] == '\0')
+ if ( BER_BVISNULL( &mapped_vals[0] ) || BER_BVISEMPTY( &mapped_vals[0] ) )
{
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, LDAP_OTHER, "compare objectClass map error" );
mapped_at = op->orc_ava->aa_desc->ad_cname;
} else {
- rwm_map( &rwmap->rwm_at,
- &op->orc_ava->aa_desc->ad_cname,
- &mapped_at,
- RWM_MAP );
- if ( mapped_at.bv_val == NULL
- || mapped_at.bv_val[0] == '\0')
+ rwm_map( &rwmap->rwm_at, &op->orc_ava->aa_desc->ad_cname,
+ &mapped_at, RWM_MAP );
+ if ( BER_BVISNULL( &mapped_at ) || BER_BVISEMPTY( &mapped_at ) )
{
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, LDAP_OTHER, "compare attributeType map error" );
if ( op->orc_ava->aa_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
{
mapped_vals[0] = op->orc_ava->aa_value;
- rc = rwm_dnattr_rewrite( op, rs, "compareAttrDN", mapped_vals );
+
+#ifdef ENABLE_REWRITE
+ rc = rwm_dnattr_rewrite( op, rs, "compareAttrDN", mapped_vals, NULL );
+#else
+ rc = 1;
+ rc = rwm_dnattr_rewrite( op, rs, &rc, mapped_vals, NULL );
+#endif
+
if ( rc != LDAP_SUCCESS ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, rc, "compareAttrDN massage error" );
}
}
- /* TODO: rewrite attribute types, values of DN-valued attributes ... */
return SLAP_CB_CONTINUE;
}
rwm_modify( Operation *op, SlapReply *rs )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
+ struct ldaprwmap *rwmap =
+ (struct ldaprwmap *)on->on_bi.bi_private;
+
+ int isupdate;
+ Modifications **mlp;
int rc;
#ifdef ENABLE_REWRITE
return rc;
}
+ isupdate = be_shadow_update( op );
+ for ( mlp = &op->oq_modify.rs_modlist; *mlp; ) {
+ int is_oc = 0;
+
+ if ( !isupdate && (*mlp)->sml_desc->ad_type->sat_no_user_mod ) {
+ Modifications *ml;
+
+ ml = *mlp;
+ *mlp = (*mlp)->sml_next;
+ slap_mod_free( &ml->sml_mod, 0 );
+ free( ml );
+
+ continue;
+ }
+
+ if ( (*mlp)->sml_desc == slap_schema.si_ad_objectClass
+ || (*mlp)->sml_desc == slap_schema.si_ad_structuralObjectClass ) {
+ is_oc = 1;
+
+ } else {
+ struct ldapmapping *m;
+ int drop_missing;
+
+ drop_missing = rwm_mapping( &rwmap->rwm_at, &(*mlp)->sml_desc->ad_cname, &m, RWM_MAP );
+ if ( drop_missing || ( m != NULL && BER_BVISNULL( &m->m_dst ) ) )
+ {
+ Modifications *ml;
+
+ ml = *mlp;
+ *mlp = (*mlp)->sml_next;
+ slap_mod_free( &ml->sml_mod, 0 );
+ free( ml );
+
+ continue;
+ }
+
+ if ( m ) {
+ /* use new attribute description */
+ assert( m->m_dst_ad );
+ (*mlp)->sml_desc = m->m_dst_ad;
+ }
+ }
+
+ if ( (*mlp)->sml_values != NULL ) {
+ if ( is_oc ) {
+ int last, j;
+
+ for ( last = 0; !BER_BVISNULL( &(*mlp)->sml_values[last] ); last++ )
+ /* count values */ ;
+ last--;
+
+ for ( j = 0; !BER_BVISNULL( &(*mlp)->sml_values[j] ); j++ ) {
+ struct berval mapped = BER_BVNULL;
+
+ rwm_map( &rwmap->rwm_oc,
+ &(*mlp)->sml_values[j],
+ &mapped, RWM_MAP );
+ if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
+ /* FIXME: we allow to remove objectClasses as well;
+ * if the resulting entry is inconsistent, that's
+ * the relayed database's business...
+ */
+#if 0
+ Modifications *ml;
+
+ ml = *mlp;
+ *mlp = (*mlp)->sml_next;
+ slap_mod_free( &ml->sml_mod, 0 );
+ free( ml );
+
+ continue;
+#endif
+ if ( last > j ) {
+ (*mlp)->sml_values[j] = (*mlp)->sml_values[last];
+ BER_BVZERO( &(*mlp)->sml_values[last] );
+ }
+ last--;
+
+ } else {
+ ch_free( (*mlp)->sml_values[j].bv_val );
+ ber_dupbv( &(*mlp)->sml_values[j], &mapped );
+ }
+ }
+
+ } else {
+ if ( (*mlp)->sml_desc->ad_type->sat_syntax ==
+ slap_schema.si_syn_distinguishedName )
+ {
+#ifdef ENABLE_REWRITE
+ rc = rwm_dnattr_rewrite( op, rs, "modifyDn",
+ (*mlp)->sml_values, &(*mlp)->sml_nvalues );
+#else
+ rc = 1;
+ rc = rwm_dnattr_rewrite( op, rs, &rc,
+ (*mlp)->sml_values, &(*mlp)->sml_nvalues );
+#endif
+ }
+
+ if ( rc != LDAP_SUCCESS ) {
+ Modifications *ml;
+
+ ml = *mlp;
+ *mlp = (*mlp)->sml_next;
+ slap_mod_free( &ml->sml_mod, 0 );
+ free( ml );
+
+ continue;
+ }
+ }
+ }
+
+ mlp = &(*mlp)->sml_next;
+ }
+
/* TODO: rewrite attribute types, values of DN-valued attributes ... */
return SLAP_CB_CONTINUE;
}
return SLAP_CB_CONTINUE;
}
+static int
+rwm_swap_attrs( Operation *op, SlapReply *rs )
+{
+ slap_callback *cb = op->o_callback;
+ AttributeName *an = (AttributeName *)cb->sc_private;
+
+ rs->sr_attrs = an;
+
+ return SLAP_CB_CONTINUE;
+}
+
static int
rwm_search( Operation *op, SlapReply *rs )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
+ struct ldaprwmap *rwmap =
+ (struct ldaprwmap *)on->on_bi.bi_private;
+
int rc;
+ dncookie dc;
+
+ struct berval fstr = BER_BVNULL;
+ Filter *f = NULL;
+
+ slap_callback *cb;
+ AttributeName *an = NULL;
+
+ char *text = NULL;
#ifdef ENABLE_REWRITE
rc = rwm_op_dn_massage( op, rs, "searchDn" );
rc = rwm_op_dn_massage( op, rs, &rc );
#endif
if ( rc != LDAP_SUCCESS ) {
- op->o_bd->bd_info = (BackendInfo *)on->on_info;
- send_ldap_error( op, rs, rc, "searchDn massage error" );
- return rc;
+ text = "searchDn massage error";
+ goto error_return;
+ }
+
+ /*
+ * Rewrite the bind dn if needed
+ */
+ dc.rwmap = rwmap;
+#ifdef ENABLE_REWRITE
+ dc.conn = op->o_conn;
+ dc.rs = rs;
+ dc.ctx = "searchFilterAttrDN";
+#else
+ dc.tofrom = 0;
+ dc.normalized = 0;
+#endif
+
+ rc = rwm_filter_map_rewrite( &dc, op->ors_filter, &fstr );
+ if ( rc != LDAP_SUCCESS ) {
+ text = "searchFilter/searchFilterAttrDN massage error";
+ goto error_return;
+ }
+
+ f = str2filter_x( op, fstr.bv_val );
+
+ if ( f == NULL ) {
+ text = "massaged filter parse error";
+ goto error_return;
+ }
+
+ if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
+ ch_free( op->ors_filterstr.bv_val );
+ }
+
+ if( op->ors_filter ) {
+ filter_free_x( op, op->ors_filter );
+ }
+
+ op->ors_filter = f;
+ op->ors_filterstr = fstr;
+
+ rc = rwm_map_attrnames( &rwmap->rwm_at, &rwmap->rwm_oc,
+ op->ors_attrs, &an, RWM_MAP );
+ if ( rc != LDAP_SUCCESS ) {
+ text = "attribute list mapping error";
+ goto error_return;
}
+ cb = (slap_callback *)ch_malloc( sizeof( slap_callback ) );
+ if ( cb == NULL ) {
+ rc = LDAP_NO_MEMORY;
+ goto error_return;
+ }
+
+ cb->sc_response = rwm_swap_attrs;
+ cb->sc_cleanup = NULL;
+ cb->sc_private = (void *)op->ors_attrs;
+ cb->sc_next = op->o_callback;
+
+ op->o_callback = cb;
+ op->ors_attrs = an;
+
/* TODO: rewrite/map filter & attrs */
return SLAP_CB_CONTINUE;
+
+error_return:;
+ if ( an != NULL ) {
+ ch_free( an );
+ }
+
+ if ( f != NULL ) {
+ filter_free_x( op, f );
+ }
+
+ if ( !BER_BVISNULL( &fstr ) ) {
+ ch_free( fstr.bv_val );
+ }
+
+ op->o_bd->bd_info = (BackendInfo *)on->on_info;
+ send_ldap_error( op, rs, rc, text );
+
+ return 1;
+
}
static int
struct berval dn, mdn;
dncookie dc;
+ int rc;
if ( rs->sr_matched == NULL ) {
return SLAP_CB_CONTINUE;
dc.normalized = 0;
#endif
ber_str2bv( rs->sr_matched, 0, 0, &dn );
- rwm_dn_massage( &dc, &dn, &mdn );
+ rc = rwm_dn_massage( &dc, &dn, &mdn, NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ rs->sr_err = rc;
+ rs->sr_text = "Rewrite error";
+ return 1;
+ }
if ( mdn.bv_val != dn.bv_val ) {
if ( rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
ch_free( (void *)rs->sr_matched );
+
} else {
rs->sr_flags |= REP_MATCHED_MUSTBEFREED;
}
(struct ldaprwmap *)on->on_bi.bi_private;
Entry *e = NULL;
- struct berval dn = BER_BVNULL, ndn = BER_BVNULL;
+ struct berval dn = BER_BVNULL,
+ ndn = BER_BVNULL;
dncookie dc;
- int rc = SLAP_CB_CONTINUE;
+ int rc;
+ Attribute **ap;
assert( rs->sr_entry );
dc.tofrom = 0;
dc.normalized = 0;
#endif
- if ( rwm_dn_massage( &dc, &e->e_name, &dn ) ) {
- return LDAP_OTHER;
- }
- if ( e->e_name.bv_val == dn.bv_val ) {
- return SLAP_CB_CONTINUE;
+ if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
+ /* FIXME: all we need to duplicate are:
+ * - dn
+ * - ndn
+ * - attributes that are requested
+ * - no values if attrsonly is set
+ */
+ e = entry_dup( e );
+ if ( e == NULL ) {
+ rc = LDAP_NO_MEMORY;
+ goto fail;
+ }
+ rs->sr_flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
}
/*
* from the one known to the meta, and a DN with unknown
* attributes is returned.
*/
- if ( dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) != LDAP_SUCCESS ) {
- if ( dn.bv_val != e->e_name.bv_val ) {
- ch_free( dn.bv_val );
- }
- rc = LDAP_INVALID_DN_SYNTAX;
+ rc = rwm_dn_massage( &dc, &e->e_name, &dn, &ndn );
+ if ( rc != LDAP_SUCCESS ) {
goto fail;
}
- if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
- e = entry_dup( e );
- if ( e == NULL ) {
- goto fail;
- }
- rs->sr_flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
+ if ( e->e_name.bv_val != dn.bv_val ) {
+ free( e->e_name.bv_val );
+ free( e->e_nname.bv_val );
+
+ e->e_name = dn;
+ e->e_nname = ndn;
}
- free( e->e_name.bv_val );
- free( e->e_nname.bv_val );
+ /* TODO: map entry attribute types, objectclasses
+ * and dn-valued attribute values */
+
+ /* FIXME: the entries are in the remote mapping form;
+ * so we need to select those attributes we are willing
+ * to return, and remap them accordingly */
+
+ for ( ap = &e->e_attrs; *ap; ) {
+ struct ldapmapping *m;
+ int drop_missing;
+ int last;
+
+ if ( op->ors_attrs != NULL && !ad_inlist( (*ap)->a_desc, op->ors_attrs ) ) {
+ Attribute *a;
+
+ a = *ap;
+ *ap = (*ap)->a_next;
+
+ attr_free( a );
+ continue;
+ }
+
+ drop_missing = rwm_mapping( &rwmap->rwm_at,
+ &(*ap)->a_desc->ad_cname, &m, RWM_REMAP );
+ if ( drop_missing || ( m != NULL && BER_BVISEMPTY( &m->m_dst ) ) ) {
+ Attribute *a;
+
+ a = *ap;
+ *ap = (*ap)->a_next;
+
+ attr_free( a );
+ continue;
+ }
+
+ /* no subschemaSubentry */
+ if ( (*ap)->a_desc == slap_schema.si_ad_subschemaSubentry ) {
+
+ /*
+ * We eat target's subschemaSubentry because
+ * a search for this value is likely not
+ * to resolve to the appropriate backend;
+ * later, the local subschemaSubentry is
+ * added.
+ */
+ Attribute *a;
+
+ a = *ap;
+ *ap = (*ap)->a_next;
+
+ attr_free( a );
+ continue;
+ }
+
+ for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[last] ); last++ )
+ /* just count */ ;
+
+ if ( last == 0 ) {
+ /* empty? for now, we leave it in place */
+ goto next_attr;
+ }
+ last--;
+
+ if ( (*ap)->a_desc == slap_schema.si_ad_objectClass
+ || (*ap)->a_desc == slap_schema.si_ad_structuralObjectClass )
+ {
+ struct berval *bv;
+
+ for ( bv = (*ap)->a_vals; !BER_BVISNULL( bv ); bv++ ) {
+ struct berval mapped;
+
+ rwm_map( &rwmap->rwm_oc, &bv[0], &mapped, RWM_REMAP );
+ if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
+ ch_free( bv[0].bv_val );
+ BER_BVZERO( &bv[0] );
+ if ( &(*ap)->a_vals[last] > &bv[0] ) {
+ bv[0] = (*ap)->a_vals[last];
+ BER_BVZERO( &(*ap)->a_vals[last] );
+ }
+ last--;
+ bv--;
+
+ } else if ( mapped.bv_val != bv[0].bv_val ) {
+ /*
+ * FIXME: after LBER_FREEing
+ * the value is replaced by
+ * ch_alloc'ed memory
+ */
+ free( bv[0].bv_val );
+ ber_dupbv( &bv[0], &mapped );
+ }
+ }
+
+ /*
+ * It is necessary to try to rewrite attributes with
+ * dn syntax because they might be used in ACLs as
+ * members of groups; since ACLs are applied to the
+ * rewritten stuff, no dn-based subject clause could
+ * be used at the ldap backend side (see
+ * http://www.OpenLDAP.org/faq/data/cache/452.html)
+ * The problem can be overcome by moving the dn-based
+ * ACLs to the target directory server, and letting
+ * everything pass thru the ldap backend.
+ */
+ } else if ( (*ap)->a_desc->ad_type->sat_syntax ==
+ slap_schema.si_syn_distinguishedName )
+ {
+ rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals );
+ if ( rc != LDAP_SUCCESS ) {
+ Attribute *a;
+
+ a = *ap;
+ *ap = (*ap)->a_next;
+
+ attr_free( a );
+ continue;
+ }
+ }
+
+ if ( m != NULL ) {
+ /* rewrite the attribute description */
+ assert( m->m_dst_ad );
+ (*ap)->a_desc = m->m_dst_ad;
+ }
+
+next_attr:;
+ ap = &(*ap)->a_next;
+ }
- e->e_name = dn;
- e->e_nname = ndn;
rs->sr_entry = e;
- /* TODO: map entry attribute types, objectclasses
- * and dn-valued attribute values */
-
return SLAP_CB_CONTINUE;
fail:;
- if ( dn.bv_val && ( dn.bv_val != e->e_name.bv_val ) ) {
+ if ( !BER_BVISNULL( &dn ) ) {
ch_free( dn.bv_val );
}
- if ( ndn.bv_val ) {
+ if ( !BER_BVISNULL( &ndn ) ) {
ch_free( ndn.bv_val );
}
+ if ( e != NULL && e != rs->sr_entry ) {
+ entry_free( e );
+ }
+
return rc;
}
static int
rwm_response( Operation *op, SlapReply *rs )
{
- int rc;
+ int rc;
if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) {
return rwm_send_entry( op, rs );
}
switch( op->o_tag ) {
+ case LDAP_REQ_SEARCH:
+ /* Note: the operation attrs are remapped */
+ if ( op->ors_attrs != NULL && op->ors_attrs != rs->sr_attrs )
+ {
+ ch_free( op->ors_attrs );
+ op->ors_attrs = rs->sr_attrs;
+ }
+ /* fall thru */
+
case LDAP_REQ_BIND:
case LDAP_REQ_ADD:
case LDAP_REQ_DELETE:
case LDAP_REQ_MODRDN:
case LDAP_REQ_MODIFY:
case LDAP_REQ_COMPARE:
- case LDAP_REQ_SEARCH:
case LDAP_REQ_EXTENDED:
rc = rwm_matched( op, rs );
break;
+
default:
rc = SLAP_CB_CONTINUE;
break;
if ( strncasecmp( argv[0], "rewrite", sizeof("rewrite") - 1 ) == 0 ) {
rc = rwm_rw_config( be, fname, lineno, argc, argv );
- } else if (strcasecmp( argv[0], "map" ) == 0 ) {
+ } else if ( strcasecmp( argv[0], "map" ) == 0 ) {
rc = rwm_m_config( be, fname, lineno, argc, argv );
- } else if (strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
+ } else if ( strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
rc = rwm_suffixmassage_config( be, fname, lineno, argc, argv );
} else {
#endif /* ENABLE_REWRITE */
- rwm_map_init( &rwmap->rwm_oc, &mapping );
- rwm_map_init( &rwmap->rwm_at, &mapping );
+ if ( rwm_map_init( &rwmap->rwm_oc, &mapping ) != LDAP_SUCCESS ||
+ rwm_map_init( &rwmap->rwm_at, &mapping ) != LDAP_SUCCESS )
+ {
+ return 1;
+ }
on->on_bi.bi_private = (void *)rwmap;
#endif
} dncookie;
-int rwm_dn_massage(dncookie *dc, struct berval *dn, struct berval *res);
+int rwm_dn_massage( dncookie *dc, struct berval *in,
+ struct berval *dn, struct berval *ndn );
/* attributeType/objectClass mapping */
int rwm_mapping_cmp (const void *, const void *);
int rwm_mapping_dup (void *, void *);
-void rwm_map_init ( struct ldapmap *lm, struct ldapmapping ** );
+int rwm_map_init ( struct ldapmap *lm, struct ldapmapping ** );
void rwm_map ( struct ldapmap *map, struct berval *s, struct berval *m,
int remap );
+int rwm_mapping ( struct ldapmap *map, struct berval *s,
+ struct ldapmapping **m, int remap );
#define RWM_MAP 0
#define RWM_REMAP 1
char *
rwm_map_filter(
struct ldapmap *at_map,
struct ldapmap *oc_map,
- struct berval *f,
- int remap
-);
+ struct berval *f );
int
rwm_map_attrs(
struct ldapmap *at_map,
AttributeName *a,
int remap,
- char ***mapped_attrs
-);
+ char ***mapped_attrs );
+
+int
+rwm_map_attrnames(
+ struct ldapmap *at_map,
+ struct ldapmap *oc_map,
+ AttributeName *an,
+ AttributeName **anp,
+ int remap );
extern void rwm_mapping_free ( void *mapping );
rwm_filter_map_rewrite(
dncookie *dc,
Filter *f,
- struct berval *fstr,
- int remap );
+ struct berval *fstr );
/* suffix massaging by means of librewrite */
#ifdef ENABLE_REWRITE
Operation *op,
SlapReply *rs,
void *cookie,
- BerVarray a_vals
- );
+ BerVarray a_vals,
+ BerVarray *pa_nvals );
extern int rwm_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals );
LDAP_END_DECL
* and add it here.
*/
- mapping[0].m_src_ad = ch_malloc( sizeof( AttributeDescription ) );
- memset( mapping[0].m_src_ad, 0, sizeof( AttributeDescription ) );
- mapping[0].m_src_ad->ad_cname = mapping[0].m_src;
- mapping[1].m_flags |= RWMMAP_F_FREE_SRC;
+ rc = slap_bv2undef_ad( &mapping[0].m_src,
+ &mapping[0].m_src_ad, &text );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr,
+ "%s: line %d: source attributeType '%s': %d (%s)\n",
+ fname, lineno, src, rc, text ? text : "null" );
+ return 1;
+ }
+
}
mapping[1].m_dst_ad = mapping[0].m_src_ad;
}
"is not defined in schema\n",
fname, lineno, dst );
- mapping[0].m_dst_ad = ch_malloc( sizeof( AttributeDescription ) );
- memset( mapping[0].m_dst_ad, 0, sizeof( AttributeDescription ) );
- mapping[0].m_dst_ad->ad_cname = mapping[0].m_dst;
- mapping[1].m_flags |= RWMMAP_F_FREE_SRC;
+ rc = slap_bv2undef_ad( &mapping[0].m_dst,
+ &mapping[0].m_dst_ad, &text );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr,
+ "%s: line %d: destination attributeType '%s': %d (%s)\n",
+ fname, lineno, src, rc, text ? text : "null" );
+ return 1;
+ }
}
mapping[1].m_src_ad = mapping[0].m_dst_ad;
}
- if ( (src[0] != '\0' && avl_find( map->map, (caddr_t)mapping, rwm_mapping_cmp ) != NULL)
+ if ( ( src[0] != '\0' && avl_find( map->map, (caddr_t)mapping, rwm_mapping_cmp ) != NULL)
|| avl_find( map->remap, (caddr_t)&mapping[1], rwm_mapping_cmp ) != NULL)
{
fprintf( stderr,
int
rwm_dn_massage(
dncookie *dc,
+ struct berval *in,
struct berval *dn,
- struct berval *res
+ struct berval *ndn
)
{
- int rc = 0;
+ int rc = 0;
+ struct berval mdn;
rc = rewrite_session( dc->rwmap->rwm_rw, dc->ctx,
- ( dn->bv_len ? dn->bv_val : "" ),
- dc->conn, &res->bv_val );
+ ( in->bv_len ? in->bv_val : "" ),
+ dc->conn, &mdn.bv_val );
switch ( rc ) {
case REWRITE_REGEXEC_OK:
- if ( res->bv_val != NULL ) {
- res->bv_len = strlen( res->bv_val );
+ if ( !BER_BVISNULL( &mdn ) ) {
+
+ mdn.bv_len = strlen( mdn.bv_val );
+
+ if ( dn != NULL && ndn != NULL ) {
+ rc = dnPrettyNormal( NULL, &mdn, dn, ndn, NULL );
+
+ } else if ( dn != NULL ) {
+ rc = dnPretty( NULL, &mdn, dn, NULL );
+
+ } else if ( ndn != NULL) {
+ rc = dnNormalize( 0, NULL, NULL, &mdn, ndn, NULL );
+ }
+
+ if ( mdn.bv_val != in->bv_val ) {
+ ch_free( mdn.bv_val );
+ }
+
} else {
- *res = *dn;
+ /* we assume the input string is already in pretty form,
+ * and that the normalized version is already available */
+ *dn = *in;
+ if ( ndn != NULL ) {
+ BER_BVZERO( ndn );
+ }
+ rc = LDAP_SUCCESS;
}
+
#ifdef NEW_LOGGING
LDAP_LOG( BACK_LDAP, DETAIL1,
"[rw] %s: \"%s\" -> \"%s\"\n",
- dc->ctx, dn->bv_val, res->bv_val );
+ dc->ctx, in->bv_val, dn->bv_val );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_ARGS,
"[rw] %s: \"%s\" -> \"%s\"\n",
- dc->ctx, dn->bv_val, res->bv_val );
+ dc->ctx, in->bv_val, dn->bv_val );
#endif /* !NEW_LOGGING */
- rc = LDAP_SUCCESS;
break;
case REWRITE_REGEXEC_UNWILLING:
int
rwm_dn_massage(
dncookie *dc,
- struct berval *odn,
- struct berval *res
+ struct berval *tmpin,
+ struct berval *dn,
+ struct berval *ndn
)
{
- int i, src, dst;
- struct berval pretty = {0,NULL}, *dn = odn;
+ int i, src, dst;
+ struct berval pretty = BER_BVNULL,
+ normal = BER_BVNULL,
+ *in = tmpin;
- assert( res );
+ assert( dn );
- if ( dn == NULL ) {
- res->bv_val = NULL;
- res->bv_len = 0;
- return 0;
+ if ( in == NULL || BER_BVISNULL( in ) ) {
+ dn->bv_val = NULL;
+ dn->bv_len = 0;
+ return LDAP_SUCCESS;
}
if ( dc->rwmap == NULL || dc->rwmap->rwm_suffix_massage == NULL ) {
- *res = *dn;
- return 0;
+ *dn = *in;
+ return LDAP_SUCCESS;
}
if ( dc->tofrom ) {
src = 0 + dc->normalized;
dst = 2 + dc->normalized;
+
} else {
+ int rc;
+
src = 2 + dc->normalized;
dst = 0 + dc->normalized;
+
/* DN from remote server may be in arbitrary form.
* Pretty it so we can parse reliably.
*/
- dnPretty( NULL, dn, &pretty, NULL );
- if (pretty.bv_val) dn = &pretty;
+ if ( dc->normalized && dn == NULL ) {
+ rc = dnNormalize( 0, NULL, NULL, in, &normal, NULL );
+
+ } else if ( !dc->normalized && ndn == NULL ) {
+ rc = dnPretty( NULL, in, &pretty, NULL );
+
+ } else {
+ rc = dnPrettyNormal( NULL, in, &pretty, &normal, NULL );
+ }
+
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ if ( dc->normalized && !BER_BVISNULL( &normal) ) {
+ in = &normal;
+
+ } else if ( !dc->normalized && !BER_BVISNULL( &pretty ) ) {
+ in = &pretty;
+ }
}
for ( i = 0;
dc->rwmap->rwm_suffix_massage[i].bv_val != NULL;
i += 4 ) {
int aliasLength = dc->rwmap->rwm_suffix_massage[i+src].bv_len;
- int diff = dn->bv_len - aliasLength;
+ int diff = in->bv_len - aliasLength;
if ( diff < 0 ) {
/* alias is longer than dn */
continue;
- } else if ( diff > 0 && ( !DN_SEPARATOR(dn->bv_val[diff-1]))) {
+
+ } else if ( diff > 0 && ( !DN_SEPARATOR(in->bv_val[diff-1]))) {
/* FIXME: DN_SEPARATOR() is intended to work
* on a normalized/pretty DN, so that ';'
* is never used as a DN separator */
/* At a DN Separator */
}
- if ( !strcmp( dc->rwmap->rwm_suffix_massage[i+src].bv_val, &dn->bv_val[diff] ) ) {
- res->bv_len = diff + dc->rwmap->rwm_suffix_massage[i+dst].bv_len;
- res->bv_val = ch_malloc( res->bv_len + 1 );
- strncpy( res->bv_val, dn->bv_val, diff );
- strcpy( &res->bv_val[diff], dc->rwmap->rwm_suffix_massage[i+dst].bv_val );
+ if ( !strcmp( dc->rwmap->rwm_suffix_massage[i+src].bv_val, &in->bv_val[diff] ) ) {
+ dn->bv_len = diff + dc->rwmap->rwm_suffix_massage[i+dst].bv_len;
+ dn->bv_val = ch_malloc( dn->bv_len + 1 );
+ strncpy( dn->bv_val, in->bv_val, diff );
+ strcpy( &dn->bv_val[diff], dc->rwmap->rwm_suffix_massage[i+dst].bv_val );
#ifdef NEW_LOGGING
LDAP_LOG ( BACK_LDAP, ARGS,
"rwm_dn_massage: converted \"%s\" to \"%s\"\n",
- dn->bv_val, res->bv_val, 0 );
+ in->bv_val, dn->bv_val, 0 );
#else
Debug( LDAP_DEBUG_ARGS,
"rwm_dn_massage:"
" converted \"%s\" to \"%s\"\n",
- dn->bv_val, res->bv_val, 0 );
+ in->bv_val, dn->bv_val, 0 );
#endif
break;
}
}
- if (pretty.bv_val) {
- ch_free(pretty.bv_val);
- dn = odn;
+
+ if ( !BER_BVISNULL( &pretty ) ) {
+ ch_free( pretty.bv_val );
+ }
+
+ if ( !BER_BVISNULL( &normal ) ) {
+ ch_free( normal.bv_val );
}
+
+ in = tmpin;
+
/* Nothing matched, just return the original DN */
- if (res->bv_val == NULL) {
- *res = *dn;
+ if ( dc->normalized && BER_BVISNULL( ndn ) ) {
+ *ndn = *in;
+
+ } else if ( !dc->normalized && BER_BVISNULL( dn ) ) {
+ *dn = *in;
}
- return 0;
+ return LDAP_SUCCESS;
}
#endif /* !ENABLE_REWRITE */
struct ldapmapping *map1 = (struct ldapmapping *)c1;
struct ldapmapping *map2 = (struct ldapmapping *)c2;
int rc = map1->m_src.bv_len - map2->m_src.bv_len;
+
if ( rc ) {
return rc;
}
+
return strcasecmp( map1->m_src.bv_val, map2->m_src.bv_val );
}
return ( ( strcasecmp( map1->m_src.bv_val, map2->m_src.bv_val ) == 0 ) ? -1 : 0 );
}
-void
+int
rwm_map_init( struct ldapmap *lm, struct ldapmapping **m )
{
- struct ldapmapping *mapping;
+ struct ldapmapping *mapping;
+ const char *text;
+ int rc;
assert( m );
return;
}
- ber_str2bv( "objectClass", sizeof("objectClass") - 1, 1,
- &mapping->m_src);
+ rc = slap_str2ad( "objectClass", &mapping->m_src_ad, &text );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ mapping->m_dst_ad = mapping->m_src_ad;
+ ber_dupbv( &mapping->m_dst, &mapping->m_src_ad->ad_cname );
ber_dupbv( &mapping->m_dst, &mapping->m_src );
+
mapping[1].m_src = mapping->m_src;
mapping[1].m_dst = mapping->m_dst;
rwm_mapping_cmp, rwm_mapping_dup );
avl_insert( &lm->remap, (caddr_t)&mapping[1],
rwm_mapping_cmp, rwm_mapping_dup );
+
*m = mapping;
+
+ return rc;
}
-void
-rwm_map( struct ldapmap *map, struct berval *s, struct berval *bv, int remap )
+int
+rwm_mapping( struct ldapmap *map, struct berval *s, struct ldapmapping **m, int remap )
{
Avlnode *tree;
- struct ldapmapping *mapping, fmapping;
+ struct ldapmapping fmapping;
- if (remap == RWM_REMAP) {
+ assert( m );
+
+ if ( remap == RWM_REMAP ) {
tree = map->remap;
+
} else {
tree = map->map;
}
- bv->bv_len = 0;
- bv->bv_val = NULL;
fmapping.m_src = *s;
- mapping = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping,
+ *m = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping,
rwm_mapping_cmp );
+
+ if ( *m == NULL ) {
+ return map->drop_missing;
+ }
+
+ return 0;
+}
+
+void
+rwm_map( struct ldapmap *map, struct berval *s, struct berval *bv, int remap )
+{
+ struct ldapmapping *mapping;
+
+ BER_BVZERO( bv );
+ rwm_mapping( map, s, &mapping, remap );
if ( mapping != NULL ) {
- if ( mapping->m_dst.bv_val ) {
+ if ( !BER_BVISNULL( &mapping->m_dst ) ) {
*bv = mapping->m_dst;
}
return;
if ( !map->drop_missing ) {
*bv = *s;
}
+}
+
+/*
+ * Map attribute names in place
+ */
+int
+rwm_map_attrnames(
+ struct ldapmap *at_map,
+ struct ldapmap *oc_map,
+ AttributeName *an,
+ AttributeName **anp,
+ int remap
+)
+{
+ int i, j;
+
+ if ( an == NULL ) {
+ return LDAP_SUCCESS;
+ }
+
+ for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
+ /* just count */ ;
+ *anp = ch_malloc( ( i + 1 )* sizeof( AttributeName ) );
+
+ for ( i = 0, j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
+ struct ldapmapping *m;
+ int at_drop_missing = 0,
+ oc_drop_missing = 0;
+
+ if ( an[i].an_desc ) {
+ if ( !at_map ) {
+ /* FIXME: better leave as is? */
+ continue;
+ }
+
+ at_drop_missing = rwm_mapping( at_map, &an[i].an_name, &m, remap );
+ if ( at_drop_missing || ( m && BER_BVISNULL( &m->m_dst ) ) ) {
+ continue;
+ }
+
+ if ( !m ) {
+ (*anp)[j] = an[i];
+ j++;
+ continue;
+ }
+
+ (*anp)[j] = an[i];
+ if ( remap == RWM_MAP ) {
+ (*anp)[j].an_name = m->m_dst;
+ (*anp)[j].an_desc = m->m_dst_ad;
+ } else {
+ (*anp)[j].an_name = m->m_src;
+ (*anp)[j].an_desc = m->m_src_ad;
+
+ }
+
+ j++;
+ continue;
+
+ } else if ( an[i].an_oc ) {
+ if ( !oc_map ) {
+ /* FIXME: better leave as is? */
+ continue;
+ }
+
+ oc_drop_missing = rwm_mapping( oc_map, &an[i].an_name, &m, remap );
+
+ if ( oc_drop_missing || ( m && BER_BVISNULL( &m->m_dst ) ) ) {
+ continue;
+ }
+
+ if ( !m ) {
+ (*anp)[j] = an[i];
+ j++;
+ continue;
+ }
+
+ (*anp)[j] = an[i];
+ if ( remap == RWM_MAP ) {
+ (*anp)[j].an_name = m->m_dst;
+ (*anp)[j].an_oc = m->m_dst_oc;
+ } else {
+ (*anp)[j].an_name = m->m_src;
+ (*anp)[j].an_oc = m->m_src_oc;
+ }
+
+ } else {
+ at_drop_missing = rwm_mapping( at_map, &an[i].an_name, &m, remap );
+
+ if ( at_drop_missing || !m ) {
+
+ oc_drop_missing = rwm_mapping( oc_map, &an[i].an_name, &m, remap );
+
+ /* if both at_map and oc_map required to drop missing,
+ * then do it */
+ if ( oc_drop_missing && at_drop_missing ) {
+ continue;
+ }
+
+ /* if no oc_map mapping was found and at_map required
+ * to drop missing, then do it; otherwise, at_map wins
+ * and an is considered an attr and is left unchanged */
+ if ( !m ) {
+ if ( at_drop_missing ) {
+ continue;
+ }
+ (*anp)[j] = an[i];
+ j++;
+ continue;
+ }
+
+ if ( BER_BVISNULL( &m->m_dst ) ) {
+ continue;
+ }
+
+ (*anp)[j] = an[i];
+ if ( remap == RWM_MAP ) {
+ (*anp)[j].an_name = m->m_dst;
+ (*anp)[j].an_oc = m->m_dst_oc;
+ } else {
+ (*anp)[j].an_name = m->m_src;
+ (*anp)[j].an_oc = m->m_src_oc;
+ }
+ j++;
+ continue;
+ }
+
+ if ( !BER_BVISNULL( &m->m_dst ) ) {
+ (*anp)[j] = an[i];
+ if ( remap == RWM_MAP ) {
+ (*anp)[j].an_name = m->m_dst;
+ (*anp)[j].an_desc = m->m_dst_ad;
+ } else {
+ (*anp)[j].an_name = m->m_src;
+ (*anp)[j].an_desc = m->m_src_ad;
+ }
+ j++;
+ continue;
+ }
+ }
+ }
+
+ if ( j == 0 && i != 0 ) {
+ memset( &(*anp)[0], 0, sizeof( AttributeName ) );
+ BER_BVSTR( &(*anp)[0].an_name, LDAP_NO_ATTRS );
+ }
+ memset( &(*anp)[j], 0, sizeof( AttributeName ) );
- return;
+ return LDAP_SUCCESS;
}
int
{
int i, j;
char **na;
- struct berval mapped;
if ( an == NULL ) {
*mapped_attrs = NULL;
return LDAP_SUCCESS;
}
- for ( i = 0; an[i].an_name.bv_val; i++ ) {
+ for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
/* */
}
return LDAP_NO_MEMORY;
}
- for ( i = j = 0; an[i].an_name.bv_val; i++ ) {
- rwm_map( at_map, &an[i].an_name, &mapped, remap );
- if ( mapped.bv_val != NULL && mapped.bv_val != '\0' ) {
- na[j++] = mapped.bv_val;
+ for ( i = j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
+ struct ldapmapping *m;
+
+ if ( rwm_mapping( at_map, &an[i].an_name, &m, remap ) ) {
+ continue;
+ }
+
+ if ( !m || ( m && !BER_BVISNULL( &m->m_dst ) ) ) {
+ na[j++] = m->m_dst.bv_val;
}
}
if ( j == 0 && i != 0 ) {
int freeval = 0;
rwm_map( &dc->rwmap->rwm_at, &ad->ad_cname, mapped_attr, remap );
- if ( mapped_attr->bv_val == NULL || mapped_attr->bv_val[0] == '\0') {
+ if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) ) {
/*
* FIXME: are we sure we need to search oc_map if at_map fails?
*/
- rwm_map( &dc->rwmap->rwm_oc, &ad->ad_cname, mapped_attr,
- remap );
- if ( mapped_attr->bv_val == NULL
- || mapped_attr->bv_val[0] == '\0' )
+ rwm_map( &dc->rwmap->rwm_oc, &ad->ad_cname, mapped_attr, remap );
+ if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) )
{
*mapped_attr = ad->ad_cname;
}
if ( ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
{
- dncookie fdc = *dc;
+ dncookie fdc = *dc;
+ int rc;
#ifdef ENABLE_REWRITE
fdc.ctx = "searchFilterAttrDN";
#endif
- switch ( rwm_dn_massage( &fdc, value, &vtmp ) ) {
+ rc = rwm_dn_massage( &fdc, value, &vtmp, NULL );
+ switch ( rc ) {
case LDAP_SUCCESS:
if ( vtmp.bv_val != value->bv_val ) {
freeval = 1;
break;
case LDAP_UNWILLING_TO_PERFORM:
- return -1;
-
case LDAP_OTHER:
+ default:
return -1;
}
|| ad == slap_schema.si_ad_structuralObjectClass )
{
rwm_map( &dc->rwmap->rwm_oc, value, &vtmp, remap );
- if ( vtmp.bv_val == NULL || vtmp.bv_val[0] == '\0' ) {
+ if ( BER_BVISNULL( &vtmp ) || BER_BVISEMPTY( &vtmp ) ) {
vtmp = *value;
}
rwm_int_filter_map_rewrite(
dncookie *dc,
Filter *f,
- struct berval *fstr,
- int remap )
+ struct berval *fstr )
{
int i;
Filter *p;
switch ( f->f_choice ) {
case LDAP_FILTER_EQUALITY:
if ( map_attr_value( dc, f->f_av_desc, &atmp,
- &f->f_av_value, &vtmp, remap ) )
+ &f->f_av_value, &vtmp, RWM_MAP ) )
{
return -1;
}
- fstr->bv_len = atmp.bv_len + vtmp.bv_len
- + ( sizeof( "(=)" ) - 1 );
+ fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
case LDAP_FILTER_GE:
if ( map_attr_value( dc, f->f_av_desc, &atmp,
- &f->f_av_value, &vtmp, remap ) )
+ &f->f_av_value, &vtmp, RWM_MAP ) )
{
return -1;
}
- fstr->bv_len = atmp.bv_len + vtmp.bv_len
- + ( sizeof( "(>=)" ) - 1 );
+ fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(>=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
case LDAP_FILTER_LE:
if ( map_attr_value( dc, f->f_av_desc, &atmp,
- &f->f_av_value, &vtmp, remap ) )
+ &f->f_av_value, &vtmp, RWM_MAP ) )
{
return -1;
}
- fstr->bv_len = atmp.bv_len + vtmp.bv_len
- + ( sizeof( "(<=)" ) - 1 );
+ fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(<=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
case LDAP_FILTER_APPROX:
if ( map_attr_value( dc, f->f_av_desc, &atmp,
- &f->f_av_value, &vtmp, remap ) )
+ &f->f_av_value, &vtmp, RWM_MAP ) )
{
return -1;
}
- fstr->bv_len = atmp.bv_len + vtmp.bv_len
- + ( sizeof( "(~=)" ) - 1 );
+ fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(~=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
case LDAP_FILTER_SUBSTRINGS:
if ( map_attr_value( dc, f->f_sub_desc, &atmp,
- NULL, NULL, remap ) )
+ NULL, NULL, RWM_MAP ) )
{
return -1;
}
/* cannot be a DN ... */
- fstr->bv_len = atmp.bv_len + ( sizeof( "(=*)" ) - 1 );
+ fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
fstr->bv_val = malloc( fstr->bv_len + 128 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
atmp.bv_val );
- if ( f->f_sub_initial.bv_val != NULL ) {
+ if ( !BER_BVISNULL( &f->f_sub_initial ) ) {
len = fstr->bv_len;
filter_escape_value( &f->f_sub_initial, &vtmp );
}
if ( f->f_sub_any != NULL ) {
- for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
+ for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) {
len = fstr->bv_len;
filter_escape_value( &f->f_sub_any[i], &vtmp );
}
}
- if ( f->f_sub_final.bv_val != NULL ) {
+ if ( !BER_BVISNULL( &f->f_sub_final ) ) {
len = fstr->bv_len;
filter_escape_value( &f->f_sub_final, &vtmp );
case LDAP_FILTER_PRESENT:
if ( map_attr_value( dc, f->f_desc, &atmp,
- NULL, NULL, remap ) )
+ NULL, NULL, RWM_MAP ) )
{
return -1;
}
- fstr->bv_len = atmp.bv_len + ( sizeof( "(=*)" ) - 1 );
+ fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
case LDAP_FILTER_AND:
case LDAP_FILTER_OR:
case LDAP_FILTER_NOT:
- fstr->bv_len = sizeof( "(%)" ) - 1;
+ fstr->bv_len = STRLENOF( "(%)" );
fstr->bv_val = malloc( fstr->bv_len + 128 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
for ( p = f->f_list; p != NULL; p = p->f_next ) {
len = fstr->bv_len;
- if ( rwm_int_filter_map_rewrite( dc, p, &vtmp, remap ) )
+ if ( rwm_int_filter_map_rewrite( dc, p, &vtmp ) )
{
return -1;
}
case LDAP_FILTER_EXT: {
if ( f->f_mr_desc ) {
if ( map_attr_value( dc, f->f_mr_desc, &atmp,
- &f->f_mr_value, &vtmp, remap ) )
+ &f->f_mr_value, &vtmp, RWM_MAP ) )
{
return -1;
}
} else {
- atmp.bv_len = 0;
- atmp.bv_val = "";
-
+ BER_BVSTR( &atmp, "" );
filter_escape_value( &f->f_mr_value, &vtmp );
}
fstr->bv_len = atmp.bv_len +
- ( f->f_mr_dnattrs ? sizeof( ":dn" ) - 1 : 0 ) +
+ ( f->f_mr_dnattrs ? STRLENOF( ":dn" ) : 0 ) +
( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len + 1 : 0 ) +
- vtmp.bv_len + ( sizeof( "(:=)" ) - 1 );
+ vtmp.bv_len + STRLENOF( "(:=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
atmp.bv_val,
f->f_mr_dnattrs ? ":dn" : "",
- f->f_mr_rule_text.bv_len ? ":" : "",
- f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
+ !BER_BVISEMPTY( &f->f_mr_rule_text ) ? ":" : "",
+ !BER_BVISEMPTY( &f->f_mr_rule_text ) ? f->f_mr_rule_text.bv_val : "",
vtmp.bv_val );
ber_memfree( vtmp.bv_val );
} break;
rwm_filter_map_rewrite(
dncookie *dc,
Filter *f,
- struct berval *fstr,
- int remap )
+ struct berval *fstr )
{
int rc;
dncookie fdc;
struct berval ftmp;
- rc = rwm_int_filter_map_rewrite( dc, f, fstr, remap );
+ rc = rwm_int_filter_map_rewrite( dc, f, fstr );
#ifdef ENABLE_REWRITE
if ( rc != LDAP_SUCCESS ) {
fdc.ctx = "searchFilter";
switch ( rewrite_session( fdc.rwmap->rwm_rw, fdc.ctx,
- ( ftmp.bv_len ? ftmp.bv_val : "" ),
+ ( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : "" ),
fdc.conn, &fstr->bv_val )) {
case REWRITE_REGEXEC_OK:
- if ( fstr->bv_val != NULL ) {
+ if ( !BER_BVISNULL( fstr ) ) {
fstr->bv_len = strlen( fstr->bv_val );
free( ftmp.bv_val );
+
} else {
*fstr = ftmp;
}
Operation *op,
SlapReply *rs,
void *cookie,
- BerVarray a_vals
- )
+ BerVarray a_vals,
+ BerVarray *pa_nvals )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
struct ldaprwmap *rwmap =
(struct ldaprwmap *)on->on_bi.bi_private;
- struct berval bv;
int i, last;
dncookie dc;
+ struct berval dn, ndn, *pndn = NULL;
+
+ assert( a_vals );
/*
* Rewrite the bind dn if needed
dc.normalized = 0;
#endif
- for ( last = 0; a_vals[last].bv_val != NULL; last++ );
+ for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ );
+ if ( pa_nvals != NULL ) {
+ pndn = &ndn;
+
+ if ( *pa_nvals == NULL ) {
+ *pa_nvals = ch_malloc( last * sizeof(struct berval) );
+ memset( *pa_nvals, 0, last * sizeof(struct berval) );
+ }
+ }
last--;
- for ( i = 0; a_vals[i].bv_val != NULL; i++ ) {
- switch ( rwm_dn_massage( &dc, &a_vals[i], &bv ) ) {
+ for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
+ int rc;
+
+ rc = rwm_dn_massage( &dc, &a_vals[i], &dn, pndn );
+ switch ( rc ) {
case LDAP_UNWILLING_TO_PERFORM:
/*
* FIXME: need to check if it may be considered
ch_free( a_vals[i].bv_val );
if (last > i ) {
a_vals[i] = a_vals[last];
+ if ( pa_nvals ) {
+ (*pa_nvals)[i] = (*pa_nvals)[last];
+ }
+ }
+ BER_BVZERO( &a_vals[last] );
+ if ( pa_nvals ) {
+ BER_BVZERO( &(*pa_nvals)[last] );
}
- a_vals[last].bv_len = 0;
- a_vals[last].bv_val = NULL;
last--;
break;
+
+ case LDAP_SUCCESS:
+ if ( !BER_BVISNULL( &dn ) && dn.bv_val != a_vals[i].bv_val ) {
+ ch_free( a_vals[i].bv_val );
+ a_vals[i] = dn;
+ if ( pa_nvals ) {
+ if ( !BER_BVISNULL( &(*pa_nvals)[i] ) ) {
+ ch_free( (*pa_nvals)[i].bv_val );
+ }
+ (*pa_nvals)[i] = *pndn;
+ }
+ }
+ break;
default:
/* leave attr untouched if massage failed */
- if ( bv.bv_val && bv.bv_val != a_vals[i].bv_val ) {
- ch_free( a_vals[i].bv_val );
- a_vals[i] = bv;
+ if ( pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
+ dnNormalize( 0, NULL, NULL, &a_vals[i], &(*pa_nvals)[i], NULL );
}
break;
}
BerVarray a_vals
)
{
- struct berval bv;
int i, last;
- for ( last = 0; a_vals[last].bv_val; last++ );
+ for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ );
last--;
- for ( i = 0; a_vals[i].bv_val; i++ ) {
- switch ( rwm_dn_massage( dc, &a_vals[i], &bv ) ) {
+ for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
+ struct berval dn;
+ int rc;
+
+ rc = rwm_dn_massage( dc, &a_vals[i], &dn, NULL );
+ switch ( rc ) {
case LDAP_UNWILLING_TO_PERFORM:
/*
* FIXME: need to check if it may be considered
if ( last > i ) {
a_vals[i] = a_vals[last];
}
- a_vals[last].bv_val = NULL;
- a_vals[last].bv_len = 0;
+ BER_BVZERO( &a_vals[last] );
last--;
break;
default:
/* leave attr untouched if massage failed */
- if ( bv.bv_val && a_vals[i].bv_val != bv.bv_val ) {
+ if ( !BER_BVISNULL( &dn ) && a_vals[i].bv_val != dn.bv_val ) {
LBER_FREE( a_vals[i].bv_val );
- a_vals[i] = bv;
+ a_vals[i] = dn;
}
break;
}
{
struct ldapmapping *mapping = v_mapping;
- if ( mapping[0].m_src.bv_val ) {
+ if ( !BER_BVISNULL( &mapping[0].m_src ) ) {
ch_free( mapping[0].m_src.bv_val );
}
}
}
- if ( mapping[0].m_dst.bv_val ) {
+ if ( !BER_BVISNULL( &mapping[0].m_dst ) ) {
ch_free( mapping[0].m_dst.bv_val );
}