mostly done...

This commit is contained in:
Pierangelo Masarati 2004-07-11 22:57:51 +00:00
parent 1b85d17afe
commit 22bd2667ce
5 changed files with 860 additions and 222 deletions

View File

@ -31,7 +31,8 @@ rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
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;
@ -48,24 +49,15 @@ rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
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 );
@ -111,7 +103,7 @@ rwm_add( Operation *op, SlapReply *rs )
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;
}
@ -123,12 +115,10 @@ rwm_add( Operation *op, SlapReply *rs )
* 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;
@ -143,12 +133,9 @@ 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;
}
@ -162,6 +149,7 @@ rwm_bind( Operation *op, SlapReply *rs )
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" );
@ -221,8 +209,7 @@ rwm_compare( Operation *op, SlapReply *rs )
{
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" );
@ -235,12 +222,9 @@ rwm_compare( Operation *op, SlapReply *rs )
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" );
@ -249,7 +233,14 @@ rwm_compare( Operation *op, SlapReply *rs )
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" );
@ -263,7 +254,6 @@ rwm_compare( Operation *op, SlapReply *rs )
}
}
/* TODO: rewrite attribute types, values of DN-valued attributes ... */
return SLAP_CB_CONTINUE;
}
@ -292,6 +282,11 @@ static int
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
@ -306,6 +301,120 @@ rwm_modify( Operation *op, SlapReply *rs )
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;
}
@ -332,11 +441,34 @@ rwm_modrdn( Operation *op, SlapReply *rs )
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" );
@ -345,13 +477,89 @@ rwm_search( Operation *op, SlapReply *rs )
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
@ -385,6 +593,7 @@ rwm_matched( Operation *op, SlapReply *rs )
struct berval dn, mdn;
dncookie dc;
int rc;
if ( rs->sr_matched == NULL ) {
return SLAP_CB_CONTINUE;
@ -400,11 +609,17 @@ rwm_matched( Operation *op, SlapReply *rs )
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;
}
@ -422,9 +637,11 @@ rwm_send_entry( Operation *op, SlapReply *rs )
(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 );
@ -442,12 +659,20 @@ rwm_send_entry( Operation *op, SlapReply *rs )
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 );
}
/*
@ -455,44 +680,165 @@ rwm_send_entry( Operation *op, SlapReply *rs )
* 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;
rs->sr_entry = e;
}
/* 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;
}
rs->sr_entry = e;
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;
}
@ -628,16 +974,25 @@ rwm_response( Operation *op, SlapReply *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;
@ -666,10 +1021,10 @@ rwm_config(
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 {
@ -720,8 +1075,11 @@ rwm_over_init(
#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;

View File

@ -93,32 +93,40 @@ typedef struct dncookie {
#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 );
@ -134,8 +142,7 @@ extern int
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
@ -147,8 +154,8 @@ extern int rwm_dnattr_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

View File

@ -172,10 +172,15 @@ rwm_map_config(
* 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;
}
@ -187,15 +192,19 @@ rwm_map_config(
"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,

View File

@ -40,32 +40,56 @@
int
rwm_dn_massage(
dncookie *dc,
struct berval *in,
struct berval *dn,
struct berval *res
struct berval *ndn
)
{
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 );
} else {
*res = *dn;
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 {
/* 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:
@ -97,48 +121,74 @@ rwm_dn_massage(
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;
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 */
@ -146,34 +196,44 @@ rwm_dn_massage(
/* 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;
}
/* Nothing matched, just return the original DN */
if (res->bv_val == NULL) {
*res = *dn;
if ( !BER_BVISNULL( &pretty ) ) {
ch_free( pretty.bv_val );
}
return 0;
if ( !BER_BVISNULL( &normal ) ) {
ch_free( normal.bv_val );
}
in = tmpin;
/* Nothing matched, just return the original DN */
if ( dc->normalized && BER_BVISNULL( ndn ) ) {
*ndn = *in;
} else if ( !dc->normalized && BER_BVISNULL( dn ) ) {
*dn = *in;
}
return LDAP_SUCCESS;
}
#endif /* !ENABLE_REWRITE */

View File

@ -42,9 +42,11 @@ rwm_mapping_cmp( const void *c1, const void *c2 )
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 );
}
@ -62,10 +64,12 @@ rwm_mapping_dup( void *c1, void *c2 )
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;
const char *text;
int rc;
assert( m );
@ -77,9 +81,15 @@ rwm_map_init( struct ldapmap *lm, struct ldapmapping **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;
@ -87,28 +97,47 @@ rwm_map_init( struct ldapmap *lm, struct ldapmapping **m )
rwm_mapping_cmp, rwm_mapping_dup );
avl_insert( &lm->remap, (caddr_t)&mapping[1],
rwm_mapping_cmp, rwm_mapping_dup );
*m = mapping;
return rc;
}
int
rwm_mapping( struct ldapmap *map, struct berval *s, struct ldapmapping **m, int remap )
{
Avlnode *tree;
struct ldapmapping fmapping;
assert( m );
if ( remap == RWM_REMAP ) {
tree = map->remap;
} else {
tree = map->map;
}
fmapping.m_src = *s;
*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 )
{
Avlnode *tree;
struct ldapmapping *mapping, fmapping;
struct ldapmapping *mapping;
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,
rwm_mapping_cmp );
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;
@ -117,8 +146,155 @@ rwm_map( struct ldapmap *map, struct berval *s, struct berval *bv, int remap )
if ( !map->drop_missing ) {
*bv = *s;
}
}
return;
/*
* 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 LDAP_SUCCESS;
}
int
@ -131,14 +307,13 @@ rwm_map_attrs(
{
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++ ) {
/* */
}
@ -148,10 +323,15 @@ rwm_map_attrs(
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 ) {
@ -176,14 +356,12 @@ map_attr_value(
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;
}
@ -196,12 +374,14 @@ map_attr_value(
if ( ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
{
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;
@ -209,9 +389,8 @@ map_attr_value(
break;
case LDAP_UNWILLING_TO_PERFORM:
return -1;
case LDAP_OTHER:
default:
return -1;
}
@ -219,7 +398,7 @@ map_attr_value(
|| 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;
}
@ -240,8 +419,7 @@ static int
rwm_int_filter_map_rewrite(
dncookie *dc,
Filter *f,
struct berval *fstr,
int remap )
struct berval *fstr )
{
int i;
Filter *p;
@ -265,13 +443,12 @@ rwm_int_filter_map_rewrite(
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)",
@ -282,13 +459,12 @@ rwm_int_filter_map_rewrite(
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)",
@ -299,13 +475,12 @@ rwm_int_filter_map_rewrite(
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)",
@ -316,13 +491,12 @@ rwm_int_filter_map_rewrite(
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)",
@ -333,20 +507,20 @@ rwm_int_filter_map_rewrite(
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 );
@ -362,7 +536,7 @@ rwm_int_filter_map_rewrite(
}
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 );
@ -376,7 +550,7 @@ rwm_int_filter_map_rewrite(
}
}
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 );
@ -395,12 +569,12 @@ rwm_int_filter_map_rewrite(
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=*)",
@ -410,7 +584,7 @@ rwm_int_filter_map_rewrite(
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)",
@ -420,7 +594,7 @@ rwm_int_filter_map_rewrite(
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;
}
@ -439,30 +613,28 @@ rwm_int_filter_map_rewrite(
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;
@ -501,14 +673,13 @@ int
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 ) {
@ -521,12 +692,13 @@ rwm_filter_map_rewrite(
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;
}
@ -576,17 +748,19 @@ rwm_dnattr_rewrite(
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
@ -601,11 +775,22 @@ rwm_dnattr_rewrite(
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
@ -615,17 +800,34 @@ rwm_dnattr_rewrite(
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;
}
@ -640,14 +842,17 @@ rwm_dnattr_result_rewrite(
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
@ -658,16 +863,15 @@ rwm_dnattr_result_rewrite(
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;
}
@ -681,7 +885,7 @@ rwm_mapping_free( void *v_mapping )
{
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 );
}
@ -698,7 +902,7 @@ rwm_mapping_free( void *v_mapping )
}
}
if ( mapping[0].m_dst.bv_val ) {
if ( !BER_BVISNULL( &mapping[0].m_dst ) ) {
ch_free( mapping[0].m_dst.bv_val );
}