ITS#9929 dynlist: more for prev commit

Was broken if only dynamic lists were configured, and not groups.
Also, optional config URIs were being ignored.
This commit is contained in:
Howard Chu 2022-10-09 15:04:31 +01:00
parent a64320d8ab
commit a3c7e5076a

View File

@ -1522,6 +1522,22 @@ dynlist_add_memberOf(Operation *op, SlapReply *rs, dynlist_search_t *ds)
}
}
static int
dynlist_check_scope( Operation *op, Entry *e, dynlist_info_t *dli )
{
if ( dli->dli_lud ) {
if ( !BER_BVISNULL( &dli->dli_uri_nbase ) &&
!dnIsSuffixScope( &e->e_nname,
&dli->dli_uri_nbase,
dli->dli_lud->lud_scope ))
return 0;
if ( dli->dli_uri_filter && test_filter( op, e,
dli->dli_uri_filter ) != LDAP_COMPARE_TRUE )
return 0;
}
return 1;
}
/* process the search responses */
static int
dynlist_search2resp( Operation *op, SlapReply *rs )
@ -1533,12 +1549,25 @@ dynlist_search2resp( Operation *op, SlapReply *rs )
if ( rs->sr_type == REP_SEARCH && rs->sr_entry != NULL ) {
rc = SLAP_CB_CONTINUE;
/* See if this is one of our dynamic entries */
dyn = ldap_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, dyn );
} else if ( ds->ds_want )
dynlist_add_memberOf( op, rs, ds );
if ( ds->ds_names ) {
dyn = ldap_tavl_find( ds->ds_names, &rs->sr_entry->e_nname, dynlist_avl_cmp );
if ( dyn ) {
dyn->dy_seen = 1;
if ( dynlist_check_scope( op, rs->sr_entry, dyn->dy_dli ))
rc = dynlist_prepare_entry( op, rs, dyn->dy_dli, dyn );
} else if ( ds->ds_want )
dynlist_add_memberOf( op, rs, ds );
} else {
dynlist_info_t *dli;
Attribute *a = attr_find ( rs->sr_entry->e_attrs, slap_schema.si_ad_objectClass );
if ( a ) {
for ( dli = ds->ds_dli; dli; dli = dli->dli_next ) {
if ( is_entry_objectclass_or_sub( rs->sr_entry, dli->dli_oc ) &&
dynlist_check_scope( op, rs->sr_entry, dli ))
rc = dynlist_prepare_entry( op, rs, dli, NULL );
}
}
}
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;
@ -1566,15 +1595,18 @@ 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, 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 )
break;
} else {
rs_flush_entry( op, &r, NULL );
if ( dynlist_check_scope( op, r.sr_entry, dyn->dy_dli )) {
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 )
break;
r.sr_entry = NULL;
}
}
if ( r.sr_entry )
rs_flush_entry( op, &r, NULL );
}
rs->sr_nentries = r.sr_nentries;
}
@ -1721,7 +1753,7 @@ dynlist_search( Operation *op, SlapReply *rs )
continue;
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
if ( dlm->dlm_mapped_ad ) {
if ( dlm->dlm_mapped_ad || !dlm->dlm_member_ad ) {
got_dn = 0;
break;
}
@ -1781,75 +1813,83 @@ dynlist_search( Operation *op, SlapReply *rs )
ds->ds_dlm = dlm;
}
}
} else {
if ( ad_infilter( dlm->dlm_member_ad, op->ors_filter ) ||
userattrs || ad_inlist( dlm->dlm_member_ad, op->ors_attrs )) {
ds->ds_want = tmpwant = WANT_MEMBER;
}
}
}
}
if ( !got_dn )
continue;
if ( got_dn ) {
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 ( 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;
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 {
o.o_req_dn = op->o_req_dn;
o.o_req_ndn = op->o_req_ndn;
o.ors_scope = op->ors_scope;
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;
}
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;
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 ( o.o_callback != sc ) {
o.o_callback = sc;
o.ors_filter = f;
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;
} else {
o.o_req_dn = op->o_req_dn;
o.o_req_ndn = op->o_req_ndn;
o.ors_scope = op->ors_scope;
}
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;
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 ( found != ds->ds_found && nested )
dynlist_nestlink( op, ds );
}
if ( ds->ds_names != NULL ) {
if ( dlg->dlg_dli || 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;
/* dynamic lists need this */
ds->ds_dli = dlg->dlg_dli;
/* see if filter needs fixing */
if ( dlg->dlg_memberOf ) {
for ( dli = dlg->dlg_dli; dli; dli = dli->dli_next ) {