(struct ldaprwmap *)on->on_bi.bi_private;
struct berval dn = BER_BVNULL,
- *dnp = NULL,
ndn = BER_BVNULL;
int rc = 0;
dncookie dc;
* and the caller sets op->o_req_dn = op->o_req_ndn,
* only rewrite the op->o_req_ndn and use it as
* op->o_req_dn as well */
+ ndn = op->o_req_ndn;
if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {
- dnp = &dn;
+ dn = op->o_req_dn;
+ rc = rwm_dn_massage_pretty_normalize( &dc, &op->o_req_dn, &dn, &ndn );
+ } else {
+ rc = rwm_dn_massage_normalize( &dc, &op->o_req_ndn, &ndn );
}
- rc = rwm_dn_massage( &dc, &op->o_req_dn, dnp, &ndn );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
- if ( ( dnp && dn.bv_val == op->o_req_dn.bv_val ) ||
- ( !dnp && ndn.bv_val == op->o_req_ndn.bv_val ) ) {
+ if ( ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val && dn.bv_val == op->o_req_dn.bv_val )
+ || ndn.bv_val == op->o_req_ndn.bv_val )
+ {
return LDAP_SUCCESS;
}
op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
- if ( dnp ) {
+ op->o_req_ndn = ndn;
+ if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {
op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
op->o_req_dn = dn;
} else {
op->o_req_dn = ndn;
}
- op->o_req_ndn = ndn;
return LDAP_SUCCESS;
}
dc.tofrom = 0;
dc.normalized = 0;
#endif /* ! ENABLE_REWRITE */
- rc = rwm_dn_massage( &dc, op->orr_newSup, &newSup, &nnewSup );
+ newSup = *op->orr_newSup;
+ nnewSup = *op->orr_nnewSup;
+ rc = rwm_dn_massage_pretty_normalize( &dc, op->orr_newSup, &newSup, &nnewSup );
if ( rc != LDAP_SUCCESS ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, rc, "newSuperiorDN massage error" );
dc.normalized = 0;
#endif /* ! ENABLE_REWRITE */
ber_str2bv( rs->sr_matched, 0, 0, &dn );
- rc = rwm_dn_massage( &dc, &dn, &mdn, NULL );
+ mdn = dn;
+ rc = rwm_dn_massage_pretty( &dc, &dn, &mdn );
if ( rc != LDAP_SUCCESS ) {
rs->sr_err = rc;
rs->sr_text = "Rewrite error";
* from the one known to the meta, and a DN with unknown
* attributes is returned.
*/
- rc = rwm_dn_massage( &dc, &e->e_name, &dn, &ndn );
+ dn = e->e_name;
+ ndn = e->e_nname;
+ rc = rwm_dn_massage_pretty_normalize( &dc, &e->e_name, &dn, &ndn );
if ( rc != LDAP_SUCCESS ) {
rc = 1;
goto fail;
#endif /* !ENABLE_REWRITE */
} dncookie;
-int rwm_dn_massage( dncookie *dc, struct berval *in,
- struct berval *dn, struct berval *ndn );
+int rwm_dn_massage( dncookie *dc, struct berval *in, struct berval *dn );
+int rwm_dn_massage_pretty( dncookie *dc, struct berval *in, struct berval *pdn );
+int rwm_dn_massage_normalize( dncookie *dc, struct berval *in, struct berval *ndn );
+int rwm_dn_massage_pretty_normalize( dncookie *dc, struct berval *in, struct berval *pdn, struct berval *ndn );
/* attributeType/objectClass mapping */
int rwm_mapping_cmp (const void *, const void *);
/* FIXME: after rewriting, we should also remap attributes ... */
+/*
+ * massages "in" and normalizes it into "ndn"
+ *
+ * "ndn" may be untouched if no massaging occurred and its value was not null
+ */
+int
+rwm_dn_massage_normalize(
+ dncookie *dc,
+ struct berval *in,
+ struct berval *ndn )
+{
+ int rc;
+ struct berval mdn = BER_BVNULL;
+
+ /* massage and normalize a DN */
+ rc = rwm_dn_massage( dc, in, &mdn );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ if ( mdn.bv_val == in->bv_val && !BER_BVISNULL( ndn ) ) {
+ return rc;
+ }
+
+ rc = dnNormalize( 0, NULL, NULL, &mdn, ndn, NULL );
+
+ if ( mdn.bv_val != in->bv_val ) {
+ ch_free( mdn.bv_val );
+ }
+
+ return rc;
+}
+
+/*
+ * massages "in" and prettifies it into "pdn"
+ *
+ * "pdn" may be untouched if no massaging occurred and its value was not null
+ */
+int
+rwm_dn_massage_pretty(
+ dncookie *dc,
+ struct berval *in,
+ struct berval *pdn )
+{
+ int rc;
+ struct berval mdn = BER_BVNULL;
+
+ /* massage and pretty a DN */
+ rc = rwm_dn_massage( dc, in, &mdn );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ if ( mdn.bv_val == in->bv_val && !BER_BVISNULL( pdn ) ) {
+ return rc;
+ }
+
+ rc = dnPretty( NULL, &mdn, pdn, NULL );
+
+ if ( mdn.bv_val != in->bv_val ) {
+ ch_free( mdn.bv_val );
+ }
+
+ return rc;
+}
+
+/*
+ * massages "in" and prettifies and normalizes it into "pdn" and "ndn"
+ *
+ * "pdn" may be untouched if no massaging occurred and its value was not null;
+ * "ndn" may be untouched if no massaging occurred and its value was not null;
+ * if no massage occurred and "ndn" value was not null, it is filled
+ * with the normaized value of "pdn", much like ndn = dnNormalize( pdn )
+ */
+int
+rwm_dn_massage_pretty_normalize(
+ dncookie *dc,
+ struct berval *in,
+ struct berval *pdn,
+ struct berval *ndn )
+{
+ int rc;
+ struct berval mdn = BER_BVNULL;
+
+ /* massage, pretty and normalize a DN */
+ rc = rwm_dn_massage( dc, in, &mdn );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ if ( mdn.bv_val == in->bv_val && !BER_BVISNULL( pdn ) ) {
+ if ( BER_BVISNULL( ndn ) ) {
+ rc = dnNormalize( 0, NULL, NULL, &mdn, ndn, NULL );
+ }
+ return rc;
+ }
+
+ rc = dnPrettyNormal( NULL, &mdn, pdn, ndn, NULL );
+
+ if ( mdn.bv_val != in->bv_val ) {
+ ch_free( mdn.bv_val );
+ }
+
+ return rc;
+}
+
#ifdef ENABLE_REWRITE
+/*
+ * massages "in" into "dn"
+ *
+ * "dn" may contain the value of "in" if no massage occurred
+ */
int
rwm_dn_massage(
dncookie *dc,
struct berval *in,
- struct berval *dn,
- struct berval *ndn
+ struct berval *dn
)
{
int rc = 0;
struct berval mdn;
+ assert( dc );
assert( in );
-
- if ( dn == NULL && ndn == NULL ) {
- return LDAP_OTHER;
- }
+ assert( dn );
rc = rewrite_session( dc->rwmap->rwm_rw, dc->ctx,
( in->bv_len ? in->bv_val : "" ),
dc->conn, &mdn.bv_val );
switch ( rc ) {
case REWRITE_REGEXEC_OK:
- if ( !BER_BVISNULL( &mdn ) ) {
-
+ if ( !BER_BVISNULL( &mdn ) && mdn.bv_val != in->bv_val ) {
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 );
- }
-
+ *dn = mdn;
} else {
- /* we assume the input string is already in pretty form,
- * and that the normalized version is already available */
- if ( dn ) {
- *dn = *in;
- if ( ndn ) {
- BER_BVZERO( ndn );
- }
- } else {
- *ndn = *in;
- }
- rc = LDAP_SUCCESS;
+ *dn = *in;
}
+ rc = LDAP_SUCCESS;
Debug( LDAP_DEBUG_ARGS,
"[rw] %s: \"%s\" -> \"%s\"\n",
- dc->ctx, in->bv_val, dn ? dn->bv_val : ndn->bv_val );
+ dc->ctx, in->bv_val, dn->bv_val );
break;
case REWRITE_REGEXEC_UNWILLING:
int
rwm_dn_massage(
dncookie *dc,
- struct berval *tmpin,
- struct berval *dn,
- struct berval *ndn
+ struct berval *in,
+ struct berval *dn
)
{
int i, src, dst;
- struct berval pretty = BER_BVNULL,
- normal = BER_BVNULL,
- *in = tmpin;
+ struct berval tmpin;
- if ( dn == NULL && ndn == NULL ) {
- return LDAP_OTHER;
- }
+ assert( dc );
+ assert( in );
+ assert( dn );
- if ( in == NULL || BER_BVISNULL( in ) ) {
- if ( dn ) {
- BER_BVZERO( dn );
- }
- if ( ndn ) {
- BER_BVZERO( ndn );
- }
+ BER_BVZERO( dn );
+
+ if ( BER_BVISNULL( in ) ) {
return LDAP_SUCCESS;
}
if ( dc->rwmap == NULL || dc->rwmap->rwm_suffix_massage == NULL ) {
- if ( dn ) {
- *dn = *in;
- if ( ndn ) {
- BER_BVZERO( ndn );
- }
- } else {
- *ndn = *in;
- }
+ *dn = *in;
return LDAP_SUCCESS;
}
src = 0 + dc->normalized;
dst = 2 + dc->normalized;
+ tmpin = *in;
+
} else {
int rc;
/* DN from remote server may be in arbitrary form.
* Pretty it so we can parse reliably.
*/
- 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 );
+ if ( dc->normalized ) {
+ rc = dnNormalize( 0, NULL, NULL, in, &tmpin, NULL );
} else {
- rc = dnPrettyNormal( NULL, in, &pretty, &normal, NULL );
+ rc = dnPretty( NULL, in, &tmpin, 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 ) {
+ !BER_BVISNULL( &dc->rwmap->rwm_suffix_massage[i] );
+ i += 4 )
+ {
int aliasLength = dc->rwmap->rwm_suffix_massage[i+src].bv_len;
- int diff = in->bv_len - aliasLength;
+ int diff = tmpin.bv_len - aliasLength;
if ( diff < 0 ) {
/* alias is longer than dn */
continue;
- } else if ( diff > 0 && ( !DN_SEPARATOR(in->bv_val[diff-1]))) {
+ } else if ( diff > 0 && ( !DN_SEPARATOR(tmpin.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, &in->bv_val[diff] ) ) {
- struct berval *out;
-
- if ( dn ) {
- out = dn;
- } else {
- out = ndn;
- }
- out->bv_len = diff + dc->rwmap->rwm_suffix_massage[i+dst].bv_len;
- out->bv_val = ch_malloc( out->bv_len + 1 );
- strncpy( out->bv_val, in->bv_val, diff );
- strcpy( &out->bv_val[diff], dc->rwmap->rwm_suffix_massage[i+dst].bv_val );
+ if ( !strcmp( dc->rwmap->rwm_suffix_massage[i+src].bv_val,
+ &tmpin.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, tmpin.bv_val, diff );
+ strcpy( &dn->bv_val[diff], dc->rwmap->rwm_suffix_massage[i+dst].bv_val );
Debug( LDAP_DEBUG_ARGS,
"rwm_dn_massage:"
" converted \"%s\" to \"%s\"\n",
- in->bv_val, out->bv_val, 0 );
- if ( dn && ndn ) {
- rc = dnNormalize( 0, NULL, NULL, dn, ndn, NULL );
- }
+ in->bv_val, dn->bv_val, 0 );
break;
}
}
- if ( !BER_BVISNULL( &pretty ) ) {
- ch_free( pretty.bv_val );
- }
-
- if ( !BER_BVISNULL( &normal ) ) {
- ch_free( normal.bv_val );
+ if ( tmpin.bv_val != in->bv_val ) {
+ ch_free( tmpin.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 ) ) {
+ if ( BER_BVISNULL( dn ) ) {
*dn = *in;
}
struct berval *mapped_value,
int remap )
{
- struct berval vtmp;
+ struct berval vtmp = BER_BVNULL;
int freeval = 0;
rwm_map( &dc->rwmap->rwm_at, &ad->ad_cname, mapped_attr, remap );
fdc.ctx = "searchFilterAttrDN";
#endif /* ENABLE_REWRITE */
- rc = rwm_dn_massage( &fdc, value, NULL, &vtmp );
+ vtmp = *value;
+ rc = rwm_dn_massage_normalize( &fdc, value, &vtmp );
switch ( rc ) {
case LDAP_SUCCESS:
if ( vtmp.bv_val != value->bv_val ) {
int i, last;
dncookie dc;
- struct berval dn, ndn, *ndnp = NULL;
+ struct berval dn = BER_BVNULL,
+ ndn = BER_BVNULL;
assert( a_vals );
dc.normalized = 0;
#endif /* ! ENABLE_REWRITE */
- for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ );
+ for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ )
+ ;
+ last--;
+
if ( pa_nvals != NULL ) {
- ndnp = &ndn;
-
if ( *pa_nvals == NULL ) {
- *pa_nvals = ch_malloc( last * sizeof(struct berval) );
- memset( *pa_nvals, 0, last * sizeof(struct berval) );
+ *pa_nvals = ch_malloc( ( last + 2 ) * sizeof(struct berval) );
+ memset( *pa_nvals, 0, ( last + 2 ) * sizeof(struct berval) );
}
}
- last--;
for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
struct berval olddn, oldval;
}
continue;
}
+
+ /* FIXME: URLs like "ldap:///dc=suffix" if passed
+ * thru ldap_url_parse() and ldap_url_desc2str()
+ * get rewritten as "ldap:///dc=suffix??base";
+ * we don't want this to occur... */
+ if ( ludp->lud_scope == LDAP_SCOPE_BASE ) {
+ ludp->lud_scope = LDAP_SCOPE_DEFAULT;
+ }
+
ber_str2bv( ludp->lud_dn, 0, 0, &olddn );
- rc = rwm_dn_massage( &dc, &olddn, &dn, ndnp );
+ dn = olddn;
+ if ( pa_nvals ) {
+ ndn = olddn;
+ rc = rwm_dn_massage_pretty_normalize( &dc, &olddn,
+ &dn, &ndn );
+ } else {
+ rc = rwm_dn_massage_pretty( &dc, &olddn, &dn );
+ }
+
switch ( rc ) {
case LDAP_UNWILLING_TO_PERFORM:
/*
ludp->lud_dn = dn.bv_val;
newurl = ldap_url_desc2str( ludp );
+ ludp->lud_dn = olddn.bv_val;
+ ch_free( dn.bv_val );
if ( newurl == NULL ) {
/* FIXME: leave attr untouched
- * even if ldap_url_desc2str failed... */
+ * even if ldap_url_desc2str failed...
+ */
break;
}
if ( pa_nvals ) {
ludp->lud_dn = ndn.bv_val;
newurl = ldap_url_desc2str( ludp );
+ ludp->lud_dn = olddn.bv_val;
+ ch_free( ndn.bv_val );
if ( newurl == NULL ) {
/* FIXME: leave attr untouched
- * even if ldap_url_desc2str failed... */
+ * even if ldap_url_desc2str failed...
+ */
ch_free( a_vals[i].bv_val );
a_vals[i] = oldval;
break;
int i, last;
dncookie dc;
- struct berval dn, *dnp = NULL, ndn, *ndnp = NULL;
+ struct berval dn = BER_BVNULL,
+ ndn = BER_BVNULL;
BerVarray in;
if ( a_vals ) {
in = a_vals;
- dnp = &dn;
} else {
if ( pa_nvals == NULL || *pa_nvals == NULL ) {
#endif /* ! ENABLE_REWRITE */
for ( last = 0; !BER_BVISNULL( &in[last] ); last++ );
+ last--;
if ( pa_nvals != NULL ) {
- ndnp = &ndn;
-
if ( *pa_nvals == NULL ) {
- *pa_nvals = ch_malloc( last * sizeof(struct berval) );
- memset( *pa_nvals, 0, last * sizeof(struct berval) );
+ *pa_nvals = ch_malloc( ( last + 2 ) * sizeof(struct berval) );
+ memset( *pa_nvals, 0, ( last + 2 ) * sizeof(struct berval) );
}
}
- last--;
for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) {
int rc;
- rc = rwm_dn_massage( &dc, &in[i], dnp, ndnp );
+ if ( a_vals ) {
+ dn = in[i];
+ if ( pa_nvals ) {
+ ndn = (*pa_nvals)[i];
+ rc = rwm_dn_massage_pretty_normalize( &dc, &in[i], &dn, &ndn );
+ } else {
+ rc = rwm_dn_massage_pretty( &dc, &in[i], &dn );
+ }
+ } else {
+ ndn = in[i];
+ rc = rwm_dn_massage_normalize( &dc, &in[i], &ndn );
+ }
+
switch ( rc ) {
case LDAP_UNWILLING_TO_PERFORM:
/*
}
} else {
- assert( ndnp != NULL );
-
if ( !BER_BVISNULL( &ndn ) && ndn.bv_val != (*pa_nvals)[i].bv_val ) {
ch_free( (*pa_nvals)[i].bv_val );
(*pa_nvals)[i] = ndn;
continue;
}
+ /* FIXME: URLs like "ldap:///dc=suffix" if passed
+ * thru ldap_url_parse() and ldap_url_desc2str()
+ * get rewritten as "ldap:///dc=suffix??base";
+ * we don't want this to occur... */
+ if ( ludp->lud_scope == LDAP_SCOPE_BASE ) {
+ ludp->lud_scope = LDAP_SCOPE_DEFAULT;
+ }
+
ber_str2bv( ludp->lud_dn, 0, 0, &olddn );
-
- rc = rwm_dn_massage( dc, &olddn, &dn, NULL );
+
+ dn = olddn;
+ rc = rwm_dn_massage_pretty( dc, &olddn, &dn );
switch ( rc ) {
case LDAP_UNWILLING_TO_PERFORM:
/*
newurl = ldap_url_desc2str( ludp );
if ( newurl == NULL ) {
/* FIXME: leave attr untouched
- * even if ldap_url_desc2str failed... */
+ * even if ldap_url_desc2str failed...
+ */
break;
}
struct berval dn;
int rc;
- rc = rwm_dn_massage( dc, &a_vals[i], &dn, NULL );
+ dn = a_vals[i];
+ rc = rwm_dn_massage_pretty( dc, &a_vals[i], &dn );
switch ( rc ) {
case LDAP_UNWILLING_TO_PERFORM:
/*