slightly rework user/operational attributes handling (including fixing a bug in the logic of the previous change to backend_operational()); cleanup; more improvements to slapo-rwm and back-relay

This commit is contained in:
Pierangelo Masarati 2004-07-25 23:16:40 +00:00
parent 01a1eec957
commit 9f6f5491fe
23 changed files with 722 additions and 131 deletions

View file

@ -17,34 +17,63 @@ It requires the
.LP
This backend and the above mentioned overlay are experimental.
.SH CONFIGURATION
These
The following
.B slapd.conf
options apply to the relay backend database.
directives apply to the relay backend database.
That is, they must follow a "database relay" line and come before any
subsequent "backend" or "database" lines.
Other database options are described in the
.BR slapd.conf (5)
manual page.
manual page; only the
.B suffix
directive is required by the
.I relay
backend.
.TP
.B relay <real naming context> [massage]
The naming context of the database that is presented
under a virtual naming context.
The presence of the directive implies that one single database
The presence of this directive implies that one specific database,
i.e. the one serving the
.BR "real naming context" ,
will be presented under a virtual naming context.
This directive automatically instantiates the
.B rwm
.BR overlay .
.IR "rwm overlay" .
If the optional
.B massage
keyword is present, the suffix massaging is automatically
configured as well.
configured as well; otherwise, specific massaging instructions
are required by means of the
.I rewrite
directives described in
.BR slapo-rwm (5).
.SH ACCESS RULES
One important issue is that access rules are based on the identity
that issued the operation.
After massaging from the virtual to the real naming context, the
frontend sees the operation as performed by the identty in the
real naming context.
Moreover, since
.B back-relay
bypasses the real database frontend operations by short-circuiting
operations thru the internal backend API, the original database
access rules do not apply but in selected cases, i.e. when the
backend itself applies access control.
As a consequence, the instances of the relay database must provide
own access rules that are consistent with those of the original
database, possibly adding further specific restrictions.
So, access rules in the
.B relay
database must refer to identities in the real naming context.
Examples are reported in the EXAMPLES section.
.SH SCENARIOS
.LP
If no
.B relay
directive is given, the
.B relay
.I relay
database does not refer to any specific database, but the most
appropriate one is looked-up after rewriting the request DN
for the operation that is being handled.
@ -52,7 +81,8 @@ for the operation that is being handled.
This allows to write carefully crafted rewrite rules that
cause some of the requests to be directed to one database, and
some to another; e.g., authentication can be mapped to one
database, and searches to another and so.
database, and searches to another, or different target databases
can be selected based on the DN of the request, and so.
.LP
Another possibility is to map the same operation to different
databases based on details of the virtual naming context,
@ -61,7 +91,7 @@ e.g. groups on one database and persons on another.
.SH Caveats
The
.B rwm overlay
is far from complete.
is experimental.
.LP
.SH EXAMPLES
To implement a plain virtual naming context mapping
@ -84,6 +114,10 @@ that looks up the real naming context for each operation, use
"dc=real,dc=naming,dc=context"
.fi
.LP
This is useful, for instance, to relay different databases that
share the terminal portion of the naming context (the one that
is rewritten).
.LP
To implement the old-fashioned suffixalias, e.g. mapping
the virtual to the real naming context, but not the results
back from the real to the virtual naming context, use
@ -95,11 +129,11 @@ back from the real to the virtual naming context, use
rewriteEngine on
rewriteContext default
rewriteRule "dc=virtual,dc=naming,dc=context"
"dc=real,dc=naming,dc=context" ":"
rewriteRule searchFilter
rewriteRule searchResult
rewriteRule searchResultAttrDN
rewriteRule matchedDN
"dc=real,dc=naming,dc=context" ":@"
rewriteContext searchFilter
rewriteContext searchEntryDN
rewriteContext searchAttrDN
rewriteContext matchedDN
.fi
.LP
Note that the virtual database is bound to a single real database,
@ -108,10 +142,45 @@ so the
is automatically instantiated, but the rewrite rules
are written explicitly to map all the virtual to real
naming context data flow, but none of the real to virtual.
.LP
Access rules:
.LP
.nf
database bdb
suffix "dc=example,dc=com"
# skip...
access to dn.subtree="dc=example,dc=com"
by dn.exact="cn=Supervisor,dc=example,dc=com" write
by * read
database relay
suffix "o=Example,c=US"
relay "dc=example,dc=com" massage
# skip ...
access to dn.subtree="o=Example,c=US"
by dn.exact="cn=Supervisor,dc=example,dc=com" write
by dn.exact="cn=Relay Supervisor,dc=example,dc=com" write
by * read
.fi
.LP
Note that, in both databases, the identities (the
.B <who>
clause) are in the
.BR "real naming context" ,
i.e.
.BR "`dc=example,dc=com'" ,
while the targets (the
.B <what>
clause) are in the
.B real
and in the
.BR "virtual naming context" ,
respectively.
.SH FILES
.TP
ETCDIR/slapd.conf
default slapd configuration file
.SH SEE ALSO
.BR slapd.conf (5),
.BR slapo-rwm (5),
.BR slapd (8).

View file

@ -52,6 +52,15 @@ with
.IR "distinguishedName syntax" ,
requires the knowledge of the attributeType syntax.
See the REWRITING section for details.
.LP
Note that when mapping DN-valued attributes from local to remote,
first the DN is rewritten, and then the attributeType is mapped;
while mapping from remote to local, first the attributeType is mapped,
and then the DN is rewritten.
As such, it is important that the local attributeType is appropriately
defined as using the distinguishedName syntax.
Also, note that there are DN-related syntaxes, like nameAndOptionalUID,
whose values are currenlty not rewritten.
.SH SUFFIX MASSAGING
A basic feature of the
.B rwm
@ -287,13 +296,13 @@ searchFilterAttrDN search
compareDN compare
compareAttrDN compare AVA
addDN add
addAttrDN add AVA
addAttrDN add AVA (including "ref")
modifyDN modify
modifyAttrDN modify AVA
modifyAttrDN modify AVA (including "ref")
modrDN modrdn
newSuperiorDN modrdn
deleteDN delete
exopPasswdDN passwd exop DN if proxy
exopPasswdDN passwd exop DN
.fi
.RE
.LP
@ -308,6 +317,8 @@ searchAttrDN search AVA (only if defined; defaults
attributes of search results)
matchedDN all ops (only if applicable; defaults
to searchEntryDN)
referralDN all ops (only if applicable; defaults
to searchEntryDN)
.fi
.RE
.LP

