[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: (ITS#7249) slapd segfault with memberof overlay on frontend db

This is a multi-part message in MIME format.
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

jvcelak@redhat.com wrote:
>> What happens is that the memberof overlay, when stacked on the frontend
>> database, keeps looping until the stack is exhausted, since internal
>> modifications keep calling the frontend's modify hook rather than the
>> actual one that needs to be called.
> I have no idea how to fix it. I probably do not understand the manipulation
> with BackedInfo structures fully.
> It is obious that it is caused by doing a search from the modrdn operation
> callback memberof_res_modrdn() which is set up in memberof_op_modrdn(). Other
> backends does not call any backend operation at the same moment (op->callback).
> Frontend fe_op_search() is called. It tries to choose the right backend with
> select_backend(). Which returns the overlay backend (bi_type == "over"),
> over_op_walk() then selects fe_op_search() again, and we are looping infinitely.
> I have no clue how to hide or temporarily deactivate the overlay in
> memberof_res_modrdn() to make the select_backend() function to choose the right
> underlaying backend. Or maybe I have choosen a wrong way of fixing it.
> All ideas are welcomed. :-)

The attached diff fixes this particular problem. I haven't spent any time to 
see if the other be_* invocations need to be protected the same way.

   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Content-Type: text/plain; charset=UTF-8;
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;

diff --git a/servers/slapd/overlays/memberof.c b/servers/slapd/overlays/memberof.c
index 502cb46..555d5d9 100644
--- a/servers/slapd/overlays/memberof.c
+++ b/servers/slapd/overlays/memberof.c
@@ -285,7 +285,8 @@ memberof_isGroupOrMember( Operation *op, memberof_cbinfo_t *mci )
 		op2.ors_filterstr = mo->mo_groupFilterstr;
 		op2.ors_filter = &mo->mo_groupFilter;
-		op2.o_bd->bd_info = (BackendInfo *)on->on_info;
+		if (bi->bi_type == memberof.on_bi.bi_type)
+			op2.o_bd->bd_info = (BackendInfo *)on->on_info;
 		(void)op->o_bd->be_search( &op2, &rs2 );
 		op2.o_bd->bd_info = bi;
@@ -307,9 +308,9 @@ memberof_isGroupOrMember( Operation *op, memberof_cbinfo_t *mci )
 		op2.ors_filterstr = mo->mo_memberFilterstr;
 		op2.ors_filter = &mo->mo_memberFilter;
-		op2.o_bd->bd_info = (BackendInfo *)on->on_info;
+		if (bi->bi_type == memberof.on_bi.bi_type)
+			op2.o_bd->bd_info = (BackendInfo *)on->on_info;
 		(void)op->o_bd->be_search( &op2, &rs2 );
-		op2.o_bd->bd_info = bi;
 		if ( mc.foundit ) {
 			iswhat |= MEMBEROF_IS_MEMBER;