mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-31 02:49:28 -05:00
ITS#9121 add dynamic memberOf support for static groups
This commit is contained in:
parent
c7b008eede
commit
9210ed1618
4 changed files with 264 additions and 70 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] ...]
|
||||
The value
|
||||
.B group\-oc
|
||||
is the name of the objectClass that triggers the dynamic expansion of the
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ typedef struct dynlist_map_t {
|
|||
AttributeDescription *dlm_member_ad;
|
||||
AttributeDescription *dlm_mapped_ad;
|
||||
AttributeDescription *dlm_memberOf_ad;
|
||||
ObjectClass *dlm_static_oc;
|
||||
int dlm_memberOf_nested;
|
||||
struct dynlist_map_t *dlm_next;
|
||||
} dynlist_map_t;
|
||||
|
||||
|
|
@ -59,12 +61,12 @@ typedef struct dynlist_info_t {
|
|||
|
||||
typedef struct dynlist_gen_t {
|
||||
dynlist_info_t *dlg_dli;
|
||||
int *dlg_memberOf;
|
||||
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>] ...]\": "
|
||||
"\"dynlist-attrset <oc> [uri] <URL-ad> [[<mapped-ad>:]<member-ad>[+<memberOf-ad>[@<static-oc>[*]] ...]\": "
|
||||
|
||||
static int
|
||||
ad_infilter( AttributeDescription *ad, Filter *f )
|
||||
|
|
@ -136,6 +138,7 @@ dynlist_make_filter( Operation *op, Entry *e, dynlist_info_t *dli, const char *u
|
|||
typedef struct dynlist_sc_t {
|
||||
dynlist_info_t *dlc_dli;
|
||||
Entry *dlc_e;
|
||||
char **dlc_attrs;
|
||||
} dynlist_sc_t;
|
||||
|
||||
static int
|
||||
|
|
@ -170,7 +173,7 @@ dynlist_sc_update( Operation *op, SlapReply *rs )
|
|||
/* if there is only one member_ad, and it's not mapped,
|
||||
* consider it as old-style member listing */
|
||||
dlm = dlc->dlc_dli->dli_dlm;
|
||||
if ( dlm && dlm->dlm_mapped_ad == NULL && dlm->dlm_next == NULL ) {
|
||||
if ( dlm && dlm->dlm_mapped_ad == NULL && dlm->dlm_next == NULL && dlc->dlc_attrs == NULL ) {
|
||||
/* if access allowed, try to add values, emulating permissive
|
||||
* control to silently ignore duplicates */
|
||||
if ( access_allowed( op, rs->sr_entry, slap_schema.si_ad_entry,
|
||||
|
|
@ -526,6 +529,7 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
|
|||
|
||||
BER_BVZERO( &o.ors_attrs[j].an_name );
|
||||
}
|
||||
dlc.dlc_attrs = lud->lud_attrs;
|
||||
|
||||
if ( lud->lud_filter == NULL ) {
|
||||
ber_dupbv_x( &o.ors_filterstr,
|
||||
|
|
@ -797,6 +801,7 @@ release:;
|
|||
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[];
|
||||
|
|
@ -805,6 +810,7 @@ typedef struct dynlist_name_t {
|
|||
typedef struct dynlist_search_t {
|
||||
TAvlnode *ds_names;
|
||||
dynlist_info_t *ds_dli;
|
||||
dynlist_map_t *ds_dlm;
|
||||
Filter *ds_origfilter;
|
||||
struct berval ds_origfilterbv;
|
||||
int ds_memberOf;
|
||||
|
|
@ -828,46 +834,61 @@ dynlist_search1resp( Operation *op, SlapReply *rs )
|
|||
{
|
||||
if ( rs->sr_type == REP_SEARCH && rs->sr_entry != NULL ) {
|
||||
dynlist_search_t *ds = op->o_callback->sc_private;
|
||||
Attribute *a = attr_find( rs->sr_entry->e_attrs, ds->ds_dli->dli_ad );
|
||||
if ( a ) {
|
||||
dynlist_name_t *dyn = ch_calloc(1, sizeof(dynlist_name_t)+rs->sr_entry->e_nname.bv_len + 1+
|
||||
(a->a_numvals * sizeof(LDAPURLDesc *)));
|
||||
Attribute *a, *b = NULL;
|
||||
|
||||
if ( ds->ds_dlm && ds->ds_dlm->dlm_static_oc && is_entry_objectclass( rs->sr_entry, ds->ds_dlm->dlm_static_oc, 0 ))
|
||||
b = attr_find( rs->sr_entry->e_attrs, ds->ds_dlm->dlm_member_ad );
|
||||
a = attr_find( rs->sr_entry->e_attrs, ds->ds_dli->dli_ad );
|
||||
if ( a || b ) {
|
||||
unsigned len;
|
||||
dynlist_name_t *dyn;
|
||||
struct berval bv, nbase;
|
||||
LDAPURLDesc *ludp;
|
||||
int i, j;
|
||||
dyn->dy_name.bv_val = ((char *)(dyn+1)) + (a->a_numvals * sizeof(LDAPURLDesc *));
|
||||
int i, j = 0;
|
||||
|
||||
if ( a )
|
||||
len = a->a_numvals * sizeof(LDAPURLDesc *);
|
||||
else
|
||||
len = 0;
|
||||
|
||||
dyn = ch_calloc(1, sizeof(dynlist_name_t)+rs->sr_entry->e_nname.bv_len + 1 + len);
|
||||
dyn->dy_name.bv_val = ((char *)(dyn+1)) + len;
|
||||
dyn->dy_dli = ds->ds_dli;
|
||||
dyn->dy_name.bv_len = rs->sr_entry->e_nname.bv_len;
|
||||
/* parse and validate the URIs */
|
||||
for (i=0, j=0; i<a->a_numvals; i++) {
|
||||
if (ldap_url_parse( a->a_vals[i].bv_val, &ludp ) != LDAP_URL_SUCCESS )
|
||||
continue;
|
||||
if (( ludp->lud_host && *ludp->lud_host)
|
||||
|| ludp->lud_exts ) {
|
||||
skipit:
|
||||
ldap_free_urldesc( ludp );
|
||||
continue;
|
||||
}
|
||||
ber_str2bv( ludp->lud_dn, 0, 0, &bv );
|
||||
if ( dnNormalize( 0, NULL, NULL, &bv, &nbase, op->o_tmpmemctx ) != LDAP_SUCCESS )
|
||||
goto skipit;
|
||||
ldap_memfree( ludp->lud_dn );
|
||||
ludp->lud_dn = ldap_strdup( nbase.bv_val );
|
||||
op->o_tmpfree( nbase.bv_val, op->o_tmpmemctx );
|
||||
/* cheat here, reuse fields */
|
||||
ludp->lud_port = nbase.bv_len;
|
||||
if ( ludp->lud_filter && *ludp->lud_filter ) {
|
||||
Filter *f = str2filter( ludp->lud_filter );
|
||||
if ( f == NULL )
|
||||
if ( a ) {
|
||||
/* parse and validate the URIs */
|
||||
for (i=0; i<a->a_numvals; i++) {
|
||||
if (ldap_url_parse( a->a_vals[i].bv_val, &ludp ) != LDAP_URL_SUCCESS )
|
||||
continue;
|
||||
if (( ludp->lud_host && *ludp->lud_host)
|
||||
|| ludp->lud_exts ) {
|
||||
skipit:
|
||||
ldap_free_urldesc( ludp );
|
||||
continue;
|
||||
}
|
||||
ber_str2bv( ludp->lud_dn, 0, 0, &bv );
|
||||
if ( dnNormalize( 0, NULL, NULL, &bv, &nbase, op->o_tmpmemctx ) != LDAP_SUCCESS )
|
||||
goto skipit;
|
||||
ldap_memfree( ludp->lud_filter );
|
||||
ludp->lud_filter = (char *)f;
|
||||
ldap_memfree( ludp->lud_dn );
|
||||
ludp->lud_dn = ldap_strdup( nbase.bv_val );
|
||||
op->o_tmpfree( nbase.bv_val, op->o_tmpmemctx );
|
||||
/* cheat here, reuse fields */
|
||||
ludp->lud_port = nbase.bv_len;
|
||||
if ( ludp->lud_filter && *ludp->lud_filter ) {
|
||||
Filter *f = str2filter( ludp->lud_filter );
|
||||
if ( f == NULL )
|
||||
goto skipit;
|
||||
ldap_memfree( ludp->lud_filter );
|
||||
ludp->lud_filter = (char *)f;
|
||||
}
|
||||
dyn->dy_uris[j] = ludp;
|
||||
j++;
|
||||
}
|
||||
dyn->dy_uris[j] = ludp;
|
||||
j++;
|
||||
}
|
||||
dyn->dy_numuris = j;
|
||||
memcpy(dyn->dy_name.bv_val, rs->sr_entry->e_nname.bv_val, rs->sr_entry->e_nname.bv_len );
|
||||
if ( b )
|
||||
dyn->dy_staticmember = ds->ds_dlm->dlm_member_ad;
|
||||
|
||||
if ( tavl_insert( &ds->ds_names, dyn, dynlist_avl_cmp, avl_dup_error )) {
|
||||
for (i=dyn->dy_numuris-1; i>=0; i--) {
|
||||
|
|
@ -885,29 +906,18 @@ skipit:
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* replace a filter clause (memberOf=<groupDN>) with an expansion of
|
||||
* (&(entryDN=<groupURIbase>)<groupURIfilter>)
|
||||
/* replace a filter clause (memberOf=<groupDN>) with an expansion
|
||||
* of its dynamic members
|
||||
* using (&(entryDN=<groupURIbase>)<groupURIfilter>)
|
||||
*/
|
||||
static int
|
||||
dynlist_filter_group( Operation *op, Filter *f, Filter *n, AttributeDescription *uri )
|
||||
dynlist_filter_dyngroup( Operation *op, Filter *f, Filter *n, Attribute *a )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
Entry *e;
|
||||
Attribute *a;
|
||||
Filter *andf = NULL, *dnf, *urif, *orf = NULL;
|
||||
LDAPURLDesc *ludp;
|
||||
struct berval bv, nbase;
|
||||
int i;
|
||||
|
||||
if ( overlay_entry_get_ov( op, &f->f_av_value, NULL, NULL, 0, &e, on ) !=
|
||||
LDAP_SUCCESS || e == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
a = attr_find( e->e_attrs, uri );
|
||||
if ( !a ) {
|
||||
overlay_entry_release_ov( op, e, 0, on );
|
||||
return -1;
|
||||
}
|
||||
for (i=0; i<a->a_numvals; i++) {
|
||||
if ( ldap_url_parse( a->a_vals[i].bv_val, &ludp ) != LDAP_URL_SUCCESS )
|
||||
continue;
|
||||
|
|
@ -951,7 +961,7 @@ dynlist_filter_group( Operation *op, Filter *f, Filter *n, AttributeDescription
|
|||
dnf->f_next = urif;
|
||||
if ( ludp->lud_scope == LDAP_SCOPE_BASE ) {
|
||||
dnf->f_choice = LDAP_FILTER_EQUALITY;
|
||||
dnf->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );
|
||||
dnf->f_ava = op->o_tmpcalloc( 1, sizeof(AttributeAssertion), op->o_tmpmemctx );
|
||||
dnf->f_av_desc = slap_schema.si_ad_entryDN;
|
||||
dnf->f_av_value = nbase;
|
||||
} else {
|
||||
|
|
@ -974,15 +984,78 @@ dynlist_filter_group( Operation *op, Filter *f, Filter *n, AttributeDescription
|
|||
}
|
||||
ldap_free_urldesc( ludp );
|
||||
}
|
||||
overlay_entry_release_ov( op, e, 0, on );
|
||||
if ( !andf )
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Dup the filter, replacing any references to given ad with dyngroup evaluation */
|
||||
/* replace a filter clause (memberOf=<groupDN>) with an expansion
|
||||
* of its static members
|
||||
* using (|(entryDN=<memberN>)[...])
|
||||
*/
|
||||
static int
|
||||
dynlist_filter_stgroup( Operation *op, Filter *f, Filter *n, Attribute *a )
|
||||
{
|
||||
Filter *dnf, *orf;
|
||||
int i;
|
||||
|
||||
if ( a->a_numvals == 1 ) {
|
||||
dnf = n;
|
||||
} else {
|
||||
orf = n;
|
||||
orf->f_choice = LDAP_FILTER_OR;
|
||||
orf->f_next = NULL;
|
||||
dnf = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/* replace a filter clause (memberOf=<groupDN>) with an expansion of
|
||||
* its members.
|
||||
*/
|
||||
static int
|
||||
dynlist_filter_group( Operation *op, Filter *f, 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 ) !=
|
||||
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 );
|
||||
}
|
||||
} else {
|
||||
a = attr_find( e->e_attrs, ds->ds_dli->dli_ad );
|
||||
if ( a ) {
|
||||
rc = dynlist_filter_dyngroup( op, f, n, a );
|
||||
}
|
||||
}
|
||||
overlay_entry_release_ov( op, e, 0, on );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Dup the filter, replacing any references to given ad with group evaluation */
|
||||
static Filter *
|
||||
dynlist_filter_dup( Operation *op, Filter *f, AttributeDescription *ad, AttributeDescription *uri )
|
||||
dynlist_filter_dup( Operation *op, Filter *f, AttributeDescription *ad, dynlist_search_t *ds )
|
||||
{
|
||||
Filter *n = NULL;
|
||||
|
||||
|
|
@ -1003,7 +1076,7 @@ dynlist_filter_dup( Operation *op, Filter *f, AttributeDescription *ad, Attribut
|
|||
break;
|
||||
|
||||
case LDAP_FILTER_EQUALITY:
|
||||
if ( f->f_av_desc == ad && !dynlist_filter_group( op, f, n, uri ))
|
||||
if ( f->f_av_desc == ad && !dynlist_filter_group( op, f, n, ds ))
|
||||
break;
|
||||
/* FALLTHRU */
|
||||
case LDAP_FILTER_GE:
|
||||
|
|
@ -1033,7 +1106,7 @@ dynlist_filter_dup( Operation *op, Filter *f, AttributeDescription *ad, Attribut
|
|||
n->f_choice = f->f_choice;
|
||||
|
||||
for ( p = &n->f_list, f = f->f_list; f; f = f->f_next ) {
|
||||
*p = dynlist_filter_dup( op, f, ad, uri );
|
||||
*p = dynlist_filter_dup( op, f, ad, ds );
|
||||
if ( !*p )
|
||||
continue;
|
||||
p = &(*p)->f_next;
|
||||
|
|
@ -1112,6 +1185,18 @@ dynlist_testurl(Operation *op, dynlist_name_t *dyn, Entry *e)
|
|||
LDAPURLDesc *ludp;
|
||||
struct berval nbase, bv;
|
||||
int i, rc = LDAP_COMPARE_FALSE;
|
||||
if ( dyn->dy_staticmember ) {
|
||||
Entry *grp;
|
||||
if ( overlay_entry_get_ov( op, &dyn->dy_name, NULL, NULL, 0, &grp, (slap_overinst *)op->o_bd->bd_info ) == LDAP_SUCCESS && grp ) {
|
||||
Attribute *a = attr_find( grp->e_attrs, dyn->dy_staticmember );
|
||||
if ( a ) {
|
||||
i = value_find_ex( dyn->dy_staticmember, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
|
||||
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, a->a_nvals, &e->e_nname, op->o_tmpmemctx );
|
||||
}
|
||||
overlay_entry_release_ov( op, grp, 0, (slap_overinst *)op->o_bd->bd_info );
|
||||
return i == LDAP_SUCCESS ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
|
||||
}
|
||||
}
|
||||
for (i=0; i<dyn->dy_numuris; i++) {
|
||||
ludp = dyn->dy_uris[i];
|
||||
nbase.bv_val = ludp->lud_dn;
|
||||
|
|
@ -1236,7 +1321,7 @@ static void
|
|||
dynlist_fix_filter( Operation *op, AttributeDescription *ad, dynlist_search_t *ds )
|
||||
{
|
||||
Filter *f;
|
||||
f = dynlist_filter_dup( op, op->ors_filter, ad, ds->ds_dli->dli_ad );
|
||||
f = dynlist_filter_dup( op, op->ors_filter, ad, ds );
|
||||
if ( ds->ds_origfilter ) {
|
||||
dynlist_filter_free( op, op->ors_filter );
|
||||
op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
|
||||
|
|
@ -1256,12 +1341,13 @@ dynlist_search( Operation *op, SlapReply *rs )
|
|||
dynlist_info_t *dli;
|
||||
Operation o = *op;
|
||||
dynlist_map_t *dlm;
|
||||
Filter f;
|
||||
AttributeAssertion ava;
|
||||
Filter f[3];
|
||||
AttributeAssertion ava[2];
|
||||
AttributeName an[2] = {0};
|
||||
|
||||
slap_callback *sc;
|
||||
dynlist_search_t *ds;
|
||||
ObjectClass *static_oc = NULL;
|
||||
|
||||
if ( get_manageDSAit( op ) )
|
||||
return SLAP_CB_CONTINUE;
|
||||
|
|
@ -1271,10 +1357,6 @@ dynlist_search( Operation *op, SlapReply *rs )
|
|||
ds = sc->sc_private;
|
||||
ds->ds_memberOf = 0;
|
||||
|
||||
f.f_choice = LDAP_FILTER_EQUALITY;
|
||||
f.f_ava = &ava;
|
||||
f.f_av_desc = slap_schema.si_ad_objectClass;
|
||||
f.f_next = NULL;
|
||||
o.o_managedsait = SLAP_CONTROL_CRITICAL;
|
||||
|
||||
/* Are we using memberOf, and does it affect this request? */
|
||||
|
|
@ -1289,6 +1371,7 @@ dynlist_search( Operation *op, SlapReply *rs )
|
|||
/* 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 );
|
||||
}
|
||||
|
||||
|
|
@ -1311,19 +1394,42 @@ dynlist_search( Operation *op, SlapReply *rs )
|
|||
}
|
||||
}
|
||||
ds->ds_memberOf = 1;
|
||||
if ( dlm->dlm_static_oc ) {
|
||||
static_oc = dlm->dlm_static_oc;
|
||||
ds->ds_dlm = dlm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Find all dyngroups in scope. For group expansion
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 ) {
|
||||
if ( o.o_callback != sc ) {
|
||||
o.o_callback = sc;
|
||||
o.ors_filter = &f;
|
||||
o.ors_filter = f;
|
||||
if ( ds->ds_memberOf ) {
|
||||
o.o_req_dn = op->o_bd->be_suffix[0];
|
||||
o.o_req_ndn = op->o_bd->be_nsuffix[0];
|
||||
|
|
@ -1340,10 +1446,15 @@ dynlist_search( Operation *op, SlapReply *rs )
|
|||
sc->sc_response = dynlist_search1resp;
|
||||
}
|
||||
ds->ds_dli = dli;
|
||||
f.f_av_value = dli->dli_oc->soc_cname;
|
||||
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 );
|
||||
filter2bv_x( &o, f, &o.ors_filterstr );
|
||||
an[0].an_desc = dli->dli_ad;
|
||||
an[0].an_name = dli->dli_ad->ad_cname;
|
||||
{
|
||||
|
|
@ -1474,8 +1585,15 @@ dl_cfgen( ConfigArgs *c )
|
|||
ptr = lutil_strcopy( ptr, dlm->dlm_member_ad->ad_cname.bv_val );
|
||||
|
||||
if ( dlm->dlm_memberOf_ad ) {
|
||||
*ptr++ = '@';
|
||||
*ptr++ = '+';
|
||||
ptr = lutil_strcopy( ptr, dlm->dlm_memberOf_ad->ad_cname.bv_val );
|
||||
if ( dlm->dlm_static_oc ) {
|
||||
*ptr++ = '@';
|
||||
ptr = lutil_strcopy( ptr, dlm->dlm_static_oc->soc_cname.bv_val );
|
||||
}
|
||||
if ( dlm->dlm_memberOf_nested ) {
|
||||
*ptr++ = '*';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1747,6 +1865,8 @@ done_uri:;
|
|||
AttributeDescription *member_ad = NULL;
|
||||
AttributeDescription *mapped_ad = NULL;
|
||||
AttributeDescription *memberOf_ad = NULL;
|
||||
ObjectClass *static_oc = NULL;
|
||||
int nested = 0;
|
||||
dynlist_map_t *dlmp;
|
||||
|
||||
|
||||
|
|
@ -1771,8 +1891,29 @@ done_uri:;
|
|||
}
|
||||
arg = cp + 1;
|
||||
}
|
||||
if ( ( cp = strchr( arg, '@' ) ) != NULL ) {
|
||||
if ( ( cp = strchr( arg, '+' ) ) != NULL ) {
|
||||
struct berval bv;
|
||||
char *ocp, *np;
|
||||
np = strrchr( cp+1, '*' );
|
||||
if ( np ) {
|
||||
nested = 1;
|
||||
*np = '\0';
|
||||
}
|
||||
ocp = strchr( cp+1, '@' );
|
||||
if ( ocp ) {
|
||||
static_oc = oc_find( ocp+1 );
|
||||
if ( !static_oc ) {
|
||||
snprintf( c->cr_msg, sizeof( c->cr_msg ),
|
||||
DYNLIST_USAGE
|
||||
"unable to find static-oc ObjectClass #%d \"%s\"\n",
|
||||
i - 3, c->argv[ i ] );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
|
||||
c->log, c->cr_msg );
|
||||
rc = 1;
|
||||
goto done_uri;
|
||||
}
|
||||
*ocp = '\0';
|
||||
}
|
||||
ber_str2bv( cp+1, 0, 0, &bv );
|
||||
rc = slap_bv2ad( &bv, &memberOf_ad, &text );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
|
|
@ -1808,6 +1949,8 @@ done_uri:;
|
|||
dlmp->dlm_member_ad = member_ad;
|
||||
dlmp->dlm_mapped_ad = mapped_ad;
|
||||
dlmp->dlm_memberOf_ad = memberOf_ad;
|
||||
dlmp->dlm_static_oc = static_oc;
|
||||
dlmp->dlm_memberOf_nested = nested;
|
||||
dlmp->dlm_next = NULL;
|
||||
|
||||
if ( dlml != NULL )
|
||||
|
|
|
|||
|
|
@ -365,3 +365,24 @@ facsimileTelephoneNumber: +1 313 555 7762
|
|||
telephoneNumber: +1 313 555 4177
|
||||
dgMemberOf: cn=dynamic list of members,ou=dynamic lists,dc=example,dc=com
|
||||
|
||||
# Testing static group memberOf functionality...
|
||||
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=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
|
||||
|
||||
|
|
|
|||
|
|
@ -702,7 +702,7 @@ delete: olcDynListAttrSet
|
|||
olcDynListAttrSet: {0}
|
||||
-
|
||||
add: olcDynListAttrSet
|
||||
olcDynListAttrSet: groupOfURLs memberURL member@dgMemberOf
|
||||
olcDynListAttrSet: groupOfURLs memberURL member+dgMemberOf
|
||||
-
|
||||
EOMODS
|
||||
|
||||
|
|
@ -733,6 +733,36 @@ if test $RC != 0 ; then
|
|||
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
|
||||
-
|
||||
EOMODS
|
||||
|
||||
echo "==========================================================" >> $LOG1
|
||||
|
||||
echo "Testing static group memberOf functionality..."
|
||||
echo "# Testing static group memberOf functionality..." >> $SEARCHOUT
|
||||
$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
|
||||
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
|
||||
LDIF=$DYNLISTOUT
|
||||
|
|
|
|||
Loading…
Reference in a new issue