Blob Blame Raw
From d9e460db38763e81f1065777dd54f95efd108017 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Thu, 13 Nov 2014 17:22:24 -0500
Subject: [PATCH 48/53] Ticket 47451 - Need to unregister tasks created by
 plugins

Bug Description:  Tasks created by plugins are not unregistered when a plugin
                  is stopped or deleted.  Repeated stopping/starting a plugin
                  that registers tasks will corrupt the dse callback linked list
                  and will crash the server if a task is invoked.

Fix Description:  Create a plugin task unregister function, and call it in the
                  clsoe functions of plugins that register functions.

https://fedorahosted.org/389/ticket/47451

Reviewed by: nhosoi(Thanks!)

(cherry picked from commit 005c4c9be360a7ebba38b61f934ace94224eef3f)
(cherry picked from commit fb7eef1c08a2d15c94eaedaabec2b07e970ffb3a)
---
 ldap/servers/plugins/automember/automember.c          |  8 ++++++++
 ldap/servers/plugins/linkedattrs/linked_attrs.c       |  2 ++
 ldap/servers/plugins/memberof/memberof.c              |  1 +
 .../plugins/posix-winsync/posix-winsync-config.c      |  1 +
 ldap/servers/plugins/schema_reload/schema_reload.c    |  2 ++
 ldap/servers/plugins/usn/usn.c                        |  1 +
 ldap/servers/plugins/usn/usn.h                        |  1 +
 ldap/servers/plugins/usn/usn_cleanup.c                |  8 ++++++++
 ldap/servers/slapd/slapi-plugin.h                     |  1 +
 ldap/servers/slapd/task.c                             | 19 +++++++++++++++++++
 10 files changed, 44 insertions(+)

diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c
index c5bb0ae..c443a65 100644
--- a/ldap/servers/plugins/automember/automember.c
+++ b/ldap/servers/plugins/automember/automember.c
@@ -397,6 +397,14 @@ automember_close(Slapi_PBlock * pb)
     slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
                     "--> automember_close\n");
 
+    /* unregister the tasks */
+    slapi_plugin_task_unregister_handler("automember rebuild membership",
+            automember_task_add);
+    slapi_plugin_task_unregister_handler("automember export updates",
+            automember_task_add_export_updates);
+    slapi_plugin_task_unregister_handler("automember map updates",
+            automember_task_add_map_entries);
+
     automember_delete_config();
     slapi_ch_free((void **)&g_automember_config);
     slapi_sdn_free(&_PluginDN);
diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.c b/ldap/servers/plugins/linkedattrs/linked_attrs.c
index 20bb9fa..e302867 100644
--- a/ldap/servers/plugins/linkedattrs/linked_attrs.c
+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.c
@@ -383,6 +383,8 @@ linked_attrs_close(Slapi_PBlock * pb)
     slapi_log_error(SLAPI_LOG_TRACE, LINK_PLUGIN_SUBSYSTEM,
                     "--> linked_attrs_close\n");
 
+    slapi_plugin_task_unregister_handler("fixup linked attributes", linked_attrs_fixup_task_add);
+
     linked_attrs_delete_config();
     slapi_destroy_rwlock(g_config_lock);
     g_config_lock = NULL;
diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
index ce48f01..cb4ef75 100644
--- a/ldap/servers/plugins/memberof/memberof.c
+++ b/ldap/servers/plugins/memberof/memberof.c
@@ -454,6 +454,7 @@ int memberof_postop_close(Slapi_PBlock *pb)
 	slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
 		     "--> memberof_postop_close\n" );
 
+	slapi_plugin_task_unregister_handler("memberof task", memberof_task_add);
 	memberof_release_config();
 	slapi_sdn_free(&_ConfigAreaDN);
 	slapi_sdn_free(&_pluginDN);
diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync-config.c b/ldap/servers/plugins/posix-winsync/posix-winsync-config.c
index 4234080..50e3a61 100644
--- a/ldap/servers/plugins/posix-winsync/posix-winsync-config.c
+++ b/ldap/servers/plugins/posix-winsync/posix-winsync-config.c
@@ -237,6 +237,7 @@ posix_winsync_config(Slapi_Entry *config_e)
 void
 posix_winsync_config_free()
 {
+    slapi_plugin_task_unregister_handler("memberuid task", posix_group_task_add);
     slapi_entry_free(theConfig.config_e);
     theConfig.config_e = NULL;
     slapi_destroy_mutex(theConfig.lock);
diff --git a/ldap/servers/plugins/schema_reload/schema_reload.c b/ldap/servers/plugins/schema_reload/schema_reload.c
index 6cf1181..3ff4c4d 100644
--- a/ldap/servers/plugins/schema_reload/schema_reload.c
+++ b/ldap/servers/plugins/schema_reload/schema_reload.c
@@ -131,6 +131,8 @@ schemareload_start(Slapi_PBlock *pb)
 static int
 schemareload_close(Slapi_PBlock *pb)
 {
+
+    slapi_plugin_task_unregister_handler("schema reload task", schemareload_add);
     PR_DestroyLock(schemareload_lock);
 
     return 0;
diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c
index 837dc2e..6b34bf4 100644
--- a/ldap/servers/plugins/usn/usn.c
+++ b/ldap/servers/plugins/usn/usn.c
@@ -300,6 +300,7 @@ usn_close(Slapi_PBlock *pb)
 {
     slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "--> usn_close\n");
 
+    usn_cleanup_close();
     slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
             "", LDAP_SCOPE_BASE, "(objectclass=*)", usn_rootdse_search);
 
diff --git a/ldap/servers/plugins/usn/usn.h b/ldap/servers/plugins/usn/usn.h
index 8e6c5c8..4bc9e97 100644
--- a/ldap/servers/plugins/usn/usn.h
+++ b/ldap/servers/plugins/usn/usn.h
@@ -54,4 +54,5 @@ void *usn_get_identity();
 
 /* usn_cleanup.c */
 int usn_cleanup_start(Slapi_PBlock *pb);
+int usn_cleanup_close();
 
diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c
index 2b1371d..c12dfd2 100644
--- a/ldap/servers/plugins/usn/usn_cleanup.c
+++ b/ldap/servers/plugins/usn/usn_cleanup.c
@@ -58,6 +58,14 @@ usn_cleanup_start(Slapi_PBlock *pb)
     return rc;
 }
 
+int
+usn_cleanup_close()
+{
+    int rc = slapi_plugin_task_unregister_handler("USN tombstone cleanup task",
+                                         usn_cleanup_add);
+    return rc;
+}
+
 /*
  * Task thread
  */
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 8ffc582..0ae3601 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6604,6 +6604,7 @@ int slapi_config_remove_callback(int operation, int flags, const char *base, int
 
 int slapi_task_register_handler(const char *name, dseCallbackFn func);
 int slapi_plugin_task_register_handler(const char *name, dseCallbackFn func, Slapi_PBlock *plugin_pb);
+int slapi_plugin_task_unregister_handler(const char *name, dseCallbackFn func);
 void slapi_task_begin(Slapi_Task *task, int total_work);
 void slapi_task_inc_progress(Slapi_Task *task);
 void slapi_task_finish(Slapi_Task *task, int rc);
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 2a0cb82..006ae53 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -461,6 +461,25 @@ int slapi_task_get_refcount(Slapi_Task *task)
 }
 
 int
+slapi_plugin_task_unregister_handler(const char *name, dseCallbackFn func)
+{
+    char *base = NULL;
+    int rc = 0;
+
+    base = slapi_create_dn_string("cn=%s,%s", name, TASK_BASE_DN);
+
+    slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, base,
+                                 LDAP_SCOPE_SUBTREE, "(objectclass=*)", func);
+    slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
+                                 base, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny);
+    slapi_config_remove_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP,
+                                 base, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny);
+    slapi_ch_free_string(&base);
+
+    return rc;
+}
+
+int
 slapi_plugin_task_register_handler(const char *name, dseCallbackFn func, Slapi_PBlock *plugin_pb)
 {
     Slapi_PBlock *add_pb = NULL;
-- 
1.9.3