Browse Source

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!)
Mark Reynolds 13 years ago
parent
commit
6c855a8ce0
1 changed files with 14 additions and 18 deletions
  1. 14 18
      ldap/servers/slapd/dse.c

+ 14 - 18
ldap/servers/slapd/dse.c

@@ -2408,31 +2408,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