ldap/servers/slapd/dse.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
New commits:
commit ba4b1c6f693cd4b30a061b760fa19921b1eeb79c
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Thu Jan 24 11:02:25 2013 -0500
Ticket 562 - Crash when deleting suffix
Bug Description: If you delete a suffix you can crash the server if
you do not have a backend "userRoot".
Fix Description: Not sure why the nsme userroot needs to be present, maybe
it impacts the callback linked list order, not sure. So
in dse_call_callback we grab the next callback before
calling the callback function. It's possible that one of
these callbacks will unregister other callbacks - potentially
the "next" callback that we already put aside. So it
gets freed, and then its read on the next pass which crashes
the server.
The fix is just to not "pre grab" the next callback, and
wait until after the callback function returns to move on
to the next callback.
Note: this only appears to happen on 32-bit platforms.
https://fedorahosted.org/389/ticket/562
Reviewed by: Ludwig & nkinder(Thanks!)
(cherry picked from commit 6c855a8ce0de3c6b34594856762e68503da433fc)
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
index fd40432..27e71b6 100644
--- a/ldap/servers/slapd/dse.c
+++ b/ldap/servers/slapd/dse.c
@@ -2396,31 +2396,27 @@ dse_call_callback(struct dse* pdse, Slapi_PBlock *pb, int
operation, int flags,
/* ONREPL callbacks can potentially modify pblock parameters like backend
* which would cause problems during request processing. We need to save
* "important" fields before calls and restoring them afterwards */
- int r = SLAPI_DSE_CALLBACK_OK;
+ int rc = SLAPI_DSE_CALLBACK_OK;
+
if (pdse->dse_callback != NULL) {
- struct dse_callback *p;
- p=pdse->dse_callback;
- while (p!=NULL) {
- struct dse_callback *p_next = p->next;
+ struct dse_callback *p = pdse->dse_callback;
+ int result;
+
+ while (p != NULL) {
if ((p->operation & operation) && (p->flags & flags))
{
- if(slapi_sdn_scope_test(slapi_entry_get_sdn_const(entryBefore),
p->base, p->scope))
- {
- if(NULL == p->slapifilter ||
- slapi_vattr_filter_test(pb, entryBefore, p->slapifilter,
- 0 /* !verify access */ )==0)
- {
- int result= (*p->fn)(pb,
entryBefore,entryAfter,returncode,returntext,p->fn_arg);
- if(result<r)
- {
- r= result;
+ if(slapi_sdn_scope_test(slapi_entry_get_sdn_const(entryBefore),
p->base, p->scope)){
+ if(NULL == p->slapifilter || slapi_vattr_filter_test(pb,
entryBefore, p->slapifilter, 0) == 0){
+ result = (*p->fn)(pb,
entryBefore,entryAfter,returncode,returntext,p->fn_arg);
+ if(result < rc){
+ rc = result;
}
- }
+ }
}
}
- p = p_next;
+ p = p->next;
}
}
- return r;
+ return rc;
}
int