mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-02-13 07:43:50 -05:00
ITS#9121 support nested groups
This commit is contained in:
parent
9210ed1618
commit
2c0499ae4e
4 changed files with 1076 additions and 161 deletions
|
|
@ -51,7 +51,7 @@ occurrences, and it must appear after the
|
|||
.B overlay
|
||||
directive.
|
||||
.TP
|
||||
.B dynlist\-attrset <group-oc> [<URI>] <URL-ad> [[<mapped-ad>:]<member-ad>[+<memberOf-ad] ...]
|
||||
.B dynlist\-attrset <group-oc> [<URI>] <URL-ad> [[<mapped-ad>:]<member-ad>[+<memberOf-ad[@<static-oc>[*]] ...]
|
||||
The value
|
||||
.B group\-oc
|
||||
is the name of the objectClass that triggers the dynamic expansion of the
|
||||
|
|
@ -94,6 +94,15 @@ If the optional
|
|||
.B memberOf-ad
|
||||
attribute is also specified, then it will be populated with the DNs of the
|
||||
dynamic groups that an entry is a member of.
|
||||
If the optional
|
||||
.B static-oc
|
||||
objectClass is also specified, then the memberOf attribute will also be
|
||||
populated with the DNs of the static groups that an entry is a member of.
|
||||
If the optional
|
||||
.B *
|
||||
character is also specified, then the member and memberOf values will be
|
||||
populated recursively, for nested groups. Note that currently nesting is
|
||||
only supported for Search operations, not Compares.
|
||||
|
||||
Alternatively,
|
||||
.B mapped-ad
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ typedef struct dynlist_map_t {
|
|||
AttributeDescription *dlm_memberOf_ad;
|
||||
ObjectClass *dlm_static_oc;
|
||||
int dlm_memberOf_nested;
|
||||
int dlm_member_oper;
|
||||
int dlm_memberOf_oper;
|
||||
struct dynlist_map_t *dlm_next;
|
||||
} dynlist_map_t;
|
||||
|
||||
|
|
@ -63,7 +65,6 @@ typedef struct dynlist_gen_t {
|
|||
dynlist_info_t *dlg_dli;
|
||||
int dlg_memberOf;
|
||||
} dynlist_gen_t;
|
||||
#define DYNLIST_HAS_MEMBEROF 1
|
||||
|
||||
#define DYNLIST_USAGE \
|
||||
"\"dynlist-attrset <oc> [uri] <URL-ad> [[<mapped-ad>:]<member-ad>[+<memberOf-ad>[@<static-oc>[*]] ...]\": "
|
||||
|
|
@ -100,8 +101,6 @@ ad_infilter( AttributeDescription *ad, Filter *f )
|
|||
static int
|
||||
dynlist_make_filter( Operation *op, Entry *e, dynlist_info_t *dli, const char *url, struct berval *oldf, struct berval *newf )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
|
||||
char *ptr;
|
||||
int needBrackets = 0;
|
||||
|
||||
|
|
@ -326,9 +325,160 @@ done:;
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
typedef struct dynlist_name_t {
|
||||
struct berval dy_name;
|
||||
dynlist_info_t *dy_dli;
|
||||
AttributeDescription *dy_staticmember;
|
||||
int dy_seen;
|
||||
int dy_numuris;
|
||||
TAvlnode *dy_subs;
|
||||
TAvlnode *dy_sups;
|
||||
LDAPURLDesc *dy_uris[];
|
||||
} dynlist_name_t;
|
||||
|
||||
static void
|
||||
dynlist_urlmembers( Operation *op, dynlist_name_t *dyn, slap_callback *sc )
|
||||
{
|
||||
Operation o = *op;
|
||||
LDAPURLDesc *ludp;
|
||||
int i;
|
||||
|
||||
o.ors_deref = LDAP_DEREF_NEVER;
|
||||
o.ors_limit = NULL;
|
||||
o.ors_tlimit = SLAP_NO_LIMIT;
|
||||
o.ors_slimit = SLAP_NO_LIMIT;
|
||||
o.ors_attrs = NULL;
|
||||
o.o_callback = sc;
|
||||
|
||||
for (i=0; i<dyn->dy_numuris; i++) {
|
||||
ludp = dyn->dy_uris[i];
|
||||
if ( ludp->lud_attrs )
|
||||
continue;
|
||||
o.o_req_dn.bv_val = ludp->lud_dn;
|
||||
o.o_req_dn.bv_len = ludp->lud_port;
|
||||
o.o_req_ndn = o.o_req_dn;
|
||||
o.ors_scope = ludp->lud_scope;
|
||||
o.ors_filter = (Filter *)ludp->lud_filter;
|
||||
filter2bv_x( op, o.ors_filter, &o.ors_filterstr );
|
||||
o.o_bd = select_backend( &o.o_req_ndn, 1 );
|
||||
if ( o.o_bd && o.o_bd->be_search ) {
|
||||
SlapReply r = { REP_SEARCH };
|
||||
r.sr_attr_flags = slap_attr_flags( o.ors_attrs );
|
||||
o.o_managedsait = SLAP_CONTROL_CRITICAL;
|
||||
(void)o.o_bd->be_search( &o, &r );
|
||||
}
|
||||
op->o_tmpfree( o.ors_filterstr.bv_val, op->o_tmpmemctx );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dynlist_nested_memberOf( Entry *e, AttributeDescription *ad, TAvlnode *sups )
|
||||
{
|
||||
TAvlnode *ptr;
|
||||
dynlist_name_t *dyn;
|
||||
Attribute *a;
|
||||
|
||||
a = attr_find( e->e_attrs, ad );
|
||||
for ( ptr = tavl_end( sups, TAVL_DIR_LEFT ); ptr;
|
||||
ptr = tavl_next( ptr, TAVL_DIR_RIGHT )) {
|
||||
dyn = ptr->avl_data;
|
||||
if ( a ) {
|
||||
unsigned slot;
|
||||
if ( attr_valfind( a, SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX |
|
||||
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH |
|
||||
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
|
||||
&dyn->dy_name, &slot, NULL ) == LDAP_SUCCESS )
|
||||
continue;
|
||||
}
|
||||
attr_merge_one( e, ad, &dyn->dy_name, &dyn->dy_name );
|
||||
if ( !a )
|
||||
a = attr_find( e->e_attrs, ad );
|
||||
if ( dyn->dy_sups )
|
||||
dynlist_nested_memberOf( e, ad, dyn->dy_sups );
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct dynlist_member_t {
|
||||
Entry *dm_e;
|
||||
AttributeDescription *dm_ad;
|
||||
Modification dm_mod;
|
||||
TAvlnode *dm_groups;
|
||||
struct berval dm_bv[2];
|
||||
struct berval dm_nbv[2];
|
||||
const char *dm_text;
|
||||
char dm_textbuf[1024];
|
||||
} dynlist_member_t;
|
||||
|
||||
static int
|
||||
dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
|
||||
dynlist_ptr_cmp( const void *c1, const void *c2 )
|
||||
{
|
||||
return ( c1 < c2 ) ? -1 : c1 > c2;
|
||||
}
|
||||
|
||||
static int
|
||||
dynlist_nested_member_dg( Operation *op, SlapReply *rs )
|
||||
{
|
||||
dynlist_member_t *dm = op->o_callback->sc_private;
|
||||
|
||||
if ( rs->sr_type != REP_SEARCH )
|
||||
return LDAP_SUCCESS;
|
||||
|
||||
dm->dm_bv[0] = rs->sr_entry->e_name;
|
||||
dm->dm_nbv[0] = rs->sr_entry->e_nname;
|
||||
modify_add_values( dm->dm_e, &dm->dm_mod, /* permissive */ 1,
|
||||
&dm->dm_text, dm->dm_textbuf, sizeof( dm->dm_textbuf ));
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
dynlist_nested_member( Operation *op, dynlist_member_t *dm, TAvlnode *subs )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
TAvlnode *ptr;
|
||||
dynlist_name_t *dyn;
|
||||
Entry *ne;
|
||||
Attribute *a, *b;
|
||||
|
||||
a = attr_find( dm->dm_e->e_attrs, dm->dm_ad );
|
||||
if ( !a )
|
||||
return;
|
||||
|
||||
for ( ptr = tavl_end( subs, TAVL_DIR_LEFT ); ptr;
|
||||
ptr = tavl_next( ptr, TAVL_DIR_RIGHT )) {
|
||||
dyn = ptr->avl_data;
|
||||
if ( tavl_insert( &dm->dm_groups, dyn, dynlist_ptr_cmp, avl_dup_error ))
|
||||
continue;
|
||||
if ( overlay_entry_get_ov( op, &dyn->dy_name, NULL, NULL, 0, &ne, on ) != LDAP_SUCCESS || ne == NULL )
|
||||
continue;
|
||||
b = attr_find( ne->e_attrs, dm->dm_ad );
|
||||
if ( b ) {
|
||||
dm->dm_mod.sm_values = b->a_vals;
|
||||
dm->dm_mod.sm_nvalues = b->a_nvals;
|
||||
dm->dm_mod.sm_numvals = b->a_numvals;
|
||||
modify_add_values( dm->dm_e, &dm->dm_mod, /* permissive */ 1,
|
||||
&dm->dm_text, dm->dm_textbuf, sizeof( dm->dm_textbuf ));
|
||||
}
|
||||
overlay_entry_release_ov( op, ne, 0, on );
|
||||
if ( dyn->dy_numuris ) {
|
||||
slap_callback cb = { 0 };
|
||||
cb.sc_private = dm;
|
||||
BER_BVZERO( &dm->dm_bv[1] );
|
||||
BER_BVZERO( &dm->dm_nbv[1] );
|
||||
dm->dm_mod.sm_values = dm->dm_bv;
|
||||
dm->dm_mod.sm_nvalues = dm->dm_nbv;
|
||||
dm->dm_mod.sm_numvals = 1;
|
||||
cb.sc_response = dynlist_nested_member_dg;
|
||||
dynlist_urlmembers( op, dyn, &cb );
|
||||
}
|
||||
if ( dyn->dy_subs )
|
||||
dynlist_nested_member( op, dm, dyn->dy_subs );
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli, dynlist_name_t *dyn )
|
||||
{
|
||||
Attribute *a, *id = NULL;
|
||||
slap_callback cb = { 0 };
|
||||
|
|
@ -340,10 +490,11 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
|
|||
dynlist_sc_t dlc = { 0 };
|
||||
dynlist_map_t *dlm;
|
||||
|
||||
e = rs->sr_entry;
|
||||
a = attrs_find( rs->sr_entry->e_attrs, dli->dli_ad );
|
||||
if ( a == NULL ) {
|
||||
/* FIXME: error? */
|
||||
return SLAP_CB_CONTINUE;
|
||||
goto checkdyn;
|
||||
}
|
||||
|
||||
opattrs = SLAP_OPATTRS( rs->sr_attr_flags );
|
||||
|
|
@ -357,7 +508,7 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
|
|||
break;
|
||||
}
|
||||
if ( dli->dli_dlm && !dlm )
|
||||
return SLAP_CB_CONTINUE;
|
||||
goto checkdyn;
|
||||
|
||||
if ( ad_dgIdentity && ( id = attrs_find( rs->sr_entry->e_attrs, ad_dgIdentity ))) {
|
||||
Attribute *authz = NULL;
|
||||
|
|
@ -370,7 +521,7 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
|
|||
if ( slap_sasl_matches( op, authz->a_nvals,
|
||||
&o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS )
|
||||
{
|
||||
return SLAP_CB_CONTINUE;
|
||||
goto checkdyn;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -379,7 +530,6 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
|
|||
o.o_groups = NULL;
|
||||
}
|
||||
|
||||
e = rs->sr_entry;
|
||||
/* ensure e is modifiable, but do not replace
|
||||
* sr_entry yet since we have pointers into it */
|
||||
if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
|
||||
|
|
@ -536,11 +686,16 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
|
|||
&dli->dli_default_filter, op->o_tmpmemctx );
|
||||
|
||||
} else {
|
||||
struct berval flt;
|
||||
ber_str2bv( lud->lud_filter, 0, 0, &flt );
|
||||
if ( dynlist_make_filter( op, rs->sr_entry, dli, url->bv_val, &flt, &o.ors_filterstr ) ) {
|
||||
/* error */
|
||||
goto cleanup;
|
||||
/* don't allow recursion in lists */
|
||||
if ( lud->lud_attrs ) {
|
||||
struct berval flt;
|
||||
ber_str2bv( lud->lud_filter, 0, 0, &flt );
|
||||
if ( dynlist_make_filter( op, rs->sr_entry, dli, url->bv_val, &flt, &o.ors_filterstr ) ) {
|
||||
/* error */
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
ber_str2bv( lud->lud_filter, 0, 0, &o.ors_filterstr );
|
||||
}
|
||||
}
|
||||
o.ors_filter = str2filter_x( op, o.ors_filterstr.bv_val );
|
||||
|
|
@ -574,12 +729,51 @@ cleanup:;
|
|||
if ( !BER_BVISNULL( &o.o_req_ndn ) ) {
|
||||
op->o_tmpfree( o.o_req_ndn.bv_val, op->o_tmpmemctx );
|
||||
}
|
||||
assert( BER_BVISNULL( &o.ors_filterstr )
|
||||
|| o.ors_filterstr.bv_val != lud->lud_filter );
|
||||
op->o_tmpfree( o.ors_filterstr.bv_val, op->o_tmpmemctx );
|
||||
if ( lud->lud_attrs ) {
|
||||
assert( BER_BVISNULL( &o.ors_filterstr )
|
||||
|| o.ors_filterstr.bv_val != lud->lud_filter );
|
||||
op->o_tmpfree( o.ors_filterstr.bv_val, op->o_tmpmemctx );
|
||||
} else {
|
||||
if ( o.ors_filterstr.bv_val != lud->lud_filter )
|
||||
op->o_tmpfree( o.ors_filterstr.bv_val, op->o_tmpmemctx );
|
||||
}
|
||||
ldap_free_urldesc( lud );
|
||||
}
|
||||
|
||||
checkdyn:
|
||||
/* handle nested groups */
|
||||
if ( dyn && ( dyn->dy_sups || dyn->dy_subs )) {
|
||||
/* ensure e is modifiable */
|
||||
if ( e == rs->sr_entry && !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
|
||||
e = entry_dup( rs->sr_entry );
|
||||
rs_replace_entry( op, rs, (slap_overinst *)op->o_bd->bd_info, e );
|
||||
rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
|
||||
}
|
||||
if ( dyn->dy_subs ) {
|
||||
for ( dlm = dyn->dy_dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
|
||||
if ( dlm->dlm_member_ad ) {
|
||||
dynlist_member_t dm;
|
||||
dm.dm_groups = NULL;
|
||||
dm.dm_mod.sm_op = LDAP_MOD_ADD;
|
||||
dm.dm_mod.sm_desc = dlm->dlm_member_ad;
|
||||
dm.dm_mod.sm_type = dlm->dlm_member_ad->ad_cname;
|
||||
dm.dm_e = e;
|
||||
dm.dm_ad = dlm->dlm_member_ad;
|
||||
dynlist_nested_member( op, &dm, dyn->dy_subs );
|
||||
if ( dm.dm_groups )
|
||||
tavl_free( dm.dm_groups, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( dyn->dy_sups ) {
|
||||
for ( dlm = dyn->dy_dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
|
||||
if ( dlm->dlm_memberOf_ad ) {
|
||||
dynlist_nested_memberOf( e, dlm->dlm_memberOf_ad, dyn->dy_sups );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( e != rs->sr_entry ) {
|
||||
rs_replace_entry( op, rs, (slap_overinst *)op->o_bd->bd_info, e );
|
||||
rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
|
||||
|
|
@ -769,7 +963,7 @@ done:;
|
|||
r.sr_attrs = an;
|
||||
|
||||
o.o_acl_priv = ACL_COMPARE;
|
||||
dynlist_prepare_entry( &o, &r, dli );
|
||||
dynlist_prepare_entry( &o, &r, dli, NULL );
|
||||
a = attrs_find( r.sr_entry->e_attrs, op->orc_ava->aa_desc );
|
||||
|
||||
ret = LDAP_NO_SUCH_ATTRIBUTE;
|
||||
|
|
@ -798,22 +992,18 @@ release:;
|
|||
return ret;
|
||||
}
|
||||
|
||||
typedef struct dynlist_name_t {
|
||||
struct berval dy_name;
|
||||
dynlist_info_t *dy_dli;
|
||||
AttributeDescription *dy_staticmember;
|
||||
int dy_seen;
|
||||
int dy_numuris;
|
||||
LDAPURLDesc *dy_uris[];
|
||||
} dynlist_name_t;
|
||||
#define WANT_MEMBEROF 1
|
||||
#define WANT_MEMBER 2
|
||||
|
||||
typedef struct dynlist_search_t {
|
||||
TAvlnode *ds_names;
|
||||
TAvlnode *ds_fnodes;
|
||||
dynlist_info_t *ds_dli;
|
||||
dynlist_map_t *ds_dlm;
|
||||
Filter *ds_origfilter;
|
||||
struct berval ds_origfilterbv;
|
||||
int ds_memberOf;
|
||||
int ds_want;
|
||||
int ds_found;
|
||||
} dynlist_search_t;
|
||||
|
||||
static int
|
||||
|
|
@ -900,6 +1090,8 @@ dynlist_search1resp( Operation *op, SlapReply *rs )
|
|||
ldap_free_urldesc( ludp );
|
||||
}
|
||||
ch_free( dyn );
|
||||
} else {
|
||||
ds->ds_found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -911,7 +1103,7 @@ dynlist_search1resp( Operation *op, SlapReply *rs )
|
|||
* using (&(entryDN=<groupURIbase>)<groupURIfilter>)
|
||||
*/
|
||||
static int
|
||||
dynlist_filter_dyngroup( Operation *op, Filter *f, Filter *n, Attribute *a )
|
||||
dynlist_filter_dyngroup( Operation *op, Filter *n, Attribute *a )
|
||||
{
|
||||
Filter *andf = NULL, *dnf, *urif, *orf = NULL;
|
||||
LDAPURLDesc *ludp;
|
||||
|
|
@ -940,23 +1132,24 @@ dynlist_filter_dyngroup( Operation *op, Filter *f, Filter *n, Attribute *a )
|
|||
} else {
|
||||
urif = NULL;
|
||||
}
|
||||
if ( !andf ) {
|
||||
if ( !andf && n->f_choice == SLAPD_FILTER_COMPUTED ) {
|
||||
andf = n;
|
||||
andf->f_next = NULL;
|
||||
} else {
|
||||
if ( !orf ) {
|
||||
orf = n;
|
||||
if ( n->f_choice != LDAP_FILTER_OR ) {
|
||||
andf = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
|
||||
andf->f_choice = n->f_choice;
|
||||
andf->f_list = n->f_list;
|
||||
orf = n;
|
||||
*andf = *n;
|
||||
orf->f_choice = LDAP_FILTER_OR;
|
||||
orf->f_next = NULL;
|
||||
orf->f_list = andf;
|
||||
}
|
||||
andf->f_next = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
|
||||
andf = andf->f_next;
|
||||
andf = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
|
||||
andf->f_next = orf->f_list;
|
||||
orf->f_list = andf;
|
||||
}
|
||||
dnf = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
|
||||
andf->f_choice = LDAP_FILTER_AND;
|
||||
andf->f_next = NULL;
|
||||
andf->f_list = dnf;
|
||||
dnf->f_next = urif;
|
||||
if ( ludp->lud_scope == LDAP_SCOPE_BASE ) {
|
||||
|
|
@ -994,32 +1187,39 @@ dynlist_filter_dyngroup( Operation *op, Filter *f, Filter *n, Attribute *a )
|
|||
* using (|(entryDN=<memberN>)[...])
|
||||
*/
|
||||
static int
|
||||
dynlist_filter_stgroup( Operation *op, Filter *f, Filter *n, Attribute *a )
|
||||
dynlist_filter_stgroup( Operation *op, Filter *n, Attribute *a )
|
||||
{
|
||||
Filter *dnf, *orf;
|
||||
Filter *dnf, *orf = NULL;
|
||||
int i;
|
||||
|
||||
if ( a->a_numvals == 1 ) {
|
||||
if ( a->a_numvals == 1 && n->f_choice == SLAPD_FILTER_COMPUTED ) {
|
||||
dnf = n;
|
||||
dnf->f_next = NULL;
|
||||
} else {
|
||||
orf = n;
|
||||
orf->f_choice = LDAP_FILTER_OR;
|
||||
orf->f_next = NULL;
|
||||
if ( n->f_choice != LDAP_FILTER_OR ) {
|
||||
dnf = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
|
||||
*dnf = *n;
|
||||
orf->f_choice = LDAP_FILTER_OR;
|
||||
orf->f_next = NULL;
|
||||
orf->f_list = dnf;
|
||||
}
|
||||
dnf = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
|
||||
dnf->f_next = orf->f_list;
|
||||
orf->f_list = dnf;
|
||||
}
|
||||
|
||||
for (i=0; i<a->a_numvals; i++) {
|
||||
if ( i > 1 ) {
|
||||
dnf->f_next = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
|
||||
dnf = dnf->f_next;
|
||||
if ( i ) {
|
||||
dnf = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
|
||||
dnf->f_next = orf->f_list;
|
||||
orf->f_list = dnf;
|
||||
}
|
||||
dnf->f_choice = LDAP_FILTER_EQUALITY;
|
||||
dnf->f_ava = op->o_tmpcalloc( 1, sizeof(AttributeAssertion), op->o_tmpmemctx );
|
||||
dnf->f_av_desc = slap_schema.si_ad_entryDN;
|
||||
ber_dupbv_x( &dnf->f_av_value, &a->a_nvals[i], op->o_tmpmemctx );
|
||||
}
|
||||
dnf->f_next = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1027,29 +1227,42 @@ dynlist_filter_stgroup( Operation *op, Filter *f, Filter *n, Attribute *a )
|
|||
* its members.
|
||||
*/
|
||||
static int
|
||||
dynlist_filter_group( Operation *op, Filter *f, Filter *n, dynlist_search_t *ds )
|
||||
dynlist_filter_group( Operation *op, dynlist_name_t *dyn, Filter *n, dynlist_search_t *ds )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
Entry *e;
|
||||
Attribute *a;
|
||||
int rc = -1;
|
||||
|
||||
if ( overlay_entry_get_ov( op, &f->f_av_value, NULL, NULL, 0, &e, on ) !=
|
||||
if ( tavl_insert( &ds->ds_fnodes, dyn, dynlist_ptr_cmp, avl_dup_error ))
|
||||
return 0;
|
||||
|
||||
if ( overlay_entry_get_ov( op, &dyn->dy_name, NULL, NULL, 0, &e, on ) !=
|
||||
LDAP_SUCCESS || e == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
if ( ds->ds_dlm->dlm_static_oc && is_entry_objectclass( e, ds->ds_dlm->dlm_static_oc, 0 )) {
|
||||
a = attr_find( e->e_attrs, ds->ds_dlm->dlm_member_ad );
|
||||
if ( a ) {
|
||||
rc = dynlist_filter_stgroup( op, f, n, a );
|
||||
rc = dynlist_filter_stgroup( op, n, a );
|
||||
}
|
||||
} else {
|
||||
a = attr_find( e->e_attrs, ds->ds_dli->dli_ad );
|
||||
if ( a ) {
|
||||
rc = dynlist_filter_dyngroup( op, f, n, a );
|
||||
rc = dynlist_filter_dyngroup( op, n, a );
|
||||
}
|
||||
}
|
||||
overlay_entry_release_ov( op, e, 0, on );
|
||||
if ( dyn->dy_subs && !rc ) {
|
||||
TAvlnode *ptr;
|
||||
for ( ptr = tavl_end( dyn->dy_subs, TAVL_DIR_LEFT ); ptr;
|
||||
ptr = tavl_next( ptr, TAVL_DIR_RIGHT )) {
|
||||
dyn = ptr->avl_data;
|
||||
rc = dynlist_filter_group( op, dyn, n, ds );
|
||||
if ( rc )
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1076,8 +1289,12 @@ dynlist_filter_dup( Operation *op, Filter *f, AttributeDescription *ad, dynlist_
|
|||
break;
|
||||
|
||||
case LDAP_FILTER_EQUALITY:
|
||||
if ( f->f_av_desc == ad && !dynlist_filter_group( op, f, n, ds ))
|
||||
break;
|
||||
n->f_choice = SLAPD_FILTER_COMPUTED;
|
||||
if ( f->f_av_desc == ad ) {
|
||||
dynlist_name_t *dyn = tavl_find( ds->ds_names, &f->f_av_value, dynlist_avl_cmp );
|
||||
if ( dyn && !dynlist_filter_group( op, dyn, n, ds ))
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case LDAP_FILTER_GE:
|
||||
case LDAP_FILTER_LE:
|
||||
|
|
@ -1155,6 +1372,10 @@ dynlist_search_free( void *ptr )
|
|||
}
|
||||
ldap_free_urldesc( ludp );
|
||||
}
|
||||
if ( dyn->dy_subs )
|
||||
tavl_free( dyn->dy_subs, NULL );
|
||||
if ( dyn->dy_sups )
|
||||
tavl_free( dyn->dy_sups, NULL );
|
||||
ch_free( ptr );
|
||||
}
|
||||
|
||||
|
|
@ -1166,6 +1387,8 @@ dynlist_search_cleanup( Operation *op, SlapReply *rs )
|
|||
slap_callback *sc = op->o_callback;
|
||||
dynlist_search_t *ds = op->o_callback->sc_private;
|
||||
tavl_free( ds->ds_names, dynlist_search_free );
|
||||
if ( ds->ds_fnodes )
|
||||
tavl_free( ds->ds_fnodes, NULL );
|
||||
if ( ds->ds_origfilter ) {
|
||||
op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
|
||||
dynlist_filter_free( op, op->ors_filter );
|
||||
|
|
@ -1180,7 +1403,7 @@ dynlist_search_cleanup( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
static int
|
||||
dynlist_testurl(Operation *op, dynlist_name_t *dyn, Entry *e)
|
||||
dynlist_test_membership(Operation *op, dynlist_name_t *dyn, Entry *e)
|
||||
{
|
||||
LDAPURLDesc *ludp;
|
||||
struct berval nbase, bv;
|
||||
|
|
@ -1233,6 +1456,52 @@ dynlist_testurl(Operation *op, dynlist_name_t *dyn, Entry *e)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
dynlist_add_memberOf(Operation *op, SlapReply *rs, dynlist_search_t *ds)
|
||||
{
|
||||
TAvlnode *ptr;
|
||||
Entry *e = rs->sr_entry;
|
||||
dynlist_name_t *dyn;
|
||||
Attribute *a;
|
||||
|
||||
/* See if there are any memberOf values to attach to this entry */
|
||||
for ( ptr = tavl_end( ds->ds_names, TAVL_DIR_LEFT ); ptr;
|
||||
ptr = tavl_next( ptr, TAVL_DIR_RIGHT )) {
|
||||
dynlist_map_t *dlm;
|
||||
dyn = ptr->avl_data;
|
||||
for ( dlm = dyn->dy_dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
|
||||
if ( dlm->dlm_memberOf_ad ) {
|
||||
if ( dynlist_test_membership( op, dyn, e ) == LDAP_COMPARE_TRUE ) {
|
||||
/* ensure e is modifiable, but do not replace
|
||||
* sr_entry yet since we have pointers into it */
|
||||
if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) && e == rs->sr_entry ) {
|
||||
e = entry_dup( rs->sr_entry );
|
||||
}
|
||||
a = attr_find( e->e_attrs, dlm->dlm_memberOf_ad );
|
||||
if ( a ) {
|
||||
unsigned slot;
|
||||
if ( attr_valfind( a, SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX |
|
||||
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH |
|
||||
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
|
||||
&dyn->dy_name, &slot, NULL ) != LDAP_SUCCESS )
|
||||
a = NULL;
|
||||
}
|
||||
if ( !a )
|
||||
attr_merge_one( e, dlm->dlm_memberOf_ad, &dyn->dy_name, &dyn->dy_name );
|
||||
if ( dyn->dy_sups ) {
|
||||
dynlist_nested_memberOf( e, dlm->dlm_memberOf_ad, dyn->dy_sups );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( e != rs->sr_entry ) {
|
||||
rs_replace_entry( op, rs, (slap_overinst *)op->o_bd->bd_info, e );
|
||||
rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
|
||||
}
|
||||
}
|
||||
|
||||
/* process the search responses */
|
||||
static int
|
||||
dynlist_search2resp( Operation *op, SlapReply *rs )
|
||||
|
|
@ -1242,52 +1511,24 @@ dynlist_search2resp( Operation *op, SlapReply *rs )
|
|||
int rc;
|
||||
|
||||
if ( rs->sr_type == REP_SEARCH && rs->sr_entry != NULL ) {
|
||||
rc = SLAP_CB_CONTINUE;
|
||||
/* See if this is one of our dynamic entries */
|
||||
dyn = tavl_find( ds->ds_names, &rs->sr_entry->e_nname, dynlist_avl_cmp );
|
||||
if ( dyn ) {
|
||||
Entry *e = rs->sr_entry;
|
||||
dyn->dy_seen = 1;
|
||||
rc = dynlist_prepare_entry( op, rs, dyn->dy_dli );
|
||||
if ( ds->ds_origfilter && test_filter( op, rs->sr_entry, ds->ds_origfilter ) != LDAP_COMPARE_TRUE ) {
|
||||
if ( e != rs->sr_entry )
|
||||
rs_flush_entry( op, rs, NULL );
|
||||
rc = LDAP_SUCCESS;
|
||||
}
|
||||
return rc;
|
||||
} else if ( ds->ds_memberOf ) {
|
||||
TAvlnode *ptr;
|
||||
Entry *e = rs->sr_entry;
|
||||
/* See if there are any memberOf values to attach to this entry */
|
||||
for ( ptr = tavl_end( ds->ds_names, TAVL_DIR_LEFT ); ptr;
|
||||
ptr = tavl_next( ptr, TAVL_DIR_RIGHT )) {
|
||||
dynlist_map_t *dlm;
|
||||
dyn = ptr->avl_data;
|
||||
for ( dlm = dyn->dy_dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
|
||||
if ( dlm->dlm_memberOf_ad ) {
|
||||
if ( dynlist_testurl( op, dyn, e ) == LDAP_COMPARE_TRUE ) {
|
||||
/* ensure e is modifiable, but do not replace
|
||||
* sr_entry yet since we have pointers into it */
|
||||
if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) && e == rs->sr_entry ) {
|
||||
e = entry_dup( rs->sr_entry );
|
||||
}
|
||||
attr_merge_one( e, dlm->dlm_memberOf_ad, &dyn->dy_name, &dyn->dy_name );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( e != rs->sr_entry ) {
|
||||
rs_replace_entry( op, rs, (slap_overinst *)op->o_bd->bd_info, e );
|
||||
rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
|
||||
}
|
||||
if ( ds->ds_origfilter && test_filter( op, rs->sr_entry, ds->ds_origfilter ) != LDAP_COMPARE_TRUE ) {
|
||||
rs_flush_entry( op, rs, NULL );
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
rc = dynlist_prepare_entry( op, rs, dyn->dy_dli, dyn );
|
||||
} else if ( ds->ds_want )
|
||||
dynlist_add_memberOf( op, rs, ds );
|
||||
if ( ds->ds_origfilter && test_filter( op, rs->sr_entry, ds->ds_origfilter ) != LDAP_COMPARE_TRUE ) {
|
||||
rs_flush_entry( op, rs, NULL );
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
return rc;
|
||||
} else if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS ) {
|
||||
TAvlnode *ptr;
|
||||
SlapReply r = *rs;
|
||||
Filter *f = ds->ds_origfilter ? ds->ds_origfilter : op->ors_filter;
|
||||
|
||||
/* Check for any unexpanded dynamic group entries that weren't picked up
|
||||
* by the original search filter.
|
||||
*/
|
||||
|
|
@ -1302,8 +1543,8 @@ dynlist_search2resp( Operation *op, SlapReply *rs )
|
|||
r.sr_entry == NULL )
|
||||
continue;
|
||||
r.sr_flags = REP_ENTRY_MUSTRELEASE;
|
||||
dynlist_prepare_entry( op, &r, dyn->dy_dli );
|
||||
if ( test_filter( op, r.sr_entry, op->ors_filter ) == LDAP_COMPARE_TRUE ) {
|
||||
dynlist_prepare_entry( op, &r, dyn->dy_dli, dyn );
|
||||
if ( test_filter( op, r.sr_entry, f ) == LDAP_COMPARE_TRUE ) {
|
||||
r.sr_attrs = op->ors_attrs;
|
||||
rs->sr_err = send_search_entry( op, &r );
|
||||
if ( rs->sr_err != LDAP_SUCCESS )
|
||||
|
|
@ -1333,6 +1574,79 @@ dynlist_fix_filter( Operation *op, AttributeDescription *ad, dynlist_search_t *d
|
|||
filter2bv_x( op, f, &op->ors_filterstr );
|
||||
}
|
||||
|
||||
typedef struct dynlist_link_t {
|
||||
dynlist_search_t *dl_ds;
|
||||
dynlist_name_t *dl_sup;
|
||||
} dynlist_link_t;
|
||||
|
||||
static int
|
||||
dynlist_nestlink_dg( Operation *op, SlapReply *rs )
|
||||
{
|
||||
dynlist_link_t *dll = op->o_callback->sc_private;
|
||||
dynlist_search_t *ds = dll->dl_ds;
|
||||
dynlist_name_t *di = dll->dl_sup, *dj;
|
||||
|
||||
if ( rs->sr_type != REP_SEARCH )
|
||||
return LDAP_SUCCESS;
|
||||
|
||||
dj = tavl_find( dll->dl_ds->ds_names, &rs->sr_entry->e_nname, dynlist_avl_cmp );
|
||||
if ( dj ) {
|
||||
if ( ds->ds_want & WANT_MEMBEROF ) {
|
||||
tavl_insert( &dj->dy_sups, di, dynlist_ptr_cmp, avl_dup_error );
|
||||
}
|
||||
if ( ds->ds_want & WANT_MEMBER ) {
|
||||
tavl_insert( &di->dy_subs, dj, dynlist_ptr_cmp, avl_dup_error );
|
||||
}
|
||||
}
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
/* Connect all nested groups to their parents/children */
|
||||
static void
|
||||
dynlist_nestlink( Operation *op, dynlist_search_t *ds )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
dynlist_name_t *di, *dj;
|
||||
TAvlnode *ptr;
|
||||
Entry *e;
|
||||
Attribute *a;
|
||||
int i;
|
||||
|
||||
for ( ptr = tavl_end( ds->ds_names, TAVL_DIR_LEFT ); ptr;
|
||||
ptr = tavl_next( ptr, TAVL_DIR_RIGHT )) {
|
||||
di = ptr->avl_data;
|
||||
if ( ds->ds_dlm ) {
|
||||
if ( overlay_entry_get_ov( op, &di->dy_name, NULL, NULL, 0, &e, on ) != LDAP_SUCCESS || e == NULL )
|
||||
continue;
|
||||
a = attr_find( e->e_attrs, ds->ds_dlm->dlm_member_ad );
|
||||
if ( a ) {
|
||||
for ( i=0; i < a->a_numvals; i++ ) {
|
||||
dj = tavl_find( ds->ds_names, &a->a_nvals[i], dynlist_avl_cmp );
|
||||
if ( dj ) {
|
||||
if ( ds->ds_want & WANT_MEMBEROF ) {
|
||||
tavl_insert( &dj->dy_sups, di, dynlist_ptr_cmp, avl_dup_error );
|
||||
}
|
||||
if ( ds->ds_want & WANT_MEMBER ) {
|
||||
tavl_insert( &di->dy_subs, dj, dynlist_ptr_cmp, avl_dup_error );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
overlay_entry_release_ov( op, e, 0, on );
|
||||
}
|
||||
|
||||
if ( di->dy_numuris ) {
|
||||
slap_callback cb = { 0 };
|
||||
dynlist_link_t dll;
|
||||
dll.dl_ds = ds;
|
||||
dll.dl_sup = di;
|
||||
cb.sc_private = &dll;
|
||||
cb.sc_response = dynlist_nestlink_dg;
|
||||
dynlist_urlmembers( op, di, &cb );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dynlist_search( Operation *op, SlapReply *rs )
|
||||
{
|
||||
|
|
@ -1347,7 +1661,9 @@ dynlist_search( Operation *op, SlapReply *rs )
|
|||
|
||||
slap_callback *sc;
|
||||
dynlist_search_t *ds;
|
||||
ObjectClass *static_oc = NULL;
|
||||
ObjectClass *static_oc;
|
||||
int nested, found, tmpwant;
|
||||
int opattrs, userattrs;
|
||||
|
||||
if ( get_manageDSAit( op ) )
|
||||
return SLAP_CB_CONTINUE;
|
||||
|
|
@ -1355,82 +1671,105 @@ dynlist_search( Operation *op, SlapReply *rs )
|
|||
sc = op->o_tmpcalloc( 1, sizeof(slap_callback)+sizeof(dynlist_search_t), op->o_tmpmemctx );
|
||||
sc->sc_private = (void *)(sc+1);
|
||||
ds = sc->sc_private;
|
||||
ds->ds_memberOf = 0;
|
||||
|
||||
o.o_managedsait = SLAP_CONTROL_CRITICAL;
|
||||
|
||||
/* Are we using memberOf, and does it affect this request? */
|
||||
if ( dlg->dlg_memberOf ) {
|
||||
int attrflags = slap_attr_flags( op->ors_attrs );
|
||||
int opattrs = SLAP_OPATTRS( attrflags );
|
||||
int userattrs = SLAP_USERATTRS( attrflags );
|
||||
|
||||
for ( dli = dlg->dlg_dli; dli; dli = dli->dli_next ) {
|
||||
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
|
||||
if ( dlm->dlm_memberOf_ad ) {
|
||||
/* if attribute is in filter, fix it */
|
||||
if ( ad_infilter( dlm->dlm_memberOf_ad, op->ors_filter )) {
|
||||
ds->ds_dli = dli;
|
||||
ds->ds_dlm = dlm;
|
||||
dynlist_fix_filter( op, dlm->dlm_memberOf_ad, ds );
|
||||
}
|
||||
|
||||
/* if attribute is not requested, skip it */
|
||||
if ( op->ors_attrs == NULL ) {
|
||||
if ( is_at_operational( dlm->dlm_memberOf_ad->ad_type ) ) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ( is_at_operational( dlm->dlm_memberOf_ad->ad_type ) ) {
|
||||
if ( !opattrs && !ad_inlist( dlm->dlm_memberOf_ad, op->ors_attrs ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ( !userattrs && !ad_inlist( dlm->dlm_memberOf_ad, op->ors_attrs ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
ds->ds_memberOf = 1;
|
||||
if ( dlm->dlm_static_oc ) {
|
||||
static_oc = dlm->dlm_static_oc;
|
||||
ds->ds_dlm = dlm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( static_oc ) {
|
||||
f[0].f_choice = LDAP_FILTER_OR;
|
||||
f[0].f_list = &f[1];
|
||||
f[0].f_next = NULL;
|
||||
f[1].f_choice = LDAP_FILTER_EQUALITY;
|
||||
f[1].f_ava = &ava[0];
|
||||
f[1].f_av_desc = slap_schema.si_ad_objectClass;
|
||||
f[1].f_next = &f[2];
|
||||
f[2].f_choice = LDAP_FILTER_EQUALITY;
|
||||
f[2].f_ava = &ava[1];
|
||||
f[2].f_av_desc = slap_schema.si_ad_objectClass;
|
||||
f[2].f_next = NULL;
|
||||
} else {
|
||||
f[0].f_choice = LDAP_FILTER_EQUALITY;
|
||||
f[0].f_ava = ava;
|
||||
f[0].f_av_desc = slap_schema.si_ad_objectClass;
|
||||
f[0].f_next = NULL;
|
||||
opattrs = SLAP_OPATTRS( attrflags );
|
||||
userattrs = SLAP_USERATTRS( attrflags );
|
||||
}
|
||||
|
||||
/* Find all groups in scope. For group expansion
|
||||
* we only need the groups within the search scope, but
|
||||
* for memberOf populating, we need all dyngroups.
|
||||
*/
|
||||
for ( dli = dlg->dlg_dli; dli != NULL; dli = dli->dli_next ) {
|
||||
for ( dli = dlg->dlg_dli; dli; dli = dli->dli_next ) {
|
||||
static_oc = NULL;
|
||||
nested = 0;
|
||||
tmpwant = 0;
|
||||
if ( dlg->dlg_memberOf ) {
|
||||
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
|
||||
if ( dlm->dlm_memberOf_ad ) {
|
||||
int want = 0;
|
||||
|
||||
/* with nesting, filter attributes also require nestlink */
|
||||
if ( dlm->dlm_memberOf_nested ) {
|
||||
/* WANT_ flags have inverted meaning here:
|
||||
* to satisfy (memberOf=) filter, we need to also
|
||||
* find all subordinate groups. No special
|
||||
* treatment is needed for (member=) since we
|
||||
* already search all group entries.
|
||||
*/
|
||||
if ( ad_infilter( dlm->dlm_memberOf_ad, op->ors_filter ))
|
||||
want |= WANT_MEMBER;
|
||||
}
|
||||
|
||||
/* if attribute is not requested, skip it */
|
||||
if ( op->ors_attrs == NULL ) {
|
||||
if ( !dlm->dlm_memberOf_oper )
|
||||
want |= WANT_MEMBEROF;
|
||||
if ( dlm->dlm_memberOf_nested && !dlm->dlm_member_oper )
|
||||
want |= WANT_MEMBER;
|
||||
} else {
|
||||
if ( ad_inlist( dlm->dlm_memberOf_ad, op->ors_attrs ))
|
||||
want |= WANT_MEMBEROF;
|
||||
if ( dlm->dlm_memberOf_nested && ad_inlist( dlm->dlm_member_ad, op->ors_attrs )) {
|
||||
want |= WANT_MEMBER;
|
||||
} else {
|
||||
if ( opattrs ) {
|
||||
if ( dlm->dlm_memberOf_oper )
|
||||
want |= WANT_MEMBEROF;
|
||||
if ( dlm->dlm_memberOf_nested && dlm->dlm_member_oper )
|
||||
want |= WANT_MEMBER;
|
||||
}
|
||||
if ( userattrs ) {
|
||||
if ( !dlm->dlm_memberOf_oper )
|
||||
want |= WANT_MEMBEROF;
|
||||
if ( dlm->dlm_memberOf_nested && !dlm->dlm_member_oper )
|
||||
want |= WANT_MEMBER;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( want ) {
|
||||
nested = dlm->dlm_memberOf_nested;
|
||||
ds->ds_want = tmpwant = want;
|
||||
if ( dlm->dlm_static_oc ) {
|
||||
static_oc = dlm->dlm_static_oc;
|
||||
ds->ds_dlm = dlm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( static_oc ) {
|
||||
f[0].f_choice = LDAP_FILTER_OR;
|
||||
f[0].f_list = &f[1];
|
||||
f[0].f_next = NULL;
|
||||
f[1].f_choice = LDAP_FILTER_EQUALITY;
|
||||
f[1].f_next = &f[2];
|
||||
f[1].f_ava = &ava[0];
|
||||
f[1].f_av_desc = slap_schema.si_ad_objectClass;
|
||||
f[1].f_av_value = dli->dli_oc->soc_cname;
|
||||
f[2].f_choice = LDAP_FILTER_EQUALITY;
|
||||
f[2].f_ava = &ava[1];
|
||||
f[2].f_av_desc = slap_schema.si_ad_objectClass;
|
||||
f[2].f_av_value = static_oc->soc_cname;
|
||||
f[2].f_next = NULL;
|
||||
} else {
|
||||
f[0].f_choice = LDAP_FILTER_EQUALITY;
|
||||
f[0].f_ava = ava;
|
||||
f[0].f_av_desc = slap_schema.si_ad_objectClass;
|
||||
f[0].f_av_value = dli->dli_oc->soc_cname;
|
||||
f[0].f_next = NULL;
|
||||
}
|
||||
|
||||
if ( o.o_callback != sc ) {
|
||||
o.o_callback = sc;
|
||||
o.ors_filter = f;
|
||||
if ( ds->ds_memberOf ) {
|
||||
if ( tmpwant ) {
|
||||
o.o_req_dn = op->o_bd->be_suffix[0];
|
||||
o.o_req_ndn = op->o_bd->be_nsuffix[0];
|
||||
o.ors_scope = LDAP_SCOPE_SUBTREE;
|
||||
|
|
@ -1445,22 +1784,20 @@ dynlist_search( Operation *op, SlapReply *rs )
|
|||
BER_BVZERO( &o.ors_filterstr );
|
||||
sc->sc_response = dynlist_search1resp;
|
||||
}
|
||||
|
||||
ds->ds_dli = dli;
|
||||
if ( static_oc ) {
|
||||
f[1].f_av_value = dli->dli_oc->soc_cname;
|
||||
f[2].f_av_value = static_oc->soc_cname;
|
||||
} else {
|
||||
f[0].f_av_value = dli->dli_oc->soc_cname;
|
||||
}
|
||||
if ( o.ors_filterstr.bv_val )
|
||||
o.o_tmpfree( o.ors_filterstr.bv_val, o.o_tmpmemctx );
|
||||
filter2bv_x( &o, f, &o.ors_filterstr );
|
||||
an[0].an_desc = dli->dli_ad;
|
||||
an[0].an_name = dli->dli_ad->ad_cname;
|
||||
found = ds->ds_found;
|
||||
{
|
||||
SlapReply r = { REP_SEARCH };
|
||||
(void)o.o_bd->be_search( &o, &r );
|
||||
}
|
||||
if ( found != ds->ds_found && nested )
|
||||
dynlist_nestlink( op, ds );
|
||||
}
|
||||
|
||||
if ( ds->ds_names != NULL ) {
|
||||
|
|
@ -1468,6 +1805,24 @@ dynlist_search( Operation *op, SlapReply *rs )
|
|||
sc->sc_cleanup = dynlist_search_cleanup;
|
||||
sc->sc_next = op->o_callback;
|
||||
op->o_callback = sc;
|
||||
|
||||
/* see if filter needs fixing */
|
||||
if ( dlg->dlg_memberOf ) {
|
||||
for ( dli = dlg->dlg_dli; dli; dli = dli->dli_next ) {
|
||||
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
|
||||
if ( dlm->dlm_memberOf_ad ) {
|
||||
|
||||
/* if attribute is in filter, fix it */
|
||||
if ( ad_infilter( dlm->dlm_memberOf_ad, op->ors_filter )) {
|
||||
ds->ds_dli = dli;
|
||||
ds->ds_dlm = dlm;
|
||||
dynlist_fix_filter( op, dlm->dlm_memberOf_ad, ds );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
op->o_tmpfree( sc, op->o_tmpmemctx );
|
||||
}
|
||||
|
|
@ -1951,6 +2306,12 @@ done_uri:;
|
|||
dlmp->dlm_memberOf_ad = memberOf_ad;
|
||||
dlmp->dlm_static_oc = static_oc;
|
||||
dlmp->dlm_memberOf_nested = nested;
|
||||
dlmp->dlm_member_oper = is_at_operational( member_ad->ad_type );
|
||||
if ( memberOf_ad ) {
|
||||
dlmp->dlm_memberOf_oper = is_at_operational( memberOf_ad->ad_type );
|
||||
} else {
|
||||
dlmp->dlm_memberOf_oper = 0;
|
||||
}
|
||||
dlmp->dlm_next = NULL;
|
||||
|
||||
if ( dlml != NULL )
|
||||
|
|
|
|||
|
|
@ -386,3 +386,375 @@ dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
|||
dgMemberOf: cn=alumni assoc staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
# Testing nested dynamic group functionality...
|
||||
dn: cn=Dynamic List,ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: groupOfURLs
|
||||
cn: Dynamic List
|
||||
memberURL: ldap:///ou=People,dc=example,dc=com?cn,mail?sub?(objectClass=person
|
||||
)
|
||||
|
||||
dn: cn=Dynamic List of Members,ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: groupOfURLs
|
||||
objectClass: dgIdentityAux
|
||||
cn: Dynamic List of Members
|
||||
memberURL: ldap:///ou=People,dc=example,dc=com??sub?(objectClass=person)
|
||||
dgIdentity: cn=Bjorn Jensen,ou=Information Technology DivisioN,ou=People,dc=ex
|
||||
ample,dc=com
|
||||
dgAuthz: {0}dn:cn=Barbara Jensen,ou=Information Technology DivisioN,ou=People,
|
||||
dc=example,dc=com
|
||||
member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=exam
|
||||
ple,dc=com
|
||||
member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=exampl
|
||||
e,dc=com
|
||||
member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=exa
|
||||
mple,dc=com
|
||||
member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc
|
||||
=com
|
||||
member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
|
||||
dn: ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: organizationalUnit
|
||||
ou: Dynamic Lists
|
||||
|
||||
dn: cn=Meta Group,ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: groupOfURLs
|
||||
cn: Meta Group
|
||||
memberURL: ldap:///ou=Dynamic Lists,dc=example,dc=com??sub?(description=Smith%
|
||||
20family)
|
||||
member: cn=The Smiths,ou=Dynamic Lists,dc=example,dc=com
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
|
||||
dn: cn=The Smiths,ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: groupOfURLs
|
||||
cn: The Smiths
|
||||
memberURL: ldap:///ou=People,dc=example,dc=com??sub?(sn=Smith)
|
||||
description: Smith family
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
dgMemberOf: cn=meta group,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
dn: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Mark Elliot
|
||||
cn: Mark A Elliot
|
||||
sn: Elliot
|
||||
uid: melliot
|
||||
postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
homePostalAddress: 199 Outer Drive $ Ypsilanti, MI 48198
|
||||
homePhone: +1 313 555 0388
|
||||
drink: Gasoline
|
||||
title: Director, UM Alumni Association
|
||||
mail: melliot@mail.alumni.example.com
|
||||
pager: +1 313 555 7671
|
||||
facsimileTelephoneNumber: +1 313 555 7762
|
||||
telephoneNumber: +1 313 555 4177
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
# Testing nested static group functionality...
|
||||
dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
|
||||
dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Barbara Jensen
|
||||
cn: Babs Jensen
|
||||
sn:: IEplbnNlbiA=
|
||||
uid: bjensen
|
||||
title: Mythical Manager, Research Systems
|
||||
postalAddress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Anyt
|
||||
own, MI 48103-4943
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
userPassword:: YmplbnNlbg==
|
||||
mail: bjensen@mailgw.example.com
|
||||
homePostalAddress: 123 Wesley $ Anytown, MI 48103
|
||||
description: Mythical manager of the rsdd unix project
|
||||
drink: water
|
||||
homePhone: +1 313 555 2333
|
||||
pager: +1 313 555 3233
|
||||
facsimileTelephoneNumber: +1 313 555 2274
|
||||
telephoneNumber: +1 313 555 9022
|
||||
dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=the jensens,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=jjs,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc
|
||||
=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Bjorn Jensen
|
||||
cn: Biiff Jensen
|
||||
sn: Jensen
|
||||
uid: bjorn
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
seeAlso: cn=itd staff,ou=groups,dc=example,dc=com
|
||||
userPassword:: Ympvcm4=
|
||||
homePostalAddress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
|
||||
drink: Iced Tea
|
||||
description: Hiker, biker
|
||||
title: Director, Embedded Systems
|
||||
postalAddress: Info Tech Division $ 535 W. William St. $ Anytown, MI 48103
|
||||
mail: bjorn@mailgw.example.com
|
||||
homePhone: +1 313 555 5444
|
||||
pager: +1 313 555 4474
|
||||
facsimileTelephoneNumber: +1 313 555 2177
|
||||
telephoneNumber: +1 313 555 0355
|
||||
dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=the jensens,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=jjs,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Ursula Hampster
|
||||
sn: Hampster
|
||||
uid: uham
|
||||
title: Secretary, UM Alumni Association
|
||||
postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
homePostalAddress: 123 Anystreet $ Anytown, MI 48104
|
||||
mail: uham@mail.alumni.example.com
|
||||
homePhone: +1 313 555 8421
|
||||
pager: +1 313 555 2844
|
||||
facsimileTelephoneNumber: +1 313 555 9700
|
||||
telephoneNumber: +1 313 555 5331
|
||||
dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=bonus group,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=alumni assoc staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=example
|
||||
,dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: James A Jones 2
|
||||
cn: James Jones
|
||||
cn: Jim Jones
|
||||
sn: Doe
|
||||
uid: jjones
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
seeAlso: cn=itd staff,ou=groups,dc=example,dc=com
|
||||
homePostalAddress: 933 Brooks $ Anytown, MI 48104
|
||||
homePhone: +1 313 555 8838
|
||||
title: Senior Manager, Information Technology Division
|
||||
description: Not around very much
|
||||
mail: jjones@mailgw.example.com
|
||||
postalAddress: Info Tech Division $ 535 W William $ Anytown, MI 48103
|
||||
pager: +1 313 555 2833
|
||||
facsimileTelephoneNumber: +1 313 555 8688
|
||||
telephoneNumber: +1 313 555 7334
|
||||
dgMemberOf: cn=jjs,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
dn: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Jane Doe
|
||||
cn: Jane Alverson
|
||||
sn: Doe
|
||||
uid: jdoe
|
||||
title: Programmer Analyst, UM Alumni Association
|
||||
postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
homePostalAddress: 123 Anystreet $ Anytown, MI 48104
|
||||
drink: diet coke
|
||||
description: Enthusiastic
|
||||
mail: jdoe@woof.net
|
||||
homePhone: +1 313 555 5445
|
||||
pager: +1 313 555 1220
|
||||
facsimileTelephoneNumber: +1 313 555 2311
|
||||
telephoneNumber: +1 313 555 4774
|
||||
dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=alumni assoc staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
dn: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: John Doe
|
||||
cn: Jonathon Doe
|
||||
sn: Doe
|
||||
uid: johnd
|
||||
postalAddress: ITD $ 535 W. William $ Anytown, MI 48109
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
seeAlso: cn=itd staff,ou=groups,dc=example,dc=com
|
||||
homePostalAddress: 912 East Bllvd $ Anytown, MI 48104
|
||||
title: System Administrator, Information Technology Division
|
||||
description: overworked!
|
||||
mail: johnd@mailgw.example.com
|
||||
homePhone: +1 313 555 3774
|
||||
pager: +1 313 555 6573
|
||||
facsimileTelephoneNumber: +1 313 555 4544
|
||||
telephoneNumber: +1 313 555 9394
|
||||
dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Jennifer Smith
|
||||
cn: Jen Smith
|
||||
sn: Smith
|
||||
uid: jen
|
||||
postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
drink: Sam Adams
|
||||
homePostalAddress: 1000 Maple #44 $ Anytown, MI 48103
|
||||
title: Telemarketer, UM Alumni Association
|
||||
mail: jen@mail.alumni.example.com
|
||||
homePhone: +1 313 555 2333
|
||||
pager: +1 313 555 6442
|
||||
facsimileTelephoneNumber: +1 313 555 2756
|
||||
telephoneNumber: +1 313 555 8232
|
||||
dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=the smiths,ou=dynamic lists,dc=example,dc=com
|
||||
dgMemberOf: cn=meta group,ou=dynamic lists,dc=example,dc=com
|
||||
dgMemberOf: cn=bonus group,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=alumni assoc staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
# Testing filtered nested memberOf functionality...
|
||||
dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Jennifer Smith
|
||||
cn: Jen Smith
|
||||
sn: Smith
|
||||
uid: jen
|
||||
postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
drink: Sam Adams
|
||||
homePostalAddress: 1000 Maple #44 $ Anytown, MI 48103
|
||||
title: Telemarketer, UM Alumni Association
|
||||
mail: jen@mail.alumni.example.com
|
||||
homePhone: +1 313 555 2333
|
||||
pager: +1 313 555 6442
|
||||
facsimileTelephoneNumber: +1 313 555 2756
|
||||
telephoneNumber: +1 313 555 8232
|
||||
dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=the smiths,ou=dynamic lists,dc=example,dc=com
|
||||
dgMemberOf: cn=meta group,ou=dynamic lists,dc=example,dc=com
|
||||
dgMemberOf: cn=bonus group,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=alumni assoc staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
dn: cn=Meta Group,ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: groupOfURLs
|
||||
cn: Meta Group
|
||||
memberURL: ldap:///ou=Dynamic Lists,dc=example,dc=com??sub?(description=Smith%
|
||||
20family)
|
||||
member: cn=The Smiths,ou=Dynamic Lists,dc=example,dc=com
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
dgMemberOf: cn=bonus group,ou=groups,dc=example,dc=com
|
||||
|
||||
dn: cn=The Smiths,ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: groupOfURLs
|
||||
cn: The Smiths
|
||||
memberURL: ldap:///ou=People,dc=example,dc=com??sub?(sn=Smith)
|
||||
description: Smith family
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
dgMemberOf: cn=meta group,ou=dynamic lists,dc=example,dc=com
|
||||
dgMemberOf: cn=bonus group,ou=groups,dc=example,dc=com
|
||||
|
||||
dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
objectClass: OpenLDAPperson
|
||||
cn: Ursula Hampster
|
||||
sn: Hampster
|
||||
uid: uham
|
||||
title: Secretary, UM Alumni Association
|
||||
postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
|
||||
seeAlso: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
homePostalAddress: 123 Anystreet $ Anytown, MI 48104
|
||||
mail: uham@mail.alumni.example.com
|
||||
homePhone: +1 313 555 8421
|
||||
pager: +1 313 555 2844
|
||||
facsimileTelephoneNumber: +1 313 555 9700
|
||||
telephoneNumber: +1 313 555 5331
|
||||
dgMemberOf: cn=all staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=bonus group,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=alumni assoc staff,ou=groups,dc=example,dc=com
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
# Testing filtered nested member functionality...
|
||||
dn: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
member: cn=Manager,dc=example,dc=com
|
||||
member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=exam
|
||||
ple,dc=com
|
||||
member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc
|
||||
=com
|
||||
member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=exa
|
||||
mple,dc=com
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=exampl
|
||||
e,dc=com
|
||||
owner: cn=Manager,dc=example,dc=com
|
||||
cn: All Staff
|
||||
description: Everyone in the sample data
|
||||
objectClass: groupofnames
|
||||
|
||||
dn: cn=Alumni Assoc Staff,ou=Groups,dc=example,dc=com
|
||||
member: cn=Manager,dc=example,dc=com
|
||||
member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
owner: cn=Manager,dc=example,dc=com
|
||||
description: All Alumni Assoc Staff
|
||||
cn: Alumni Assoc Staff
|
||||
objectClass: groupofnames
|
||||
|
||||
dn: cn=Bonus Group,ou=Groups,dc=example,dc=com
|
||||
objectClass: groupOfNames
|
||||
cn: Bonus Group
|
||||
member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Meta Group,ou=Dynamic Lists,dc=example,dc=com
|
||||
member: cn=The Smiths,ou=Dynamic Lists,dc=example,dc=com
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
|
||||
dn: cn=Dynamic List of Members,ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: groupOfURLs
|
||||
objectClass: dgIdentityAux
|
||||
cn: Dynamic List of Members
|
||||
memberURL: ldap:///ou=People,dc=example,dc=com??sub?(objectClass=person)
|
||||
dgIdentity: cn=Bjorn Jensen,ou=Information Technology DivisioN,ou=People,dc=ex
|
||||
ample,dc=com
|
||||
dgAuthz: {0}dn:cn=Barbara Jensen,ou=Information Technology DivisioN,ou=People,
|
||||
dc=example,dc=com
|
||||
member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=exam
|
||||
ple,dc=com
|
||||
member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=exampl
|
||||
e,dc=com
|
||||
member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=James A Jones 2,ou=Information Technology Division,ou=People,dc=exa
|
||||
mple,dc=com
|
||||
member: cn=Jane Doe,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=John Doe,ou=Information Technology Division,ou=People,dc=example,dc
|
||||
=com
|
||||
member: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
member: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
|
||||
dn: cn=Meta Group,ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: groupOfURLs
|
||||
cn: Meta Group
|
||||
memberURL: ldap:///ou=Dynamic Lists,dc=example,dc=com??sub?(description=Smith%
|
||||
20family)
|
||||
member: cn=The Smiths,ou=Dynamic Lists,dc=example,dc=com
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
dgMemberOf: cn=bonus group,ou=groups,dc=example,dc=com
|
||||
|
||||
dn: cn=The Smiths,ou=Dynamic Lists,dc=example,dc=com
|
||||
objectClass: groupOfURLs
|
||||
cn: The Smiths
|
||||
memberURL: ldap:///ou=People,dc=example,dc=com??sub?(sn=Smith)
|
||||
description: Smith family
|
||||
member: cn=Jennifer Smith,ou=Alumni Association,ou=People,dc=example,dc=com
|
||||
dgMemberOf: cn=meta group,ou=dynamic lists,dc=example,dc=com
|
||||
dgMemberOf: cn=bonus group,ou=groups,dc=example,dc=com
|
||||
|
||||
|
|
|
|||
|
|
@ -763,6 +763,179 @@ if test $RC != 0 ; then
|
|||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Reconfiguring slapd..."
|
||||
$LDAPMODIFY -x -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF > \
|
||||
$TESTOUT 2>&1 << EOMODS
|
||||
version: 1
|
||||
dn: olcOverlay={0}dynlist,olcDatabase={$DBIX}$BACKEND,cn=config
|
||||
changetype: modify
|
||||
delete: olcDynListAttrSet
|
||||
olcDynListAttrSet: {0}
|
||||
-
|
||||
add: olcDynListAttrSet
|
||||
olcDynListAttrSet: groupOfURLs memberURL member+dgMemberOf*
|
||||
-
|
||||
EOMODS
|
||||
|
||||
echo "==========================================================" >> $LOG1
|
||||
|
||||
echo "Adding a couple dynamic groups..."
|
||||
$LDAPADD -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
|
||||
> $TESTOUT 2>&1 << EOMODS
|
||||
dn: cn=The Smiths,$LISTDN
|
||||
objectClass: groupOfURLs
|
||||
cn: The Smiths
|
||||
memberURL: ldap:///ou=People,${BASEDN}??sub?(sn=Smith)
|
||||
description: Smith family
|
||||
|
||||
dn: cn=Meta Group,$LISTDN
|
||||
objectClass: groupOfURLs
|
||||
cn: Meta Group
|
||||
memberURL: ldap:///${LISTDN}??sub?(description=Smith%20family)
|
||||
EOMODS
|
||||
|
||||
echo "Testing nested dynamic group functionality..."
|
||||
echo "# Testing nested dynamic group functionality..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -S "" -b "$LISTDN" -h $LOCALHOST -p $PORT1 \
|
||||
-D "$BABSDN" -w bjensen \
|
||||
'(objectclass=*)' '*' \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
$LDAPSEARCH -S "" -b "ou=People,$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||
-D "$BABSDN" -w bjensen \
|
||||
'(cn=Mark Elliot)' '*' \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Reconfiguring slapd..."
|
||||
$LDAPMODIFY -x -D cn=config -h $LOCALHOST -p $PORT1 -y $CONFIGPWF > \
|
||||
$TESTOUT 2>&1 << EOMODS
|
||||
version: 1
|
||||
dn: olcOverlay={0}dynlist,olcDatabase={$DBIX}$BACKEND,cn=config
|
||||
changetype: modify
|
||||
delete: olcDynListAttrSet
|
||||
olcDynListAttrSet: {0}
|
||||
-
|
||||
add: olcDynListAttrSet
|
||||
olcDynListAttrSet: groupOfURLs memberURL member+dgMemberOf@groupOfNames*
|
||||
olcDynListAttrSet: labeledURIObject labeledURI uniqueMember+seeAlso@groupOfUniqueNames
|
||||
-
|
||||
EOMODS
|
||||
|
||||
echo "==========================================================" >> $LOG1
|
||||
|
||||
echo "Adding a couple static groups..."
|
||||
$LDAPADD -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
|
||||
> $TESTOUT 2>&1 << EOMODS
|
||||
dn: cn=The Jensens,ou=Groups,$BASEDN
|
||||
objectClass: groupOfnames
|
||||
cn: The Jensens
|
||||
member: cn=Bjorn Jensen,ou=Information Technology DivisioN,ou=People,$BASEDN
|
||||
member: cn=Barbara Jensen,ou=Information Technology DivisioN,ou=People,$BASEDN
|
||||
|
||||
dn: cn=JJs,ou=Groups,$BASEDN
|
||||
objectClass: groupOfnames
|
||||
cn: JJs
|
||||
member: cn=James A Jones 1,ou=Alumni Association,ou=People,$BASEDN
|
||||
member: cn=James A Jones 2,ou=Information Technology Division,ou=People,$BASEDN
|
||||
member: cn=The Jensens,ou=Groups,$BASEDN
|
||||
EOMODS
|
||||
|
||||
echo "Testing nested static group functionality..."
|
||||
echo "# Testing nested static group functionality..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -S "" -b "ou=People,$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||
-D "$BABSDN" -w bjensen \
|
||||
'(sn=Jensen)' '*' \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Adding another nested group..."
|
||||
$LDAPADD -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
|
||||
> $TESTOUT 2>&1 << EOMODS
|
||||
dn: cn=Bonus Group,ou=Groups,$BASEDN
|
||||
objectClass: groupOfnames
|
||||
cn: Bonus Group
|
||||
member: cn=Ursula Hampster,ou=Alumni Association,ou=People,$BASEDN
|
||||
member: cn=Meta Group,$LISTDN
|
||||
EOMODS
|
||||
|
||||
$LDAPSEARCH -S "" -b "ou=People,$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||
-D "$BABSDN" -w bjensen \
|
||||
'(sn=Hampster)' '*' \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
$LDAPSEARCH -S "" -b "ou=People,$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||
-D "$BABSDN" -w bjensen \
|
||||
'(sn=Doe)' '*' \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
$LDAPSEARCH -S "" -b "ou=People,$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||
-D "$BABSDN" -w bjensen \
|
||||
'(sn=Smith)' '*' \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Testing filtered nested memberOf functionality..."
|
||||
echo "# Testing filtered nested memberOf functionality..." >> $SEARCHOUT
|
||||
|
||||
$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||
-D "$BABSDN" -w bjensen \
|
||||
"(dgMemberOf=cn=bonus group,ou=groups,$BASEDN)" '*' \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Testing filtered nested member functionality..."
|
||||
echo "# Testing filtered nested member functionality..." >> $SEARCHOUT
|
||||
|
||||
$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||
-D "$BABSDN" -w bjensen \
|
||||
"(member=cn=Jennifer Smith,ou=Alumni Association,ou=People,$BASEDN)" '*' \
|
||||
>> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
|
||||
LDIF=$DYNLISTOUT
|
||||
|
|
|
|||
Loading…
Reference in a new issue