mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-25 00:59:45 -05:00
ITS#9121 dynlist enhancements
1) allow filtering on dynamic attribute values 2) populate an optionally configured memberOf attribute test044 script still needs to be extended to test these enhancements. We need to define an interim attributeType for testing memberOf functionality.
This commit is contained in:
parent
44a7b4632e
commit
90b0abd894
4 changed files with 300 additions and 32 deletions
|
|
@ -19,17 +19,11 @@ of the attributes listed in the URI are added to the original
|
|||
entry.
|
||||
No recursion is allowed, to avoid potential infinite loops.
|
||||
|
||||
Since the resulting entry is dynamically constructed,
|
||||
it does not exist until it is constructed while being returned.
|
||||
As a consequence, dynamically added attributes do not participate
|
||||
in the filter matching phase of the search request handling.
|
||||
In other words, \fIfiltering for dynamically added attributes always fails\fP.
|
||||
|
||||
The resulting entry must comply with the LDAP data model, so constraints
|
||||
are enforced.
|
||||
For example, if a \fISINGLE\-VALUE\fP attribute is listed,
|
||||
only the first value found during the list expansion appears in the final entry.
|
||||
The above described behavior is disabled when the \fImanageDSAit\fP
|
||||
All dynamic behavior is disabled when the \fImanageDSAit\fP
|
||||
control (RFC 3296) is used.
|
||||
In that case, the contents of the dynamic group entry is returned;
|
||||
namely, the URLs are returned instead of being expanded.
|
||||
|
|
@ -57,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> ...]
|
||||
.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
|
||||
|
|
@ -96,6 +90,10 @@ of the URI were present in the
|
|||
entry as values of the
|
||||
.B member-ad
|
||||
attribute.
|
||||
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.
|
||||
|
||||
Alternatively,
|
||||
.B mapped-ad
|
||||
|
|
@ -103,7 +101,9 @@ can be used to remap attributes obtained through expansion.
|
|||
.B member-ad
|
||||
attributes are not filled by expanded DN, but are remapped as
|
||||
.B mapped-ad
|
||||
attributes. Multiple mapping statements can be used.
|
||||
attributes. Multiple mapping statements can be used. The
|
||||
.B memberOf-ad
|
||||
option is not used in this case.
|
||||
|
||||
.LP
|
||||
The dynlist overlay may be used with any backend, but it is mainly
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ static AttributeDescription *ad_dgIdentity, *ad_dgAuthz;
|
|||
typedef struct dynlist_map_t {
|
||||
AttributeDescription *dlm_member_ad;
|
||||
AttributeDescription *dlm_mapped_ad;
|
||||
AttributeDescription *dlm_memberOf_ad;
|
||||
struct dynlist_map_t *dlm_next;
|
||||
} dynlist_map_t;
|
||||
|
||||
|
|
@ -57,7 +58,7 @@ typedef struct dynlist_info_t {
|
|||
} dynlist_info_t;
|
||||
|
||||
#define DYNLIST_USAGE \
|
||||
"\"dynlist-attrset <oc> [uri] <URL-ad> [[<mapped-ad>:]<member-ad> ...]\": "
|
||||
"\"dynlist-attrset <oc> [uri] <URL-ad> [[<mapped-ad>:]<member-ad>[@<memberOf-ad>] ...]\": "
|
||||
|
||||
static dynlist_info_t *
|
||||
dynlist_is_dynlist_next( Operation *op, SlapReply *rs, dynlist_info_t *old_dli )
|
||||
|
|
@ -113,10 +114,9 @@ dynlist_is_dynlist_next( Operation *op, SlapReply *rs, dynlist_info_t *old_dli )
|
|||
}
|
||||
|
||||
static int
|
||||
dynlist_make_filter( Operation *op, Entry *e, const char *url, struct berval *oldf, struct berval *newf )
|
||||
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;
|
||||
dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private;
|
||||
|
||||
char *ptr;
|
||||
int needBrackets = 0;
|
||||
|
|
@ -549,7 +549,7 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
|
|||
} else {
|
||||
struct berval flt;
|
||||
ber_str2bv( lud->lud_filter, 0, 0, &flt );
|
||||
if ( dynlist_make_filter( op, rs->sr_entry, url->bv_val, &flt, &o.ors_filterstr ) ) {
|
||||
if ( dynlist_make_filter( op, rs->sr_entry, dli, url->bv_val, &flt, &o.ors_filterstr ) ) {
|
||||
/* error */
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -563,6 +563,7 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
|
|||
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 );
|
||||
}
|
||||
|
||||
|
|
@ -636,11 +637,20 @@ dynlist_compare( Operation *op, SlapReply *rs )
|
|||
Entry *e = NULL;
|
||||
dynlist_map_t *dlm;
|
||||
BackendDB *be;
|
||||
int ret = SLAP_CB_CONTINUE;
|
||||
|
||||
if ( get_manageDSAit( op ) )
|
||||
return SLAP_CB_CONTINUE;
|
||||
|
||||
for ( ; dli != NULL; dli = dli->dli_next ) {
|
||||
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next )
|
||||
if ( op->oq_compare.rs_ava->aa_desc == dlm->dlm_member_ad )
|
||||
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
|
||||
AttributeDescription *ad = dlm->dlm_mapped_ad ? dlm->dlm_mapped_ad : dlm->dlm_member_ad;
|
||||
/* builtin dyngroup evaluator only works for DNs */
|
||||
if ( ad->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName )
|
||||
continue;
|
||||
if ( op->oq_compare.rs_ava->aa_desc == ad )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( dlm ) {
|
||||
/* This compare is for one of the attributes we're
|
||||
|
|
@ -696,7 +706,8 @@ dynlist_compare( Operation *op, SlapReply *rs )
|
|||
done:;
|
||||
if ( id ) ber_bvarray_free_x( id, o.o_tmpmemctx );
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
send_ldap_result( op, rs );
|
||||
return rs->sr_err;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -746,12 +757,8 @@ done:;
|
|||
/* generate dynamic list with dynlist_response() and compare */
|
||||
{
|
||||
SlapReply r = { REP_SEARCH };
|
||||
dynlist_cc_t dc = { { 0, dynlist_sc_compare_entry, 0, 0 }, 0 };
|
||||
AttributeName an[2];
|
||||
|
||||
dc.dc_ava = op->orc_ava;
|
||||
dc.dc_res = &rs->sr_err;
|
||||
o.o_callback = (slap_callback *) &dc;
|
||||
Attribute *a;
|
||||
AttributeName an[2];
|
||||
|
||||
o.o_tag = LDAP_REQ_SEARCH;
|
||||
o.ors_limit = NULL;
|
||||
|
|
@ -768,15 +775,29 @@ done:;
|
|||
BER_BVZERO( &an[1].an_name );
|
||||
o.ors_attrs = an;
|
||||
o.ors_attrsonly = 0;
|
||||
r.sr_entry = e;
|
||||
r.sr_attrs = an;
|
||||
|
||||
o.o_acl_priv = ACL_COMPARE;
|
||||
dynlist_prepare_entry( &o, &r, dli );
|
||||
a = attrs_find( r.sr_entry->e_attrs, op->orc_ava->aa_desc );
|
||||
|
||||
o.o_bd = be;
|
||||
(void)be->be_search( &o, &r );
|
||||
|
||||
if ( o.o_dn.bv_val != op->o_dn.bv_val ) {
|
||||
slap_op_groups_free( &o );
|
||||
ret = LDAP_NO_SUCH_ATTRIBUTE;
|
||||
for ( ; a ; a = attrs_find( a->a_next, op->orc_ava->aa_desc )) {
|
||||
ret = LDAP_COMPARE_FALSE;
|
||||
if ( attr_valfind( a,
|
||||
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
|
||||
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
|
||||
&op->orc_ava->aa_value, NULL, op->o_tmpmemctx ) == LDAP_SUCCESS ) {
|
||||
ret = LDAP_COMPARE_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rs->sr_err = ret;
|
||||
|
||||
if ( r.sr_entry != e )
|
||||
entry_free( r.sr_entry );
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
|
||||
release:;
|
||||
|
|
@ -784,9 +805,225 @@ release:;
|
|||
overlay_entry_release_ov( &o, e, 0, on );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ad_infilter( Filter *f, AttributeDescription *ad )
|
||||
{
|
||||
if ( !f )
|
||||
return 0;
|
||||
|
||||
switch( f->f_choice & SLAPD_FILTER_MASK ) {
|
||||
case SLAPD_FILTER_COMPUTED:
|
||||
return 0;
|
||||
case LDAP_FILTER_PRESENT:
|
||||
return f->f_desc == ad;
|
||||
case LDAP_FILTER_EQUALITY:
|
||||
case LDAP_FILTER_GE:
|
||||
case LDAP_FILTER_LE:
|
||||
case LDAP_FILTER_APPROX:
|
||||
case LDAP_FILTER_SUBSTRINGS:
|
||||
case LDAP_FILTER_EXT:
|
||||
return f->f_av_desc == ad;
|
||||
case LDAP_FILTER_AND:
|
||||
case LDAP_FILTER_OR:
|
||||
case LDAP_FILTER_NOT: {
|
||||
int ret = 0;
|
||||
for ( f = f->f_list; f; f = f->f_next )
|
||||
ret |= ad_infilter( f, ad );
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct dynlist_name_t {
|
||||
struct berval dy_name;
|
||||
dynlist_info_t *dy_dli;
|
||||
int dy_seen;
|
||||
} dynlist_name_t;
|
||||
|
||||
typedef struct dynlist_search_t {
|
||||
TAvlnode *ds_names;
|
||||
dynlist_info_t *ds_dli;
|
||||
} dynlist_search_t;
|
||||
|
||||
static int
|
||||
dynlist_avl_cmp( const void *c1, const void *c2 )
|
||||
{
|
||||
const dynlist_name_t *n1, *n2;
|
||||
int rc;
|
||||
n1 = c1; n2 = c2;
|
||||
|
||||
rc = n1->dy_name.bv_len - n2->dy_name.bv_len;
|
||||
if ( rc ) return rc;
|
||||
return ber_bvcmp( &n1->dy_name, &n2->dy_name );
|
||||
}
|
||||
|
||||
/* build a list of dynamic entries */
|
||||
static int
|
||||
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;
|
||||
dynlist_name_t *dyn = ch_calloc(1, sizeof(dynlist_name_t)+rs->sr_entry->e_nname.bv_len + 1);
|
||||
dyn->dy_name.bv_val = (void *)(dyn+1);
|
||||
dyn->dy_dli = ds->ds_dli;
|
||||
dyn->dy_name.bv_len = rs->sr_entry->e_nname.bv_len;
|
||||
memcpy(dyn->dy_name.bv_val, rs->sr_entry->e_nname.bv_val, rs->sr_entry->e_nname.bv_len );
|
||||
if ( tavl_insert( &ds->ds_names, dyn, dynlist_avl_cmp, avl_dup_error ))
|
||||
ch_free( dyn );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dynlist_search_cleanup( Operation *op, SlapReply *rs )
|
||||
{
|
||||
if ( rs->sr_type == REP_RESULT || op->o_abandon ||
|
||||
rs->sr_err == SLAPD_ABANDON ) {
|
||||
slap_callback *sc = op->o_callback;
|
||||
dynlist_search_t *ds = op->o_callback->sc_private;
|
||||
tavl_free( ds->ds_names, ch_free );
|
||||
op->o_callback = sc->sc_next;
|
||||
op->o_tmpfree( sc, op->o_tmpmemctx );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* process the search responses */
|
||||
static int
|
||||
dynlist_search2resp( Operation *op, SlapReply *rs )
|
||||
{
|
||||
dynlist_search_t *ds = op->o_callback->sc_private;
|
||||
dynlist_name_t *dyn;
|
||||
int rc;
|
||||
|
||||
if ( rs->sr_type == REP_SEARCH && rs->sr_entry != NULL ) {
|
||||
dyn = tavl_find( ds->ds_names, &rs->sr_entry->e_nname, dynlist_avl_cmp );
|
||||
if ( dyn ) {
|
||||
dyn->dy_seen = 1;
|
||||
rc = dynlist_prepare_entry( op, rs, dyn->dy_dli );
|
||||
return rc;
|
||||
} else {
|
||||
TAvlnode *ptr;
|
||||
Entry *e = rs->sr_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 ) {
|
||||
rc = backend_group( op, NULL, &dyn->dy_name,
|
||||
&e->e_nname, dyn->dy_dli->dli_oc, dyn->dy_dli->dli_ad );
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
/* 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 = entry_dup( rs->sr_entry );
|
||||
}
|
||||
attr_merge_one( e, dlm->dlm_memberOf_ad, &dyn->dy_name, &dyn->dy_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else if ( rs->sr_type == REP_RESULT ) {
|
||||
TAvlnode *ptr;
|
||||
SlapReply r = *rs;
|
||||
for ( ptr = tavl_end( ds->ds_names, TAVL_DIR_LEFT ); ptr;
|
||||
ptr = tavl_next( ptr, TAVL_DIR_RIGHT )) {
|
||||
dyn = ptr->avl_data;
|
||||
if ( dyn->dy_seen )
|
||||
continue;
|
||||
if ( !dnIsSuffixScope( &dyn->dy_name, &op->o_req_ndn, op->ors_scope ))
|
||||
continue;
|
||||
if ( overlay_entry_get_ov( op, &dyn->dy_name, NULL, NULL, 0, &r.sr_entry, (slap_overinst *)op->o_bd->bd_info ) != LDAP_SUCCESS ||
|
||||
r.sr_entry == NULL )
|
||||
continue;
|
||||
r.sr_flags = REP_ENTRY_MUSTRELEASE;
|
||||
dynlist_prepare_entry( op, &r, dyn->dy_dli );
|
||||
send_search_entry( op, &r );
|
||||
}
|
||||
rs->sr_nentries = r.sr_nentries;
|
||||
}
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
dynlist_search( Operation *op, SlapReply *rs )
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private;
|
||||
Operation o = *op;
|
||||
dynlist_map_t *dlm;
|
||||
Filter f;
|
||||
AttributeAssertion ava;
|
||||
AttributeName an[2] = {0};
|
||||
|
||||
slap_callback *sc;
|
||||
dynlist_search_t *ds;
|
||||
|
||||
if ( get_manageDSAit( op ) )
|
||||
return SLAP_CB_CONTINUE;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/* Find all dyngroups in tree. For group expansion
|
||||
* we only need the groups within the search scope, but
|
||||
* for memberOf populating, we need all dyngroups.
|
||||
*/
|
||||
for ( ; dli != NULL; dli = dli->dli_next ) {
|
||||
if ( o.o_callback != sc ) {
|
||||
o.o_callback = sc;
|
||||
o.ors_filter = &f;
|
||||
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;
|
||||
o.ors_attrsonly = 0;
|
||||
o.ors_attrs = an;
|
||||
o.o_bd = select_backend( op->o_bd->be_nsuffix, 1 );
|
||||
BER_BVZERO( &o.ors_filterstr );
|
||||
sc->sc_response = dynlist_search1resp;
|
||||
}
|
||||
ds->ds_dli = dli;
|
||||
f.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;
|
||||
{
|
||||
SlapReply r = { REP_SEARCH };
|
||||
(void)o.o_bd->be_search( &o, &r );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ds->ds_names != NULL ) {
|
||||
sc->sc_response = dynlist_search2resp;
|
||||
sc->sc_cleanup = dynlist_search_cleanup;
|
||||
sc->sc_next = op->o_callback;
|
||||
op->o_callback = sc;
|
||||
} else {
|
||||
op->o_tmpfree( sc, op->o_tmpmemctx );
|
||||
}
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
dynlist_response( Operation *op, SlapReply *rs )
|
||||
{
|
||||
|
|
@ -824,6 +1061,7 @@ dynlist_response( Operation *op, SlapReply *rs )
|
|||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
dynlist_build_def_filter( dynlist_info_t *dli )
|
||||
|
|
@ -933,6 +1171,11 @@ dl_cfgen( ConfigArgs *c )
|
|||
}
|
||||
|
||||
ptr = lutil_strcopy( ptr, dlm->dlm_member_ad->ad_cname.bv_val );
|
||||
|
||||
if ( dlm->dlm_memberOf_ad ) {
|
||||
*ptr++ = '@';
|
||||
ptr = lutil_strcopy( ptr, dlm->dlm_memberOf_ad->ad_cname.bv_val );
|
||||
}
|
||||
}
|
||||
|
||||
bv.bv_val = c->cr_msg;
|
||||
|
|
@ -1199,6 +1442,7 @@ done_uri:;
|
|||
char *cp;
|
||||
AttributeDescription *member_ad = NULL;
|
||||
AttributeDescription *mapped_ad = NULL;
|
||||
AttributeDescription *memberOf_ad = NULL;
|
||||
dynlist_map_t *dlmp;
|
||||
|
||||
|
||||
|
|
@ -1223,6 +1467,22 @@ done_uri:;
|
|||
}
|
||||
arg = cp + 1;
|
||||
}
|
||||
if ( ( cp = strchr( arg, '@' ) ) != NULL ) {
|
||||
struct berval bv;
|
||||
ber_str2bv( cp+1, 0, 0, &bv );
|
||||
rc = slap_bv2ad( &bv, &memberOf_ad, &text );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
snprintf( c->cr_msg, sizeof( c->cr_msg ),
|
||||
DYNLIST_USAGE
|
||||
"unable to find memberOf AttributeDescription #%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;
|
||||
}
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
rc = slap_str2ad( arg, &member_ad, &text );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
|
|
@ -1242,6 +1502,7 @@ done_uri:;
|
|||
}
|
||||
dlmp->dlm_member_ad = member_ad;
|
||||
dlmp->dlm_mapped_ad = mapped_ad;
|
||||
dlmp->dlm_memberOf_ad = memberOf_ad;
|
||||
dlmp->dlm_next = NULL;
|
||||
|
||||
if ( dlml != NULL )
|
||||
|
|
@ -1550,7 +1811,8 @@ dynlist_initialize(void)
|
|||
dynlist.on_bi.bi_db_open = dynlist_db_open;
|
||||
dynlist.on_bi.bi_db_destroy = dynlist_db_destroy;
|
||||
|
||||
dynlist.on_response = dynlist_response;
|
||||
dynlist.on_bi.bi_op_search = dynlist_search;
|
||||
dynlist.on_bi.bi_op_compare = dynlist_compare;
|
||||
|
||||
dynlist.on_bi.bi_cf_ocs = dlocs;
|
||||
|
||||
|
|
|
|||
|
|
@ -204,8 +204,9 @@ FALSE
|
|||
# Testing list compare (should return FALSE)...
|
||||
FALSE
|
||||
|
||||
# Testing list compare with manageDSAit...
|
||||
FALSE
|
||||
# Testing list compare with manageDSAit (should return UNDEFINED)...
|
||||
Compare Result: No such attribute (16)
|
||||
UNDEFINED
|
||||
|
||||
# Testing list search without dgIdentity...
|
||||
dn: cn=Dynamic List of Members,ou=Dynamic Lists,dc=example,dc=com
|
||||
|
|
|
|||
|
|
@ -526,8 +526,8 @@ case $RC in
|
|||
esac
|
||||
echo "" >> $SEARCHOUT
|
||||
|
||||
echo "Testing list compare with manageDSAit..."
|
||||
echo "# Testing list compare with manageDSAit..." >> $SEARCHOUT
|
||||
echo "Testing list compare with manageDSAit (should return UNDEFINED)..."
|
||||
echo "# Testing list compare with manageDSAit (should return UNDEFINED)..." >> $SEARCHOUT
|
||||
$LDAPCOMPARE -h $LOCALHOST -p $PORT1 -MM \
|
||||
"cn=Dynamic List,$LISTDN" "member:$CMPDN" \
|
||||
>> $SEARCHOUT 2>&1
|
||||
|
|
@ -535,12 +535,17 @@ RC=$?
|
|||
case $RC in
|
||||
5)
|
||||
echo "ldapcompare returned FALSE ($RC)"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
6)
|
||||
echo "ldapcompare returned TRUE ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
16|32)
|
||||
echo "ldapcompare returned UNDEFINED ($RC)"
|
||||
;;
|
||||
0)
|
||||
echo "ldapcompare returned success ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
|
|
|
|||
Loading…
Reference in a new issue