View file

@ -44,8 +44,9 @@
void
attr_free( Attribute *a )
{
if ( a->a_nvals && a->a_nvals != a->a_vals )
ber_bvarray_free( a->a_nvals );
ber_bvarray_free( a->a_vals );
if (a->a_nvals != a->a_vals) ber_bvarray_free( a->a_nvals );
free( a );
}

View file

@ -100,7 +100,7 @@ bdb_operational(
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count */ ;
if ( rs->sr_opattrs == SLAP_OPATTRS ||
if ( SLAP_OPATTRS( rs->sr_attr_flags ) ||
ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
{
int hasSubordinates;

View file

@ -41,8 +41,6 @@ ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent,
struct berval *bdn, int flags );
#define LDAP_BUILD_ENTRY_PRIVATE 0x01
static struct berval dummy = BER_BVNULL;
int
ldap_back_search(
Operation *op,
@ -200,7 +198,7 @@ fail:;
ent.e_attrs = a->a_next;
v = a->a_vals;
if ( a->a_vals != &dummy ) {
if ( a->a_vals != &slap_dummy_bv ) {
ber_bvarray_free(a->a_vals);
}
if ( a->a_nvals != v ) {
@ -453,7 +451,7 @@ ldap_build_entry(
* values result filter
*/
if ( private ) {
attr->a_vals = &dummy;
attr->a_vals = &slap_dummy_bv;
} else {
attr->a_vals = ch_malloc( sizeof( struct berval ) );
BER_BVZERO( &attr->a_vals[0] );

View file

@ -38,7 +38,7 @@ ldap_back_conn_destroy(
)
{
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
struct ldapconn *lc, lc_curr;
struct ldapconn *lc = NULL, lc_curr;
#ifdef NEW_LOGGING
LDAP_LOG( BACK_LDAP, INFO,
@ -56,6 +56,13 @@ ldap_back_conn_destroy(
lc = avl_delete( &li->conntree, (caddr_t)&lc_curr, ldap_back_conn_cmp );
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
#ifdef ENABLE_REWRITE
/*
* Cleanup rewrite session
*/
rewrite_session_delete( li->rwmap.rwm_rw, conn );
#endif /* ENABLE_REWRITE */
if (lc) {
#ifdef NEW_LOGGING
LDAP_LOG( BACK_LDAP, DETAIL1,
@ -67,13 +74,6 @@ ldap_back_conn_destroy(
lc->conn->c_connid, 0, 0 );
#endif
#ifdef ENABLE_REWRITE
/*
* Cleanup rewrite session
*/
rewrite_session_delete( li->rwmap.rwm_rw, conn );
#endif /* ENABLE_REWRITE */
/*
* Needs a test because the handler may be corrupted,
* and calling ldap_unbind on a corrupted header results

View file

@ -60,7 +60,7 @@ ldbm_back_operational(
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count */ ;
if ( rs->sr_opattrs == SLAP_OPATTRS ||
if ( SLAP_OPATTRS( rs->sr_attr_flags ) ||
ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
{
int hs;

View file

@ -556,7 +556,6 @@ meta_send_entry(
Entry ent = {0};
BerElement ber = *e->lm_ber;
Attribute *attr, **attrp;
struct berval dummy = BER_BVNULL;
struct berval *bv, bdn;
const char *text;
dncookie dc;
@ -652,7 +651,7 @@ meta_send_entry(
if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
|| attr->a_vals == NULL ) {
attr->a_vals = &dummy;
attr->a_vals = &slap_dummy_bv;
} else if ( attr->a_desc == slap_schema.si_ad_objectClass
|| attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
@ -724,7 +723,7 @@ meta_send_entry(
while ( ent.e_attrs ) {
attr = ent.e_attrs;
ent.e_attrs = attr->a_next;
if ( attr->a_vals != &dummy ) {
if ( attr->a_vals != &slap_dummy_bv ) {
ber_bvarray_free( attr->a_vals );
}
free( attr );

View file

@ -46,7 +46,7 @@ monitor_back_operational(
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count */ ;
if ( rs->sr_opattrs == SLAP_OPATTRS ||
if ( SLAP_OPATTRS( rs->sr_attr_flags ) ||
ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
{
int hs;

View file

@ -95,7 +95,7 @@ backsql_compare( Operation *op, SlapReply *rs )
nrs.sr_attrs = anlist;
nrs.sr_entry = &user_entry;
nrs.sr_opattrs = SLAP_OPATTRS_NO;
nrs.sr_attr_flags = SLAP_OPATTRS_NO;
nrs.sr_operational_attrs = NULL;
rs->sr_err = backsql_operational( op, &nrs );

View file

@ -49,7 +49,7 @@ backsql_operational(
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count */ ;
if ( ( rs->sr_opattrs == SLAP_OPATTRS || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
&& attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL ) {
rc = backsql_get_db_conn( op, &dbh );

View file

@ -1502,19 +1502,25 @@ int backend_operational(
* and the backend supports specific operational attributes,
* add them to the attribute list
*/
if ( rs->sr_opattrs == SLAP_OPATTRS || ( op->ors_attrs &&
if ( SLAP_OPATTRS( rs->sr_attr_flags ) || ( op->ors_attrs &&
ad_inlist( slap_schema.si_ad_subschemaSubentry, op->ors_attrs )) ) {
*ap = slap_operational_subschemaSubentry( op->o_bd );
ap = &(*ap)->a_next;
}
if ( ( rs->sr_opattrs == SLAP_OPATTRS || op->ors_attrs ) && op->o_bd &&
if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || op->ors_attrs ) && op->o_bd &&
op->o_bd->be_operational != NULL )
{
Attribute *a;
a = rs->sr_operational_attrs;
rs->sr_operational_attrs = NULL;
rc = op->o_bd->be_operational( op, rs );
*ap = rs->sr_operational_attrs;
if ( a != NULL ) {
rs->sr_operational_attrs = a;
}
for ( ; *ap; ap = &(*ap)->a_next )
/* just count them */ ;

View file

@ -40,7 +40,7 @@ rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
dncookie dc;
/*
* Rewrite the bind dn if needed
* Rewrite the dn if needed
*/
dc.rwmap = rwmap;
#ifdef ENABLE_REWRITE
@ -73,14 +73,11 @@ rwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie )
op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
if ( dnp ) {
op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
}
op->o_req_ndn = ndn;
if ( dnp ) {
op->o_req_dn = dn;
} else {
op->o_req_dn = ndn;
}
op->o_req_ndn = ndn;
return LDAP_SUCCESS;
}
@ -110,8 +107,8 @@ rwm_add( Operation *op, SlapReply *rs )
}
if ( olddn != op->o_req_dn.bv_val ) {
ber_memfree( op->ora_e->e_name.bv_val );
ber_memfree( op->ora_e->e_nname.bv_val );
ch_free( op->ora_e->e_name.bv_val );
ch_free( op->ora_e->e_nname.bv_val );
ber_dupbv( &op->ora_e->e_name, &op->o_req_dn );
ber_dupbv( &op->ora_e->e_nname, &op->o_req_ndn );
@ -151,8 +148,23 @@ rwm_add( Operation *op, SlapReply *rs )
if ( rc ) {
goto cleanup_attr;
}
} else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {
#ifdef ENABLE_REWRITE
rc = rwm_referral_rewrite( op, rs, "addAttrDN",
(*ap)->a_vals,
(*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
#else
rc = 1;
rc = rwm_referral_rewrite( op, rs, &rc, (*ap)->a_vals,
(*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
#endif
if ( rc != LDAP_SUCCESS ) {
goto cleanup_attr;
}
}
next_attr:;
ap = &(*ap)->a_next;
continue;
@ -261,13 +273,18 @@ rwm_compare( Operation *op, SlapReply *rs )
}
if ( op->orc_ava->aa_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
{
struct berval *mapped_valsp[2];
mapped_valsp[0] = &mapped_vals[0];
mapped_valsp[1] = &mapped_vals[1];
mapped_vals[0] = op->orc_ava->aa_value;
#ifdef ENABLE_REWRITE
rc = rwm_dnattr_rewrite( op, rs, "compareAttrDN", mapped_vals, NULL );
rc = rwm_dnattr_rewrite( op, rs, "compareAttrDN", NULL, mapped_valsp );
#else
rc = 1;
rc = rwm_dnattr_rewrite( op, rs, &rc, mapped_vals, NULL );
rc = rwm_dnattr_rewrite( op, rs, &rc, NULL, mapped_valsp );
#endif
if ( rc != LDAP_SUCCESS ) {
@ -276,10 +293,7 @@ rwm_compare( Operation *op, SlapReply *rs )
return -1;
}
if ( mapped_vals[0].bv_val != op->orc_ava->aa_value.bv_val ) {
free( op->orc_ava->aa_value.bv_val );
op->orc_ava->aa_value = mapped_vals[0];
}
op->orc_ava->aa_value = mapped_vals[0];
}
}
@ -397,7 +411,7 @@ rwm_modify( Operation *op, SlapReply *rs )
slap_schema.si_syn_distinguishedName )
{
#ifdef ENABLE_REWRITE
rc = rwm_dnattr_rewrite( op, rs, "modifyDN",
rc = rwm_dnattr_rewrite( op, rs, "modifyAttrDN",
(*mlp)->sml_values,
(*mlp)->sml_nvalues ? &(*mlp)->sml_nvalues : NULL );
#else
@ -406,6 +420,20 @@ rwm_modify( Operation *op, SlapReply *rs )
(*mlp)->sml_values,
(*mlp)->sml_nvalues ? &(*mlp)->sml_nvalues : NULL );
#endif
} else if ( (*mlp)->sml_desc == slap_schema.si_ad_ref ) {
#ifdef ENABLE_REWRITE
rc = rwm_referral_rewrite( op, rs, "modifyAttrDN",
(*mlp)->sml_values,
(*mlp)->sml_nvalues ? &(*mlp)->sml_nvalues : NULL );
#else
rc = 1;
rc = rwm_referral_rewrite( op, rs, &rc,
(*mlp)->sml_values,
(*mlp)->sml_nvalues ? &(*mlp)->sml_nvalues : NULL );
#endif
if ( rc != LDAP_SUCCESS ) {
goto cleanup_mod;
}
}
if ( rc != LDAP_SUCCESS ) {
@ -470,6 +498,9 @@ rwm_modrdn( Operation *op, SlapReply *rs )
}
}
/*
* Rewrite the dn, if needed
*/
#ifdef ENABLE_REWRITE
rc = rwm_op_dn_massage( op, rs, "renameDN" );
#else
@ -539,7 +570,7 @@ rwm_search( Operation *op, SlapReply *rs )
}
/*
* Rewrite the bind dn if needed
* Rewrite the dn if needed
*/
dc.rwmap = rwmap;
#ifdef ENABLE_REWRITE
@ -698,13 +729,12 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
Attribute **ap;
/*
* Rewrite the dn of the result, if needed
* Rewrite the dn attrs, if needed
*/
dc.rwmap = rwmap;
#ifdef ENABLE_REWRITE
dc.conn = op->o_conn;
dc.rs = NULL;
dc.ctx = "searchAttrDN";
#else
dc.tofrom = 0;
dc.normalized = 0;
@ -728,11 +758,13 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
int last;
Attribute *a;
if ( rs->sr_opattrs == SLAP_OPATTRS && is_at_operational( (*ap)->a_desc->ad_type ) )
if ( SLAP_OPATTRS( rs->sr_attr_flags ) && is_at_operational( (*ap)->a_desc->ad_type ) )
{
/* go on */ ;
} else if ( op->ors_attrs != NULL && !ad_inlist( (*ap)->a_desc, op->ors_attrs ) )
} else if ( op->ors_attrs != NULL &&
!SLAP_USERATTRS( rs->sr_attr_flags ) &&
!ad_inlist( (*ap)->a_desc, op->ors_attrs ) )
{
goto cleanup_attr;
}
@ -781,7 +813,7 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
* the value is replaced by
* ch_alloc'ed memory
*/
free( bv[0].bv_val );
ch_free( bv[0].bv_val );
ber_dupbv( &bv[0], &mapped );
}
}
@ -801,10 +833,22 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
} else if ( (*ap)->a_desc->ad_type->sat_syntax ==
slap_schema.si_syn_distinguishedName )
{
#ifdef ENABLE_REWRITE
dc.ctx = "searchAttrDN";
#endif
rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals );
if ( rc != LDAP_SUCCESS ) {
goto cleanup_attr;
}
} else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {
#ifdef ENABLE_REWRITE
dc.ctx = "searchAttrDN";
#endif
rc = rwm_referral_result_rewrite( &dc, (*ap)->a_vals );
if ( rc != LDAP_SUCCESS ) {
goto cleanup_attr;
}
}
if ( m != NULL ) {
@ -882,12 +926,13 @@ rwm_send_entry( Operation *op, SlapReply *rs )
*/
rc = rwm_dn_massage( &dc, &e->e_name, &dn, &ndn );
if ( rc != LDAP_SUCCESS ) {
rc = 1;
goto fail;
}
if ( e->e_name.bv_val != dn.bv_val ) {
free( e->e_name.bv_val );
free( e->e_nname.bv_val );
ch_free( e->e_name.bv_val );
ch_free( e->e_nname.bv_val );
e->e_name = dn;
e->e_nname = ndn;
@ -899,7 +944,7 @@ rwm_send_entry( Operation *op, SlapReply *rs )
/* 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 */
rwm_attrs( op, rs, &e->e_attrs );
(void)rwm_attrs( op, rs, &e->e_attrs );
rs->sr_entry = e;
rs->sr_flags = flags;
@ -1060,6 +1105,10 @@ rwm_m_config(
static int
rwm_response( 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;
if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) {
@ -1083,6 +1132,27 @@ rwm_response( Operation *op, SlapReply *rs )
case LDAP_REQ_MODIFY:
case LDAP_REQ_COMPARE:
case LDAP_REQ_EXTENDED:
if ( rs->sr_ref ) {
dncookie dc;
/*
* Rewrite the dn of the referrals, if needed
*/
dc.rwmap = rwmap;
#ifdef ENABLE_REWRITE
dc.conn = op->o_conn;
dc.rs = NULL;
dc.ctx = "referralDN";
#else
dc.tofrom = 0;
dc.normalized = 0;
#endif
rc = rwm_referral_result_rewrite( &dc, rs->sr_ref );
if ( rc != LDAP_SUCCESS ) {
rc = 1;
break;
}
}
rc = rwm_matched( op, rs );
break;

View file

@ -156,7 +156,14 @@ extern int rwm_dnattr_rewrite(
void *cookie,
BerVarray a_vals,
BerVarray *pa_nvals );
extern int rwm_referral_rewrite(
Operation *op,
SlapReply *rs,
void *cookie,
BerVarray a_vals,
BerVarray *pa_nvals );
extern int rwm_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals );
extern int rwm_referral_result_rewrite( dncookie *dc, BerVarray a_vals );
LDAP_END_DECL

View file

@ -244,9 +244,12 @@ rwm_suffix_massage_regexize( const char *s )
p = r + 1, i++ )
;
res = ch_calloc( sizeof( char ), strlen( s ) + 4 + 4*i + 1 );
res = ch_calloc( sizeof( char ), strlen( s )
+ STRLENOF( "((.+),)?" )
+ STRLENOF( "[ ]?" ) * i
+ STRLENOF( "$" ) + 1 );
ptr = lutil_strcopy( res, "(.*)" );
ptr = lutil_strcopy( res, "((.+),)?" );
for ( i = 0, p = s;
( r = strchr( p, ',' ) ) != NULL;
p = r + 1 , i++ ) {
@ -257,7 +260,9 @@ rwm_suffix_massage_regexize( const char *s )
r++;
}
}
lutil_strcopy( ptr, p );
ptr = lutil_strcopy( ptr, p );
ptr[0] = '$';
ptr[1] = '\0';
return res;
}
@ -333,6 +338,13 @@ rwm_suffix_massage_config(
rargv[ 4 ] = NULL;
rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "referralDN";
rargv[ 2 ] = "alias";
rargv[ 3 ] = "searchEntryDN";
rargv[ 4 ] = NULL;
rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "searchAttrDN";
rargv[ 2 ] = "alias";

View file

@ -48,6 +48,12 @@ rwm_dn_massage(
int rc = 0;
struct berval mdn;
assert( in );
if ( dn == NULL && ndn == NULL ) {
return LDAP_OTHER;
}
rc = rewrite_session( dc->rwmap->rwm_rw, dc->ctx,
( in->bv_len ? in->bv_val : "" ),
dc->conn, &mdn.bv_val );
@ -74,9 +80,13 @@ rwm_dn_massage(
} 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 );
if ( dn ) {
*dn = *in;
if ( ndn ) {
BER_BVZERO( ndn );
}
} else {
*ndn = *in;
}
rc = LDAP_SUCCESS;
}
@ -84,11 +94,11 @@ rwm_dn_massage(
#ifdef NEW_LOGGING
LDAP_LOG( BACK_LDAP, DETAIL1,
"[rw] %s: \"%s\" -> \"%s\"\n",
dc->ctx, in->bv_val, dn->bv_val );
dc->ctx, in->bv_val, dn ? dn->bv_val : ndn->bv_val );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_ARGS,
"[rw] %s: \"%s\" -> \"%s\"\n",
dc->ctx, in->bv_val, dn->bv_val );
dc->ctx, in->bv_val, dn ? dn->bv_val : ndn->bv_val );
#endif /* !NEW_LOGGING */
break;
@ -131,15 +141,29 @@ rwm_dn_massage(
normal = BER_BVNULL,
*in = tmpin;
assert( dn );
if ( dn == NULL && ndn == NULL ) {
return LDAP_OTHER;
}
if ( in == NULL || BER_BVISNULL( in ) ) {
dn->bv_val = NULL;
dn->bv_len = 0;
if ( dn ) {
BER_BVZERO( dn );
}
if ( ndn ) {
BER_BVZERO( ndn );
}
return LDAP_SUCCESS;
}
if ( dc->rwmap == NULL || dc->rwmap->rwm_suffix_massage == NULL ) {
*dn = *in;
if ( dn ) {
*dn = *in;
if ( ndn ) {
BER_BVZERO( ndn );
}
} else {
*ndn = *in;
}
return LDAP_SUCCESS;
}
@ -170,7 +194,7 @@ rwm_dn_massage(
return rc;
}
if ( dc->normalized && !BER_BVISNULL( &normal) ) {
if ( dc->normalized && !BER_BVISNULL( &normal ) ) {
in = &normal;
} else if ( !dc->normalized && !BER_BVISNULL( &pretty ) ) {
@ -197,20 +221,31 @@ rwm_dn_massage(
}
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 );
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 );
#ifdef NEW_LOGGING
LDAP_LOG ( BACK_LDAP, ARGS,
"rwm_dn_massage: converted \"%s\" to \"%s\"\n",
in->bv_val, dn->bv_val, 0 );
in->bv_val, out->bv_val, 0 );
#else
Debug( LDAP_DEBUG_ARGS,
"rwm_dn_massage:"
" converted \"%s\" to \"%s\"\n",
in->bv_val, dn->bv_val, 0 );
in->bv_val, out->bv_val, 0 );
#endif
if ( dn && ndn ) {
rc = dnNormalize( 0, NULL, NULL, dn, ndn, NULL );
}
break;
}
}

View file

@ -163,6 +163,10 @@ rwm_map_attrnames(
{
int i, j;
assert( anp );
*anp = NULL;
if ( an == NULL ) {
return LDAP_SUCCESS;
}
@ -384,7 +388,7 @@ map_attr_value(
fdc.ctx = "searchFilterAttrDN";
#endif
rc = rwm_dn_massage( &fdc, value, &vtmp, NULL );
rc = rwm_dn_massage( &fdc, value, NULL, &vtmp );
switch ( rc ) {
case LDAP_SUCCESS:
if ( vtmp.bv_val != value->bv_val ) {
@ -413,7 +417,7 @@ map_attr_value(
filter_escape_value( &vtmp, mapped_value );
if ( freeval ) {
ber_memfree( vtmp.bv_val );
ch_free( vtmp.bv_val );
}
return 0;
@ -453,12 +457,12 @@ rwm_int_filter_map_rewrite(
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
atmp.bv_val, vtmp.bv_val );
ber_memfree( vtmp.bv_val );
ch_free( vtmp.bv_val );
break;
case LDAP_FILTER_GE:
@ -469,12 +473,12 @@ rwm_int_filter_map_rewrite(
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(>=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
atmp.bv_val, vtmp.bv_val );
ber_memfree( vtmp.bv_val );
ch_free( vtmp.bv_val );
break;
case LDAP_FILTER_LE:
@ -485,12 +489,12 @@ rwm_int_filter_map_rewrite(
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(<=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
atmp.bv_val, vtmp.bv_val );
ber_memfree( vtmp.bv_val );
ch_free( vtmp.bv_val );
break;
case LDAP_FILTER_APPROX:
@ -501,12 +505,12 @@ rwm_int_filter_map_rewrite(
}
fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(~=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
atmp.bv_val, vtmp.bv_val );
ber_memfree( vtmp.bv_val );
ch_free( vtmp.bv_val );
break;
case LDAP_FILTER_SUBSTRINGS:
@ -519,7 +523,7 @@ rwm_int_filter_map_rewrite(
/* cannot be a DN ... */
fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
fstr->bv_val = malloc( fstr->bv_len + 128 );
fstr->bv_val = ch_malloc( fstr->bv_len + 128 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
atmp.bv_val );
@ -536,7 +540,7 @@ rwm_int_filter_map_rewrite(
/* "(attr=" */ "%s*)",
vtmp.bv_val );
ber_memfree( vtmp.bv_val );
ch_free( vtmp.bv_val );
}
if ( f->f_sub_any != NULL ) {
@ -550,7 +554,7 @@ rwm_int_filter_map_rewrite(
snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
/* "(attr=[init]*[any*]" */ "%s*)",
vtmp.bv_val );
ber_memfree( vtmp.bv_val );
ch_free( vtmp.bv_val );
}
}
@ -566,7 +570,7 @@ rwm_int_filter_map_rewrite(
/* "(attr=[init*][any*]" */ "%s)",
vtmp.bv_val );
ber_memfree( vtmp.bv_val );
ch_free( vtmp.bv_val );
}
break;
@ -579,7 +583,7 @@ rwm_int_filter_map_rewrite(
}
fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
atmp.bv_val );
@ -589,7 +593,7 @@ rwm_int_filter_map_rewrite(
case LDAP_FILTER_OR:
case LDAP_FILTER_NOT:
fstr->bv_len = STRLENOF( "(%)" );
fstr->bv_val = malloc( fstr->bv_len + 128 );
fstr->bv_val = ch_malloc( fstr->bv_len + 128 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
f->f_choice == LDAP_FILTER_AND ? '&' :
@ -632,7 +636,7 @@ rwm_int_filter_map_rewrite(
( 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 + STRLENOF( "(:=)" );
fstr->bv_val = malloc( fstr->bv_len + 1 );
fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
atmp.bv_val,
@ -640,8 +644,9 @@ rwm_int_filter_map_rewrite(
!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;
ch_free( vtmp.bv_val );
break;
}
case SLAPD_FILTER_COMPUTED:
switch ( f->f_result ) {
@ -701,7 +706,7 @@ rwm_filter_map_rewrite(
case REWRITE_REGEXEC_OK:
if ( !BER_BVISNULL( fstr ) ) {
fstr->bv_len = strlen( fstr->bv_val );
free( ftmp.bv_val );
ch_free( ftmp.bv_val );
} else {
*fstr = ftmp;
@ -748,7 +753,7 @@ rwm_filter_map_rewrite(
* routines may be macros with args
*/
int
rwm_dnattr_rewrite(
rwm_referral_rewrite(
Operation *op,
SlapReply *rs,
void *cookie,
@ -762,12 +767,12 @@ rwm_dnattr_rewrite(
int i, last;
dncookie dc;
struct berval dn, ndn, *pndn = NULL;
struct berval dn, ndn, *ndnp = NULL;
assert( a_vals );
/*
* Rewrite the bind dn if needed
* Rewrite the dn if needed
*/
dc.rwmap = rwmap;
#ifdef ENABLE_REWRITE
@ -781,7 +786,7 @@ rwm_dnattr_rewrite(
for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ );
if ( pa_nvals != NULL ) {
pndn = &ndn;
ndnp = &ndn;
if ( *pa_nvals == NULL ) {
*pa_nvals = ch_malloc( last * sizeof(struct berval) );
@ -791,9 +796,22 @@ rwm_dnattr_rewrite(
last--;
for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
struct berval olddn, oldval;
int rc;
LDAPURLDesc *ludp;
rc = rwm_dn_massage( &dc, &a_vals[i], &dn, pndn );
oldval = a_vals[i];
rc = ldap_url_parse( oldval.bv_val, &ludp );
if ( rc != LDAP_URL_SUCCESS ) {
/* leave attr untouched if massage failed */
if ( pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
ber_dupbv( &(*pa_nvals)[i], &oldval );
}
continue;
}
ber_str2bv( ludp->lud_dn, 0, 0, &olddn );
rc = rwm_dn_massage( &dc, &olddn, &dn, ndnp );
switch ( rc ) {
case LDAP_UNWILLING_TO_PERFORM:
/*
@ -816,21 +834,168 @@ rwm_dnattr_rewrite(
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 ( !BER_BVISNULL( &dn ) && dn.bv_val != olddn.bv_val ) {
char *newurl;
ludp->lud_dn = dn.bv_val;
newurl = ldap_url_desc2str( ludp );
if ( newurl == NULL ) {
/* FIXME: leave attr untouched
* even if ldap_url_desc2str failed... */
break;
}
ber_str2bv( newurl, 0, 1, &a_vals[i] );
LDAP_FREE( newurl );
if ( pa_nvals ) {
ludp->lud_dn = ndn.bv_val;
newurl = ldap_url_desc2str( ludp );
if ( newurl == NULL ) {
/* FIXME: leave attr untouched
* even if ldap_url_desc2str failed... */
ch_free( a_vals[i].bv_val );
a_vals[i] = oldval;
break;
}
if ( !BER_BVISNULL( &(*pa_nvals)[i] ) ) {
ch_free( (*pa_nvals)[i].bv_val );
}
(*pa_nvals)[i] = *pndn;
ber_str2bv( newurl, 0, 1, &(*pa_nvals)[i] );
LDAP_FREE( newurl );
}
ch_free( oldval.bv_val );
ludp->lud_dn = olddn.bv_val;
}
break;
default:
/* leave attr untouched if massage failed */
if ( pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
ber_dupbv( &(*pa_nvals)[i], &a_vals[i] );
}
break;
}
ldap_free_urldesc( ludp );
}
return 0;
}
/*
* I don't like this much, but we need two different
* functions because different heap managers may be
* in use in back-ldap/meta to reduce the amount of
* calls to malloc routines, and some of the free()
* routines may be macros with args
*/
int
rwm_dnattr_rewrite(
Operation *op,
SlapReply *rs,
void *cookie,
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;
int i, last;
dncookie dc;
struct berval dn, *dnp = NULL, ndn, *ndnp = NULL;
BerVarray in;
if ( a_vals ) {
in = a_vals;
dnp = &dn;
} else {
if ( pa_nvals == NULL || *pa_nvals == NULL ) {
return LDAP_OTHER;
}
in = *pa_nvals;
}
/*
* Rewrite the dn if needed
*/
dc.rwmap = rwmap;
#ifdef ENABLE_REWRITE
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = (char *)cookie;
#else
dc.tofrom = ((int *)cookie)[0];
dc.normalized = 0;
#endif
for ( last = 0; !BER_BVISNULL( &in[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) );
}
}
last--;
for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) {
int rc;
rc = rwm_dn_massage( &dc, &in[i], dnp, ndnp );
switch ( rc ) {
case LDAP_UNWILLING_TO_PERFORM:
/*
* FIXME: need to check if it may be considered
* legal to trim values when adding/modifying;
* it should be when searching (e.g. ACLs).
*/
ch_free( in[i].bv_val );
if (last > i ) {
in[i] = in[last];
if ( a_vals && pa_nvals ) {
(*pa_nvals)[i] = (*pa_nvals)[last];
}
}
BER_BVZERO( &in[last] );
if ( a_vals && pa_nvals ) {
BER_BVZERO( &(*pa_nvals)[last] );
}
last--;
break;
case LDAP_SUCCESS:
if ( a_vals ) {
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] = ndn;
}
}
} 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;
}
}
break;
default:
/* leave attr untouched if massage failed */
if ( a_vals && pa_nvals && BER_BVISNULL( &(*pa_nvals)[i] ) ) {
dnNormalize( 0, NULL, NULL, &a_vals[i], &(*pa_nvals)[i], NULL );
}
break;
@ -840,6 +1005,73 @@ rwm_dnattr_rewrite(
return 0;
}
int
rwm_referral_result_rewrite(
dncookie *dc,
BerVarray a_vals
)
{
int i, last;
for ( last = 0; !BER_BVISNULL( &a_vals[last] ); last++ );
last--;
for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
struct berval dn, olddn;
int rc;
LDAPURLDesc *ludp;
rc = ldap_url_parse( a_vals[i].bv_val, &ludp );
if ( rc != LDAP_URL_SUCCESS ) {
/* leave attr untouched if massage failed */
continue;
}
ber_str2bv( ludp->lud_dn, 0, 0, &olddn );
rc = rwm_dn_massage( dc, &olddn, &dn, NULL );
switch ( rc ) {
case LDAP_UNWILLING_TO_PERFORM:
/*
* FIXME: need to check if it may be considered
* legal to trim values when adding/modifying;
* it should be when searching (e.g. ACLs).
*/
ch_free( &a_vals[i].bv_val );
if ( last > i ) {
a_vals[i] = a_vals[last];
}
BER_BVZERO( &a_vals[last] );
last--;
break;
default:
/* leave attr untouched if massage failed */
if ( !BER_BVISNULL( &dn ) && olddn.bv_val != dn.bv_val ) {
char *newurl;
ludp->lud_dn = dn.bv_val;
newurl = ldap_url_desc2str( ludp );
if ( newurl == NULL ) {
/* FIXME: leave attr untouched
* even if ldap_url_desc2str failed... */
break;
}
ch_free( a_vals[i].bv_val );
ber_str2bv( newurl, 0, 1, &a_vals[i] );
LDAP_FREE( newurl );
ludp->lud_dn = olddn.bv_val;
}
break;
}
ldap_free_urldesc( ludp );
}
return 0;
}
int
rwm_dnattr_result_rewrite(
dncookie *dc,
@ -863,7 +1095,7 @@ rwm_dnattr_result_rewrite(
* legal to trim values when adding/modifying;
* it should be when searching (e.g. ACLs).
*/
LBER_FREE( &a_vals[i].bv_val );
ch_free( &a_vals[i].bv_val );
if ( last > i ) {
a_vals[i] = a_vals[last];
}
@ -874,7 +1106,7 @@ rwm_dnattr_result_rewrite(
default:
/* leave attr untouched if massage failed */
if ( !BER_BVISNULL( &dn ) && a_vals[i].bv_val != dn.bv_val ) {
LBER_FREE( a_vals[i].bv_val );
ch_free( a_vals[i].bv_val );
a_vals[i] = dn;
}
break;

View file

@ -975,6 +975,8 @@ LDAP_SLAPD_F (int) str2result LDAP_P(( char *s,
int *code, char **matched, char **info ));
LDAP_SLAPD_F (int) slap_map_api2result LDAP_P(( SlapReply *rs ));
LDAP_SLAPD_V( const struct berval ) slap_dummy_bv;
/*
* root_dse.c
*/

View file

@ -41,6 +41,8 @@
#include "slapi/slapi.h"
#endif
const struct berval slap_dummy_bv = BER_BVNULL;
int slap_null_cb( Operation *op, SlapReply *rs )
{
return 0;
@ -784,8 +786,15 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
/* FIXME: maybe we could se this flag at the operation level;
* however, in principle the caller of send_search_entry() may
* change the attribute list at each call */
rs->sr_opattrs = ( rs->sr_attrs == NULL ) ? SLAP_OPATTRS_NO
: ( an_find( rs->sr_attrs, &AllOper ) ? SLAP_OPATTRS : SLAP_OPATTRS_NO );
if ( rs->sr_attrs == NULL ) {
rs->sr_attr_flags = ( SLAP_OPATTRS_NO | SLAP_USERATTRS_YES );
} else {
rs->sr_attr_flags |= an_find( rs->sr_attrs, &AllOper ) ?
SLAP_OPATTRS_YES : SLAP_OPATTRS_NO;
rs->sr_attr_flags |= an_find( rs->sr_attrs, &AllUser ) ?
SLAP_USERATTRS_YES : SLAP_USERATTRS_NO;
}
rc = backend_operational( op, rs );
if ( rc ) {
@ -967,7 +976,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
} else {
/* specific attrs requested */
if ( is_at_operational( desc->ad_type ) ) {
if ( rs->sr_opattrs != SLAP_OPATTRS &&
if ( !SLAP_OPATTRS( rs->sr_attr_flags ) &&
!ad_inlist( desc, rs->sr_attrs ) )
{
continue;
@ -1177,7 +1186,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
} else {
/* specific attrs requested */
if( is_at_operational( desc->ad_type ) ) {
if ( rs->sr_opattrs != SLAP_OPATTRS &&
if ( !SLAP_OPATTRS( rs->sr_attr_flags ) &&
!ad_inlist( desc, rs->sr_attrs ) )
{
continue;
@ -1295,7 +1304,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
ctx.cac_attrs = rs->sr_attrs;
ctx.cac_attrsonly = op->ors_attrsonly;
ctx.cac_userattrs = userattrs;
ctx.cac_opattrs = rs->sr_opattrs;
ctx.cac_opattrs = rs->sr_attr_flags;
ctx.cac_acl_state = acl_state;
ctx.cac_private = (void *)ber;
@ -1433,7 +1442,7 @@ error_return:;
attrs_free( rs->sr_operational_attrs );
rs->sr_operational_attrs = NULL;
}
rs->sr_opattrs = SLAP_OPATTRS_UNDEFINED;
rs->sr_attr_flags = SLAP_ATTRS_UNDEFINED;
/* FIXME: I think rs->sr_type should be explicitly set to
* REP_SEARCH here. That's what it was when we entered this

View file

@ -1687,10 +1687,16 @@ typedef struct rep_extended_s {
typedef struct rep_search_s {
Entry *r_entry;
int r_opattrs;
#define SLAP_OPATTRS_UNDEFINED (0)
#define SLAP_OPATTRS_NO (-1)
#define SLAP_OPATTRS (1)
int r_attr_flags;
#define SLAP_ATTRS_UNDEFINED (0)
#define SLAP_OPATTRS_NO (0x01)
#define SLAP_OPATTRS_YES (0x02)
#define SLAP_USERATTRS_NO (0x10)
#define SLAP_USERATTRS_YES (0x20)
#define SLAP_OPATTRS_MASK(f) ( (f) & (SLAP_OPATTRS_NO|SLAP_OPATTRS_YES) )
#define SLAP_OPATTRS(f) ( (f) & SLAP_OPATTRS_YES )
#define SLAP_USERATTRS_MASK(f) ( (f) & (SLAP_USERATTRS_NO|SLAP_USERATTRS_YES) )
#define SLAP_USERATTRS(f) ( (f) & SLAP_USERATTRS_YES )
Attribute *r_operational_attrs;
AttributeName *r_attrs;
int r_nentries;
@ -1722,7 +1728,7 @@ typedef struct slap_rep {
#define sr_attrs sr_un.sru_search.r_attrs
#define sr_entry sr_un.sru_search.r_entry
#define sr_operational_attrs sr_un.sru_search.r_operational_attrs
#define sr_opattrs sr_un.sru_search.r_opattrs
#define sr_attr_flags sr_un.sru_search.r_attr_flags
#define sr_v2ref sr_un.sru_search.r_v2ref
#define sr_nentries sr_un.sru_search.r_nentries
#define sr_rspoid sr_un.sru_extended.r_rspoid

View file

@ -2031,7 +2031,8 @@ homePhone: +1 313 555 8421
pager: +1 313 555 2844
facsimileTelephoneNumber: +1 313 555 9700
telephoneNumber: +1 313 555 5331
description: Just added self in o=Beispiel,c=DE virtual naming context
description: Just added self to seeAlso in o=Beispiel,c=DE virtual naming cont
ext
dn: cn=Added User,ou=Alumni Association,ou=People,o=Esempio,c=IT
objectClass: OpenLDAPperson
@ -2042,5 +2043,69 @@ seeAlso: cn=All Staff,ou=Groups,o=Esempio,c=IT
homePhone: +49 1234567890
drink: Beer
mail: auser@mail.alumni.example.com
telephoneNumber: +1 313 555 4178
telephoneNumber: +49 1234-567-890
description: Just added in o=Beispiel,c=DE naming context
dn: ou=Referrals,dc=example,dc=com
objectClass: referral
objectClass: extensibleObject
ou: Referrals
description: Just added as ldap://localhost:9011/ou=Referrals,o=Beispiel,c=DE
description: ...and modified as ldap://localhost:9012/ou=Referrals,o=Beispiel,
c=DE
ref: ldap://localhost:9012/ou=Referrals,dc=example,dc=com??base
dn: ou=Referrals,o=Example,c=US
objectClass: referral
objectClass: extensibleObject
ou: Referrals
description: Just added as ldap://localhost:9011/ou=Referrals,o=Beispiel,c=DE
description: ...and modified as ldap://localhost:9012/ou=Referrals,o=Beispiel,
c=DE
ref: ldap://localhost:9012/ou=Referrals,o=Example,c=US??base
dn: ou=Referrals,o=Esempio,c=IT
objectClass: referral
objectClass: extensibleObject
ou: Referrals
description: Just added as ldap://localhost:9011/ou=Referrals,o=Beispiel,c=DE
description: ...and modified as ldap://localhost:9012/ou=Referrals,o=Beispiel,
c=DE
ref: ldap://localhost:9012/ou=Referrals,o=Esempio,c=IT??base
dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,o=Example,c
=US
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=Example,c=U
S
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=Example,c=US
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
dn: cn=James A Jones 1,ou=Alumni Association,ou=People,o=Example,c=US
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,o=Example,
c=US
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
dn: cn=Jane Q. Doe,ou=Information Technology Division,ou=People,o=Example,c=US
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=Example,c=US
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
dn: cn=John P. Doe,ou=Information Technology Division,ou=People,o=Example,c=US
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Example,c=US
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
seeAlso: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Example,c=US
dn: cn=Added User,ou=Alumni Association,ou=People,o=Example,c=US
seeAlso: cn=All Staff,ou=Groups,o=Example,c=US

View file

@ -120,7 +120,7 @@ PORT4=9014
PORT5=9015
PORT6=9016
URI1="ldap://${LOCALHOST}:$PORT1/"
URI2="ldap://${LOCALHOST}:$PORT2"
URI2="ldap://${LOCALHOST}:$PORT2/"
URI3="ldap://${LOCALHOST}:$PORT3/"
URI4="ldap://${LOCALHOST}:$PORT4/"
URI5="ldap://${LOCALHOST}:$PORT5/"

View file

@ -114,7 +114,7 @@ fi
BASEDN="o=Beispiel,c=DE"
echo "modifying database \"$BASEDN\"..."
$LDAPMODIFY -v -D "cn=Manager,$BASEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
>> $TESTOUT 2>&1 << EOMODS
-e manageDSAit >> $TESTOUT 2>&1 << EOMODS
dn: cn=Added User,ou=Alumni Association,ou=People,$BASEDN
changetype: add
objectClass: OpenLDAPperson
@ -125,7 +125,8 @@ seealso: cn=All Staff,ou=Groups,$BASEDN
homephone: +49 1234567890
drink: Beer
mail: auser@mail.alumni.example.com
telephonenumber: +1 313 555 4178
telephonenumber: +49 1234-567-890
description: Just added in o=Beispiel,c=DE naming context
dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,$BASEDN
changetype: modify
@ -133,7 +134,7 @@ add: seeAlso
seeAlso: cn=Ursula Hampster,ou=Alumni Association,ou=People,$BASEDN
-
add: description
description: Just added self in $BASEDN virtual naming context
description: Just added self to seeAlso in $BASEDN virtual naming context
-
dn: cn=Mark Elliot,ou=Alumni Association,ou=People,$BASEDN
@ -150,6 +151,22 @@ newrdn: cn=Jane Q. Doe
deleteoldrdn: 1
newsuperior: ou=Information Technology Division,ou=People,$BASEDN
dn: ou=Referrals,$BASEDN
changetype: add
objectclass: referral
objectclass: extensibleObject
ou: Referrals
ref: ${URI1}ou=Referrals,$BASEDN
description: Just added as ${URI1}ou=Referrals,$BASEDN
dn: ou=Referrals,$BASEDN
changetype: modify
replace: ref
ref: ${URI2}ou=Referrals,$BASEDN
-
add: description
description: ...and modified as ${URI2}ou=Referrals,$BASEDN
-
EOMODS
if test $RC != 0 ; then
@ -168,6 +185,57 @@ if test $RC != 0 ; then
exit $RC
fi
FILTER="(objectClass=referral)"
echo "searching filter=\"$FILTER\""
echo " attrs=\"'*' ref\"..."
BASEDN="dc=example,dc=com"
echo " base=\"$BASEDN\"..."
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" "$FILTER" "*" ref \
-e manageDSAit >> $SEARCHOUT 2>&1
RC=$?
if test $RC != 0 ; then
echo "Search failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
BASEDN="o=Example,c=US"
echo " base=\"$BASEDN\"..."
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" "$FILTER" "*" ref \
-e manageDSAit >> $SEARCHOUT 2>&1
RC=$?
if test $RC != 0 ; then
echo "Search failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
BASEDN="o=Esempio,c=IT"
echo " base=\"$BASEDN\"..."
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" "$FILTER" "*" ref \
-e manageDSAit >> $SEARCHOUT 2>&1
RC=$?
if test $RC != 0 ; then
echo "Search failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
BASEDN="o=Example,c=US"
FILTER="(seeAlso=cn=all staff,ou=Groups,$BASEDN)"
echo "searching filter=\"$FILTER\""
echo " attrs=\"seeAlso\"..."
echo " base=\"$BASEDN\""
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" "$FILTER" seeAlso \
>> $SEARCHOUT 2>&1
RC=$?
if test $RC != 0 ; then
echo "Search failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
echo "Filtering ldapsearch results..."
. $LDIFFILTER < $SEARCHOUT > $SEARCHFLT
echo "Filtering original ldif used to create database..."
@ -193,6 +261,7 @@ if test $RC != 0 ; then
exit $RC
fi
BASEDN="o=Beispiel,c=DE"
echo "binding with newly changed password to database \"$BASEDN\"..."
$LDAPWHOAMI -h $LOCALHOST -p $PORT1 \
-D "cn=Added User,ou=Alumni Association,ou=People,$BASEDN" \