ldap/ldif/template-dse.ldif.in | 1
ldap/schema/01core389.ldif | 1
ldap/servers/plugins/acct_usability/acct_usability.c | 9
ldap/servers/plugins/acctpolicy/acct_config.c | 9
ldap/servers/plugins/acctpolicy/acct_init.c | 19
ldap/servers/plugins/acctpolicy/acctpolicy.h | 1
ldap/servers/plugins/acl/acl.h | 1
ldap/servers/plugins/acl/acl_ext.c | 16
ldap/servers/plugins/acl/aclgroup.c | 4
ldap/servers/plugins/acl/aclplugin.c | 1
ldap/servers/plugins/automember/automember.c | 135 -
ldap/servers/plugins/chainingdb/cb.h | 7
ldap/servers/plugins/chainingdb/cb_close.c | 76
ldap/servers/plugins/chainingdb/cb_instance.c | 60
ldap/servers/plugins/cos/cos.c | 3
ldap/servers/plugins/cos/cos_cache.c | 14
ldap/servers/plugins/deref/deref.c | 9
ldap/servers/plugins/dna/dna.c | 70
ldap/servers/plugins/linkedattrs/fixup_task.c | 25
ldap/servers/plugins/linkedattrs/linked_attrs.c | 70
ldap/servers/plugins/linkedattrs/linked_attrs.h | 3
ldap/servers/plugins/memberof/memberof.c | 40
ldap/servers/plugins/memberof/memberof.h | 4
ldap/servers/plugins/memberof/memberof_config.c | 47
ldap/servers/plugins/mep/mep.c | 63
ldap/servers/plugins/pam_passthru/pam_passthru.h | 3
ldap/servers/plugins/pam_passthru/pam_ptconfig.c | 9
ldap/servers/plugins/pam_passthru/pam_ptimpl.c | 9
ldap/servers/plugins/pam_passthru/pam_ptpreop.c | 41
ldap/servers/plugins/passthru/passthru.h | 5
ldap/servers/plugins/passthru/ptconfig.c | 483 ++--
ldap/servers/plugins/passthru/ptpreop.c | 15
ldap/servers/plugins/posix-winsync/posix-group-func.c | 7
ldap/servers/plugins/posix-winsync/posix-group-func.h | 1
ldap/servers/plugins/posix-winsync/posix-winsync-config.c | 23
ldap/servers/plugins/posix-winsync/posix-winsync.c | 128 +
ldap/servers/plugins/posix-winsync/posix-wsp-ident.h | 5
ldap/servers/plugins/referint/referint.c | 23
ldap/servers/plugins/retrocl/retrocl.c | 32
ldap/servers/plugins/retrocl/retrocl_po.c | 13
ldap/servers/plugins/roles/roles_cache.c | 12
ldap/servers/plugins/roles/roles_plugin.c | 20
ldap/servers/plugins/rootdn_access/rootdn_access.c | 27
ldap/servers/plugins/schema_reload/schema_reload.c | 35
ldap/servers/plugins/statechange/statechange.c | 48
ldap/servers/plugins/sync/sync.h | 1
ldap/servers/plugins/sync/sync_init.c | 5
ldap/servers/plugins/sync/sync_persist.c | 43
ldap/servers/plugins/sync/sync_refresh.c | 11
ldap/servers/plugins/usn/usn.c | 27
ldap/servers/plugins/usn/usn.h | 1
ldap/servers/plugins/usn/usn_cleanup.c | 13
ldap/servers/plugins/views/views.c | 111 -
ldap/servers/plugins/whoami/whoami.c | 5
ldap/servers/slapd/apibroker.c | 2
ldap/servers/slapd/config.c | 11
ldap/servers/slapd/configdse.c | 2
ldap/servers/slapd/dse.c | 289 ++
ldap/servers/slapd/factory.c | 210 +-
ldap/servers/slapd/fedse.c | 48
ldap/servers/slapd/libglobs.c | 31
ldap/servers/slapd/main.c | 8
ldap/servers/slapd/plugin.c | 1436 ++++++++++++--
ldap/servers/slapd/proto-slap.h | 14
ldap/servers/slapd/result.c | 1
ldap/servers/slapd/schema.c | 10
ldap/servers/slapd/slap.h | 11
ldap/servers/slapd/slapi-plugin.h | 55
ldap/servers/slapd/task.c | 52
ldap/servers/slapd/thread_data.c | 56
ldap/servers/slapd/tools/pwenc.c | 7
71 files changed, 2920 insertions(+), 1167 deletions(-)
New commits:
commit dbfab50e01c9ae494c26e3c567cbd8adb7c59b18
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Thu Mar 20 16:09:43 2014 -0400
Ticket 47451 - add/enable/disable/remove plugins without server restart
Previous Design: All plugins were only loaded at startup. A global plugin list,
a shutdown list, and plugin DN hash are created.
New Design: The lists/hash are now all protected by a r/w lock. The read lock
is only used when calling plugin_call_func(), the write lock is
used
for adding and removing plugins. Since plugins can call plugins,
etc, the locking in the plugin_call_* functions is determined by
the use of local thread storage: is locked, or is not locked.
This mechanism prevents deadlocks.
Plugin updates(add, mod, delete) happen in the pre op stage of a
dse update, so that we can reject the update before the config is
updated, otherwise at the next server restart the server might
unexpectedly fail to start.
Plugins can now be added/enabled and deleted/disabled dynamically.
All plugin configuration (libpath, type, precedence, etc) is now
updated dynamically, unless that change breaks something. Then it
is not dynamically applied, but it is still written to the
dse.ldif.
A new internal reference counter has been added to
plugin_call_func().
These are used to keep track of the active number of concurrent
operations being performed by the plugin. This is used when
disabling
a plugin or server shutdown - so that we do not free global locks
and
config while there are still operations using them. Since tasks do
not
have access to the slapd plugin structure(for the plugin operation
count),
they have their own ref counter where needed. This task counter is
implemented when the task is created using slapi_plugin_task_new(),
instead of slapi_task_new(). Also, slapi_task_register_handler,
needs
to be replaced with slapi_plugin_task_register_handler().
Plugins that register callbacks shouldi not use
slapi_config_register_callback(),
and now use slapi_config_register_callback_plugin() - which takes
the pblock so the reference counters can be updated.
Plugins that create object extensions must also unregister those
extensions in the CLOSE function, as same goes for config
callbacks.
This feature can also be turned on/off via
"nsslapd-dynamic-pluings: on|off"
https://fedorahosted.org/389/ticket/47451
Jenkins: Passed.
Coverity: Passed.
Valgrind: Passed.
Reviewed by: rmeggins(Thanks!!)
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in
index cc2efe7..8f00772 100644
--- a/ldap/ldif/template-dse.ldif.in
+++ b/ldap/ldif/template-dse.ldif.in
@@ -58,6 +58,7 @@ nsslapd-maxdescriptors: 1024
nsslapd-max-filter-nest-level: 40
nsslapd-ndn-cache-enabled: on
nsslapd-sasl-mapping-fallback: off
+nsslapd-dynamic-plugins: off
dn: cn=features,cn=config
objectclass: top
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index 04043c1..c5e4877 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -295,6 +295,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2300 NAME
'nsslapd-connection-nocanon' D
attributeTypes: ( 2.16.840.1.113730.3.1.2301 NAME 'nsslapd-plugin-logging' DESC
'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2302 NAME 'nsslapd-listen-backlog-size'
DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2303 NAME 'nsslapd-ignore-time-skew' DESC
'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2304 NAME 'nsslapd-dynamic-plugins' DESC
'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2305 NAME 'nsslapd-moddn-aci' DESC
'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
#
# objectclasses
diff --git a/ldap/servers/plugins/acct_usability/acct_usability.c
b/ldap/servers/plugins/acct_usability/acct_usability.c
index f41f934..b4679ff 100644
--- a/ldap/servers/plugins/acct_usability/acct_usability.c
+++ b/ldap/servers/plugins/acct_usability/acct_usability.c
@@ -53,7 +53,6 @@
*/
static void *_PluginID = NULL;
static char *_PluginDN = NULL;
-static int g_plugin_started = 0;
static Slapi_PluginDesc pdesc = { AUC_FEATURE_DESC,
VENDOR,
@@ -156,18 +155,12 @@ auc_start(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, AUC_PLUGIN_SUBSYSTEM,
"--> auc_start\n");
- /* Check if we're already started */
- if (g_plugin_started) {
- goto done;
- }
-
- g_plugin_started = 1;
slapi_log_error(SLAPI_LOG_PLUGIN, AUC_PLUGIN_SUBSYSTEM,
"account usability control plug-in: ready for service\n");
+
slapi_log_error(SLAPI_LOG_TRACE, AUC_PLUGIN_SUBSYSTEM,
"<-- auc_start\n");
-done:
return 0;
}
diff --git a/ldap/servers/plugins/acctpolicy/acct_config.c
b/ldap/servers/plugins/acctpolicy/acct_config.c
index 8dfde0b..5277103 100644
--- a/ldap/servers/plugins/acctpolicy/acct_config.c
+++ b/ldap/servers/plugins/acctpolicy/acct_config.c
@@ -152,3 +152,12 @@ get_config() {
return( &globalcfg );
}
+void
+free_config()
+{
+ slapi_ch_free_string(&globalcfg.state_attr_name);
+ slapi_ch_free_string(&globalcfg.alt_state_attr_name);
+ slapi_ch_free_string(&globalcfg.spec_attr_name);
+ slapi_ch_free_string(&globalcfg.limit_attr_name);
+}
+
diff --git a/ldap/servers/plugins/acctpolicy/acct_init.c
b/ldap/servers/plugins/acctpolicy/acct_init.c
index 52e0cfa..c4dba22 100644
--- a/ldap/servers/plugins/acctpolicy/acct_init.c
+++ b/ldap/servers/plugins/acctpolicy/acct_init.c
@@ -56,6 +56,7 @@ static Slapi_PluginDesc post_plugin_desc = { PRE_PLUGIN_NAME,
PLUGIN_VENDOR,
/* Local function prototypes */
int acct_policy_start( Slapi_PBlock *pb );
+int acct_policy_close( Slapi_PBlock *pb );
int acct_policy_init( Slapi_PBlock *pb );
int acct_preop_init( Slapi_PBlock *pb );
int acct_postop_init( Slapi_PBlock *pb );
@@ -78,10 +79,13 @@ acct_policy_init( Slapi_PBlock *pb )
return( CALLBACK_OK );
}
+
if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
SLAPI_PLUGIN_VERSION_01 ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
(void *)&plugin_desc ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN,
+ (void *)&acct_policy_close ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN,
(void *)acct_policy_start ) != 0 ) {
slapi_log_error( SLAPI_LOG_FATAL, PLUGIN_NAME,
@@ -120,6 +124,10 @@ acct_policy_start( Slapi_PBlock *pb ) {
acctPluginCfg *cfg;
void *plugin_id = get_identity();
+ if(slapi_plugin_running(pb)){
+ return 0;
+ }
+
/* Load plugin configuration */
if( acct_policy_load_config_startup( pb, plugin_id ) ) {
slapi_log_error( SLAPI_LOG_FATAL, PLUGIN_NAME,
@@ -134,10 +142,21 @@ acct_policy_start( Slapi_PBlock *pb ) {
"alwaysRecordLogin=%d\n",
cfg->state_attr_name,
cfg->alt_state_attr_name?cfg->alt_state_attr_name:"not configured",
cfg->spec_attr_name,
cfg->limit_attr_name, cfg->always_record_login);
+
return( CALLBACK_OK );
}
int
+acct_policy_close( Slapi_PBlock *pb )
+{
+ int rc = 0;
+
+ free_config();
+
+ return rc;
+}
+
+int
acct_preop_init( Slapi_PBlock *pb ) {
/* Which slapi plugin API we're compatible with. */
if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
diff --git a/ldap/servers/plugins/acctpolicy/acctpolicy.h
b/ldap/servers/plugins/acctpolicy/acctpolicy.h
index 5c202d3..fcfd120 100644
--- a/ldap/servers/plugins/acctpolicy/acctpolicy.h
+++ b/ldap/servers/plugins/acctpolicy/acctpolicy.h
@@ -79,4 +79,5 @@ int update_is_allowed_attr (const char *attr);
/* acct_config.c */
int acct_policy_load_config_startup( Slapi_PBlock* pb, void* plugin_id );
acctPluginCfg* get_config();
+void free_config();
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index 2631ee9..86ac12f 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -833,6 +833,7 @@ int acllist_insert_aci_needsLock_ext( Slapi_PBlock *pb, const
Slapi_DN *e_sdn,
const struct berval* aci_attr);
char * acl_access2str ( int access );
int acl_init_ext ();
+void acl_remove_ext ();
void * acl_get_ext (ext_type type, void *object);
void acl_set_ext (ext_type type, void *object, void *data);
void acl_reset_ext_status (ext_type type, void *object);
diff --git a/ldap/servers/plugins/acl/acl_ext.c b/ldap/servers/plugins/acl/acl_ext.c
index 91135b7..126a234 100644
--- a/ldap/servers/plugins/acl/acl_ext.c
+++ b/ldap/servers/plugins/acl/acl_ext.c
@@ -63,7 +63,7 @@ struct acl_pbqueue {
};
typedef struct acl_pbqueue Acl_PBqueue;
-static Acl_PBqueue *aclQueue;
+static Acl_PBqueue *aclQueue = NULL;
/* structure with information for each extension */
typedef struct acl_ext
@@ -105,6 +105,20 @@ acl_init_ext ()
}
+void
+acl_remove_ext ()
+{
+ slapi_unregister_object_extension(plugin_name,
+ SLAPI_EXT_OPERATION,
+ &acl_ext_list[ACL_EXT_OPERATION].object_type,
+ &acl_ext_list[ACL_EXT_OPERATION].handle);
+
+ slapi_unregister_object_extension(plugin_name,
+ SLAPI_EXT_CONNECTION,
+ &acl_ext_list[ACL_EXT_CONNECTION].object_type,
+ &acl_ext_list[ACL_EXT_CONNECTION].handle);
+}
+
/* Interface to get the extensions */
void *
acl_get_ext (ext_type type, void *object)
diff --git a/ldap/servers/plugins/acl/aclgroup.c b/ldap/servers/plugins/acl/aclgroup.c
index be897cd..f0bef93 100644
--- a/ldap/servers/plugins/acl/aclgroup.c
+++ b/ldap/servers/plugins/acl/aclgroup.c
@@ -299,7 +299,7 @@ aclg_get_usersGroup ( struct acl_pblock *aclpb , char *n_dn)
/*
* It is possible at this point that we already have a group cache for the user
- * but is is invalid. We can't use it anayway. So, we march along and allocate a new
one.
+ * but is is invalid. We can't use it anyway. So, we march along and allocate a new
one.
* That's fine as the invalid one will be deallocated when done.
*/
@@ -329,7 +329,7 @@ aclg_get_usersGroup ( struct acl_pblock *aclpb , char *n_dn)
u_group->aclug_signature = aclUserGroups->aclg_signature;
- /* Do we have alreday the max number. If we have then delete the last one */
+ /* Do we have already the max number. If we have then delete the last one */
if ( aclUserGroups->aclg_num_userGroups >= ACL_MAXCACHE_USERGROUPS - 5 ) {
aclUserGroup *d_group;
diff --git a/ldap/servers/plugins/acl/aclplugin.c b/ldap/servers/plugins/acl/aclplugin.c
index ce87327..c6ad719 100644
--- a/ldap/servers/plugins/acl/aclplugin.c
+++ b/ldap/servers/plugins/acl/aclplugin.c
@@ -300,6 +300,7 @@ aclplugin_stop ( Slapi_PBlock *pb )
ACL_Destroy();
acl_destroy_aclpb_pool();
+ acl_remove_ext();
ACL_AttrGetterHashDestroy();
ACL_MethodHashDestroy();
ACL_DestroyPools();
diff --git a/ldap/servers/plugins/automember/automember.c
b/ldap/servers/plugins/automember/automember.c
index 13ec13e..c5bb0ae 100644
--- a/ldap/servers/plugins/automember/automember.c
+++ b/ldap/servers/plugins/automember/automember.c
@@ -49,12 +49,11 @@
* Plug-in globals
*/
static PRCList *g_automember_config = NULL;
-static Slapi_RWLock *g_automember_config_lock;
+static Slapi_RWLock *g_automember_config_lock = NULL;
static void *_PluginID = NULL;
static Slapi_DN *_PluginDN = NULL;
static Slapi_DN *_ConfigAreaDN = NULL;
-static int g_plugin_started = 0;
static Slapi_PluginDesc pdesc = { AUTOMEMBER_FEATURE_DESC,
VENDOR,
@@ -339,21 +338,13 @@ automember_start(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"--> automember_start\n");
- /* Check if we're already started */
- if (g_plugin_started) {
- goto done;
- }
-
- slapi_task_register_handler("automember rebuild membership",
automember_task_add);
- slapi_task_register_handler("automember export updates",
automember_task_add_export_updates);
- slapi_task_register_handler("automember map updates",
automember_task_add_map_entries);
+ slapi_plugin_task_register_handler("automember rebuild membership",
automember_task_add, pb);
+ slapi_plugin_task_register_handler("automember export updates",
automember_task_add_export_updates, pb);
+ slapi_plugin_task_register_handler("automember map updates",
automember_task_add_map_entries, pb);
- g_automember_config_lock = slapi_new_rwlock();
-
- if (!g_automember_config_lock) {
+ if ((g_automember_config_lock = slapi_new_rwlock()) == NULL) {
slapi_log_error(SLAPI_LOG_FATAL, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"automember_start: lock creation failed\n");
-
return -1;
}
@@ -387,13 +378,11 @@ automember_start(Slapi_PBlock * pb)
return -1;
}
- g_plugin_started = 1;
slapi_log_error(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"auto membership plug-in: ready for service\n");
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"<-- automember_start\n");
-done:
return 0;
}
@@ -408,28 +397,13 @@ automember_close(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"--> automember_close\n");
- if (!g_plugin_started) {
- goto done;
- }
-
- automember_config_write_lock();
- g_plugin_started = 0;
automember_delete_config();
- automember_config_unlock();
-
slapi_ch_free((void **)&g_automember_config);
slapi_sdn_free(&_PluginDN);
slapi_sdn_free(&_ConfigAreaDN);
+ slapi_destroy_rwlock(g_automember_config_lock);
+ g_automember_config_lock = NULL;
- /* We explicitly don't destroy the config lock here. If we did,
- * there is the slight possibility that another thread that just
- * passed the g_plugin_started check is about to try to obtain
- * a reader lock. We leave the lock around so these threads
- * don't crash the process. If we always check the started
- * flag again after obtaining a reader lock, no free'd resources
- * will be used. */
-
-done:
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"<-- automember_close\n");
@@ -1706,10 +1680,6 @@ automember_pre_op(Slapi_PBlock * pb, int modop)
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"--> automember_pre_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started)
- goto bail;
-
if (0 == (sdn = automember_get_sdn(pb)))
goto bail;
@@ -1822,11 +1792,6 @@ automember_mod_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"--> automember_mod_post_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started) {
- goto bail;
- }
-
if (automember_oktodo(pb) && (sdn = automember_get_sdn(pb))) {
/* Check if the config is being modified and reload if so. */
if (automember_dn_is_config(sdn)) {
@@ -1834,7 +1799,6 @@ automember_mod_post_op(Slapi_PBlock *pb)
}
}
- bail:
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"<-- automember_mod_post_op\n");
@@ -1853,10 +1817,6 @@ automember_add_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"--> automember_add_post_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started || !automember_oktodo(pb))
- return SLAPI_PLUGIN_SUCCESS;
-
/* Reload config if a config entry was added. */
if ((sdn = automember_get_sdn(pb))) {
if (automember_dn_is_config(sdn)) {
@@ -1892,12 +1852,6 @@ automember_add_post_op(Slapi_PBlock *pb)
* to the entry being added. */
automember_config_read_lock();
- /* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
- automember_config_unlock();
- return SLAPI_PLUGIN_SUCCESS;
- }
-
if (!PR_CLIST_IS_EMPTY(g_automember_config)) {
list = PR_LIST_HEAD(g_automember_config);
while (list != g_automember_config) {
@@ -1953,11 +1907,6 @@ automember_del_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"--> automember_del_post_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started || !automember_oktodo(pb)) {
- return SLAPI_PLUGIN_SUCCESS;
- }
-
/* Reload config if a config entry was deleted. */
if ((sdn = automember_get_sdn(pb))) {
if (automember_dn_is_config(sdn))
@@ -2082,14 +2031,6 @@ automember_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry
*eAfter,
*returncode = LDAP_SUCCESS;
/*
- * Make sure the plugin is started
- */
- if(!g_plugin_started){
- *returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- goto out;
- }
- /*
* Grab the task params
*/
if((base_dn = fetch_attr(e, "basedn", 0)) == NULL){
@@ -2106,7 +2047,7 @@ automember_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry
*eAfter,
/*
* setup our task data
*/
- mytaskdata = (task_data*)slapi_ch_malloc(sizeof(task_data));
+ mytaskdata = (task_data*)slapi_ch_calloc(1, sizeof(task_data));
if (mytaskdata == NULL){
*returncode = LDAP_OPERATIONS_ERROR;
rv = SLAPI_DSE_CALLBACK_ERROR;
@@ -2117,6 +2058,7 @@ automember_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry
*eAfter,
mytaskdata->bind_dn = slapi_ch_strdup(bind_dn);
mytaskdata->base_dn = slapi_sdn_new_dn_byval(base_dn);
mytaskdata->filter_str = slapi_ch_strdup(filter);
+
if(scope){
if(strcasecmp(scope,"sub")== 0){
mytaskdata->scope = 2;
@@ -2132,7 +2074,7 @@ automember_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry
*eAfter,
/* subtree by default */
mytaskdata->scope = 2;
}
- task = slapi_new_task(slapi_entry_get_ndn(e));
+ task = slapi_plugin_new_task(slapi_entry_get_ndn(e), arg);
slapi_task_set_destructor_fn(task, automember_task_destructor);
slapi_task_set_data(task, mytaskdata);
/*
@@ -2145,13 +2087,14 @@ automember_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry
*eAfter,
slapi_log_error( SLAPI_LOG_FATAL, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"unable to create task thread!\n");
*returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
slapi_task_finish(task, *returncode);
+ rv = SLAPI_DSE_CALLBACK_ERROR;
} else {
rv = SLAPI_DSE_CALLBACK_OK;
}
out:
+
return rv;
}
@@ -2231,12 +2174,6 @@ void automember_rebuild_task_thread(void *arg){
*/
automember_config_read_lock();
for (i = 0; entries && (entries[i] != NULL); i++){
- /* make sure the plugin is still up, as this loop could run for awhile */
- if (!g_plugin_started) {
- automember_config_unlock();
- result = -1;
- goto out;
- }
if (!PR_CLIST_IS_EMPTY(g_automember_config)) {
list = PR_LIST_HEAD(g_automember_config);
while (list != g_automember_config) {
@@ -2311,15 +2248,6 @@ automember_task_add_export_updates(Slapi_PBlock *pb, Slapi_Entry
*e, Slapi_Entry
*returncode = LDAP_SUCCESS;
- /*
- * Make sure the plugin is started
- */
- if(!g_plugin_started){
- *returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- goto out;
- }
-
if((ldif = fetch_attr(e, "ldif", 0)) == NULL){
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rv = SLAPI_DSE_CALLBACK_ERROR;
@@ -2339,7 +2267,7 @@ automember_task_add_export_updates(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry
slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn);
- mytaskdata = (task_data*)slapi_ch_malloc(sizeof(task_data));
+ mytaskdata = (task_data*)slapi_ch_calloc(1, sizeof(task_data));
if (mytaskdata == NULL){
*returncode = LDAP_OPERATIONS_ERROR;
rv = SLAPI_DSE_CALLBACK_ERROR;
@@ -2349,6 +2277,7 @@ automember_task_add_export_updates(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry
mytaskdata->ldif_out = slapi_ch_strdup(ldif);
mytaskdata->base_dn = slapi_sdn_new_dn_byval(base_dn);
mytaskdata->filter_str = slapi_ch_strdup(filter);
+
if(scope){
if(strcasecmp(scope,"sub")== 0){
mytaskdata->scope = 2;
@@ -2365,7 +2294,7 @@ automember_task_add_export_updates(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry
mytaskdata->scope = 2;
}
- task = slapi_new_task(slapi_entry_get_ndn(e));
+ task = slapi_plugin_new_task(slapi_entry_get_ndn(e), arg);
slapi_task_set_destructor_fn(task, automember_task_export_destructor);
slapi_task_set_data(task, mytaskdata);
/*
@@ -2385,6 +2314,7 @@ automember_task_add_export_updates(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry
}
out:
+
return rv;
}
@@ -2447,12 +2377,6 @@ void automember_export_task_thread(void *arg){
*/
automember_config_read_lock();
for (i = 0; entries && (entries[i] != NULL); i++){
- /* make sure the plugin is still up, as this loop could run for awhile */
- if (!g_plugin_started) {
- automember_config_unlock();
- result = SLAPI_DSE_CALLBACK_ERROR;
- goto out;
- }
if (!PR_CLIST_IS_EMPTY(g_automember_config)) {
list = PR_LIST_HEAD(g_automember_config);
while (list != g_automember_config) {
@@ -2517,14 +2441,7 @@ automember_task_add_map_entries(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *e
const char *ldif_in;
*returncode = LDAP_SUCCESS;
- /*
- * Make sure the plugin is started
- */
- if(!g_plugin_started){
- *returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- goto out;
- }
+
/*
* Get the params
*/
@@ -2541,7 +2458,7 @@ automember_task_add_map_entries(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *e
/*
* Setup the task data
*/
- mytaskdata = (task_data*)slapi_ch_malloc(sizeof(task_data));
+ mytaskdata = (task_data*)slapi_ch_calloc(1, sizeof(task_data));
if (mytaskdata == NULL){
*returncode = LDAP_OPERATIONS_ERROR;
rv = SLAPI_DSE_CALLBACK_ERROR;
@@ -2552,7 +2469,7 @@ automember_task_add_map_entries(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *e
mytaskdata->ldif_out = slapi_ch_strdup(ldif_out);
mytaskdata->ldif_in = slapi_ch_strdup(ldif_in);
- task = slapi_new_task(slapi_entry_get_ndn(e));
+ task = slapi_plugin_new_task(slapi_entry_get_ndn(e), arg);
slapi_task_set_destructor_fn(task, automember_task_map_destructor);
slapi_task_set_data(task, mytaskdata);
/*
@@ -2652,11 +2569,6 @@ void automember_map_task_thread(void *arg){
#endif
e = slapi_str2entry( entrystr, 0 );
if ( e != NULL ){
- if (!g_plugin_started) {
- automember_config_unlock();
- result = -1;
- goto out;
- }
if (!PR_CLIST_IS_EMPTY(g_automember_config)) {
list = PR_LIST_HEAD(g_automember_config);
while (list != g_automember_config) {
@@ -2720,8 +2632,9 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
"--> automember_modrdn_post_op\n");
/* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started || !automember_oktodo(pb))
+ if (!automember_oktodo(pb)){
return SLAPI_PLUGIN_SUCCESS;
+ }
/*
* Reload config if an existing config entry was renamed,
@@ -2759,12 +2672,6 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
*/
automember_config_read_lock();
- /* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
- automember_config_unlock();
- return SLAPI_PLUGIN_SUCCESS;
- }
-
if (!PR_CLIST_IS_EMPTY(g_automember_config)) {
list = PR_LIST_HEAD(g_automember_config);
while (list != g_automember_config) {
diff --git a/ldap/servers/plugins/chainingdb/cb.h b/ldap/servers/plugins/chainingdb/cb.h
index 90bcb46..3fc1862 100644
--- a/ldap/servers/plugins/chainingdb/cb.h
+++ b/ldap/servers/plugins/chainingdb/cb.h
@@ -461,9 +461,10 @@ void cb_close_conn_pool(cb_conn_pool * pool);
void cb_update_monitor_info(Slapi_PBlock * pb, cb_backend_instance * inst,int op);
void cb_send_ldap_result(Slapi_PBlock *pb, int err, char *m,char *t, int ne, struct
berval **urls );
void cb_stale_all_connections( cb_backend_instance * be);
-int
-cb_config_add_instance_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore,
Slapi_Entry* e,
- int *returncode, char *returntext, void *arg);
+int cb_config_add_instance_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore,
Slapi_Entry* e,
+ int *returncode, char *returntext, void *arg);
+int cb_instance_modify_config_check_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore,
Slapi_Entry* e,
+ int *returncode, char *returntext, void *arg);
int chaining_back_add ( Slapi_PBlock *pb );
diff --git a/ldap/servers/plugins/chainingdb/cb_close.c
b/ldap/servers/plugins/chainingdb/cb_close.c
index ecac585..e3b6726 100644
--- a/ldap/servers/plugins/chainingdb/cb_close.c
+++ b/ldap/servers/plugins/chainingdb/cb_close.c
@@ -47,33 +47,51 @@
** Should be followed by a cleanup
*/
+
+static void
+free_cb_backend(cb_backend *cb)
+{
+ if(cb){
+ slapi_destroy_rwlock(cb->config.rwl_config_lock);
+ slapi_ch_free_string(&cb->pluginDN);
+ slapi_ch_free_string(&cb->configDN);
+ slapi_ch_array_free(cb->config.chainable_components);
+ slapi_ch_array_free(cb->config.forward_ctrls);
+ slapi_ch_free((void **)&cb);
+ }
+}
+
int cb_back_close( Slapi_PBlock *pb )
{
- Slapi_Backend * be;
- cb_backend_instance * inst;
- int rc;
-
- slapi_pblock_get( pb, SLAPI_BACKEND, &be );
- if (be == NULL) {
+ Slapi_Backend *be;
+ cb_backend_instance *inst;
+ cb_backend *cb = cb_get_backend_type();
+ int rc;
- cb_backend * cb = cb_get_backend_type();
- CB_ASSERT(cb!=NULL);
- slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP,
cb->configDN, LDAP_SCOPE_BASE,
- "(objectclass=*)",cb_config_modify_callback);
- slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
cb->configDN, LDAP_SCOPE_BASE,
- "(objectclass=*)",cb_config_modify_check_callback);
- slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP,
cb->configDN, LDAP_SCOPE_BASE,
- "(objectclass=*)",cb_config_add_callback);
- slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP,
cb->configDN, LDAP_SCOPE_BASE,
- "(objectclass=*)",cb_config_add_check_callback);
+ slapi_pblock_get( pb, SLAPI_BACKEND, &be );
+ if (be == NULL) {
- slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
cb->configDN, LDAP_SCOPE_BASE,
- "(objectclass=*)",cb_config_search_callback);
+ CB_ASSERT(cb!=NULL);
- slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP,
cb->pluginDN,
- LDAP_SCOPE_SUBTREE, CB_CONFIG_INSTANCE_FILTER, cb_config_add_instance_callback);
+ slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP, cb->configDN,
LDAP_SCOPE_BASE,
+ "(objectclass=*)",cb_config_modify_callback);
+ slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, cb->configDN,
LDAP_SCOPE_BASE,
+
"(objectclass=*)",cb_config_modify_check_callback);
+ slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP, cb->configDN,
LDAP_SCOPE_BASE,
+ "(objectclass=*)",cb_config_add_callback);
+ slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, cb->configDN,
LDAP_SCOPE_BASE,
+
"(objectclass=*)",cb_config_add_check_callback);
+ slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, cb->configDN,
LDAP_SCOPE_BASE,
+ "(objectclass=*)",cb_config_search_callback);
+ slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_POSTOP, cb->pluginDN,
+ LDAP_SCOPE_SUBTREE, CB_CONFIG_INSTANCE_FILTER,
+ cb_config_add_instance_callback);
+ slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, cb->pluginDN,
+ LDAP_SCOPE_SUBTREE, CB_CONFIG_INSTANCE_FILTER,
+ cb_config_add_instance_check_callback);
+ free_cb_backend(cb);
return 0;
}
@@ -82,23 +100,23 @@ int cb_back_close( Slapi_PBlock *pb )
/* gets called with a ldbm backend instance... */
{
- const char * betype = slapi_be_gettype(be);
+ const char *betype = slapi_be_gettype(be);
if (!betype || strcasecmp(betype,CB_CHAINING_BACKEND_TYPE)) {
-
- slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
- "Wrong database type.\n");
+ slapi_log_error( SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM, "Wrong database
type.\n");
return 0;
}
}
inst = cb_get_instance(be);
- CB_ASSERT( inst!=NULL );
+ CB_ASSERT( inst != NULL );
slapi_log_error( SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,"Stopping chaining database
instance %s\n",
- inst->configDn);
- /* emulate a backend instance deletion */
- /* to clean up everything */
+ inst->configDn);
+ /*
+ * emulate a backend instance deletion to clean up everything
+ */
cb_instance_delete_config_callback(NULL, NULL,NULL, &rc, NULL, inst);
+ free_cb_backend(cb);
- return 0;
+ return 0;
}
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c
b/ldap/servers/plugins/chainingdb/cb_instance.c
index 86bb635..e3a3d99 100644
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
@@ -185,8 +185,9 @@ static void cb_instance_config_set_default(cb_backend_instance *inst)
** Allocate a new chaining backend instance. Internal structure
*/
-static cb_backend_instance * cb_instance_alloc(cb_backend * cb, char * name, char *
basedn) {
-
+static cb_backend_instance *
+cb_instance_alloc(cb_backend *cb, char *name, char *basedn)
+{
int i;
cb_backend_instance * inst =
@@ -252,7 +253,7 @@ void cb_instance_free(cb_backend_instance * inst) {
if (inst->bind_pool)
{
- cb_close_conn_pool(inst->bind_pool);
+ cb_close_conn_pool(inst->bind_pool);
slapi_destroy_condvar(inst->bind_pool->conn.conn_list_cv);
slapi_destroy_mutex(inst->bind_pool->conn.conn_list_mutex);
slapi_ch_free((void **) &inst->bind_pool);
@@ -260,7 +261,7 @@ void cb_instance_free(cb_backend_instance * inst) {
if (inst->pool)
{
- cb_close_conn_pool(inst->pool);
+ cb_close_conn_pool(inst->pool);
slapi_destroy_condvar(inst->pool->conn.conn_list_cv);
slapi_ch_free_string(&inst->pool->password);
slapi_ch_free_string(&inst->pool->binddn);
@@ -280,7 +281,7 @@ void cb_instance_free(cb_backend_instance * inst) {
slapi_rwlock_unlock(inst->rwl_config_lock);
slapi_destroy_rwlock(inst->rwl_config_lock);
-
+ charray_free(inst->url_array);
slapi_ch_free((void **) &inst);
}
/* XXXSD */
@@ -852,6 +853,7 @@ static int cb_instance_binduser_set(void *arg, void *value, char
*errorbuf, int
}
/* normalize and ignore the case */
+ slapi_ch_free_string(&inst->pool->binddn);
inst->pool->binddn = slapi_create_dn_string_case("%s", (char *)value);
/* not normalized */
inst->pool->binddn2=slapi_ch_strdup((char *) value);
@@ -1684,13 +1686,13 @@ int cb_instance_search_config_callback(Slapi_PBlock *pb,
Slapi_Entry* e, Slapi_E
}
/*
-** Ooops!!! The backend instance is beeing deleted
+** Ooops!!! The backend instance is being deleted
*/
int cb_instance_delete_config_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry*
e2,
- int *returncode, char *returntext, void *arg) {
+ int *returncode, char *returntext, void *arg) {
- cb_backend_instance * inst = (cb_backend_instance *) arg;
+ cb_backend_instance * inst = (cb_backend_instance *) arg;
int rc;
Slapi_Entry * anEntry=NULL;
Slapi_DN * aDn;
@@ -1703,36 +1705,33 @@ int cb_instance_delete_config_callback(Slapi_PBlock *pb,
Slapi_Entry* e, Slapi_E
/* Now it is safe to stop */
/* No pending op */
-
/* unregister callbacks */
- slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
inst->configDn,
+ slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, inst->configDn,
LDAP_SCOPE_BASE, "(objectclass=*)", cb_instance_search_config_callback);
-
- slapi_config_remove_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP,
inst->configDn,
- LDAP_SCOPE_BASE, "(objectclass=*)", cb_instance_delete_config_callback);
-
- slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
inst->configDn,
+ slapi_config_remove_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP,
inst->configDn,
+ LDAP_SCOPE_BASE, "(objectclass=*)", cb_instance_delete_config_callback);
+ slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, inst->configDn,
LDAP_SCOPE_BASE, "(objectclass=*)",
cb_instance_modify_config_check_callback);
- slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP,
inst->configDn,
+ slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP,
inst->configDn,
LDAP_SCOPE_BASE, "(objectclass=*)", cb_instance_modify_config_callback);
/* At this point, the monitor entry should have been removed */
/* If not, manually call delete callback */
- aDn = slapi_sdn_new_dn_byref(inst->monitorDn);
- if ( LDAP_SUCCESS==(slapi_search_internal_get_entry(aDn,NULL,
&anEntry,inst->backend_type->identity))) {
+ aDn = slapi_sdn_new_dn_byref(inst->monitorDn);
+ if ( LDAP_SUCCESS==(slapi_search_internal_get_entry(aDn,NULL,
&anEntry,inst->backend_type->identity))) {
cb_delete_monitor_callback( NULL, anEntry, NULL, &rc , NULL, inst );
if (anEntry)
- slapi_entry_free(anEntry);
+ slapi_entry_free(anEntry);
}
- slapi_sdn_done(aDn);
- slapi_sdn_free(&aDn);
+ slapi_sdn_done(aDn);
+ slapi_sdn_free(&aDn);
/* free resources */
- cb_close_conn_pool(inst->bind_pool);
- cb_close_conn_pool(inst->pool);
+ cb_close_conn_pool(inst->bind_pool);
+ cb_close_conn_pool(inst->pool);
slapi_be_free(&(inst->inst_be));
- cb_instance_free(inst);
+ cb_instance_free(inst);
return SLAPI_DSE_CALLBACK_OK;
}
@@ -1749,7 +1748,6 @@ static void cb_instance_add_monitor_later(time_t when, void *arg) {
if (LDAP_SUCCESS == cb_config_add_dse_entries(inst->backend_type,
cb_skeleton_entries,
inst->inst_name,CB_PLUGIN_NAME, NULL))
{
-
/* add monitor callbacks */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
inst->monitorDn, LDAP_SCOPE_BASE,
"(objectclass=*)", cb_search_monitor_callback, (void *) inst);
@@ -1902,17 +1900,17 @@ int cb_instance_add_config_callback(Slapi_PBlock *pb, Slapi_Entry*
e, Slapi_Entr
if (!inst->isconfigured)
{
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
inst->configDn,
- LDAP_SCOPE_BASE,"(objectclass=*)",cb_instance_modify_config_check_callback,
(void *) inst);
+
LDAP_SCOPE_BASE,"(objectclass=*)",cb_instance_modify_config_check_callback,
(void *) inst);
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP,
inst->configDn,
- LDAP_SCOPE_BASE,"(objectclass=*)",cb_instance_modify_config_callback, (void
*) inst);
-
+ LDAP_SCOPE_BASE,"(objectclass=*)",cb_instance_modify_config_callback,
(void *) inst);
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
inst->configDn,
- LDAP_SCOPE_BASE,"(objectclass=*)", cb_instance_search_config_callback, (void
*) inst);
+ LDAP_SCOPE_BASE,"(objectclass=*)",
cb_instance_search_config_callback, (void *) inst);
/* allow deletion otherwise impossible to remote a backend instance */
/* dynamically... */
- slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP,
inst->configDn,
- LDAP_SCOPE_BASE,"(objectclass=*)", cb_instance_delete_config_callback, (void
*) inst);
+
+ slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP,
inst->configDn,
+ LDAP_SCOPE_BASE,"(objectclass=*)",
cb_instance_delete_config_callback, (void *) inst);
}
/* Notify the front-end */
diff --git a/ldap/servers/plugins/cos/cos.c b/ldap/servers/plugins/cos/cos.c
index 55ff850..1e963e5 100644
--- a/ldap/servers/plugins/cos/cos.c
+++ b/ldap/servers/plugins/cos/cos.c
@@ -92,7 +92,6 @@ int cos_start( Slapi_PBlock *pb );
int cos_close( Slapi_PBlock *pb );
int cos_post_op( Slapi_PBlock *pb );
-
static Slapi_PluginDesc pdesc = { "cos", VENDOR, DS_PACKAGE_VERSION,
"class of service plugin" };
@@ -243,6 +242,7 @@ int cos_start( Slapi_PBlock *pb )
}
else
{
+
/* problems we are hosed */
cos_cache_stop();
LDAPDebug( LDAP_DEBUG_ANY, "cos_start: failed to initialise\n",0,0,0);
@@ -306,6 +306,7 @@ int cos_post_op( Slapi_PBlock *pb )
cos_cache_change_notify(pb);
LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_post_op\n",0,0,0);
+
return SLAPI_PLUGIN_SUCCESS; /* always succeed */
}
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
index 80eee95..3f3841f 100644
--- a/ldap/servers/plugins/cos/cos_cache.c
+++ b/ldap/servers/plugins/cos/cos_cache.c
@@ -3414,15 +3414,15 @@ void cos_cache_stop()
/* release the caches reference to the cache */
cos_cache_release(pCache);
-
- slapi_destroy_mutex(cache_lock);
- slapi_destroy_mutex(change_lock);
- slapi_destroy_condvar(something_changed);
+ slapi_destroy_mutex(cache_lock); cache_lock = NULL;
+ slapi_destroy_mutex(change_lock); change_lock = NULL;
+ slapi_destroy_condvar(something_changed); something_changed = NULL;
slapi_unlock_mutex(stop_lock);
- slapi_destroy_mutex(stop_lock);
- slapi_destroy_condvar(start_cond);
- slapi_destroy_mutex(start_lock);
+
+ slapi_destroy_mutex(stop_lock); stop_lock = NULL;
+ slapi_destroy_condvar(start_cond); start_cond = NULL;
+ slapi_destroy_mutex(start_lock); start_lock = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_cache_stop\n",0,0,0);
}
diff --git a/ldap/servers/plugins/deref/deref.c b/ldap/servers/plugins/deref/deref.c
index 8414452..ea24dc5 100644
--- a/ldap/servers/plugins/deref/deref.c
+++ b/ldap/servers/plugins/deref/deref.c
@@ -55,7 +55,6 @@
*/
static void *_PluginID = NULL;
static char *_PluginDN = NULL;
-static int g_plugin_started = 0;
static Slapi_PluginDesc pdesc = { DEREF_FEATURE_DESC,
VENDOR,
@@ -234,18 +233,12 @@ deref_start(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, DEREF_PLUGIN_SUBSYSTEM,
"--> deref_start\n");
- /* Check if we're already started */
- if (g_plugin_started) {
- goto done;
- }
-
- g_plugin_started = 1;
slapi_log_error(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM,
"linked attributes plug-in: ready for service\n");
+
slapi_log_error(SLAPI_LOG_TRACE, DEREF_PLUGIN_SUBSYSTEM,
"<-- deref_start\n");
-done:
return 0;
}
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 9794a4a..cf88597 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -194,8 +194,6 @@ static Slapi_RWLock *g_dna_cache_lock;
static void *_PluginID = NULL;
static const char *_PluginDN = NULL;
-static int g_plugin_started = 0;
-
static char *hostname = NULL;
static char *portnum = NULL;
static char *secureportnum = NULL;
@@ -547,11 +545,6 @@ dna_start(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"--> dna_start\n");
- /* Check if we're already started */
- if (g_plugin_started) {
- goto done;
- }
-
g_dna_cache_lock = slapi_new_rwlock();
if (!g_dna_cache_lock) {
@@ -601,13 +594,11 @@ dna_start(Slapi_PBlock * pb)
return DNA_FAILURE;
}
- g_plugin_started = 1;
slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
"dna: ready for service\n");
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"<-- dna_start\n");
-done:
return DNA_SUCCESS;
}
@@ -622,30 +613,15 @@ dna_close(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"--> dna_close\n");
- if (!g_plugin_started) {
- goto done;
- }
-
- dna_write_lock();
- g_plugin_started = 0;
dna_delete_config();
- dna_unlock();
-
slapi_ch_free((void **)&dna_global_config);
+ slapi_destroy_rwlock(g_dna_cache_lock);
+ g_dna_cache_lock = NULL;
slapi_ch_free_string(&hostname);
slapi_ch_free_string(&portnum);
slapi_ch_free_string(&secureportnum);
- /* We explicitly don't destroy the config lock here. If we did,
- * there is the slight possibility that another thread that just
- * passed the g_plugin_started check is about to try to obtain
- * a reader lock. We leave the lock around so these threads
- * don't crash the process. If we always check the started
- * flag again after obtaining a reader lock, no free'd resources
- * will be used. */
-
-done:
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"<-- dna_close\n");
@@ -1335,11 +1311,6 @@ dna_update_config_event(time_t event_time, void *arg)
/* Get read lock to prevent config changes */
dna_read_lock();
- /* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
- goto bail;
- }
-
/* Loop through all config entries and update the shared
* config entries. */
if (!PR_CLIST_IS_EMPTY(dna_global_config)) {
@@ -3030,11 +3001,6 @@ _dna_pre_op_add(Slapi_PBlock *pb, Slapi_Entry *e, char **errstr)
PRUint64 setval = 0;
int i;
- /* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
- goto bail;
- }
-
if (0 == (dn = dna_get_dn(pb))) {
goto bail;
}
@@ -3234,11 +3200,6 @@ _dna_pre_op_modify(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Mods
*smods, char **e
int len = 0;
int i;
- /* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
- goto bail;
- }
-
if (0 == (dn = dna_get_dn(pb))) {
goto bail;
}
@@ -3501,11 +3462,6 @@ dna_pre_op(Slapi_PBlock * pb, int modtype)
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"--> dna_pre_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started) {
- goto bail;
- }
-
if (0 == (dn = dna_get_dn(pb))) {
goto bail;
}
@@ -3669,7 +3625,7 @@ static int dna_be_txn_pre_op(Slapi_PBlock *pb, int modtype)
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"--> dna_be_txn_pre_op\n");
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
goto bail;
}
@@ -3924,9 +3880,14 @@ static int dna_config_check_post_op(Slapi_PBlock * pb)
{
char *dn;
+ if(!slapi_plugin_running(pb)){
+ return DNA_SUCCESS;
+ }
+
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"--> dna_config_check_post_op\n");
+
if (!slapi_op_internal(pb)) { /* If internal, no need to check. */
if ((dn = dna_get_dn(pb))) {
if (dna_dn_is_config(dn)) {
@@ -3956,6 +3917,10 @@ static int dna_extend_exop(Slapi_PBlock *pb)
PRUint64 lower = 0;
PRUint64 upper = 0;
+ if(!slapi_plugin_running(pb)){
+ return ret;
+ }
+
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"--> dna_extend_exop\n");
@@ -4096,11 +4061,6 @@ dna_release_range(char *range_dn, PRUint64 *lower, PRUint64
*upper)
dna_read_lock();
- /* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
- goto bail;
- }
-
/* Go through the config entries to see if we
* have a shared range configured that matches
* the range from the exop request. */
@@ -4281,11 +4241,6 @@ void dna_dump_config()
dna_read_lock();
- /* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
- goto bail;
- }
-
if (!PR_CLIST_IS_EMPTY(dna_global_config)) {
list = PR_LIST_HEAD(dna_global_config);
while (list != dna_global_config) {
@@ -4294,7 +4249,6 @@ void dna_dump_config()
}
}
-bail:
dna_unlock();
}
diff --git a/ldap/servers/plugins/linkedattrs/fixup_task.c
b/ldap/servers/plugins/linkedattrs/fixup_task.c
index ff6dd82..5447b38 100644
--- a/ldap/servers/plugins/linkedattrs/fixup_task.c
+++ b/ldap/servers/plugins/linkedattrs/fixup_task.c
@@ -71,18 +71,6 @@ linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
*returncode = LDAP_SUCCESS;
- /* make sure the plugin is not closed */
- if(!linked_attrs_is_started()){
- *returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- goto out;
- }
-
- /* get arg(s) */
- linkdn = fetch_attr(e, "linkdn", 0);
-
- /* setup our task data */
- slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn);
mytaskdata = (task_data*)slapi_ch_calloc(1, sizeof(task_data));
if (mytaskdata == NULL) {
*returncode = LDAP_OPERATIONS_ERROR;
@@ -90,13 +78,16 @@ linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
goto out;
}
+ /* get arg(s) and setup our task data */
+ linkdn = fetch_attr(e, "linkdn", 0);
if (linkdn) {
mytaskdata->linkdn = slapi_dn_normalize(slapi_ch_strdup(linkdn));
}
+ slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn);
mytaskdata->bind_dn = slapi_ch_strdup(bind_dn);
/* allocate new task now */
- task = slapi_new_task(slapi_entry_get_ndn(e));
+ task = slapi_plugin_new_task(slapi_entry_get_ndn(e), arg);
/* register our destructor for cleaning up our private data */
slapi_task_set_destructor_fn(task, linked_attrs_fixup_task_destructor);
@@ -112,13 +103,17 @@ linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
slapi_log_error( SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM,
"unable to create task thread!\n");
*returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
slapi_task_finish(task, *returncode);
+ rv = SLAPI_DSE_CALLBACK_ERROR;
} else {
rv = SLAPI_DSE_CALLBACK_OK;
}
out:
+ if(rv != SLAPI_DSE_CALLBACK_OK){
+ linked_attrs_op_finished();
+ }
+
return rv;
}
@@ -210,6 +205,8 @@ linked_attrs_fixup_task_thread(void *arg)
slapi_log_error(SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM, "Linked attributes fixup
task complete.\n");
slapi_task_inc_progress(task);
+ linked_attrs_op_finished();
+
/* this will queue the destruction of the task */
slapi_task_finish(task, rc);
}
diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.c
b/ldap/servers/plugins/linkedattrs/linked_attrs.c
index 1945828..73247e5 100644
--- a/ldap/servers/plugins/linkedattrs/linked_attrs.c
+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.c
@@ -54,7 +54,6 @@ static Slapi_RWLock *g_config_lock;
static void *_PluginID = NULL;
static char *_PluginDN = NULL;
-static int g_plugin_started = 0;
int plugin_is_betxn = 0;
static Slapi_PluginDesc pdesc = { LINK_FEATURE_DESC,
@@ -323,11 +322,6 @@ linked_attrs_start(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, LINK_PLUGIN_SUBSYSTEM,
"--> linked_attrs_start\n");
- /* Check if we're already started */
- if (g_plugin_started) {
- goto done;
- }
-
g_config_lock = slapi_new_rwlock();
if (!g_config_lock) {
@@ -366,15 +360,13 @@ linked_attrs_start(Slapi_PBlock * pb)
/*
* Register our task callback
*/
- slapi_task_register_handler("fixup linked attributes",
linked_attrs_fixup_task_add);
+ slapi_plugin_task_register_handler("fixup linked attributes",
linked_attrs_fixup_task_add, pb);
- g_plugin_started = 1;
slapi_log_error(SLAPI_LOG_PLUGIN, LINK_PLUGIN_SUBSYSTEM,
"linked attributes plug-in: ready for service\n");
slapi_log_error(SLAPI_LOG_TRACE, LINK_PLUGIN_SUBSYSTEM,
"<-- linked_attrs_start\n");
-done:
return 0;
}
@@ -389,27 +381,12 @@ linked_attrs_close(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, LINK_PLUGIN_SUBSYSTEM,
"--> linked_attrs_close\n");
- if (!g_plugin_started) {
- goto done;
- }
-
- linked_attrs_write_lock();
- g_plugin_started = 0;
linked_attrs_delete_config();
- linked_attrs_unlock();
-
+ slapi_destroy_rwlock(g_config_lock);
+ g_config_lock = NULL;
slapi_ch_free((void **)&g_link_config);
slapi_ch_free((void **)&g_managed_config_index);
- /* We explicitly don't destroy the config lock here. If we did,
- * there is the slight possibility that another thread that just
- * passed the g_plugin_started check is about to try to obtain
- * a reader lock. We leave the lock around so these threads
- * don't crash the process. If we always check the started
- * flag again after obtaining a reader lock, no free'd resources
- * will be used. */
-
-done:
slapi_log_error(SLAPI_LOG_TRACE, LINK_PLUGIN_SUBSYSTEM,
"<-- linked_attrs_close\n");
@@ -1540,10 +1517,6 @@ linked_attrs_pre_op(Slapi_PBlock * pb, int modop)
slapi_log_error(SLAPI_LOG_TRACE, LINK_PLUGIN_SUBSYSTEM,
"--> linked_attrs_pre_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started)
- goto bail;
-
if (0 == (dn = linked_attrs_get_dn(pb)))
goto bail;
@@ -1638,10 +1611,6 @@ linked_attrs_mod_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, LINK_PLUGIN_SUBSYSTEM,
"--> linked_attrs_mod_post_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started)
- return SLAPI_PLUGIN_SUCCESS;
-
/* We don't want to process internal modify
* operations that originate from this plugin.
* Doing so could cause a deadlock. */
@@ -1673,7 +1642,7 @@ linked_attrs_mod_post_op(Slapi_PBlock *pb)
linked_attrs_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
linked_attrs_unlock();
return SLAPI_PLUGIN_SUCCESS;
}
@@ -1741,10 +1710,6 @@ linked_attrs_add_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, LINK_PLUGIN_SUBSYSTEM,
"--> linked_attrs_add_post_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started || !linked_attrs_oktodo(pb))
- return SLAPI_PLUGIN_SUCCESS;
-
/* Reload config if a config entry was added. */
if ((dn = linked_attrs_get_dn(pb))) {
if (linked_attrs_dn_is_config(dn))
@@ -1771,7 +1736,7 @@ linked_attrs_add_post_op(Slapi_PBlock *pb)
linked_attrs_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
linked_attrs_unlock();
return SLAPI_PLUGIN_SUCCESS;
}
@@ -1821,8 +1786,9 @@ linked_attrs_del_post_op(Slapi_PBlock *pb)
"--> linked_attrs_del_post_op\n");
/* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started || !linked_attrs_oktodo(pb))
+ if (!linked_attrs_oktodo(pb)){
return SLAPI_PLUGIN_SUCCESS;
+ }
/* Reload config if a config entry was deleted. */
if ((dn = linked_attrs_get_dn(pb))) {
@@ -1850,7 +1816,7 @@ linked_attrs_del_post_op(Slapi_PBlock *pb)
linked_attrs_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
linked_attrs_unlock();
return SLAPI_PLUGIN_SUCCESS;
}
@@ -1938,7 +1904,7 @@ linked_attrs_modrdn_post_op(Slapi_PBlock *pb)
"--> linked_attrs_modrdn_post_op\n");
/* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started || !linked_attrs_oktodo(pb)) {
+ if (!linked_attrs_oktodo(pb)) {
goto done;
}
@@ -1976,7 +1942,7 @@ linked_attrs_modrdn_post_op(Slapi_PBlock *pb)
linked_attrs_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
linked_attrs_unlock();
return SLAPI_PLUGIN_SUCCESS;
}
@@ -2073,6 +2039,7 @@ done:
slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
rc = SLAPI_PLUGIN_FAILURE;
}
+
return rc;
}
@@ -2087,10 +2054,6 @@ linked_attrs_dump_config()
linked_attrs_read_lock();
- /* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started)
- goto bail;
-
if (!PR_CLIST_IS_EMPTY(g_link_config)) {
list = PR_LIST_HEAD(g_link_config);
while (list != g_link_config) {
@@ -2099,7 +2062,6 @@ linked_attrs_dump_config()
}
}
-bail:
linked_attrs_unlock();
}
@@ -2110,10 +2072,6 @@ linked_attrs_dump_config_index()
linked_attrs_read_lock();
- /* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started)
- goto bail;
-
if (!PR_CLIST_IS_EMPTY(g_managed_config_index)) {
list = PR_LIST_HEAD(g_managed_config_index);
while (list != g_managed_config_index) {
@@ -2122,7 +2080,6 @@ linked_attrs_dump_config_index()
}
}
-bail:
linked_attrs_unlock();
}
@@ -2141,8 +2098,3 @@ linked_attrs_dump_config_entry(struct configEntry * entry)
slapi_log_error(SLAPI_LOG_FATAL, LINK_PLUGIN_SUBSYSTEM,
"<---- scope ---------------> %s\n",
entry->scope);
}
-
-int
-linked_attrs_is_started(){
- return g_plugin_started;
-}
diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.h
b/ldap/servers/plugins/linkedattrs/linked_attrs.h
index 4721151..d1dacb6 100644
--- a/ldap/servers/plugins/linkedattrs/linked_attrs.h
+++ b/ldap/servers/plugins/linkedattrs/linked_attrs.h
@@ -143,4 +143,7 @@ int linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
* misc
*/
int linked_attrs_is_started();
+void linked_attrs_op_started();
+void linked_attrs_op_finished();
+
extern int plugin_is_betxn;
diff --git a/ldap/servers/plugins/memberof/memberof.c
b/ldap/servers/plugins/memberof/memberof.c
index 71bddd3..f377105 100644
--- a/ldap/servers/plugins/memberof/memberof.c
+++ b/ldap/servers/plugins/memberof/memberof.c
@@ -80,7 +80,6 @@ static Slapi_RWLock *config_rwlock = NULL;
static Slapi_DN* _pluginDN = NULL;
static PRMonitor *memberof_operation_lock = 0;
MemberOfConfig *qsortConfig = 0;
-static int g_plugin_started = 0;
static int usetxn = 0;
static int premodfn = 0;
@@ -356,11 +355,6 @@ int memberof_postop_start(Slapi_PBlock *pb)
slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
"--> memberof_postop_start\n" );
- /* Check if we're already started */
- if (g_plugin_started) {
- goto bail;
- }
-
memberof_operation_lock = PR_NewMonitor();
if(0 == memberof_operation_lock)
{
@@ -416,21 +410,19 @@ int memberof_postop_start(Slapi_PBlock *pb)
memberof_set_plugin_area(slapi_entry_get_sdn(config_e));
memberof_set_config_area(slapi_entry_get_sdn(config_e));
- if (( rc = memberof_config( config_e )) != LDAP_SUCCESS ) {
+ if (( rc = memberof_config( config_e, pb )) != LDAP_SUCCESS ) {
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
"configuration failed (%s)\n", ldap_err2string( rc ));
rc = -1;
goto bail;
}
- rc = slapi_task_register_handler("memberof task", memberof_task_add);
+ rc = slapi_plugin_task_register_handler("memberof task", memberof_task_add,
pb);
if(rc)
{
goto bail;
}
- g_plugin_started = 1;
-
/*
* TODO: start up operation actor thread
* need to get to a point where server failure
@@ -462,7 +454,13 @@ int memberof_postop_close(Slapi_PBlock *pb)
slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
"--> memberof_postop_close\n" );
- g_plugin_started = 0;
+ memberof_release_config();
+ slapi_sdn_free(&_ConfigAreaDN);
+ slapi_sdn_free(&_pluginDN);
+ slapi_destroy_rwlock(config_rwlock);
+ config_rwlock = NULL;
+ PR_DestroyMonitor(memberof_operation_lock);
+ memberof_operation_lock = NULL;
slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
"<-- memberof_postop_close\n" );
@@ -790,8 +788,9 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
{
int ret = SLAPI_PLUGIN_SUCCESS;
void *caller_id = NULL;
- Slapi_DN *entry_scope = memberof_config_get_entry_scope();
+ Slapi_DN *entry_scope = NULL;
+ entry_scope = memberof_config_get_entry_scope();
slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
"--> memberof_postop_modrdn\n" );
@@ -867,7 +866,6 @@ int memberof_postop_modrdn(Slapi_PBlock *pb)
memberof_free_config(&configCopy);
}
-
slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
"<-- memberof_postop_modrdn\n" );
return ret;
@@ -1200,6 +1198,7 @@ int memberof_postop_add(Slapi_PBlock *pb)
slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
"<-- memberof_postop_add\n" );
+
return ret;
}
@@ -1223,7 +1222,7 @@ int memberof_oktodo(Slapi_PBlock *pb)
slapi_log_error( SLAPI_LOG_TRACE, MEMBEROF_PLUGIN_SUBSYSTEM,
"--> memberof_postop_oktodo\n" );
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
ret = 0;
goto bail;
}
@@ -2589,14 +2588,6 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
*returncode = LDAP_SUCCESS;
- /* make sure the plugin was not stopped from a shutdown */
- if (!g_plugin_started)
- {
- *returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- goto out;
- }
-
/* get arg(s) */
if ((dn = fetch_attr(e, "basedn", 0)) == NULL)
{
@@ -2626,7 +2617,7 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
mytaskdata->bind_dn = slapi_ch_strdup(bind_dn);
/* allocate new task now */
- task = slapi_new_task(slapi_entry_get_ndn(e));
+ task = slapi_plugin_new_task(slapi_entry_get_ndn(e), pb);
/* register our destructor for cleaning up our private data */
slapi_task_set_destructor_fn(task, memberof_task_destructor);
@@ -2643,8 +2634,8 @@ int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM,
"unable to create task thread!\n");
*returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
slapi_task_finish(task, *returncode);
+ rv = SLAPI_DSE_CALLBACK_ERROR;
} else {
rv = SLAPI_DSE_CALLBACK_OK;
}
@@ -2755,4 +2746,3 @@ int memberof_fix_memberof_callback(Slapi_Entry *e, void
*callback_data)
return rc;
}
-
diff --git a/ldap/servers/plugins/memberof/memberof.h
b/ldap/servers/plugins/memberof/memberof.h
index 46da1c3..d0532cf 100644
--- a/ldap/servers/plugins/memberof/memberof.h
+++ b/ldap/servers/plugins/memberof/memberof.h
@@ -88,7 +88,7 @@ typedef struct memberofconfig {
/*
* functions
*/
-int memberof_config(Slapi_Entry *config_e);
+int memberof_config(Slapi_Entry *config_e, Slapi_PBlock *pb);
void memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src);
void memberof_free_config(MemberOfConfig *config);
MemberOfConfig *memberof_get_config();
@@ -107,5 +107,7 @@ int memberof_shared_config_validate(Slapi_PBlock *pb);
int memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
int *returncode, char *returntext, void *arg);
void *memberof_get_plugin_id();
+void memberof_release_config();
+PRUint64 get_plugin_started();
#endif /* _MEMBEROF_H_ */
diff --git a/ldap/servers/plugins/memberof/memberof_config.c
b/ldap/servers/plugins/memberof/memberof_config.c
index 36734ca..0c10dbe 100644
--- a/ldap/servers/plugins/memberof/memberof_config.c
+++ b/ldap/servers/plugins/memberof/memberof_config.c
@@ -99,7 +99,7 @@ static int dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore,
Slapi_Ent
* Returns an LDAP error code (LDAP_SUCCESS if all goes well).
*/
int
-memberof_config(Slapi_Entry *config_e)
+memberof_config(Slapi_Entry *config_e, Slapi_PBlock *pb)
{
int returncode = LDAP_SUCCESS;
char returntext[SLAPI_DSE_RETURNTEXT_SIZE];
@@ -126,21 +126,21 @@ memberof_config(Slapi_Entry *config_e)
*/
if (returncode == LDAP_SUCCESS) {
const char *config_dn = slapi_sdn_get_dn(memberof_get_plugin_area());
- slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
+ slapi_config_register_callback_plugin(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP |
DSE_FLAG_PLUGIN,
config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
- memberof_validate_config,NULL);
- slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP,
+ memberof_validate_config, NULL,pb);
+ slapi_config_register_callback_plugin(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP |
DSE_FLAG_PLUGIN,
config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
- memberof_apply_config,NULL);
- slapi_config_register_callback(SLAPI_OPERATION_MODRDN, DSE_FLAG_PREOP,
+ memberof_apply_config, NULL, pb);
+ slapi_config_register_callback_plugin(SLAPI_OPERATION_MODRDN, DSE_FLAG_PREOP |
DSE_FLAG_PLUGIN,
config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
- dont_allow_that, NULL);
- slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP,
+ dont_allow_that, NULL, pb);
+ slapi_config_register_callback_plugin(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP |
DSE_FLAG_PLUGIN,
config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
- dont_allow_that, NULL);
- slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
+ dont_allow_that, NULL, pb);
+ slapi_config_register_callback_plugin(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP |
DSE_FLAG_PLUGIN,
config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
- memberof_search,NULL);
+ memberof_search, NULL, pb);
}
inited = 1;
@@ -153,6 +153,31 @@ memberof_config(Slapi_Entry *config_e)
return returncode;
}
+void
+memberof_release_config()
+{
+ const char *config_dn = slapi_sdn_get_dn(memberof_get_plugin_area());
+
+ slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
+ config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
+ memberof_validate_config);
+ slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP,
+ config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
+ memberof_apply_config);
+ slapi_config_remove_callback(SLAPI_OPERATION_MODRDN, DSE_FLAG_PREOP,
+ config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
+ dont_allow_that);
+ slapi_config_remove_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP,
+ config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
+ dont_allow_that);
+ slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
+ config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER,
+ memberof_search);
+
+ slapi_destroy_rwlock(memberof_config_lock);
+ memberof_config_lock = NULL;
+ inited = 0;
+}
/*
* memberof_validate_config()
diff --git a/ldap/servers/plugins/mep/mep.c b/ldap/servers/plugins/mep/mep.c
index 3e63773..1c614e8 100644
--- a/ldap/servers/plugins/mep/mep.c
+++ b/ldap/servers/plugins/mep/mep.c
@@ -55,7 +55,6 @@ static Slapi_RWLock *g_mep_config_lock;
static void *_PluginID = NULL;
static Slapi_DN *_PluginDN = NULL;
static Slapi_DN *_ConfigAreaDN = NULL;
-static int g_plugin_started = 0;
static Slapi_PluginDesc pdesc = { MEP_FEATURE_DESC,
VENDOR,
@@ -336,11 +335,6 @@ mep_start(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
"--> mep_start\n");
- /* Check if we're already started */
- if (g_plugin_started) {
- goto done;
- }
-
g_mep_config_lock = slapi_new_rwlock();
if (!g_mep_config_lock) {
@@ -380,13 +374,11 @@ mep_start(Slapi_PBlock * pb)
return -1;
}
- g_plugin_started = 1;
slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
"managed entries plug-in: ready for service\n");
slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
"<-- mep_start\n");
-done:
return 0;
}
@@ -401,28 +393,13 @@ mep_close(Slapi_PBlock * pb)
slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
"--> mep_close\n");
- if (!g_plugin_started) {
- goto done;
- }
-
- mep_config_write_lock();
- g_plugin_started = 0;
mep_delete_config();
- mep_config_unlock();
-
+ slapi_destroy_rwlock(g_mep_config_lock);
+ g_mep_config_lock = NULL;
slapi_ch_free((void **)&g_mep_config);
slapi_sdn_free(&_PluginDN);
slapi_sdn_free(&_ConfigAreaDN);
- /* We explicitly don't destroy the config lock here. If we did,
- * there is the slight possibility that another thread that just
- * passed the g_plugin_started check is about to try to obtain
- * a reader lock. We leave the lock around so these threads
- * don't crash the process. If we always check the started
- * flag again after obtaining a reader lock, no free'd resources
- * will be used. */
-
-done:
slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
"<-- mep_close\n");
@@ -1989,10 +1966,6 @@ mep_pre_op(Slapi_PBlock * pb, int modop)
slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
"--> mep_pre_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started)
- goto bail;
-
/* See if we're calling ourselves. */
slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &caller_id);
@@ -2058,7 +2031,7 @@ mep_pre_op(Slapi_PBlock * pb, int modop)
mep_config_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
mep_config_unlock();
goto bail;
}
@@ -2183,7 +2156,7 @@ mep_pre_op(Slapi_PBlock * pb, int modop)
mep_config_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
mep_config_unlock();
goto bail;
}
@@ -2321,10 +2294,6 @@ mep_mod_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
"--> mep_mod_post_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started)
- return SLAPI_PLUGIN_SUCCESS;
-
if (mep_oktodo(pb) && (sdn = mep_get_sdn(pb))) {
/* First check if the config or a template is being modified. */
if (mep_dn_is_config(sdn) || mep_dn_is_template(sdn)) {
@@ -2357,7 +2326,7 @@ mep_mod_post_op(Slapi_PBlock *pb)
mep_config_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
mep_config_unlock();
goto bail;
}
@@ -2453,10 +2422,6 @@ mep_add_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
"--> mep_add_post_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started || !mep_oktodo(pb))
- return SLAPI_PLUGIN_SUCCESS;
-
/* Reload config if a config entry was added. */
if ((sdn = mep_get_sdn(pb))) {
if (mep_dn_is_config(sdn)) {
@@ -2487,7 +2452,7 @@ mep_add_post_op(Slapi_PBlock *pb)
mep_config_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
mep_config_unlock();
return SLAPI_PLUGIN_SUCCESS;
}
@@ -2519,11 +2484,6 @@ mep_del_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
"--> mep_del_post_op\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started || !mep_oktodo(pb)) {
- return SLAPI_PLUGIN_SUCCESS;
- }
-
/* Reload config if a config entry was deleted. */
if ((sdn = mep_get_sdn(pb))) {
if (mep_dn_is_config(sdn))
@@ -2593,9 +2553,9 @@ mep_modrdn_post_op(Slapi_PBlock *pb)
"--> mep_modrdn_post_op\n");
/* Just bail if we aren't ready to service requests yet. */
- if (!g_plugin_started || !mep_oktodo(pb))
- return SLAPI_PLUGIN_SUCCESS;;
-
+ if (!mep_oktodo(pb)){
+ return SLAPI_PLUGIN_SUCCESS;
+ }
/* Reload config if an existing config entry was renamed,
* or if the new dn brings an entry into the scope of the
* config entries. */
@@ -2645,7 +2605,7 @@ mep_modrdn_post_op(Slapi_PBlock *pb)
mep_config_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
mep_config_unlock();
slapi_pblock_destroy(mep_pb);
return SLAPI_PLUGIN_SUCCESS;
@@ -2817,7 +2777,7 @@ bailmod:
mep_config_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
mep_config_unlock();
return SLAPI_PLUGIN_SUCCESS;
}
@@ -2829,7 +2789,6 @@ bailmod:
mep_config_unlock();
}
-
slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
"<-- mep_modrdn_post_op\n");
diff --git a/ldap/servers/plugins/pam_passthru/pam_passthru.h
b/ldap/servers/plugins/pam_passthru/pam_passthru.h
index 7075b48..949cd9d 100644
--- a/ldap/servers/plugins/pam_passthru/pam_passthru.h
+++ b/ldap/servers/plugins/pam_passthru/pam_passthru.h
@@ -78,7 +78,6 @@
/*
* Plug-in globals
*/
-extern int g_plugin_started;
extern PRCList *pam_passthru_global_config;
/*
@@ -155,11 +154,13 @@ int pam_passthru_validate_config (Slapi_Entry* e, char
*returntext);
int pam_passthru_dn_is_config(Slapi_DN *sdn);
void pam_passthru_set_config_area(Slapi_DN *sdn);
Slapi_DN* pam_passthru_get_config_area();
+void pam_passthru_free_config_area();
/*
* pam_ptimpl.c
*/
int pam_passthru_pam_init( void );
+int pam_passthru_pam_free( void );
int pam_passthru_do_pam_auth(Slapi_PBlock *pb, Pam_PassthruConfig *cfg);
#endif /* _PAM_PASSTHRU_H_ */
diff --git a/ldap/servers/plugins/pam_passthru/pam_ptconfig.c
b/ldap/servers/plugins/pam_passthru/pam_ptconfig.c
index c40b87e..832f1f5 100644
--- a/ldap/servers/plugins/pam_passthru/pam_ptconfig.c
+++ b/ldap/servers/plugins/pam_passthru/pam_ptconfig.c
@@ -859,3 +859,12 @@ pam_passthru_get_config_area()
return _ConfigArea;
}
+/*
+ * Free the active config area.
+ */
+void
+pam_passthru_free_config_area()
+{
+ slapi_sdn_free(&_ConfigArea);
+}
+
diff --git a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
index 2558b9e..73a01d6 100644
--- a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
+++ b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
@@ -427,6 +427,15 @@ pam_passthru_pam_init( void )
return 0;
}
+int
+pam_passthru_pam_free( void )
+{
+ slapi_destroy_mutex(PAMLock);
+ PAMLock = NULL;
+
+ return 0;
+}
+
/*
* Entry point into the PAM auth code. Shields the rest of the app
* from PAM API code. Get our config params, then call the actual
diff --git a/ldap/servers/plugins/pam_passthru/pam_ptpreop.c
b/ldap/servers/plugins/pam_passthru/pam_ptpreop.c
index abf93e3..a25b9fa 100644
--- a/ldap/servers/plugins/pam_passthru/pam_ptpreop.c
+++ b/ldap/servers/plugins/pam_passthru/pam_ptpreop.c
@@ -56,7 +56,6 @@ static Slapi_RWLock *g_pam_config_lock = NULL;
/*
* Plug-in globals
*/
-int g_pam_plugin_started = 0;
PRCList *pam_passthru_global_config = NULL;
/*
@@ -333,11 +332,6 @@ pam_passthru_bindpreop_start( Slapi_PBlock *pb )
slapi_log_error( SLAPI_LOG_TRACE, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
"=> pam_passthru_bindpreop_start\n" );
- /* Check if we're already started */
- if (g_pam_plugin_started) {
- goto done;
- }
-
/* Get the plug-in configuration DN and store it for later use. */
slapi_pblock_get(pb, SLAPI_TARGET_SDN, &pluginsdn);
if (NULL == pluginsdn || 0 == slapi_sdn_get_ndn_len(pluginsdn)) {
@@ -394,7 +388,6 @@ done:
g_pam_config_lock = NULL;
slapi_ch_free((void **)&pam_passthru_global_config);
} else {
- g_pam_plugin_started = 1;
slapi_log_error( SLAPI_LOG_PLUGIN, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
"pam_passthru: ready for service\n" );
}
@@ -417,26 +410,16 @@ pam_passthru_bindpreop_close( Slapi_PBlock *pb )
slapi_log_error( SLAPI_LOG_TRACE, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
"=> pam_passthru_bindpreop_close\n" );
- if (!g_pam_plugin_started) {
- goto done;
- }
-
- pam_passthru_write_lock();
- g_pam_plugin_started = 0;
pam_passthru_delete_config();
pam_passthru_unlock();
+ slapi_sdn_free((Slapi_DN **)&pam_passthruauth_plugin_sdn);
+ pam_passthru_free_config_area();
slapi_ch_free((void **)&pam_passthru_global_config);
+ pam_passthru_pam_free();
+ slapi_destroy_rwlock(g_pam_config_lock);
+ g_pam_config_lock = NULL;
- /* We explicitly don't destroy the config lock here. If we did,
- * there is the slight possibility that another thread that just
- * passed the g_pam_plugin_started check is about to try to obtain
- * a reader lock. We leave the lock around so these threads
- * don't crash the process. If we always check the started
- * flag again after obtaining a reader lock, no free'd resources
- * will be used. */
-
-done:
slapi_log_error( SLAPI_LOG_TRACE, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
"<= pam_passthru_bindpreop_close\n" );
@@ -489,7 +472,7 @@ pam_passthru_bindpreop( Slapi_PBlock *pb )
pam_passthru_read_lock();
/* Bail out if the plug-in close function was just called. */
- if (!g_pam_plugin_started) {
+ if (!slapi_plugin_running(pb)) {
goto done;
}
@@ -579,11 +562,6 @@ pam_passthru_preop(Slapi_PBlock *pb, int modtype)
slapi_log_error(SLAPI_LOG_TRACE, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
"=> pam_passthru_preop\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_pam_plugin_started) {
- goto bail;
- }
-
/* Get the target SDN. */
slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
if (!sdn) {
@@ -646,7 +624,6 @@ bail:
slapi_send_ldap_result(pb, ret, NULL, returntext, 0, NULL);
ret = SLAPI_PLUGIN_FAILURE;
}
-
slapi_log_error(SLAPI_LOG_TRACE, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
"<= pam_passthru_preop\n");
@@ -693,11 +670,6 @@ pam_passthru_postop(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
"=> pam_passthru_postop\n");
- /* Just bail if we aren't ready to service requests yet. */
- if (!g_pam_plugin_started) {
- goto bail;
- }
-
/* Make sure the operation succeeded and bail if it didn't. */
slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc);
if (oprc != 0) {
@@ -738,6 +710,7 @@ pam_passthru_postop(Slapi_PBlock *pb)
"<= pam_passthru_postop\n");
bail:
+
return ret;
}
diff --git a/ldap/servers/plugins/passthru/passthru.h
b/ldap/servers/plugins/passthru/passthru.h
index e0421ac..a195f38 100644
--- a/ldap/servers/plugins/passthru/passthru.h
+++ b/ldap/servers/plugins/passthru/passthru.h
@@ -162,4 +162,9 @@ struct berval **passthru_strs2bervals( char **ss );
char ** passthru_bervals2strs( struct berval **bvs );
void passthru_free_bervals( struct berval **bvs );
+/*
+ * ptpreop.c
+ */
+void passthru_free_config();
+
#endif /* _PASSTHRU_H_ */
diff --git a/ldap/servers/plugins/passthru/ptconfig.c
b/ldap/servers/plugins/passthru/ptconfig.c
index 850bd3d..1256943 100644
--- a/ldap/servers/plugins/passthru/ptconfig.c
+++ b/ldap/servers/plugins/passthru/ptconfig.c
@@ -109,10 +109,10 @@ passthru_config( int argc, char **argv )
int ret = LDAP_SUCCESS;
if ( inited ) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- "only one pass through plugin instance can be used\n" );
- ret = LDAP_PARAM_ERROR;
- goto error;
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "only one pass through plugin instance can be used\n" );
+ ret = LDAP_PARAM_ERROR;
+ goto error;
}
inited = 1;
@@ -122,11 +122,11 @@ passthru_config( int argc, char **argv )
* providing at least one remote server. Return an error if attempted.
*/
if ( argc < 1 ) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- "no pass through servers found in configuration"
- " (at least one must be listed)\n" );
- ret = LDAP_PARAM_ERROR;
- goto error;
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "no pass through servers found in configuration "
+ "(at least one must be listed)\n" );
+ ret = LDAP_PARAM_ERROR;
+ goto error;
}
/*
@@ -134,232 +134,224 @@ passthru_config( int argc, char **argv )
*/
prevsrvr = NULL;
for ( i = 0; i < argc; ++i ) {
- int secure = 0;
- char *p = NULL;
- srvr = (PassThruServer *)slapi_ch_calloc( 1, sizeof( PassThruServer ));
- srvr->ptsrvr_url = slapi_ch_strdup( argv[i] );
-
- /* since the ldap url may contain both spaces (to delimit multiple hosts)
- and commas (in suffixes), we have to search for the first space
- after the last /, then look for any commas after that
- This assumes the ldap url looks like this:
- ldap(s)://host:port host:port .... host:port/suffixes
- That is, it assumes there is always a trailing slash on the ldapurl
- and that the url does not look like this: ldap://host
- also assumes suffixes do not have any / in them
- */
- if ((p = strrchr(srvr->ptsrvr_url, '/'))) { /* look for last / */
- p = strchr(p, ' '); /* look for first space after last / */
- if (p) {
- if (!strchr(p, ',')) { /* no comma */
- p = NULL; /* just use defaults */
- }
- }
- }
-
- if (!p) {
- /*
- * use defaults for maxconnections, maxconcurrency, timeout,
- * LDAP version, and connlifetime.
- */
- srvr->ptsrvr_maxconnections = PASSTHRU_DEF_SRVR_MAXCONNECTIONS;
- srvr->ptsrvr_maxconcurrency = PASSTHRU_DEF_SRVR_MAXCONCURRENCY;
- srvr->ptsrvr_timeout = (struct timeval *)slapi_ch_calloc( 1,
- sizeof( struct timeval ));
- srvr->ptsrvr_timeout->tv_sec = PASSTHRU_DEF_SRVR_TIMEOUT;
- srvr->ptsrvr_ldapversion = PASSTHRU_DEF_SRVR_PROTOCOL_VERSION;
- using_def_connlifetime = 1;
- } else {
- /*
- * parse parameters. format is:
- * maxconnections,maxconcurrency,timeout,ldapversion
- * OR maxconnections,maxconcurrency,timeout,ldapversion,lifetime
- * OR maxconnections,maxconcurrency,timeout,ldapversion,lifetime,starttls
- */
- *p++ = '\0'; /* p points at space preceding optional arguments */
- rc = sscanf( p, "%d,%d,%d,%d,%d,%d", &srvr->ptsrvr_maxconnections,
- &srvr->ptsrvr_maxconcurrency, &tosecs,
- &srvr->ptsrvr_ldapversion, &srvr->ptsrvr_connlifetime,
- &starttls);
- if ( rc < 4 ) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- "server parameters should be in the form "
- "\"maxconnections,maxconcurrency,timeout,ldapversion,"
- "connlifetime\" (got \"%s\")\n", p );
- ret = LDAP_PARAM_ERROR;
- goto error;
- } else if ( rc < 5 ) {
- using_def_connlifetime = 1;
- srvr->ptsrvr_connlifetime = PASSTHRU_DEF_SRVR_CONNLIFETIME;
- starttls = 0;
- } else if ( rc < 6 ) {
- using_def_connlifetime = 0; /* lifetime specified */
- starttls = 0; /* but not starttls */
- } else { /* all 6 args supplied */
- using_def_connlifetime = 0; /* lifetime specified */
- /* and starttls */
- }
-
- if ( srvr->ptsrvr_ldapversion != LDAP_VERSION2
- && srvr->ptsrvr_ldapversion != LDAP_VERSION3 ) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- "LDAP protocol version should be %d or %d (got %d)\n",
- LDAP_VERSION2, LDAP_VERSION3,
- srvr->ptsrvr_ldapversion );
- ret = LDAP_PARAM_ERROR;
- goto error;
- }
-
- if ( srvr->ptsrvr_maxconnections <= 0 ) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- "maximum connections must be greater than "
- "zero (got %d)\n", srvr->ptsrvr_maxconnections );
- ret = LDAP_PARAM_ERROR;
- goto error;
- }
-
- if ( srvr->ptsrvr_maxconcurrency <= 0 ) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- "maximum concurrency must be greater than "
- "zero (got %d)\n", srvr->ptsrvr_maxconcurrency );
- ret = LDAP_PARAM_ERROR;
- goto error;
- }
-
- if ( tosecs <= 0 ) {
- srvr->ptsrvr_timeout = NULL;
- } else {
- srvr->ptsrvr_timeout = (struct timeval *)slapi_ch_calloc( 1,
- sizeof( struct timeval ));
- srvr->ptsrvr_timeout->tv_sec = tosecs;
- }
- }
-
- /*
- * parse the LDAP URL
- */
- if (( rc = slapi_ldap_url_parse( srvr->ptsrvr_url, &ludp, 1, &secure )) != 0
) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- "unable to parse LDAP URL \"%s\" (%s)\n",
- srvr->ptsrvr_url, slapi_urlparse_err2string( rc ));
- ret = LDAP_PARAM_ERROR;
- goto error;
- }
-
- if ( ludp->lud_dn == NULL || *ludp->lud_dn == '\0' ) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- "missing suffix in LDAP URL \"%s\"\n",
- srvr->ptsrvr_url );
- ret = LDAP_PARAM_ERROR;
- goto error;
- }
+ int secure = 0;
+ char *p = NULL;
+
+ srvr = (PassThruServer *)slapi_ch_calloc( 1, sizeof( PassThruServer ));
+ srvr->ptsrvr_url = slapi_ch_strdup( argv[i] );
+
+ /*
+ * since the ldap url may contain both spaces (to delimit multiple hosts)
+ * and commas (in suffixes), we have to search for the first space
+ * after the last /, then look for any commas after that
+ * This assumes the ldap url looks like this:
+ * ldap(s)://host:port host:port .... host:port/suffixes
+ * That is, it assumes there is always a trailing slash on the ldapurl
+ * and that the url does not look like this: ldap://host
+ * also assumes suffixes do not have any / in them
+ */
+ if ((p = strrchr(srvr->ptsrvr_url, '/'))) { /* look for last / */
+ p = strchr(p, ' '); /* look for first space after last / */
+ if (p) {
+ if (!strchr(p, ',')) { /* no comma */
+ p = NULL; /* just use defaults */
+ }
+ }
+ }
+
+ if (!p) {
+ /*
+ * use defaults for maxconnections, maxconcurrency, timeout,
+ * LDAP version, and connlifetime.
+ */
+ srvr->ptsrvr_maxconnections = PASSTHRU_DEF_SRVR_MAXCONNECTIONS;
+ srvr->ptsrvr_maxconcurrency = PASSTHRU_DEF_SRVR_MAXCONCURRENCY;
+ srvr->ptsrvr_timeout = (struct timeval *)slapi_ch_calloc( 1,sizeof( struct
timeval ));
+ srvr->ptsrvr_timeout->tv_sec = PASSTHRU_DEF_SRVR_TIMEOUT;
+ srvr->ptsrvr_ldapversion = PASSTHRU_DEF_SRVR_PROTOCOL_VERSION;
+ using_def_connlifetime = 1;
+ } else {
+ /*
+ * parse parameters. format is:
+ * maxconnections,maxconcurrency,timeout,ldapversion
+ * OR maxconnections,maxconcurrency,timeout,ldapversion,lifetime
+ * OR maxconnections,maxconcurrency,timeout,ldapversion,lifetime,starttls
+ */
+ *p++ = '\0'; /* p points at space preceding optional arguments */
+ rc = sscanf( p, "%d,%d,%d,%d,%d,%d",
&srvr->ptsrvr_maxconnections,
+ &srvr->ptsrvr_maxconcurrency, &tosecs,
&srvr->ptsrvr_ldapversion,
+ &srvr->ptsrvr_connlifetime, &starttls);
+ if ( rc < 4 ) {
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "server parameters should be in the form "
+
"\"maxconnections,maxconcurrency,timeout,ldapversion,"
+ "connlifetime\" (got \"%s\")\n", p );
+ ret = LDAP_PARAM_ERROR;
+ goto error;
+ } else if ( rc < 5 ) {
+ using_def_connlifetime = 1;
+ srvr->ptsrvr_connlifetime = PASSTHRU_DEF_SRVR_CONNLIFETIME;
+ starttls = 0;
+ } else if ( rc < 6 ) {
+ using_def_connlifetime = 0; /* lifetime specified */
+ starttls = 0; /* but not starttls */
+ } else { /* all 6 args supplied */
+ using_def_connlifetime = 0; /* lifetime specified */
+ /* and starttls */
+ }
+
+ if ( srvr->ptsrvr_ldapversion != LDAP_VERSION2 &&
srvr->ptsrvr_ldapversion != LDAP_VERSION3 ) {
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "LDAP protocol version should be %d or %d (got %d)\n",
+ LDAP_VERSION2, LDAP_VERSION3, srvr->ptsrvr_ldapversion );
+ ret = LDAP_PARAM_ERROR;
+ goto error;
+ }
+
+ if ( srvr->ptsrvr_maxconnections <= 0 ) {
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "maximum connections must be greater than "
+ "zero (got %d)\n", srvr->ptsrvr_maxconnections );
+ ret = LDAP_PARAM_ERROR;
+ goto error;
+ }
+
+ if ( srvr->ptsrvr_maxconcurrency <= 0 ) {
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "maximum concurrency must be greater than "
+ "zero (got %d)\n", srvr->ptsrvr_maxconcurrency );
+ ret = LDAP_PARAM_ERROR;
+ goto error;
+ }
+
+ if ( tosecs <= 0 ) {
+ srvr->ptsrvr_timeout = NULL;
+ } else {
+ srvr->ptsrvr_timeout = (struct timeval *)slapi_ch_calloc( 1, sizeof(
struct timeval ));
+ srvr->ptsrvr_timeout->tv_sec = tosecs;
+ }
+ }
+
+ /*
+ * parse the LDAP URL
+ */
+ if (( rc = slapi_ldap_url_parse( srvr->ptsrvr_url, &ludp, 1, &secure
)) != 0 ) {
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "unable to parse LDAP URL \"%s\" (%s)\n",
+ srvr->ptsrvr_url, slapi_urlparse_err2string( rc ));
+ ret = LDAP_PARAM_ERROR;
+ goto error;
+ }
+
+ if ( ludp->lud_dn == NULL || *ludp->lud_dn == '\0' ) {
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "missing suffix in LDAP URL \"%s\"\n",
srvr->ptsrvr_url );
+ ret = LDAP_PARAM_ERROR;
+ goto error;
+ }
- srvr->ptsrvr_hostname = slapi_ch_strdup( ludp->lud_host );
- srvr->ptsrvr_port = ludp->lud_port;
- srvr->ptsrvr_secure = secure;
- if (starttls) {
- srvr->ptsrvr_secure = 2;
- }
-
- /*
- * If a space-separated list of hosts is configured for failover,
- * use a different (non infinite) default for connection lifetime.
- */
- if ( using_def_connlifetime &&
- strchr( srvr->ptsrvr_hostname, ' ' ) != NULL ) {
- srvr->ptsrvr_connlifetime =
- PASSTHRU_DEF_SRVR_FAILOVERCONNLIFETIME;
- }
-
- /*
- * split the DN into multiple suffixes (separated by ';')
- */
- if (( suffixarray = slapi_str2charray( ludp->lud_dn, ";" )) == NULL ) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- "unable to parse suffix string \"%s\" within \"%s\"\n",
- ludp->lud_dn, srvr->ptsrvr_url );
- ret = LDAP_PARAM_ERROR;
- goto error;
- }
-
- /*
- * free our LDAP URL descriptor
- */
- ldap_free_urldesc( ludp );
- ludp = NULL;
-
- /*
- * reorganize the suffixes into a linked list and normalize them
- */
- prevsuffix = NULL;
- for ( j = 0; suffixarray[ j ] != NULL; ++j ) {
-
- /*
- * allocate a new PassThruSuffix structure and fill it in.
- */
- suffix = (PassThruSuffix *)slapi_ch_malloc(
- sizeof( PassThruSuffix ));
- suffix->ptsuffix_normsuffix =
- slapi_dn_normalize( suffixarray[ j ] );
- suffixarray[ j ] = NULL;
- suffix->ptsuffix_len = strlen( suffix->ptsuffix_normsuffix );
- suffix->ptsuffix_next = NULL;
-
- /*
- * add to end of list
- */
- if ( prevsuffix == NULL ) {
- srvr->ptsrvr_suffixes = suffix;
- } else {
- prevsuffix->ptsuffix_next = suffix;
- }
- prevsuffix = suffix;
- }
- ldap_memfree( suffixarray );
-
- /*
- * create mutexes and condition variables for this server
- */
- if (( srvr->ptsrvr_connlist_mutex = slapi_new_mutex()) == NULL ||
- ( srvr->ptsrvr_connlist_cv = slapi_new_condvar(
- srvr->ptsrvr_connlist_mutex )) == NULL ) {
- ret = LDAP_LOCAL_ERROR;
- goto error;
- }
-
- /*
- * add this server to the end of our list
- */
- if ( prevsrvr == NULL ) {
- theConfig.ptconfig_serverlist = srvr;
- } else {
- prevsrvr->ptsrvr_next = srvr;
- }
- prevsrvr = srvr;
+ srvr->ptsrvr_hostname = slapi_ch_strdup( ludp->lud_host );
+ srvr->ptsrvr_port = ludp->lud_port;
+ srvr->ptsrvr_secure = secure;
+ if (starttls) {
+ srvr->ptsrvr_secure = 2;
+ }
+
+ /*
+ * If a space-separated list of hosts is configured for failover,
+ * use a different (non infinite) default for connection lifetime.
+ */
+ if ( using_def_connlifetime &&
+ strchr( srvr->ptsrvr_hostname, ' ' ) != NULL ) {
+ srvr->ptsrvr_connlifetime = PASSTHRU_DEF_SRVR_FAILOVERCONNLIFETIME;
+ }
+
+ /*
+ * split the DN into multiple suffixes (separated by ';')
+ */
+ if (( suffixarray = slapi_str2charray( ludp->lud_dn, ";" )) == NULL
) {
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "unable to parse suffix string \"%s\" within
\"%s\"\n",
+ ludp->lud_dn, srvr->ptsrvr_url );
+ ret = LDAP_PARAM_ERROR;
+ goto error;
+ }
+
+ /*
+ * free our LDAP URL descriptor
+ */
+ ldap_free_urldesc( ludp );
+ ludp = NULL;
+
+ /*
+ * reorganize the suffixes into a linked list and normalize them
+ */
+ prevsuffix = NULL;
+ for ( j = 0; suffixarray[ j ] != NULL; ++j ) {
+ /*
+ * allocate a new PassThruSuffix structure and fill it in.
+ */
+ suffix = (PassThruSuffix *)slapi_ch_calloc(1, sizeof( PassThruSuffix ));
+ suffix->ptsuffix_normsuffix = slapi_dn_normalize( suffixarray[ j ] );
+ suffixarray[ j ] = NULL;
+ suffix->ptsuffix_len = strlen( suffix->ptsuffix_normsuffix );
+ suffix->ptsuffix_next = NULL;
+
+ /*
+ * add to end of list
+ */
+ if ( prevsuffix == NULL ) {
+ srvr->ptsrvr_suffixes = suffix;
+ } else {
+ prevsuffix->ptsuffix_next = suffix;
+ }
+ prevsuffix = suffix;
+ }
+ ldap_memfree( suffixarray );
+
+ /*
+ * create mutexes and condition variables for this server
+ */
+ if (( srvr->ptsrvr_connlist_mutex = slapi_new_mutex()) == NULL ||
+ ( srvr->ptsrvr_connlist_cv =
slapi_new_condvar(srvr->ptsrvr_connlist_mutex )) == NULL )
+ {
+ ret = LDAP_LOCAL_ERROR;
+ goto error;
+ }
+
+ /*
+ * add this server to the end of our list
+ */
+ if ( prevsrvr == NULL ) {
+ theConfig.ptconfig_serverlist = srvr;
+ } else {
+ prevsrvr->ptsrvr_next = srvr;
+ }
+ prevsrvr = srvr;
#ifdef PASSTHRU_VERBOSE_LOGGING
- /*
- * log configuration for debugging purposes
- */
- slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
- "PTA server host: \"%s\", port: %d, secure: %d,"
- " maxconnections: %d, maxconcurrency: %d, timeout: %d,"
- " ldversion: %d, connlifetime: %d\n",
- srvr->ptsrvr_hostname, srvr->ptsrvr_port,
- srvr->ptsrvr_secure, srvr->ptsrvr_maxconnections,
- srvr->ptsrvr_maxconcurrency,
- srvr->ptsrvr_timeout == NULL ? -1
- : srvr->ptsrvr_timeout->tv_sec, srvr->ptsrvr_ldapversion,
- srvr->ptsrvr_connlifetime );
- for ( prevsuffix = srvr->ptsrvr_suffixes; prevsuffix != NULL;
- prevsuffix = prevsuffix->ptsuffix_next ) {
- slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
- " normalized suffix: \"%s\"\n",
- prevsuffix->ptsuffix_normsuffix );
- }
+ /*
+ * log configuration for debugging purposes
+ */
+ slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "PTA server host: \"%s\", port: %d, secure: %d, "
+ "maxconnections: %d, maxconcurrency: %d, timeout: %d, "
+ "ldversion: %d, connlifetime: %d\n",
+ srvr->ptsrvr_hostname, srvr->ptsrvr_port,
+ srvr->ptsrvr_secure, srvr->ptsrvr_maxconnections,
+ srvr->ptsrvr_maxconcurrency,
+ srvr->ptsrvr_timeout == NULL ? -1 :
srvr->ptsrvr_timeout->tv_sec,
+ srvr->ptsrvr_ldapversion,
+ srvr->ptsrvr_connlifetime );
+ for ( prevsuffix = srvr->ptsrvr_suffixes; prevsuffix != NULL;
+ prevsuffix = prevsuffix->ptsuffix_next )
+ {
+ slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
+ " normalized suffix: \"%s\"\n",
prevsuffix->ptsuffix_normsuffix );
+ }
#endif
- }
+ } /* End of argv for loop */
goto done;
@@ -380,3 +372,34 @@ passthru_get_config( void )
{
return( &theConfig );
}
+
+void
+passthru_free_config()
+{
+ PassThruServer *server, *next_server;
+ PassThruSuffix *suffix, *next_suffix;
+
+ inited = 0;
+ server = theConfig.ptconfig_serverlist;
+ while(server){
+ next_server = server->ptsrvr_next;
+ suffix = server->ptsrvr_suffixes;
+
+ /* free the server's suffix list */
+ while(suffix){
+ next_suffix = suffix->ptsuffix_next;
+ slapi_ch_free_string(&suffix->ptsuffix_normsuffix);
+ slapi_ch_free((void **)&suffix);
+ suffix = next_suffix;
+ }
+ /* free the server */
+ slapi_ch_free_string(&server->ptsrvr_url);
+ slapi_ch_free_string(&server->ptsrvr_hostname);
+ slapi_ch_free((void **)&server->ptsrvr_timeout);
+ slapi_destroy_mutex(server->ptsrvr_connlist_mutex);
+ slapi_destroy_condvar(server->ptsrvr_connlist_cv);
+ slapi_ch_free((void **)&server);
+
+ server = next_server;
+ }
+}
diff --git a/ldap/servers/plugins/passthru/ptpreop.c
b/ldap/servers/plugins/passthru/ptpreop.c
index 1f73cf1..8425e34 100644
--- a/ldap/servers/plugins/passthru/ptpreop.c
+++ b/ldap/servers/plugins/passthru/ptpreop.c
@@ -140,6 +140,7 @@ passthru_bindpreop_close( Slapi_PBlock *pb )
* XXXmcs: free any memory, mutexes, etc.
*/
passthru_close_all_connections( passthru_get_config() );
+ passthru_free_config();
return( 0 );
}
@@ -184,9 +185,9 @@ passthru_bindpreop( Slapi_PBlock *pb )
*/
if ( method != LDAP_AUTH_SIMPLE || *normbinddn == '\0'
|| creds->bv_len == 0 ) {
- slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
- "<= not handled (not simple bind or NULL dn/credentials)\n" );
- return( PASSTHRU_OP_NOT_HANDLED );
+ slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "<= not handled (not simple bind or NULL dn/credentials)\n"
);
+ return( PASSTHRU_OP_NOT_HANDLED );
}
/*
@@ -199,9 +200,9 @@ passthru_bindpreop( Slapi_PBlock *pb )
* another server.
*/
if ( passthru_dn2server( cfg, normbinddn, &srvr ) != LDAP_SUCCESS ) {
- slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
- "<= not handled (not one of our suffixes)\n" );
- return( PASSTHRU_OP_NOT_HANDLED );
+ slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
+ "<= not handled (not one of our suffixes)\n" );
+ return( PASSTHRU_OP_NOT_HANDLED );
}
/*
@@ -285,7 +286,7 @@ passthru_bindpreop( Slapi_PBlock *pb )
if ( matcheddn != NULL ) {
ldap_memfree( matcheddn );
}
-
+
slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
"<= handled (error %d - %s)\n", rc, ldap_err2string( rc ));
diff --git a/ldap/servers/plugins/posix-winsync/posix-group-func.c
b/ldap/servers/plugins/posix-winsync/posix-group-func.c
index 4e2dae5..11e9a7f 100644
--- a/ldap/servers/plugins/posix-winsync/posix-group-func.c
+++ b/ldap/servers/plugins/posix-winsync/posix-group-func.c
@@ -49,6 +49,13 @@ memberUidLockInit()
}
void
+memberUidLockDestroy()
+{
+ PR_DestroyMonitor(memberuid_operation_lock);
+ memberuid_operation_lock = NULL;
+}
+
+void
addDynamicGroupIfNecessary(Slapi_Entry *entry, Slapi_Mods *smods) {
Slapi_Attr *oc_attr = NULL;
Slapi_Value *voc = slapi_value_new();
diff --git a/ldap/servers/plugins/posix-winsync/posix-group-func.h
b/ldap/servers/plugins/posix-winsync/posix-group-func.h
index 85e5235..e9db3a2 100644
--- a/ldap/servers/plugins/posix-winsync/posix-group-func.h
+++ b/ldap/servers/plugins/posix-winsync/posix-group-func.h
@@ -17,6 +17,7 @@ char * searchUid(const char *udn);
void memberUidLock();
void memberUidUnlock();
int memberUidLockInit();
+void memberUidLockDestroy();
int addUserToGroupMembership(Slapi_Entry *entry);
void propogateDeletionsUpward(Slapi_Entry *, const Slapi_DN *, Slapi_ValueSet*,
Slapi_ValueSet *, int);
diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync-config.c
b/ldap/servers/plugins/posix-winsync/posix-winsync-config.c
index a7fd6e9..1f025a6 100644
--- a/ldap/servers/plugins/posix-winsync/posix-winsync-config.c
+++ b/ldap/servers/plugins/posix-winsync/posix-winsync-config.c
@@ -66,6 +66,12 @@ posix_winsync_agmt_init(const Slapi_DN *ds_subtree, const Slapi_DN
*ad_subtree)
void *node = NULL;
Slapi_DN *sdn = NULL;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return NULL;
+ }
+
slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
"--> posix_winsync_agmt_init [%s] [%s] -- begin\n",
slapi_sdn_get_dn(ds_subtree), slapi_sdn_get_dn(ad_subtree));
@@ -87,6 +93,7 @@ posix_winsync_agmt_init(const Slapi_DN *ds_subtree, const Slapi_DN
*ad_subtree)
slapi_ch_free_string(&pardn);
}
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
"<-- posix_winsync_agmt_init -- end\n");
@@ -165,6 +172,10 @@ posix_winsync_config(Slapi_Entry *config_e)
int returncode = LDAP_SUCCESS;
char returntext[SLAPI_DSE_RETURNTEXT_SIZE];
+ /* basic init */
+ theConfig.config_e = NULL;
+ theConfig.lock = NULL;
+
slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "--> _config %s
-- begin\n",
slapi_entry_get_dn_const(config_e));
if (inited) {
@@ -222,6 +233,18 @@ posix_winsync_config(Slapi_Entry *config_e)
return returncode;
}
+void
+posix_winsync_config_free()
+{
+ slapi_entry_free(theConfig.config_e);
+ theConfig.config_e = NULL;
+ slapi_destroy_mutex(theConfig.lock);
+ theConfig.lock = NULL;
+ memberUidLockDestroy();
+ inited = 0;
+}
+
+
static int
posix_winsync_apply_config(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
int *returncode, char *returntext, void *arg)
diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync.c
b/ldap/servers/plugins/posix-winsync/posix-winsync.c
index 129bdac..00dd922 100644
--- a/ldap/servers/plugins/posix-winsync/posix-winsync.c
+++ b/ldap/servers/plugins/posix-winsync/posix-winsync.c
@@ -117,6 +117,13 @@ static windows_attribute_map group_mssfu_attribute_map[] = { {
"msSFU30memberUid
{ NULL, NULL } };
static char *posix_winsync_plugin_name = POSIX_WINSYNC_PLUGIN_NAME;
+static PRUint64 g_plugin_started = 0;
+
+/*
+ * We can not fully use the built in plugin counter in the posix-winsync plugin,
+ * so we have to use our own.
+ */
+static Slapi_Counter *op_counter = NULL;
enum
{
@@ -568,6 +575,12 @@ posix_winsync_pre_ad_mod_user_cb(void *cbdata, const Slapi_Entry
*rawentry, Slap
Slapi_Attr *attr = NULL;
windows_attribute_map *attr_map = user_attribute_map;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"--> posix_winsync_pre_ad_mod_user_cb -- begin DS account
[%s]\n",
slapi_entry_get_dn_const(ds_entry));
@@ -642,6 +655,7 @@ posix_winsync_pre_ad_mod_user_cb(void *cbdata, const Slapi_Entry
*rawentry, Slap
slapi_mod_dump(mod, 0);
}
}
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- posix_winsync_pre_ad_mod_user_cb -- end\n");
@@ -657,6 +671,12 @@ posix_winsync_pre_ad_mod_group_cb(void *cbdata, const Slapi_Entry
*rawentry, Sla
Slapi_Attr *attr = NULL;
windows_attribute_map *attr_map = group_attribute_map;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
if (posix_winsync_config_get_msSFUSchema())
attr_map = group_mssfu_attribute_map;
@@ -755,6 +775,7 @@ posix_winsync_pre_ad_mod_group_cb(void *cbdata, const Slapi_Entry
*rawentry, Sla
slapi_mod_dump(mod, 0);
}
}
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- _pre_ad_mod_group_cb -- end\n");
@@ -774,6 +795,12 @@ posix_winsync_pre_ds_mod_user_cb(void *cbdata, const Slapi_Entry
*rawentry, Slap
windows_attribute_map *attr_map = user_attribute_map;
PRBool posixval = PR_TRUE;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"--> _pre_ds_mod_user_cb -- begin\n");
@@ -781,6 +808,7 @@ posix_winsync_pre_ds_mod_user_cb(void *cbdata, const Slapi_Entry
*rawentry, Slap
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- _pre_ds_mod_user_cb -- Empty %s entry.\n",
(NULL==rawentry)?"rawentry":(NULL==ad_entry)?"ad
entry":"ds entry");
+ plugin_op_finished();
return;
}
@@ -908,7 +936,7 @@ posix_winsync_pre_ds_mod_user_cb(void *cbdata, const Slapi_Entry
*rawentry, Slap
slapi_mod_dump(mod, 0);
}
}
-
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name, "<--
_pre_ds_mod_user_cb -- end\n");
return;
@@ -925,6 +953,12 @@ posix_winsync_pre_ds_mod_group_cb(void *cbdata, const Slapi_Entry
*rawentry, Sla
int rc;
windows_attribute_map *attr_map = group_attribute_map;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
if (posix_winsync_config_get_msSFUSchema())
attr_map = group_mssfu_attribute_map;
@@ -1020,6 +1054,7 @@ posix_winsync_pre_ds_mod_group_cb(void *cbdata, const Slapi_Entry
*rawentry, Sla
slapi_mod_dump(mod, 0);
}
}
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- _pre_ds_mod_group_cb -- end\n");
@@ -1036,6 +1071,12 @@ posix_winsync_pre_ds_add_user_cb(void *cbdata, const Slapi_Entry
*rawentry, Slap
windows_attribute_map *attr_map = user_attribute_map;
int i = 0;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
if (posix_winsync_config_get_msSFUSchema())
attr_map = user_mssfu_attribute_map;
@@ -1110,6 +1151,7 @@ posix_winsync_pre_ds_add_user_cb(void *cbdata, const Slapi_Entry
*rawentry, Slap
}
}
sync_acct_disable(cbdata, rawentry, ds_entry, ACCT_DISABLE_TO_DS, ds_entry, NULL,
NULL);
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name, "<--
_pre_ds_add_user_cb -- end\n");
return;
@@ -1124,6 +1166,12 @@ posix_winsync_pre_ds_add_group_cb(void *cbdata, const Slapi_Entry
*rawentry, Sla
PRBool posixval = PR_FALSE;
windows_attribute_map *attr_map = group_attribute_map;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
if (posix_winsync_config_get_msSFUSchema())
attr_map = group_mssfu_attribute_map;
@@ -1170,7 +1218,7 @@ posix_winsync_pre_ds_add_group_cb(void *cbdata, const Slapi_Entry
*rawentry, Sla
addGroupMembership(ds_entry, ad_entry);
memberUidUnlock();
}
-
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- posix_winsync_pre_ds_add_group_cb -- end\n");
@@ -1217,6 +1265,12 @@ posix_winsync_pre_ad_mod_user_mods_cb(void *cbdata, const
Slapi_Entry *rawentry,
LDAPMod *mod = NULL;
windows_attribute_map *attr_map = user_attribute_map;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
if (posix_winsync_config_get_msSFUSchema())
attr_map = user_mssfu_attribute_map;
@@ -1271,6 +1325,7 @@ posix_winsync_pre_ad_mod_user_mods_cb(void *cbdata, const
Slapi_Entry *rawentry,
slapi_mods_free(&smods);
slapi_mods_free(&new_smods);
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- _pre_ad_mod_user_mods_cb -- end\n");
@@ -1287,6 +1342,12 @@ posix_winsync_pre_ad_mod_group_mods_cb(void *cbdata, const
Slapi_Entry *rawentry
LDAPMod *mod = NULL;
windows_attribute_map *attr_map = group_attribute_map;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
if (posix_winsync_config_get_msSFUSchema())
attr_map = group_mssfu_attribute_map;
@@ -1338,6 +1399,7 @@ posix_winsync_pre_ad_mod_group_mods_cb(void *cbdata, const
Slapi_Entry *rawentry
}
slapi_mods_free(&smods);
slapi_mods_free(&new_smods);
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- _pre_ad_mod_group_mods_cb -- end\n");
@@ -1362,10 +1424,16 @@ static void
posix_winsync_begin_update_cb(void *cbdata, const Slapi_DN *ds_subtree, const Slapi_DN
*ad_subtree,
int is_total)
{
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"--> posix_winsync_begin_update_cb -- begin\n");
-
posix_winsync_config_reset_MOFTaskCreated();
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- posix_winsync_begin_update_cb -- end\n");
@@ -1378,6 +1446,12 @@ posix_winsync_end_update_cb(void *cbdata, const Slapi_DN
*ds_subtree, const Slap
int is_total)
{
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"--> posix_winsync_end_update_cb -- begin %d %d\n",
posix_winsync_config_get_MOFTaskCreated(),
@@ -1397,6 +1471,7 @@ posix_winsync_end_update_cb(void *cbdata, const Slapi_DN
*ds_subtree, const Slap
"posix_winsync_end_update_cb: "
"failed to create task dn:
cn=%s,%s,cn=tasks,cn=config\n",
posix_winsync_plugin_name, MEMBEROFTASK);
+ plugin_op_finished();
return;
}
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
@@ -1438,7 +1513,7 @@ posix_winsync_end_update_cb(void *cbdata, const Slapi_DN
*ds_subtree, const Slap
pb = NULL;
posix_winsync_config_reset_MOFTaskCreated();
}
-
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- posix_winsync_end_update_cb -- end\n");
@@ -1573,6 +1648,12 @@ posix_winsync_pre_ad_add_user_cb(void *cookie, Slapi_Entry
*ad_entry, Slapi_Entr
windows_attribute_map *attr_map=user_attribute_map;
int rc = 0;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
if(posix_winsync_config_get_msSFUSchema())
attr_map=user_mssfu_attribute_map;
@@ -1636,6 +1717,7 @@ posix_winsync_pre_ad_add_user_cb(void *cookie, Slapi_Entry
*ad_entry, Slapi_Entr
}
}
}
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- _pre_ad_add_user_cb -- end\n");
@@ -1649,6 +1731,12 @@ posix_winsync_pre_ad_add_group_cb(void *cookie, Slapi_Entry
*ad_entry, Slapi_Ent
windows_attribute_map *attr_map = group_attribute_map;
int rc = 0;
+ plugin_op_started();
+ if(!get_plugin_started()){
+ plugin_op_finished();
+ return;
+ }
+
if (posix_winsync_config_get_msSFUSchema()) {
attr_map=group_mssfu_attribute_map;
}
@@ -1708,6 +1796,7 @@ posix_winsync_pre_ad_add_group_cb(void *cookie, Slapi_Entry
*ad_entry, Slapi_Ent
}
}
}
+ plugin_op_finished();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- _pre_ad_add_group_cb -- end\n");
@@ -1871,6 +1960,8 @@ posix_winsync_plugin_start(Slapi_PBlock *pb)
ldap_err2string(rc));
return (-1);
}
+ g_plugin_started = 1;
+ op_counter = slapi_counter_new();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- posix_winsync_plugin_start -- registered; end\n");
@@ -1883,7 +1974,10 @@ posix_winsync_plugin_close(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"--> posix_winsync_plugin_close -- begin\n");
+ g_plugin_started = 0;
+ plugin_op_all_finished();
slapi_apib_unregister(WINSYNC_v1_0_GUID);
+ posix_winsync_config_free();
slapi_log_error(SLAPI_LOG_PLUGIN, posix_winsync_plugin_name,
"<-- posix_winsync_plugin_close -- end\n");
@@ -1933,3 +2027,29 @@ posix_winsync_plugin_init(Slapi_PBlock *pb)
return 0;
}
+PRUint64
+get_plugin_started()
+{
+ return g_plugin_started;
+}
+
+void
+plugin_op_started()
+{
+ slapi_counter_increment(op_counter);
+}
+
+void
+plugin_op_finished()
+{
+ slapi_counter_decrement(op_counter);
+}
+
+void
+plugin_op_all_finished()
+{
+ while(slapi_counter_get_value(op_counter) > 0){
+ PR_Sleep(PR_MillisecondsToInterval(100));
+ }
+ slapi_counter_destroy(&op_counter);
+}
diff --git a/ldap/servers/plugins/posix-winsync/posix-wsp-ident.h
b/ldap/servers/plugins/posix-winsync/posix-wsp-ident.h
index f36fe40..24b4052 100644
--- a/ldap/servers/plugins/posix-winsync/posix-wsp-ident.h
+++ b/ldap/servers/plugins/posix-winsync/posix-wsp-ident.h
@@ -34,6 +34,7 @@ typedef struct posix_winsync_config_struct {
} POSIX_WinSync_Config;
int posix_winsync_config(Slapi_Entry *config_e);
+void posix_winsync_config_free();
POSIX_WinSync_Config *posix_winsync_get_config();
PRBool posix_winsync_config_get_mapMemberUid();
PRBool posix_winsync_config_get_msSFUSchema();
@@ -49,5 +50,9 @@ int posix_group_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *eAfter, int *returncode, char *returntext,
void *arg);
+PRUint64 get_plugin_started();
+void plugin_op_started();
+void plugin_op_finished();
+void plugin_op_all_finished();
#endif
diff --git a/ldap/servers/plugins/referint/referint.c
b/ldap/servers/plugins/referint/referint.c
index 4c99666..9ffd038 100644
--- a/ldap/servers/plugins/referint/referint.c
+++ b/ldap/servers/plugins/referint/referint.c
@@ -81,6 +81,7 @@ typedef struct referint_config {
int logchanges;
char **attrs;
} referint_config;
+
Slapi_RWLock *config_rwlock = NULL;
/* function prototypes */
@@ -115,7 +116,6 @@ static PRThread *referint_tid = NULL;
static PRLock *keeprunning_mutex = NULL;
static PRCondVar *keeprunning_cv = NULL;
static int keeprunning = 0;
-static int refint_started = 0;
static referint_config *config = NULL;
static Slapi_DN* _ConfigAreaDN = NULL;
static Slapi_DN* _pluginDN = NULL;
@@ -204,7 +204,7 @@ referint_postop_init( Slapi_PBlock *pb )
int delfn = SLAPI_PLUGIN_POST_DELETE_FN;
int mdnfn = SLAPI_PLUGIN_POST_MODRDN_FN;
int modfn = SLAPI_PLUGIN_POST_MODIFY_FN; /* for config changes */
- char *preop_plugin_type = NULL;
+ char *preop_plugin_type = "preoperation";
/*
* Get plugin identity and stored it for later use.
@@ -341,6 +341,10 @@ load_config(Slapi_PBlock *pb, Slapi_Entry *config_entry, int apply)
int argc = 0;
int rc = SLAPI_PLUGIN_SUCCESS;
+ if(config_entry == NULL){
+ return rc;
+ }
+
slapi_rwlock_wrlock(config_rwlock);
if(config == NULL){
@@ -657,11 +661,6 @@ referint_postop_del( Slapi_PBlock *pb )
int oprc;
int rc = SLAPI_PLUGIN_SUCCESS;
- if (0 == refint_started) {
- /* not initialized yet */
- return SLAPI_PLUGIN_SUCCESS;
- }
-
if ( slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION, &isrepop ) != 0 ||
slapi_pblock_get( pb, SLAPI_DELETE_TARGET_SDN, &sdn ) != 0 ||
slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0)
@@ -1383,8 +1382,6 @@ int referint_postop_start( Slapi_PBlock *pb)
}
}
- refint_started = 1;
-
bail:
slapi_free_search_results_internal(search_pb);
slapi_pblock_destroy(search_pb);
@@ -1407,8 +1404,13 @@ int referint_postop_close( Slapi_PBlock *pb)
}
slapi_destroy_rwlock(config_rwlock);
+ config_rwlock = NULL;
+
+ slapi_ch_free_string(&config->logfile);
+ slapi_ch_array_free(config->attrs);
+ slapi_ch_free((void **)&config);
+
- refint_started = 0;
return(0);
}
@@ -1758,6 +1760,7 @@ referint_validate_config(Slapi_PBlock *pb)
slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
"referint_validate_config: "
"configuration validation failed.\n");
rc = LDAP_UNWILLING_TO_PERFORM;
+ goto bail;
}
} else if (slapi_sdn_compare(sdn, referint_get_plugin_area()) == 0){
/*
diff --git a/ldap/servers/plugins/retrocl/retrocl.c
b/ldap/servers/plugins/retrocl/retrocl.c
index af410f0..0d2a6dc 100644
--- a/ldap/servers/plugins/retrocl/retrocl.c
+++ b/ldap/servers/plugins/retrocl/retrocl.c
@@ -74,7 +74,6 @@ void plugin_init_debug_level(int *level_ptr)
#endif
void* g_plg_identity [PLUGIN_MAX];
-
Slapi_Backend *retrocl_be_changelog = NULL;
PRLock *retrocl_internal_lock = NULL;
Slapi_RWLock *retrocl_cn_lock;
@@ -88,7 +87,7 @@ int retrocl_log_deleted = 0;
static Slapi_PluginDesc retrocldesc = {"retrocl", VENDOR, DS_PACKAGE_VERSION,
"Retrocl Plugin"};
static Slapi_PluginDesc retroclpostopdesc = {"retrocl-postop", VENDOR,
DS_PACKAGE_VERSION, "retrocl post-operation plugin"};
static Slapi_PluginDesc retroclinternalpostopdesc = {"retrocl-internalpostop",
VENDOR, DS_PACKAGE_VERSION, "retrocl internal post-operation plugin"};
-
+static int legacy_initialised= 0;
/*
* Function: retrocl_*
@@ -188,19 +187,19 @@ retrocl_internalpostop_init( Slapi_PBlock *pb )
*
* Returns: LDAP_SUCCESS
*
- * Arguments: none
+ * Arguments: Slapi_PBlock
*
* Description: The FE DSE *must* be initialised before we get here.
*
*/
-static int retrocl_rootdse_init(void)
+static int retrocl_rootdse_init(Slapi_PBlock *pb)
{
int return_value= LDAP_SUCCESS;
- slapi_config_register_callback(SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,"",
+ slapi_config_register_callback_plugin(SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP |
DSE_FLAG_PLUGIN, "",
LDAP_SCOPE_BASE,"(objectclass=*)",
- retrocl_rootdse_search,NULL);
+ retrocl_rootdse_search, NULL, pb);
return return_value;
}
@@ -322,16 +321,11 @@ char *retrocl_get_config_str(const char *attrt)
static int retrocl_start (Slapi_PBlock *pb)
{
- static int retrocl_started = 0;
int rc = 0;
Slapi_Entry *e = NULL;
char **values = NULL;
- if (retrocl_started) {
- return rc;
- }
-
- retrocl_rootdse_init();
+ retrocl_rootdse_init(pb);
rc = retrocl_select_backend();
@@ -408,8 +402,6 @@ static int retrocl_start (Slapi_PBlock *pb)
slapi_ch_array_free(values);
}
- retrocl_started = 1;
-
return 0;
}
@@ -436,6 +428,14 @@ static int retrocl_stop (Slapi_PBlock *pb)
retrocl_stop_trimming();
retrocl_be_changelog = NULL;
retrocl_forget_changenumbers();
+ PR_DestroyLock(retrocl_internal_lock);
+ retrocl_internal_lock = NULL;
+ slapi_destroy_rwlock(retrocl_cn_lock);
+ retrocl_cn_lock = NULL;
+ legacy_initialised = 0;
+
+ slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, "",
+ LDAP_SCOPE_BASE,"(objectclass=*)", retrocl_rootdse_search);
return rc;
}
@@ -454,7 +454,6 @@ static int retrocl_stop (Slapi_PBlock *pb)
int
retrocl_plugin_init(Slapi_PBlock *pb)
{
- static int legacy_initialised= 0;
int rc = 0;
int precedence = 0;
void *identity = NULL;
@@ -495,6 +494,3 @@ retrocl_plugin_init(Slapi_PBlock *pb)
legacy_initialised = 1;
return rc;
}
-
-
-
diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c
b/ldap/servers/plugins/retrocl/retrocl_po.c
index b3bfafe..0e2abc8 100644
--- a/ldap/servers/plugins/retrocl/retrocl_po.c
+++ b/ldap/servers/plugins/retrocl/retrocl_po.c
@@ -572,7 +572,7 @@ modrdn2reple(
*
*/
-int retrocl_postob (Slapi_PBlock *pb,int optype)
+int retrocl_postob (Slapi_PBlock *pb, int optype)
{
char *dn;
LDAPMod **log_m = NULL;
@@ -630,10 +630,10 @@ int retrocl_postob (Slapi_PBlock *pb,int optype)
return SLAPI_PLUGIN_SUCCESS;
}
- if (operation_is_flag_set(op, OP_FLAG_TOMBSTONE_ENTRY)){
+ if (operation_is_flag_set(op, OP_FLAG_TOMBSTONE_ENTRY)){
LDAPDebug0Args(LDAP_DEBUG_TRACE,"not applying change for nsTombstone
entries\n");
return SLAPI_PLUGIN_SUCCESS;
- }
+ }
switch ( optype ) {
case OP_MODIFY:
@@ -650,9 +650,9 @@ int retrocl_postob (Slapi_PBlock *pb,int optype)
}
break;
case OP_DELETE:
- if (retrocl_log_deleted)
- (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &te);
- break;
+ if (retrocl_log_deleted)
+ (void)slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &te);
+ break;
case OP_MODRDN:
/* newrdn is used just for logging; no need to be normalized */
(void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn );
@@ -662,7 +662,6 @@ int retrocl_postob (Slapi_PBlock *pb,int optype)
break;
}
-
/* check if we should log change to retro changelog, and
* if so, do it here */
write_replog_db( pb, optype, dn, log_m, flag, curtime, te,
diff --git a/ldap/servers/plugins/roles/roles_cache.c
b/ldap/servers/plugins/roles/roles_cache.c
index a7e489e..16e450f 100644
--- a/ldap/servers/plugins/roles/roles_cache.c
+++ b/ldap/servers/plugins/roles/roles_cache.c
@@ -693,6 +693,8 @@ void roles_cache_stop()
current_role = next_role;
}
slapi_rwlock_unlock(global_lock);
+ slapi_ch_free((void **)&vattr_handle);
+ roles_list = NULL;
slapi_log_error( SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, "<--
roles_cache_stop\n");
}
@@ -797,6 +799,11 @@ void roles_cache_change_notify(Slapi_PBlock *pb)
int do_update = 0;
int rc = -1;
+ if (!slapi_plugin_running(pb)) {
+ /* not initialized yet */
+ return ;
+ }
+
slapi_log_error(SLAPI_LOG_PLUGIN,
ROLES_PLUGIN_SUBSYSTEM,
"--> roles_cache_change_notify\n");
@@ -943,7 +950,6 @@ if ( e != NULL )
}
}
-
slapi_log_error( SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, "<--
roles_cache_change_notify\n");
}
@@ -1579,7 +1585,7 @@ int roles_cache_listroles_ext(vattr_context *c, Slapi_Entry *entry,
int return_v
}
/* Free the list (we already did that) */
}
- else
+ else
{
if ( return_values )
{
@@ -2116,9 +2122,11 @@ static void roles_cache_role_def_free(roles_cache_def *role_def)
slapi_destroy_mutex(role_def->change_lock);
role_def->change_lock = NULL;
slapi_destroy_condvar(role_def->something_changed);
+ role_def->something_changed = NULL;
slapi_destroy_mutex(role_def->create_lock);
role_def->create_lock = NULL;
slapi_destroy_condvar(role_def->suffix_created);
+ role_def->suffix_created = NULL;
slapi_ch_free((void**)&role_def->notified_dn);
if ( role_def->notified_entry != NULL )
diff --git a/ldap/servers/plugins/roles/roles_plugin.c
b/ldap/servers/plugins/roles/roles_plugin.c
index b00e9a7..80794df 100644
--- a/ldap/servers/plugins/roles/roles_plugin.c
+++ b/ldap/servers/plugins/roles/roles_plugin.c
@@ -209,7 +209,7 @@ static int roles_start( Slapi_PBlock *pb )
slapi_log_error( SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM,
"=> roles_start\n" );
-
+
roles_cache_init();
/* from Pete Rowley for vcache
@@ -222,7 +222,12 @@ static int roles_start( Slapi_PBlock *pb )
if(!slapi_apib_get_interface(StateChange_v1_0_GUID, &statechange_api))
{
- statechange_register(statechange_api, STATECHANGE_ROLES_ID, NULL,
STATECHANGE_ROLES_CONFG_FILTER, &vattr_global_invalidate, (notify_callback)
statechange_vattr_cache_invalidator_callback(statechange_api));
+ statechange_register(statechange_api,
+ STATECHANGE_ROLES_ID,
+ NULL,
+ STATECHANGE_ROLES_CONFG_FILTER,
+ &vattr_global_invalidate,
+ (notify_callback)
statechange_vattr_cache_invalidator_callback(statechange_api));
}
slapi_log_error( SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM,
@@ -236,13 +241,22 @@ static int roles_start( Slapi_PBlock *pb )
*/
static int roles_close( Slapi_PBlock *pb )
{
+ void **statechange_api;
int rc = 0;
slapi_log_error( SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM,
"=> roles_close\n" );
-
+
roles_cache_stop();
+ if(!slapi_apib_get_interface(StateChange_v1_0_GUID, &statechange_api))
+ {
+ statechange_unregister(statechange_api,
+ NULL,
+ STATECHANGE_ROLES_CONFG_FILTER,
+ (notify_callback)
statechange_vattr_cache_invalidator_callback(statechange_api));
+ }
+
slapi_log_error( SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM,
"<= roles_close %d\n", rc );
return rc;
diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c
b/ldap/servers/plugins/rootdn_access/rootdn_access.c
index 5328462..9122f9b 100644
--- a/ldap/servers/plugins/rootdn_access/rootdn_access.c
+++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c
@@ -79,6 +79,7 @@
*/
int rootdn_init(Slapi_PBlock *pb);
static int rootdn_start(Slapi_PBlock *pb);
+static int rootdn_close(Slapi_PBlock *pb);
static int rootdn_load_config(Slapi_PBlock *pb);
static int rootdn_check_access(Slapi_PBlock *pb);
static int rootdn_check_host_wildcard(char *host, char *client_host);
@@ -91,7 +92,6 @@ char * strToLower(char *str);
*/
static void *_PluginID = NULL;
static char *_PluginDN = NULL;
-static int g_plugin_started = 0;
static int open_time = 0;
static int close_time = 0;
static char *daysAllowed = NULL;
@@ -149,6 +149,7 @@ rootdn_init(Slapi_PBlock *pb){
/* Register callbacks */
if(slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01) != 0 ||
slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, (void *) rootdn_start) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *) rootdn_close) != 0 ||
slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *) &pdesc) != 0 )
{
slapi_log_error(SLAPI_LOG_FATAL, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_init:
failed to register plugin\n");
@@ -200,23 +201,29 @@ rootdn_preop_bind_init(Slapi_PBlock *pb)
static int
rootdn_start(Slapi_PBlock *pb)
{
- /* Check if we're already started */
- if (g_plugin_started) {
- goto done;
- }
-
slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "-->
rootdn_start\n");
- g_plugin_started = 1;
rootdn_set_plugin_dn(ROOTDN_PLUGIN_DN);
slapi_log_error(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "<--
rootdn_start\n");
-done:
return 0;
}
static int
+rootdn_close(Slapi_PBlock *pb)
+{
+ slapi_ch_free_string(&daysAllowed);
+ slapi_ch_array_free(hosts);
+ slapi_ch_array_free(hosts_to_deny);
+ slapi_ch_array_free(ips);
+ slapi_ch_array_free(ips);
+
+ return 0;
+}
+
+
+static int
rootdn_load_config(Slapi_PBlock *pb)
{
Slapi_Entry *e = NULL;
@@ -430,7 +437,7 @@ rootdn_check_access(Slapi_PBlock *pb){
struct tm *timeinfo;
char *dnsName = NULL;
int isRoot = 0;
- int rc = 0;
+ int rc = SLAPI_PLUGIN_SUCCESS;
int i;
/*
@@ -438,7 +445,7 @@ rootdn_check_access(Slapi_PBlock *pb){
*/
slapi_pblock_get ( pb, SLAPI_REQUESTOR_ISROOT, &isRoot );
if(!isRoot){
- return 0;
+ return SLAPI_PLUGIN_SUCCESS;
}
/*
* grab the current time/info if we need it
diff --git a/ldap/servers/plugins/schema_reload/schema_reload.c
b/ldap/servers/plugins/schema_reload/schema_reload.c
index efc0de2..6cf1181 100644
--- a/ldap/servers/plugins/schema_reload/schema_reload.c
+++ b/ldap/servers/plugins/schema_reload/schema_reload.c
@@ -85,6 +85,7 @@ static int schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *eAfter, int *returncode, char *returntext,
void *arg);
static int schemareload_start(Slapi_PBlock *pb);
+static int schemareload_close(Slapi_PBlock *pb);
/*
* Init function
@@ -94,18 +95,14 @@ int
schemareload_init( Slapi_PBlock *pb )
{
int rc = 0;
- schemareload_lock = PR_NewLock();
- if (NULL == schemareload_lock) {
- slapi_log_error(SLAPI_LOG_FATAL, "schemareload",
- "Failed to create global schema reload lock.");
- return rc;
- }
+
rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
(void *) SLAPI_PLUGIN_VERSION_03 );
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
(void *)&pdesc );
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN,
(void *) schemareload_start );
+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN, (void *) schemareload_close );
return rc;
}
@@ -117,10 +114,28 @@ schemareload_init( Slapi_PBlock *pb )
static int
schemareload_start(Slapi_PBlock *pb)
{
- int rc = slapi_task_register_handler("schema reload task",
schemareload_add);
+ int rc = 0;
+
+ if ((schemareload_lock = PR_NewLock()) == NULL) {
+ slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Failed to create
global schema reload lock.");
+ return -1;
+ }
+ rc = slapi_plugin_task_register_handler("schema reload task",
schemareload_add, pb);
+ if(rc != LDAP_SUCCESS){
+ PR_DestroyLock(schemareload_lock);
+ }
+
return rc;
}
+static int
+schemareload_close(Slapi_PBlock *pb)
+{
+ PR_DestroyLock(schemareload_lock);
+
+ return 0;
+}
+
typedef struct _task_data
{
char *schemadir;
@@ -207,6 +222,7 @@ static const char *fetch_attr(Slapi_Entry *e, const char *attrname,
if (slapi_entry_attr_find(e, attrname, &attr) != 0)
return default_val;
slapi_attr_first_value(attr, &val);
+
return slapi_value_get_string(val);
}
@@ -239,7 +255,6 @@ schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e,
int rv = SLAPI_DSE_CALLBACK_OK;
Slapi_Task *task = NULL;
task_data *mytaskdata = NULL;
-
char *bind_dn;
*returncode = LDAP_SUCCESS;
@@ -256,7 +271,7 @@ schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e,
schemadir = fetch_attr(e, "schemadir", NULL);
/* allocate new task now */
- task = slapi_new_task(slapi_entry_get_ndn(e));
+ task = slapi_plugin_new_task(slapi_entry_get_ndn(e), pb);
if (task == NULL) {
slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "unable to
allocate new task!\n");
*returncode = LDAP_OPERATIONS_ERROR;
@@ -290,12 +305,12 @@ schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e,
"unable to create schema reload task thread!\n");
*returncode = LDAP_OPERATIONS_ERROR;
rv = SLAPI_DSE_CALLBACK_ERROR;
- slapi_task_finish(task, *returncode);
} else {
/* thread successful */
rv = SLAPI_DSE_CALLBACK_OK;
}
out:
+
return rv;
}
diff --git a/ldap/servers/plugins/statechange/statechange.c
b/ldap/servers/plugins/statechange/statechange.c
index 307ea75..ad2cc0a 100644
--- a/ldap/servers/plugins/statechange/statechange.c
+++ b/ldap/servers/plugins/statechange/statechange.c
@@ -72,6 +72,13 @@ static SCNotify *head; /* a place to start in the list */
static void *api[5];
static Slapi_Mutex *buffer_lock = 0;
+static PRUint64 g_plugin_started = 0;
+
+/*
+ * We can not fully use the built in plugin counter in the statechange plugin,
+ * so we have to use our own.
+ */
+static Slapi_Counter *op_counter = NULL;
/* other function prototypes */
int statechange_init( Slapi_PBlock *pb );
@@ -189,6 +196,10 @@ static int statechange_start( Slapi_PBlock *pb )
}
head = 0;
+ if(ret == SLAPI_PLUGIN_SUCCESS){
+ op_counter = slapi_counter_new();
+ g_plugin_started = 1;
+ }
slapi_log_error( SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "<--
statechange_start\n");
return ret;
@@ -203,7 +214,16 @@ static int statechange_close( Slapi_PBlock *pb )
{
slapi_log_error( SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "-->
statechange_close\n");
+ g_plugin_started = 0;
+
+ while(slapi_counter_get_value(op_counter) > 0){
+ PR_Sleep(PR_MillisecondsToInterval(100));
+ }
+ slapi_counter_destroy(&op_counter);
+
slapi_apib_unregister(StateChange_v1_0_GUID);
+ slapi_destroy_mutex(buffer_lock);
+ buffer_lock = NULL;
slapi_log_error( SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "<--
statechange_close\n");
@@ -250,13 +270,13 @@ static int statechange_post_op( Slapi_PBlock *pb, int modtype )
struct slapi_entry *e_before = NULL;
struct slapi_entry *e_after = NULL;
- if(head == 0)
+ if(head == 0){
return SLAPI_PLUGIN_SUCCESS;
+ }
slapi_log_error( SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "-->
statechange_post_op\n");
/* evaluate this operation against the notification entries */
-
slapi_lock_mutex(buffer_lock);
if(head)
{
@@ -315,8 +335,8 @@ static int statechange_post_op( Slapi_PBlock *pb, int modtype )
}
bail:
slapi_unlock_mutex(buffer_lock);
-
slapi_log_error( SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "<--
statechange_post_op\n");
+
return SLAPI_PLUGIN_SUCCESS; /* always succeed */
}
@@ -326,8 +346,13 @@ static int _statechange_register(char *caller_id, char *dn, char
*filter, void *
int ret = SLAPI_PLUGIN_FAILURE;
SCNotify *item;
+ slapi_counter_increment(op_counter);
+ if (!g_plugin_started) {
+ slapi_counter_decrement(op_counter);
+ return ret;
+ }
+
/* simple - we don't check for duplicates */
-
item = (SCNotify*)slapi_ch_malloc(sizeof(SCNotify));
if(item)
{
@@ -352,6 +377,7 @@ static int _statechange_register(char *caller_id, char *dn, char
*filter, void *
slapi_ch_free_string(&item->filter);
slapi_ch_free_string(&writable_filter);
slapi_ch_free((void **)&item);
+ slapi_counter_decrement(op_counter);
return ret;
} else if (!writable_filter) {
item->realfilter = NULL;
@@ -377,6 +403,7 @@ static int _statechange_register(char *caller_id, char *dn, char
*filter, void *
ret = SLAPI_PLUGIN_SUCCESS;
}
+ slapi_counter_decrement(op_counter);
return ret;
}
@@ -386,8 +413,11 @@ static void *_statechange_unregister(char *dn, char *filter,
notify_callback the
void *ret = NULL;
SCNotify *func = NULL;
- if(buffer_lock == 0)
+ slapi_counter_increment(op_counter);
+ if (!g_plugin_started || !buffer_lock) {
+ slapi_counter_decrement(op_counter);
return ret;
+ }
slapi_lock_mutex(buffer_lock);
@@ -413,6 +443,7 @@ static void *_statechange_unregister(char *dn, char *filter,
notify_callback the
}
slapi_unlock_mutex(buffer_lock);
+ slapi_counter_decrement(op_counter);
return ret;
}
@@ -422,12 +453,14 @@ static void _statechange_unregister_all(char *caller_id,
caller_data_free_callba
SCNotify *notify = head;
SCNotify *start_notify = head;
- if(buffer_lock == 0)
+ slapi_counter_increment(op_counter);
+ if (!g_plugin_started || !buffer_lock) {
+ slapi_counter_decrement(op_counter);
return;
+ }
slapi_lock_mutex(buffer_lock);
-
if(notify)
{
do
@@ -463,6 +496,7 @@ static void _statechange_unregister_all(char *caller_id,
caller_data_free_callba
}
slapi_unlock_mutex(buffer_lock);
+ slapi_counter_decrement(op_counter);
}
/* this func needs looking at to make work */
diff --git a/ldap/servers/plugins/sync/sync.h b/ldap/servers/plugins/sync/sync.h
index 8cdc7d0..9168039 100644
--- a/ldap/servers/plugins/sync/sync.h
+++ b/ldap/servers/plugins/sync/sync.h
@@ -85,6 +85,7 @@ typedef struct sync_callback {
} Sync_CallBackData;
int sync_register_operation_extension(void);
+int sync_unregister_operation_entension(void);
int sync_srch_refresh_pre_search(Slapi_PBlock *pb);
int sync_srch_refresh_post_search(Slapi_PBlock *pb);
diff --git a/ldap/servers/plugins/sync/sync_init.c
b/ldap/servers/plugins/sync/sync_init.c
index d648c79..3b54367 100644
--- a/ldap/servers/plugins/sync/sync_init.c
+++ b/ldap/servers/plugins/sync/sync_init.c
@@ -117,6 +117,7 @@ sync_preop_init( Slapi_PBlock *pb )
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ENTRY_FN, (void *)
sync_srch_refresh_pre_entry);
rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_RESULT_FN, (void *)
sync_srch_refresh_pre_result);
rc |= sync_register_operation_extension();
+
return(rc);
}
@@ -169,6 +170,8 @@ sync_start(Slapi_PBlock * pb)
static int
sync_close(Slapi_PBlock * pb)
{
- sync_persist_terminate_all();
+ sync_persist_terminate_all();
+ sync_unregister_operation_entension();
+
return (0);
}
diff --git a/ldap/servers/plugins/sync/sync_persist.c
b/ldap/servers/plugins/sync/sync_persist.c
index 680bcf6..4216a87 100644
--- a/ldap/servers/plugins/sync/sync_persist.c
+++ b/ldap/servers/plugins/sync/sync_persist.c
@@ -54,7 +54,8 @@ static SyncRequestList *sync_request_list = NULL;
*/
#define SYNC_IS_INITIALIZED() (sync_request_list != NULL)
-
+static int plugin_closing = 0;
+static PRUint64 thread_count = 0;
static int sync_add_request( SyncRequest *req );
static void sync_remove_request( SyncRequest *req );
static SyncRequest *sync_request_alloc();
@@ -73,8 +74,10 @@ int sync_add_persist_post_op(Slapi_PBlock *pb)
if ( !SYNC_IS_INITIALIZED()) {
return(0);
}
+
slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
sync_queue_change(e, NULL, LDAP_REQ_ADD);
+
return( 0 );
}
@@ -85,8 +88,10 @@ int sync_del_persist_post_op(Slapi_PBlock *pb)
if ( !SYNC_IS_INITIALIZED()) {
return(0);
}
+
slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e);
sync_queue_change(e, NULL, LDAP_REQ_DELETE);
+
return( 0 );
}
@@ -97,8 +102,10 @@ int sync_mod_persist_post_op(Slapi_PBlock *pb)
if ( !SYNC_IS_INITIALIZED()) {
return(0);
}
+
slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
sync_queue_change(e, NULL, LDAP_REQ_MODIFY);
+
return( 0 );
}
@@ -109,9 +116,11 @@ int sync_modrdn_persist_post_op(Slapi_PBlock *pb)
if ( !SYNC_IS_INITIALIZED()) {
return(0);
}
+
slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e_prev);
sync_queue_change(e, e_prev, LDAP_REQ_MODRDN);
+
return( 0 );
}
@@ -258,6 +267,7 @@ sync_persist_initialize (int argc, char **argv)
sync_request_list->sync_req_max_persist = SYNC_MAX_CONCURRENT;
}
}
+ plugin_closing = 0;
}
return (0);
}
@@ -307,6 +317,7 @@ sync_persist_add (Slapi_PBlock *pb)
slapi_ch_free((void **) &req->req_pblock );
slapi_ch_free((void **) &req );
} else {
+ thread_count++;
return( req->req_tid);
}
}
@@ -365,19 +376,27 @@ sync_persist_terminate (PRThread *tid)
}
return(rc);
}
+
+/*
+ * Called when stopping/disabling the plugin
+ */
int
sync_persist_terminate_all ()
{
- SyncRequest *cur;
-
if ( SYNC_IS_INITIALIZED() ) {
- SYNC_LOCK_READ();
- cur = sync_request_list->sync_req_head;
- while ( NULL != cur ) {
- cur->req_complete = PR_TRUE;
- cur = cur->req_next;
+ /* signal the threads to stop */
+ plugin_closing = 1;
+ sync_request_wakeup_all();
+
+ /* wait for all the threads to finish */
+ while(thread_count > 0){
+ PR_Sleep(PR_SecondsToInterval(1));
}
- SYNC_UNLOCK_READ();
+
+ slapi_destroy_rwlock(sync_request_list->sync_req_rwlock);
+ PR_DestroyLock( sync_request_list->sync_req_cvarlock);
+ PR_DestroyCondVar(sync_request_list->sync_req_cvar);
+ slapi_ch_free((void **)&sync_request_list);
}
return (0);
@@ -478,6 +497,7 @@ sync_request_wakeup_all()
PR_Unlock( sync_request_list->sync_req_cvarlock );
}
}
+
static int
sync_acquire_connection (Slapi_Connection *conn)
{
@@ -559,7 +579,7 @@ sync_send_results( void *arg )
PR_Lock( sync_request_list->sync_req_cvarlock );
- while ( (conn_acq_flag == 0) && !req->req_complete ) {
+ while ( (conn_acq_flag == 0) && !req->req_complete &&
!plugin_closing) {
/* Check for an abandoned operation */
Slapi_Operation *op;
slapi_pblock_get(req->req_pblock, SLAPI_OPERATION, &op);
@@ -637,7 +657,7 @@ sync_send_results( void *arg )
ectrls = (LDAPControl **)slapi_ch_calloc(2, sizeof (LDAPControl *));
if (req->req_cookie)
sync_cookie_update(req->req_cookie, ec);
- sync_create_state_control(ec, &ectrls[0], chg_type, req->req_cookie);
+ sync_create_state_control(ec, &ectrls[0], chg_type, req->req_cookie);
rc = slapi_send_ldap_search_entry( req->req_pblock,
ec, ectrls,
noattrs?noattrs:attrs, attrsonly );
@@ -675,6 +695,7 @@ sync_send_results( void *arg )
sync_node_free( &qnode );
}
slapi_ch_free((void **) &req );
+ thread_count--;
}
diff --git a/ldap/servers/plugins/sync/sync_refresh.c
b/ldap/servers/plugins/sync/sync_refresh.c
index c506a8a..4b02659 100644
--- a/ldap/servers/plugins/sync/sync_refresh.c
+++ b/ldap/servers/plugins/sync/sync_refresh.c
@@ -740,3 +740,14 @@ sync_register_operation_extension(void)
&sync_extension_type,
&sync_extension_handle);
}
+
+int
+sync_unregister_operation_entension(void)
+{
+ int rc = slapi_unregister_object_extension(SYNC_PLUGIN_SUBSYSTEM,
+ SLAPI_EXT_OPERATION,
+ &sync_extension_type,
+ &sync_extension_handle);
+
+ return rc;
+}
diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c
index 73323b3..837dc2e 100644
--- a/ldap/servers/plugins/usn/usn.c
+++ b/ldap/servers/plugins/usn/usn.c
@@ -51,7 +51,7 @@ static int usn_preop_init(Slapi_PBlock *pb);
static int usn_bepreop_init(Slapi_PBlock *pb);
static int usn_betxnpreop_init(Slapi_PBlock *pb);
static int usn_bepostop_init(Slapi_PBlock *pb);
-static int usn_rootdse_init();
+static int usn_rootdse_init(Slapi_PBlock *pb);
static int usn_preop_delete(Slapi_PBlock *pb);
static int usn_bepreop_modify(Slapi_PBlock *pb);
@@ -68,7 +68,6 @@ static int usn_get_attr(Slapi_PBlock *pb, const char* type, void
*value);
static int usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e,
Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg);
-static int g_plugin_started = 0;
/*
* Register USN plugin
* Note: USN counter initialization is done in the backend (ldbm_usn_init).
@@ -234,13 +233,13 @@ usn_bepostop_init(Slapi_PBlock *pb)
}
static int
-usn_rootdse_init()
+usn_rootdse_init(Slapi_PBlock *pb)
{
int rc = SLAPI_PLUGIN_FAILURE;
- if (slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
+ if (slapi_config_register_callback_plugin(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP |
DSE_FLAG_PLUGIN,
"", LDAP_SCOPE_BASE,
"(objectclass=*)",
- usn_rootdse_search, NULL)) {
+ usn_rootdse_search, NULL, pb)) {
rc = SLAPI_PLUGIN_SUCCESS;
}
@@ -259,7 +258,7 @@ usn_start(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "-->
usn_start\n");
- rc = usn_rootdse_init();
+ rc = usn_rootdse_init(pb);
rc |= usn_cleanup_start(pb);
if (rc) {
rc = SLAPI_PLUGIN_FAILURE;
@@ -289,7 +288,7 @@ usn_start(Slapi_PBlock *pb)
rc = SLAPI_PLUGIN_FAILURE;
}
slapi_value_free(&value);
- g_plugin_started = 1;
+
bail:
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
"<-- usn_start (rc: %d)\n", rc);
@@ -301,7 +300,8 @@ usn_close(Slapi_PBlock *pb)
{
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "-->
usn_close\n");
- g_plugin_started = 0;
+ slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
+ "", LDAP_SCOPE_BASE, "(objectclass=*)",
usn_rootdse_search);
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "<--
usn_close\n");
@@ -433,6 +433,7 @@ usn_betxnpreop_add(Slapi_PBlock *pb)
bail:
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
"<-- usn_betxnpreop_add\n");
+
return rc;
}
@@ -469,6 +470,7 @@ usn_betxnpreop_delete(Slapi_PBlock *pb)
bail:
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
"<-- usn_betxnpreop_delete\n");
+
return rc;
}
@@ -539,6 +541,7 @@ usn_bepostop (Slapi_PBlock *pb)
bail:
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
"<-- usn_bepostop\n");
+
return rc;
}
@@ -590,6 +593,7 @@ usn_bepostop_modify (Slapi_PBlock *pb)
bail:
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
"<-- usn_bepostop_mod\n");
+
return rc;
}
@@ -626,6 +630,7 @@ usn_bepostop_delete (Slapi_PBlock *pb)
bail:
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
"<-- usn_bepostop\n");
+
return rc;
}
@@ -747,9 +752,3 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry*
entryAfter,
"<-- usn_rootdse_search\n");
return SLAPI_DSE_CALLBACK_OK;
}
-
-int
-usn_is_started()
-{
- return g_plugin_started;
-}
diff --git a/ldap/servers/plugins/usn/usn.h b/ldap/servers/plugins/usn/usn.h
index 46bcd16..8e6c5c8 100644
--- a/ldap/servers/plugins/usn/usn.h
+++ b/ldap/servers/plugins/usn/usn.h
@@ -51,7 +51,6 @@
/* usn.c */
void usn_set_identity(void *identity);
void *usn_get_identity();
-int usn_is_started();
/* usn_cleanup.c */
int usn_cleanup_start(Slapi_PBlock *pb);
diff --git a/ldap/servers/plugins/usn/usn_cleanup.c
b/ldap/servers/plugins/usn/usn_cleanup.c
index ab6362f..2b1371d 100644
--- a/ldap/servers/plugins/usn/usn_cleanup.c
+++ b/ldap/servers/plugins/usn/usn_cleanup.c
@@ -53,8 +53,8 @@ static int usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e,
int
usn_cleanup_start(Slapi_PBlock *pb)
{
- int rc = slapi_task_register_handler("USN tombstone cleanup task",
- usn_cleanup_add);
+ int rc = slapi_plugin_task_register_handler("USN tombstone cleanup task",
+ usn_cleanup_add, pb);
return rc;
}
@@ -263,13 +263,6 @@ usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry
*eAfter,
/* get the requestor dn */
slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn);
- /* make sure plugin is not closed*/
- if(!usn_is_started()){
- *returncode = LDAP_OPERATIONS_ERROR;
- rv = SLAPI_DSE_CALLBACK_ERROR;
- goto bail;
- }
-
cn = slapi_entry_attr_get_charptr(e, "cn");
if (NULL == cn) {
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
@@ -323,7 +316,7 @@ usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry
*eAfter,
cleanup_data->bind_dn = slapi_ch_strdup(bind_dn);
/* allocate new task now */
- task = slapi_new_task(slapi_entry_get_ndn(e));
+ task = slapi_plugin_new_task(slapi_entry_get_ndn(e), arg);
if (task == NULL) {
slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
"USN tombstone cleanup: unable to allocate new task.\n");
diff --git a/ldap/servers/plugins/views/views.c b/ldap/servers/plugins/views/views.c
index c6fd628..282acfd 100644
--- a/ldap/servers/plugins/views/views.c
+++ b/ldap/servers/plugins/views/views.c
@@ -116,6 +116,12 @@ struct _globalViewCache
typedef struct _globalViewCache golbalViewCache;
static golbalViewCache theCache;
+static PRUint64 g_plugin_started = 0;
+/*
+ * We can not fully use the built in plugin counter in the views plugin,
+ * so we have to use our own.
+ */
+static Slapi_Counter *op_counter = NULL;
/* other function prototypes */
int views_init( Slapi_PBlock *pb );
@@ -140,6 +146,7 @@ static int view_search_rewrite_callback(Slapi_PBlock *pb);
static void views_cache_backend_state_change(void *handle, char *be_name, int
old_be_state, int new_be_state);
static void views_cache_act_on_change_thread(void *arg);
static viewEntry *views_cache_find_view(char *view);
+static void views_cache_free();
/* our api broker published api */
static void *api[3];
@@ -245,12 +252,12 @@ static int views_start( Slapi_PBlock *pb )
theCache.cache_built = 0;
g_views_cache_lock = slapi_new_rwlock();
+ g_plugin_started = 1;
/* first register our backend state change func (we'll use func pointer as handle)
*/
slapi_register_backend_state_change((void *)views_cache_backend_state_change,
views_cache_backend_state_change);
/* create the view cache */
-
views_cache_create();
/* register callbacks for filter and search rewriting */
@@ -259,7 +266,12 @@ static int views_start( Slapi_PBlock *pb )
/* register for state changes to view configuration */
if(!slapi_apib_get_interface(StateChange_v1_0_GUID, &statechange_api))
{
- statechange_register(statechange_api, STATECHANGE_VIEWS_ID, NULL,
STATECHANGE_VIEWS_CONFG_FILTER, NULL, views_update_views_cache);
+ statechange_register(statechange_api,
+ STATECHANGE_VIEWS_ID,
+ NULL,
+ STATECHANGE_VIEWS_CONFG_FILTER,
+ NULL,
+ views_update_views_cache);
}
/* register our api so that other subsystems can be views aware */
@@ -270,7 +282,19 @@ static int views_start( Slapi_PBlock *pb )
if( slapi_apib_register(Views_v1_0_GUID, api) )
{
slapi_log_error( SLAPI_LOG_FATAL, VIEWS_PLUGIN_SUBSYSTEM, "views: failed to
publish views interface\n");
+ if(statechange_api){
+ statechange_unregister(statechange_api,
+ NULL,
+ STATECHANGE_VIEWS_CONFG_FILTER,
+ views_update_views_cache);
+ }
+ views_cache_free();
+ slapi_destroy_rwlock(g_views_cache_lock);
+ g_views_cache_lock = NULL;
+ g_plugin_started = 0;
ret = SLAPI_PLUGIN_FAILURE;
+ } else {
+ op_counter = slapi_counter_new();
}
slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "<--
views_start\n");
@@ -300,6 +324,12 @@ static int _internal_api_views_entry_exists_general(char *view_dn,
Slapi_Entry *
viewEntry *view;
char *dn;
+ slapi_counter_increment(op_counter);
+ if(g_plugin_started == 0){
+ slapi_counter_decrement(op_counter);
+ return ret;
+ }
+
/* there are two levels of scope for a view,
* from the parent of the view without a view filter
* and the parent of the top most view including a
@@ -352,10 +382,48 @@ static int _internal_api_views_entry_exists_general(char *view_dn,
Slapi_Entry *
bail:
views_unlock();
+ slapi_counter_decrement(op_counter);
+
return ret;
}
-void views_cache_free()
+/*
+ views_close
+ ---------
+ unregisters the interface for this plugin
+*/
+static int views_close( Slapi_PBlock *pb )
+{
+ void **statechange_api;
+ slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "-->
views_close\n");
+
+ g_plugin_started = 0;
+
+ while(slapi_counter_get_value(op_counter) > 0){
+ PR_Sleep(PR_MillisecondsToInterval(100));
+ }
+ slapi_counter_destroy(&op_counter);
+
+ /* unregister backend state change notification */
+ slapi_unregister_backend_state_change((void *)views_cache_backend_state_change);
+ /* unregister the api-broker callback */
+ if(!slapi_apib_get_interface(StateChange_v1_0_GUID, &statechange_api))
+ {
+ statechange_unregister(statechange_api,
+ NULL,
+ STATECHANGE_VIEWS_CONFG_FILTER,
+ views_update_views_cache);
+ }
+ views_cache_free();
+ slapi_destroy_rwlock(g_views_cache_lock);
+ g_views_cache_lock = NULL;
+
+ slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "<--
views_close\n");
+
+ return SLAPI_PLUGIN_SUCCESS;
+}
+
+static void views_cache_free()
{
viewEntry *head = theCache.pCacheViews;
viewEntry *current;
@@ -393,26 +461,6 @@ void views_cache_free()
}
/*
- views_close
- ---------
- unregisters the interface for this plugin
-*/
-static int views_close( Slapi_PBlock *pb )
-{
- slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "-->
views_close\n");
-
- /* unregister backend state change notification */
- slapi_unregister_backend_state_change((void *)views_cache_backend_state_change);
-
- views_cache_free();
-
- slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "<--
views_close\n");
-
- return SLAPI_PLUGIN_SUCCESS;
-}
-
-
-/*
views_cache_create
---------------------
Walks the views in the DIT and populates the cache.
@@ -421,8 +469,13 @@ static int views_cache_create()
{
int ret = SLAPI_PLUGIN_FAILURE;
- slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "-->
views_cache_create\n");
+ slapi_counter_increment(op_counter);
+ if (0 == g_plugin_started) {
+ slapi_counter_decrement(op_counter);
+ return SLAPI_PLUGIN_SUCCESS;
+ }
+ slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "-->
views_cache_create\n");
/* lock cache */
views_write_lock();
@@ -481,8 +534,9 @@ static int views_cache_create()
/* unlock cache */
views_unlock();
-
+ slapi_counter_decrement(op_counter);
slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "<--
views_cache_create\n");
+
return ret;
}
@@ -1361,6 +1415,12 @@ static void views_update_views_cache( Slapi_Entry *e, char *dn, int
modtype, Sla
struct berval val;
int build_cache = 0;
+ slapi_counter_increment(op_counter);
+ if (0 == g_plugin_started) {
+ slapi_counter_decrement(op_counter);
+ return;
+ }
+
slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "-->
views_update_views_cache\n");
views_write_lock();
@@ -1649,6 +1709,7 @@ unlock_cache:
{
views_cache_create();
}
+ slapi_counter_decrement(op_counter);
slapi_log_error( SLAPI_LOG_TRACE, VIEWS_PLUGIN_SUBSYSTEM, "<--
views_update_views_cache\n");
}
diff --git a/ldap/servers/plugins/whoami/whoami.c b/ldap/servers/plugins/whoami/whoami.c
index 42df8c1..73865fa 100644
--- a/ldap/servers/plugins/whoami/whoami.c
+++ b/ldap/servers/plugins/whoami/whoami.c
@@ -134,7 +134,10 @@ int whoami_init( Slapi_PBlock *pb )
/* Register the plugin function as an extended operation plugin function */
- if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03 ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, ( void * )&expdesc ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_FN, ( void * )whoami_exop ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, ( void * )whoami_exop_oid_list ) !=0 )
+ if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03 ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, ( void * )&expdesc ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_FN, ( void * )whoami_exop ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, ( void * )whoami_exop_oid_list )
!=0 )
{
slapi_log_error( SLAPI_LOG_FATAL, PLUGIN_NAME, "whoami_init: Failed to register
plug-in.\n" );
return( -1 );
diff --git a/ldap/servers/slapd/apibroker.c b/ldap/servers/slapd/apibroker.c
index 9937b88..7e2931d 100644
--- a/ldap/servers/slapd/apibroker.c
+++ b/ldap/servers/slapd/apibroker.c
@@ -146,6 +146,8 @@ int slapi_apib_unregister(char *guid)
if(*api == head) /* must be the last item, turn off the lights */
head = 0;
+ (*api)->guid = NULL;
+ (*api)->api = NULL;
slapi_ch_free((void**)api);
*api = 0;
ret = 0;
diff --git a/ldap/servers/slapd/config.c b/ldap/servers/slapd/config.c
index deecc66..8dbb103 100644
--- a/ldap/servers/slapd/config.c
+++ b/ldap/servers/slapd/config.c
@@ -162,6 +162,7 @@ slapd_bootstrap_config(const char *configdir)
int done = 0;
PRInt32 nr = 0;
PRFileDesc *prfd = 0;
+ char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";
char *buf = 0;
char *lastp = 0;
char *entrystr = 0;
@@ -402,9 +403,10 @@ slapd_bootstrap_config(const char *configdir)
"matchingrule", 0)))
{
/* add the syntax/matching scheme rule plugin */
- if (plugin_setup(e, 0, 0, 1))
+ if (plugin_setup(e, 0, 0, 1, returntext))
{
- LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was
invalid\n", slapi_entry_get_dn(e), configfile, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was
invalid. %s\n",
+ slapi_entry_get_dn(e), configfile, returntext);
rc = 0;
slapi_sdn_done(&plug_dn);
goto bail;
@@ -424,9 +426,10 @@ slapd_bootstrap_config(const char *configdir)
"reverpwdstoragescheme", 0) ) )
{
/* add the pwd storage scheme rule plugin */
- if (plugin_setup(e, 0, 0, 1))
+ if (plugin_setup(e, 0, 0, 1, returntext))
{
- LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was
invalid\n", slapi_entry_get_dn(e), configfile, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was
invalid. %s\n",
+ slapi_entry_get_dn(e), configfile, returntext);
rc = 0;
slapi_sdn_done(&plug_dn);
goto bail;
diff --git a/ldap/servers/slapd/configdse.c b/ldap/servers/slapd/configdse.c
index b54062d..2cea73a 100644
--- a/ldap/servers/slapd/configdse.c
+++ b/ldap/servers/slapd/configdse.c
@@ -353,7 +353,7 @@ load_plugin_entry(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry*
ignored, int *r
/*
* Process plugins that were not loaded during bootstrap.
*/
- retval = plugin_setup(e, 0, 0, 1);
+ retval = plugin_setup(e, 0, 0, 1, returntext);
/*
* well this damn well sucks, but this function is used as a callback
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
index f859650..fc5f492 100644
--- a/ldap/servers/slapd/dse.c
+++ b/ldap/servers/slapd/dse.c
@@ -111,6 +111,7 @@ struct dse_callback
Slapi_Filter *slapifilter; /* NULL means match all entries */
int (*fn)(Slapi_PBlock *,Slapi_Entry *,Slapi_Entry *,int*,char*,void *);
void *fn_arg;
+ struct slapdplugin *plugin;
struct dse_callback *next;
};
@@ -153,6 +154,10 @@ static void dse_search_set_add_entry (dse_search_set *ss, Slapi_Entry
*e);
static Slapi_Entry* dse_search_set_get_next_entry (dse_search_set *ss);
static int dse_add_entry_pb(struct dse* pdse, Slapi_Entry *e, Slapi_PBlock *pb);
static struct dse_node *dse_find_node( struct dse* pdse, const Slapi_DN *dn );
+static int dse_modify_plugin(Slapi_Entry *pre_entry, Slapi_Entry *post_entry, char
*returntext);
+static int dse_add_plugin(Slapi_Entry *entry, char *returntext);
+static int dse_delete_plugin(Slapi_Entry *entry, char *returntext);
+static void dse_post_modify_plugin(Slapi_Entry *entryBefore, Slapi_Entry *entryAfter,
LDAPMod **mods);
/*
richm: In almost all modes e.g. db2ldif, ldif2db, etc. we do not need/want
@@ -227,10 +232,17 @@ dse_get_entry_copy( struct dse* pdse, const Slapi_DN *dn, int
use_lock )
}
static struct dse_callback *
-dse_callback_new(int operation, int flags, const Slapi_DN *base, int scope, const char
*filter, dseCallbackFn fn, void *fn_arg)
+dse_callback_new(int operation,
+ int flags,
+ const Slapi_DN *base,
+ int scope,
+ const char *filter,
+ dseCallbackFn fn,
+ void *fn_arg,
+ struct slapdplugin *plugin)
{
struct dse_callback *p= NULL;
- p = (struct dse_callback *)slapi_ch_malloc(sizeof(struct dse_callback));
+ p = (struct dse_callback *)slapi_ch_calloc(1, sizeof(struct dse_callback));
if (p!=NULL) {
p->operation= operation;
p->flags = flags;
@@ -246,6 +258,7 @@ dse_callback_new(int operation, int flags, const Slapi_DN *base, int
scope, cons
}
p->fn= fn;
p->fn_arg= fn_arg;
+ p->plugin = plugin;
p->next= NULL;
}
return p;
@@ -332,7 +345,7 @@ dse_callback_removefromlist(struct dse_callback **pplist, int
operation, int fla
struct dse_callback *t= *pplist;
struct dse_callback *prev= NULL;
for(; t!=NULL; ) {
- if ((t->operation == operation) && (t->flags == flags)
&&
+ if ((t->operation & operation) && (t->flags & flags)
&&
(t->fn == fn) && (scope == t->scope) &&
(slapi_sdn_compare(base,t->base) == 0) &&
((NULL == filter && NULL == t->filter) || /* both are NULL OR
*/
@@ -1804,15 +1817,16 @@ dse_modify(Slapi_PBlock *pb) /* JCM There should only be one exit
point from thi
LDAPMod **mods; /*Used to apply the modifications*/
char *errbuf = NULL; /* To get error back */
struct dse* pdse;
- Slapi_Entry *ec= NULL;
- Slapi_Entry *ecc= NULL;
- int returncode= LDAP_SUCCESS;
- char returntext[SLAPI_DSE_RETURNTEXT_SIZE]= "";
+ Slapi_Entry *ec = NULL;
+ Slapi_Entry *ecc = NULL;
+ int returncode = LDAP_SUCCESS;
+ char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";
Slapi_DN *sdn = NULL;
int dont_write_file = 0; /* default */
int rc = SLAPI_DSE_CALLBACK_DO_NOT_APPLY;
int retval = -1;
int need_be_postop = 0;
+ int plugin_started = 0;
PR_ASSERT(pb);
if (slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &pdse ) < 0 ||
@@ -1898,7 +1912,15 @@ dse_modify(Slapi_PBlock *pb) /* JCM There should only be one exit
point from thi
}
}
} else {
- rc = SLAPI_DSE_CALLBACK_OK;
+ /*
+ * Check if we are enabling/disabling a plugin
+ */
+ if((plugin_started = dse_modify_plugin(ec, ecc, returntext)) == -1){
+ returncode = LDAP_UNWILLING_TO_PERFORM;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ } else {
+ rc = SLAPI_DSE_CALLBACK_OK;
+ }
}
}
@@ -2016,11 +2038,174 @@ dse_modify(Slapi_PBlock *pb) /* JCM There should only be one exit
point from thi
}
}
}
+ /*
+ * Perform postop plugin configuration changes
+ */
+ if(returncode == LDAP_SUCCESS){
+ dse_post_modify_plugin(ec, ecc, mods);
+ } else if(plugin_started){
+ if(plugin_started == 1){
+ /* the op failed, turn the plugin off */
+ plugin_delete(ecc, returntext, 0 /* not locked */);
+ } else if (plugin_started == 2){
+ /*
+ * This probably can't happen, but...
+ * the op failed, turn the plugin back on.
+ */
+ plugin_add(ecc, returntext, 0 /* not locked */);
+ }
+ }
+
slapi_send_ldap_result( pb, returncode, NULL, returntext[0] ? returntext : NULL, 0,
NULL );
return dse_modify_return(retval, ec, ecc);
}
+static void
+dse_post_modify_plugin(Slapi_Entry *entryBefore, Slapi_Entry *entryAfter, LDAPMod
**mods)
+{
+ char *enabled = NULL;
+ int i;
+
+ if (!slapi_entry_attr_hasvalue(entryBefore, SLAPI_ATTR_OBJECTCLASS,
"nsSlapdPlugin") ||
+ !config_get_dynamic_plugins() ){
+ /* not a plugin, or we aren't applying updates dynamically - just move on */
+ return;
+ }
+
+ /*
+ * Only check the mods if the plugin is enabled - no need to restart a plugin if
it's not running.
+ */
+ if ( (enabled = slapi_entry_attr_get_charptr(entryBefore, ATTR_PLUGIN_ENABLED))
&&
+ !strcasecmp(enabled, "on"))
+ {
+ for(i = 0; mods && mods[i]; i++){
+ /* Check if we are modifying a plugin's config, if so restart the plugin
*/
+ if (strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_PATH) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_INITFN) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_TYPE) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_DEPENDS_ON_TYPE) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_DEPENDS_ON_NAMED) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_SCHEMA_CHECK) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_BE_TXN) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_TARGET_SUBTREE) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_EXCLUDE_TARGET_SUBTREE) == 0
||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_BIND_SUBTREE) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_EXCLUDE_BIND_SUBTREE) == 0
||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_LOAD_NOW) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_LOAD_GLOBAL) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_PRECEDENCE) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_LOG_ACCESS) == 0 ||
+ strcasecmp(mods[i]->mod_type, ATTR_PLUGIN_LOG_AUDIT) == 0 )
+ {
+ /* for all other plugin config changes, restart the plugin */
+ if(plugin_restart(entryBefore, entryAfter) != LDAP_SUCCESS){
+ slapi_log_error(SLAPI_LOG_FATAL,"dse_post_modify_plugin",
"The configuration change "
+ "for plugin (%s) could not be applied dynamically, and
will be ignored until "
+ "the server is restarted.\n",
+ slapi_entry_get_dn(entryBefore));
+ }
+ }
+ }
+ }
+ slapi_ch_free_string(&enabled);
+}
+
+/*
+ * If this is modifying a plugin, check if we are disabling/enabling it - update the
+ * global plugins as needed.
+ *
+ * Return 1 if the plugin was successfully started
+ * Return 2 if the plugin was successfully stopped
+ * Return -1 on error
+ * Return 0 if nothing was done
+ */
+static int
+dse_modify_plugin(Slapi_Entry *pre_entry, Slapi_Entry *post_entry, char *returntext)
+{
+ int rc = LDAP_SUCCESS;
+
+ if (!slapi_entry_attr_hasvalue(post_entry, SLAPI_ATTR_OBJECTCLASS,
"nsSlapdPlugin") ||
+ !config_get_dynamic_plugins() )
+ {
+ return rc;
+ }
+
+ if( slapi_entry_attr_hasvalue(pre_entry, "nsslapd-pluginEnabled",
"on") &&
+ slapi_entry_attr_hasvalue(post_entry, "nsslapd-pluginEnabled",
"off") )
+ {
+ /*
+ * Plugin has been disabled
+ */
+ if(plugin_delete(post_entry, returntext, 0 /* not locked */)){
+ rc = -1;
+ } else {
+ rc = 2; /* plugin disabled */
+ slapi_log_error(SLAPI_LOG_PLUGIN,"dse_modify_plugin",
"Disabled plugin (%s)\n",
+ slapi_entry_get_dn(post_entry));
+ }
+ } else if ( slapi_entry_attr_hasvalue(pre_entry, "nsslapd-pluginEnabled",
"off") &&
+ slapi_entry_attr_hasvalue(post_entry, "nsslapd-pluginEnabled",
"on") )
+ {
+ /*
+ * Plugin has been enabled
+ */
+ if(plugin_add(post_entry, returntext, 0 /* not locked */)){
+ rc = -1;
+ } else {
+ rc = 1; /* plugin started */
+ slapi_log_error(SLAPI_LOG_PLUGIN,"dse_modify_plugin", "Enabled
plugin (%s)\n",
+ slapi_entry_get_dn(post_entry));
+ }
+ }
+
+ return rc;
+}
+
+/*
+ * Add the plugin to the global plugin list
+ */
+static int
+dse_add_plugin(Slapi_Entry *entry, char *returntext)
+{
+ int rc = LDAP_SUCCESS;
+
+ if (!slapi_entry_attr_hasvalue(entry, SLAPI_ATTR_OBJECTCLASS,
"nsSlapdPlugin") ||
+ !config_get_dynamic_plugins() )
+ {
+ /*
+ * This is not a plugin, or we are not allowing dynamic updates.
+ */
+ return rc;
+ }
+ rc = plugin_add(entry, returntext, 0 /* not locked */);
+
+ return rc;
+}
+
+/*
+ * Delete the plugin from the global plugin list
+ */
+static int
+dse_delete_plugin(Slapi_Entry *entry, char *returntext)
+{
+ int rc = LDAP_SUCCESS;
+
+ if (!slapi_entry_attr_hasvalue(entry, SLAPI_ATTR_OBJECTCLASS,
"nsSlapdPlugin") ||
+ slapi_entry_attr_hasvalue(entry, "nsslapd-PluginEnabled",
"off") ||
+ !config_get_dynamic_plugins() )
+ {
+ /*
+ * This is not a plugin, this plugin was not enabled to begin with, or we
+ * are not allowing dynamic updates .
+ */
+ return rc;
+ }
+ rc = plugin_delete(entry, returntext, 0 /* not locked */);
+
+ return rc;
+}
+
static int
dse_add_return( int rv, Slapi_Entry *e)
{
@@ -2042,8 +2227,8 @@ dse_add(Slapi_PBlock *pb) /* JCM There should only be one exit point
from this f
int error = -1;
int dont_write_file = 0; /* default */
struct dse* pdse;
- int returncode= LDAP_SUCCESS;
- char returntext[SLAPI_DSE_RETURNTEXT_SIZE]= "";
+ int returncode = LDAP_SUCCESS;
+ char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";
Slapi_DN *sdn = NULL;
Slapi_DN parent;
int need_be_postop = 0;
@@ -2204,6 +2389,13 @@ dse_add(Slapi_PBlock *pb) /* JCM There should only be one exit
point from this f
e = NULL; /* caller will free upon error */
goto done;
}
+ /*
+ * Check if we are adding a plugin
+ */
+ if(dse_add_plugin(e, returntext)){
+ returncode = LDAP_UNWILLING_TO_PERFORM;
+ goto done;
+ }
/* make copy for postop fns because add_entry_pb consumes the given entry */
e_copy = slapi_entry_dup(e);
@@ -2265,8 +2457,8 @@ dse_delete(Slapi_PBlock *pb) /* JCM There should only be one exit
point from thi
int rc= -1;
int dont_write_file = 0; /* default */
struct dse* pdse = NULL;
- int returncode= LDAP_SUCCESS;
- char returntext[SLAPI_DSE_RETURNTEXT_SIZE]= "";
+ int returncode = LDAP_SUCCESS;
+ char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";
char *entry_str = "entry";
char *errbuf = NULL;
char *attrs[2] = { NULL, NULL };
@@ -2377,15 +2569,32 @@ done:
PL_strncpyz(returntext, ldap_result_message, sizeof(returntext));
}
}
+ /*
+ * Check if we are deleting a plugin
+ */
+ if(returncode == LDAP_SUCCESS){
+ if(dse_delete_plugin(ec, returntext)){
+ rc = LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
+
slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry);
slapi_send_ldap_result( pb, returncode, NULL, returntext, 0, NULL );
return dse_delete_return(returncode, ec);
}
struct dse_callback *
-dse_register_callback(struct dse* pdse, int operation, int flags, const Slapi_DN *base,
int scope, const char *filter, dseCallbackFn fn, void *fn_arg)
-{
- struct dse_callback *callback = dse_callback_new(operation, flags, base, scope,
filter, fn, fn_arg);
+dse_register_callback(struct dse* pdse,
+ int operation,
+ int flags,
+ const Slapi_DN *base,
+ int scope,
+ const char *filter,
+ dseCallbackFn fn,
+ void *fn_arg,
+ struct slapdplugin *plugin)
+{
+ struct dse_callback *callback = dse_callback_new(operation, flags, base, scope,
filter, fn, fn_arg, plugin);
dse_callback_addtolist(&pdse->dse_callback, callback);
return callback;
}
@@ -2412,16 +2621,33 @@ dse_call_callback(struct dse* pdse, Slapi_PBlock *pb, int
operation, int flags,
if (pdse->dse_callback != NULL) {
struct dse_callback *p = pdse->dse_callback;
- int result;
+ int result = SLAPI_DSE_CALLBACK_OK;
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) == 0){
- result = (*p->fn)(pb,
entryBefore,entryAfter,returncode,returntext,p->fn_arg);
+ int plugin_started = 1;
+
+ if(p->plugin){
+ /* this is a plugin callback, update the operation counter
*/
+ slapi_plugin_op_started(p->plugin);
+ if(!p->plugin->plg_started){
+ /* must be a task function being called */
+ result = SLAPI_DSE_CALLBACK_ERROR;
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,
+ "Task entry (%s) could not added
because the (%s) plugin is disabled.",
+ slapi_entry_get_dn(entryBefore),
p->plugin->plg_dn);
+ plugin_started = 0;
+ }
+ }
+ if(plugin_started){
+ result = (*p->fn)(pb,
entryBefore,entryAfter,returncode,returntext,p->fn_arg);
+ }
if(result < rc){
rc = result;
}
+ slapi_plugin_op_finished(p->plugin);
}
}
}
@@ -2432,7 +2658,29 @@ dse_call_callback(struct dse* pdse, Slapi_PBlock *pb, int
operation, int flags,
}
int
-slapi_config_register_callback(int operation, int flags, const char *base, int scope,
const char *filter, dseCallbackFn fn, void *fn_arg)
+slapi_config_register_callback(int operation,
+ int flags,
+ const char *base,
+ int scope,
+ const char *filter,
+ dseCallbackFn fn,
+ void *fn_arg)
+{
+ return slapi_config_register_callback_plugin(operation, flags, base, scope, filter,
fn, fn_arg, NULL);
+}
+
+/*
+ * We pass in the pblock so we can update the operation counter for "dynamic
plugins".
+ */
+int
+slapi_config_register_callback_plugin(int operation,
+ int flags,
+ const char *base,
+ int scope,
+ const char *filter,
+ dseCallbackFn fn,
+ void *fn_arg,
+ Slapi_PBlock *pb)
{
int rc= 0;
Slapi_Backend *be= slapi_be_select_by_instance_name(DSE_BACKEND);
@@ -2440,14 +2688,17 @@ slapi_config_register_callback(int operation, int flags, const
char *base, int s
struct dse* pdse= (struct dse*)be->be_database->plg_private;
if (pdse!=NULL) {
Slapi_DN dn;
+
slapi_sdn_init_dn_byref(&dn,base);
- rc = (NULL != dse_register_callback(pdse, operation, flags, &dn, scope,
filter, fn, fn_arg));
+ rc = (NULL != dse_register_callback(pdse, operation, flags, &dn, scope,
filter, fn, fn_arg, pb ? pb->pb_plugin: NULL));
slapi_sdn_done(&dn);
}
}
return rc;
}
+
+
int
slapi_config_remove_callback(int operation, int flags, const char *base, int scope, const
char *filter, dseCallbackFn fn)
{
diff --git a/ldap/servers/slapd/factory.c b/ldap/servers/slapd/factory.c
index 8a1dc2d..ecd6d24 100644
--- a/ldap/servers/slapd/factory.c
+++ b/ldap/servers/slapd/factory.c
@@ -71,7 +71,7 @@
*
* When an extensible object is destroyed the extension block must also
* be destroyed. The factory_destroy_extension call is provided to
- * tidy up and free any extenions created for this object.
+ * tidy up and free any extensions created for this object.
*
* --- An interface is made available to the plugins.
*
@@ -117,6 +117,7 @@ struct factory_extension
const char *pluginname;
slapi_extension_constructor_fnptr constructor;
slapi_extension_destructor_fnptr destructor;
+ int removed;
};
static struct factory_extension*
@@ -125,13 +126,12 @@ new_factory_extension(
slapi_extension_constructor_fnptr constructor,
slapi_extension_destructor_fnptr destructor)
{
- struct factory_extension* fe= (struct
factory_extension*)slapi_ch_malloc(sizeof(struct factory_extension));
- if(pluginname!=NULL)
- {
- fe->pluginname= slapi_ch_strdup(pluginname);
- }
+ struct factory_extension* fe = (struct factory_extension*)slapi_ch_calloc(1,
sizeof(struct factory_extension));
+
+ fe->pluginname= slapi_ch_strdup(pluginname);
fe->constructor= constructor;
fe->destructor= destructor;
+
return fe;
}
@@ -159,7 +159,7 @@ struct factory_type
static struct factory_type*
new_factory_type(const char *name, size_t offset)
{
- struct factory_type* ft= (struct factory_type*)slapi_ch_malloc(sizeof(struct
factory_type));
+ struct factory_type* ft= (struct factory_type*)slapi_ch_calloc(1, sizeof(struct
factory_type));
ft->name= slapi_ch_strdup(name);
ft->extension_lock = PR_NewLock();
ft->extension_count= 0;
@@ -168,41 +168,45 @@ new_factory_type(const char *name, size_t offset)
return ft;
}
-static void
-delete_factory_type(struct factory_type **ft)
-{
- slapi_ch_free( (void **) &((*ft)->name));
- PR_DestroyLock((*ft)->extension_lock);
- slapi_ch_free( (void **) ft);
-}
-
static int
-factory_type_add_extension(struct factory_type *ft,struct factory_extension *fe)
+factory_type_add_extension(struct factory_type *ft, struct factory_extension *fe)
{
- int extensionhandle= -1;
- PR_Lock(ft->extension_lock);
- if(ft->existence_count>0)
- {
- /* Can't register an extension if there are objects already with extension
blocks */
- LDAPDebug( LDAP_DEBUG_ANY, "ERROR: factory.c: Registration of %s extension by %s
failed.\n", ft->name, fe->pluginname, 0);
- LDAPDebug( LDAP_DEBUG_ANY, "ERROR: factory.c: %lu %s objects already in
existence.\n", ft->existence_count, ft->name, 0);
- }
- else
- {
- if(ft->extension_count<MAX_EXTENSIONS)
- {
- extensionhandle= ft->extension_count;
- ft->extensions[ft->extension_count]= fe;
- ft->extension_count++;
- }
- else
- {
- LDAPDebug( LDAP_DEBUG_ANY, "ERROR: factory.c: Registration of %s extension by
%s failed.\n", ft->name, fe->pluginname, 0);
- LDAPDebug( LDAP_DEBUG_ANY, "ERROR: factory.c: %d extensions already
registered. Max is %d\n", ft->extension_count, MAX_EXTENSIONS, 0);
- }
- }
- PR_Unlock(ft->extension_lock);
- return extensionhandle;
+ int extensionhandle = -1;
+ int added = 0;
+ int i;
+
+ PR_Lock(ft->extension_lock);
+
+ if(ft->extension_count<MAX_EXTENSIONS)
+ {
+ for(i = 0; i < ft->extension_count; i++){
+ if(strcasecmp(ft->extensions[i]->pluginname,fe->pluginname) == 0){
+ if(ft->extensions[i]->removed){
+ /* this extension was previously added, and then removed. Reuse the
slot */
+ delete_factory_extension(&ft->extensions[i]);
+ extensionhandle = i;
+ ft->extensions[i] = fe;
+ added = 1;
+ break;
+ }
+ }
+ }
+ if(!added){
+ extensionhandle= ft->extension_count;
+ ft->extensions[ft->extension_count]= fe;
+ ft->extension_count++;
+ }
+ }
+ else
+ {
+ LDAPDebug( LDAP_DEBUG_ANY, "ERROR: factory.c: Registration of %s extension
by %s failed.\n",
+ ft->name, fe->pluginname, 0);
+ LDAPDebug( LDAP_DEBUG_ANY, "ERROR: factory.c: %d extensions already
registered. Max is %d\n",
+ ft->extension_count, MAX_EXTENSIONS, 0);
+ }
+
+ PR_Unlock(ft->extension_lock);
+ return extensionhandle;
}
static void
@@ -250,34 +254,6 @@ factory_type_store_add(struct factory_type* ft)
return type;
}
-static void
-factory_type_store_remove(struct factory_type *ft)
-{
- int i;
- int found_it = 0;
-
- for (i = 0; i < number_of_types; i++)
- {
- if (!found_it)
- {
- if (factory_type_store[i] == ft)
- {
- found_it = 1;
- }
- }
- else
- {
- factory_type_store[i-1] = factory_type_store[i];
- }
- }
-
- if (found_it)
- {
- factory_type_store[i-1] = NULL;
- number_of_types--;
- }
-}
-
static struct factory_type*
factory_type_store_get_factory_type(int type)
{
@@ -354,9 +330,12 @@ factory_create_extension(int type,void *object,void *parent)
int i;
factory_type_increment_existence(ft);
PR_Unlock(ft->extension_lock);
- extension= (void**)slapi_ch_malloc(n*sizeof(void*));
+ extension= (void**)slapi_ch_calloc(n + 1,sizeof(void*));
for(i=0;i<n;i++)
{
+ if(ft->extensions[i] == NULL || ft->extensions[i]->removed){
+ continue;
+ }
slapi_extension_constructor_fnptr constructor=
ft->extensions[i]->constructor;
if(constructor!=NULL)
{
@@ -385,39 +364,71 @@ factory_create_extension(int type,void *object,void *parent)
void
factory_destroy_extension(int type,void *object,void *parent,void **extension)
{
- if(extension!=NULL && *extension!=NULL)
+ if(extension!=NULL && *extension!=NULL)
{
- struct factory_type* ft= factory_type_store_get_factory_type(type);
- if(ft!=NULL)
- {
- int i,n;
+ struct factory_type* ft= factory_type_store_get_factory_type(type);
+ if(ft!=NULL)
+ {
+ int i,n;
- PR_Lock(ft->extension_lock);
- n=ft->extension_count;
- factory_type_decrement_existence(ft);
- PR_Unlock(ft->extension_lock);
- for(i=0;i<n;i++)
- {
- slapi_extension_destructor_fnptr destructor=
ft->extensions[i]->destructor;
- if(destructor!=NULL)
- {
- void **extention_array= (void**)(*extension);
- (*destructor)(extention_array[i],object,parent);
- }
- }
- }
- else
- {
- /* The type wasn't registered. Programming error? */
- LDAPDebug( LDAP_DEBUG_ANY, "ERROR: factory.c: Object type handle %d not
valid. Object not registered?\n", type, 0, 0);
- }
- slapi_ch_free(extension);
+ PR_Lock(ft->extension_lock);
+ n=ft->extension_count;
+ factory_type_decrement_existence(ft);
+ for(i=0;i<n;i++)
+ {
+ slapi_extension_destructor_fnptr destructor;
+
+ if(ft->extensions[i] == NULL){
+ continue;
+ }
+ destructor = ft->extensions[i]->destructor;
+ if(destructor!=NULL)
+ {
+ void **extention_array= (void**)(*extension);
+ (*destructor)(extention_array[i],object,parent);
+ }
+ }
+ PR_Unlock(ft->extension_lock);
+ }
+ else
+ {
+ /* The type wasn't registered. Programming error? */
+ LDAPDebug( LDAP_DEBUG_ANY, "ERROR: factory.c: Object type handle %d not valid.
Object not registered?\n", type, 0, 0);
+ }
+ slapi_ch_free(extension);
}
}
/* ---------------------- Slapi Functions ---------------------- */
/*
+ * The caller should reset
+ */
+int
+slapi_unregister_object_extension(
+ const char* pluginname,
+ const char* objectname,
+ int *objecttype,
+ int *extensionhandle)
+{
+ struct factory_type* ft;
+ int rc = 0;
+
+ *objecttype = factory_type_store_name_to_type(objectname);
+ ft = factory_type_store_get_factory_type(*objecttype);
+ if(ft){
+ PR_Lock(ft->extension_lock);
+ ft->extensions[*extensionhandle]->removed = 1;
+ PR_Unlock(ft->extension_lock);
+ } else {
+ /* extension not found */
+ rc = -1;
+ }
+
+ return rc;
+}
+
+/*
* Function for plugin usage.
* See documentation at head of file.
*/
@@ -436,15 +447,14 @@ slapi_register_object_extension(
fe= new_factory_extension(pluginname,constructor, destructor);
*objecttype= factory_type_store_name_to_type(objectname);
ft= factory_type_store_get_factory_type(*objecttype);
+
if(ft!=NULL)
{
*extensionhandle= factory_type_add_extension(ft,fe);
- if(*extensionhandle==-1)
- {
- delete_factory_extension(&fe);
- factory_type_store_remove(ft);
- delete_factory_type(&ft);
- }
+ if(*extensionhandle==-1)
+ {
+ delete_factory_extension(&fe);
+ }
}
else
{
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index 0b537bb..1ffa08d 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -1601,10 +1601,10 @@ init_dse_file(const char *configdir, Slapi_DN *config)
int dont_write = 1;
dse_register_callback(pfedse,DSE_OPERATION_READ,DSE_FLAG_PREOP,config,
LDAP_SCOPE_SUBTREE,"(objectclass=nsslapdPlugin)",
- load_plugin_entry, NULL);
+ load_plugin_entry, NULL, NULL);
dse_register_callback(pfedse,DSE_OPERATION_READ,DSE_FLAG_PREOP,config,
LDAP_SCOPE_BASE,"(objectclass=*)",
- load_config_dse,NULL);
+ load_config_dse,NULL, NULL);
slapi_pblock_set(&pb, SLAPI_CONFIG_DIRECTORY, (void*)configdir);
/* don't write out the file when reading */
@@ -1801,36 +1801,36 @@ setup_internal_backends(char *configdir)
slapi_sdn_init_ndn_byref(&plugins,"cn=plugins,cn=config");
/* Search */
- dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",read_config_dse,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_BASE,"(objectclass=*)",monitor_info,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",read_root_dse,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_SUBTREE,EGG_FILTER,search_easter_egg,NULL);
/* Egg */
- dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&counters,LDAP_SCOPE_BASE,"(objectclass=*)",search_counters,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&snmp,LDAP_SCOPE_BASE,"(objectclass=*)",search_snmp,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&encryption,LDAP_SCOPE_BASE,"(objectclass=*)",search_encryption,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",read_config_dse,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_BASE,"(objectclass=*)",monitor_info,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",read_root_dse,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_SUBTREE,EGG_FILTER,search_easter_egg,NULL,
NULL); /* Egg */
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&counters,LDAP_SCOPE_BASE,"(objectclass=*)",search_counters,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&snmp,LDAP_SCOPE_BASE,"(objectclass=*)",search_snmp,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&encryption,LDAP_SCOPE_BASE,"(objectclass=*)",search_encryption,NULL,
NULL);
/* Modify */
- dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",modify_config_dse,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_POSTOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",postop_modify_config_dse,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",modify_root_dse,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&saslmapping,LDAP_SCOPE_SUBTREE,"(objectclass=nsSaslMapping)",sasl_map_config_modify,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&plugins,LDAP_SCOPE_SUBTREE,"(objectclass=nsSlapdPlugin)",check_plugin_path,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",modify_config_dse,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_POSTOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",postop_modify_config_dse,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",modify_root_dse,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&saslmapping,LDAP_SCOPE_SUBTREE,"(objectclass=nsSaslMapping)",sasl_map_config_modify,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&plugins,LDAP_SCOPE_SUBTREE,"(objectclass=nsSlapdPlugin)",check_plugin_path,NULL,
NULL);
/* Delete */
- dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&counters,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&snmp,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&encryption,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&saslmapping,LDAP_SCOPE_SUBTREE,"(objectclass=nsSaslMapping)",sasl_map_config_delete,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&config,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&counters,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&snmp,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&root,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&encryption,LDAP_SCOPE_BASE,"(objectclass=*)",dont_allow_that,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&saslmapping,LDAP_SCOPE_SUBTREE,"(objectclass=nsSaslMapping)",sasl_map_config_delete,NULL,
NULL);
/* Write */
- dse_register_callback(pfedse,DSE_OPERATION_WRITE,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_SUBTREE,EGG_FILTER,dont_allow_that,NULL);
/* Egg */
+ dse_register_callback(pfedse,DSE_OPERATION_WRITE,DSE_FLAG_PREOP,&monitor,LDAP_SCOPE_SUBTREE,EGG_FILTER,dont_allow_that,NULL,
NULL); /* Egg */
/* Add */
- dse_register_callback(pfedse,SLAPI_OPERATION_ADD,DSE_FLAG_PREOP,&saslmapping,LDAP_SCOPE_SUBTREE,"(objectclass=nsSaslMapping)",sasl_map_config_add,NULL);
- dse_register_callback(pfedse,SLAPI_OPERATION_ADD,DSE_FLAG_PREOP,&plugins,LDAP_SCOPE_SUBTREE,"(objectclass=nsSlapdPlugin)",check_plugin_path,NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_ADD,DSE_FLAG_PREOP,&saslmapping,LDAP_SCOPE_SUBTREE,"(objectclass=nsSaslMapping)",sasl_map_config_add,NULL,
NULL);
+ dse_register_callback(pfedse,SLAPI_OPERATION_ADD,DSE_FLAG_PREOP,&plugins,LDAP_SCOPE_SUBTREE,"(objectclass=nsSlapdPlugin)",check_plugin_path,NULL,
NULL);
be = be_new_internal(pfedse, "DSE", DSE_BACKEND);
be_addsuffix(be,&root);
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 06bfc92..d1a3dc0 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -270,6 +270,7 @@ slapi_onoff_t init_plugin_logging;
slapi_int_t init_connection_buffer;
slapi_int_t init_listen_backlog_size;
slapi_onoff_t init_ignore_time_skew;
+slapi_onoff_t init_dynamic_plugins;
#if defined (LINUX)
slapi_int_t init_malloc_mxfast;
slapi_int_t init_malloc_trim_threshold;
@@ -1087,6 +1088,10 @@ static struct config_get_and_set {
NULL, 0,
(void**)&global_slapdFrontendConfig.listen_backlog_size, CONFIG_INT,
(ConfigGetFunc)config_get_listen_backlog_size, &init_listen_backlog_size},
+ {CONFIG_DYNAMIC_PLUGINS, config_set_dynamic_plugins,
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.dynamic_plugins, CONFIG_ON_OFF,
+ (ConfigGetFunc)config_get_dynamic_plugins, &init_dynamic_plugins},
#if defined(LINUX)
{CONFIG_MALLOC_MXFAST, config_set_malloc_mxfast,
NULL, 0,
@@ -1552,6 +1557,7 @@ FrontendConfig_init () {
init_plugin_logging = cfg->plugin_logging = LDAP_OFF;
init_listen_backlog_size = cfg->listen_backlog_size = DAEMON_LISTEN_SIZE;
init_ignore_time_skew = cfg->ignore_time_skew = LDAP_OFF;
+ init_dynamic_plugins = cfg->dynamic_plugins = LDAP_OFF;
#if defined(LINUX)
init_malloc_mxfast = cfg->malloc_mxfast = DEFAULT_MALLOC_UNSET;
init_malloc_trim_threshold = cfg->malloc_trim_threshold = DEFAULT_MALLOC_UNSET;
@@ -3271,6 +3277,31 @@ config_set_moddn_aci( const char *attrname, char *value, char
*errorbuf, int app
}
int
+config_set_dynamic_plugins( const char *attrname, char *value, char *errorbuf, int apply
) {
+ int retVal = LDAP_SUCCESS;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ retVal = config_set_onoff ( attrname,
+ value,
+ &(slapdFrontendConfig->dynamic_plugins),
+ errorbuf,
+ apply);
+
+ return retVal;
+}
+int
+config_get_dynamic_plugins() {
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ int retVal;
+
+ CFG_ONOFF_LOCK_READ(slapdFrontendConfig);
+ retVal = (int)slapdFrontendConfig->dynamic_plugins;
+ CFG_ONOFF_UNLOCK_READ(slapdFrontendConfig);
+
+ return retVal;
+}
+
+int
config_set_security( const char *attrname, char *value, char *errorbuf, int apply ) {
int retVal = LDAP_SUCCESS;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index dd1f88a..d577514 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -814,6 +814,11 @@ main( int argc, char **argv)
init_controls();
/*
+ * Initialize the global plugin list lock
+ */
+ global_plugin_init();
+
+ /*
* Process the config files.
*/
if (0 == slapd_bootstrap_config(slapdFrontendConfig->configdir)) {
@@ -1173,8 +1178,9 @@ main( int argc, char **argv)
*/
task_cleanup();
- /* init the thread data index for bind dn's */
+ /* init the thread data indexes */
slapi_td_dn_init();
+ slapi_td_plugin_lock_init();
/*
* Initialize password storage in entry extension.
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index b13ecbb..4337db7 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -54,6 +54,17 @@
#define ROOT_BIND "directory manager"
#define ANONYMOUS_BIND "anonymous"
+/* dependency checking flags */
+#define CHECK_ALL 0
+#define CHECK_TYPE 1
+
+static char *critical_plugins[] = { "cn=ldbm database,cn=plugins,cn=config",
+ "cn=ACL Plugin,cn=plugins,cn=config",
+ "cn=ACL
preoperation,cn=plugins,cn=config",
+ "cn=chaining
database,cn=plugins,cn=config",
+ "cn=Multimaster Replication
Plugin,cn=plugins,cn=config",
+ NULL };
+
/* Forward Declarations */
static int plugin_call_list (struct slapdplugin *list, int operation, Slapi_PBlock *pb);
static int plugin_call_one (struct slapdplugin *list, int operation, Slapi_PBlock *pb);
@@ -79,6 +90,10 @@ int ptd_get_subtree_count (const PluginTargetData *ptd);
static void plugin_set_global (PluginTargetData *ptd);
static PRBool plugin_is_global (const PluginTargetData *ptd);
static void plugin_set_default_access (struct pluginconfig *config);
+static int plugin_delete_check_dependency(struct slapdplugin *plugin_entry, int flag,
char *returntext);
+static char *plugin_get_type_str( int type );
+static void plugin_cleanup_list();
+static int plugin_remove_plugins(struct slapdplugin *plugin_entry, char *plugin_type);
static PLHashTable *global_plugin_dns = NULL;
@@ -86,11 +101,11 @@ static PLHashTable *global_plugin_dns = NULL;
static struct slapdplugin *global_plugin_list[PLUGIN_LIST_GLOBAL_MAX];
/* plugin structure used to configure internal operation issued by the core server */
-static int global_server_plg_initialised= 0;
+static int global_server_plg_initialised = 0;
struct slapdplugin global_server_plg;
/* plugin structure used to configure internal operation issued by the core server */
-static int global_server_plg_id_initialised= 0;
+static int global_server_plg_id_initialised = 0;
struct slapi_componentid global_server_id_plg;
/* plugin structure used to configure operations issued by the old plugins that
@@ -100,6 +115,16 @@ static struct slapdplugin global_default_plg;
/* Enable/disable plugin callbacks for clean startup */
static int global_plugin_callbacks_enabled = 0;
+static Slapi_RWLock *global_rwlock = NULL;
+
+void
+global_plugin_init()
+{
+ if((global_rwlock = slapi_new_rwlock()) == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, "startup", "Failed to create
global plugin rwlock.\n" );
+ exit (1);
+ }
+}
static void
add_plugin_to_list(struct slapdplugin **list, struct slapdplugin *plugin)
@@ -192,6 +217,23 @@ add_plugin_entries()
}
#endif
+static int
+plugin_is_critical(Slapi_Entry *plugin_entry)
+{
+ char *plugin_dn = NULL;
+ int i;
+
+ plugin_dn = slapi_entry_get_ndn(plugin_entry);
+
+ for( i = 0; critical_plugins[i]; i++){
+ if(strcasecmp(plugin_dn, critical_plugins[i]) == 0){
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static void
new_plugin_entry(entry_and_plugin_t **ep, Slapi_Entry *e, struct slapdplugin *plugin)
{
@@ -216,7 +258,6 @@ new_plugin_entry(entry_and_plugin_t **ep, Slapi_Entry *e, struct
slapdplugin *pl
else
*ep = newep;
}
-
static void
add_plugin_entry_dn(const Slapi_DN *plugin_dn)
@@ -227,7 +268,6 @@ add_plugin_entry_dn(const Slapi_DN *plugin_dn)
PL_CompareStrings,
PL_CompareValues, 0, 0);
}
-
PL_HashTableAdd(global_plugin_dns,
slapi_sdn_get_ndn(plugin_dn),
(void*)plugin_dn);
@@ -267,12 +307,13 @@ slapi_register_plugin_ext(
int precedence
)
{
- int ii = 0;
- int found_precedence;
- int rc = 0;
Slapi_Entry *e = NULL;
+ char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";
char *dn = slapi_ch_smprintf("cn=%s,%s", name, PLUGIN_BASE_DN);
Slapi_DN *sdn = slapi_sdn_new_normdn_passin(dn);
+ int found_precedence;
+ int ii = 0;
+ int rc = 0;
e = slapi_entry_alloc();
/* this function consumes dn */
@@ -285,20 +326,20 @@ slapi_register_plugin_ext(
slapi_entry_attr_set_charptr(e, ATTR_PLUGIN_ENABLED, "off");
slapi_entry_attr_set_charptr(e, ATTR_PLUGIN_INITFN, initsymbol);
- /* If the plugin belong to a group, get the precedence from the group */
- found_precedence = precedence;
- if ((found_precedence == PLUGIN_DEFAULT_PRECEDENCE) && group_identity) {
- struct slapi_componentid * cid = (struct slapi_componentid *)
group_identity;
- if (cid->sci_plugin &&
- (cid->sci_plugin->plg_precedence !=
PLUGIN_DEFAULT_PRECEDENCE)) {
- slapi_log_error(SLAPI_LOG_PLUGIN, NULL,
- "Plugin precedence (%s) reset to group precedence
(%s): %d \n",
- name ? name : "",
- cid->sci_plugin->plg_name ?
cid->sci_plugin->plg_name : "",
- cid->sci_plugin->plg_precedence);
- found_precedence = cid->sci_plugin->plg_precedence;
- }
- }
+
+ /* If the plugin belong to a group, get the precedence from the group */
+ found_precedence = precedence;
+ if ((found_precedence == PLUGIN_DEFAULT_PRECEDENCE) && group_identity) {
+ struct slapi_componentid * cid = (struct slapi_componentid *) group_identity;
+ if (cid->sci_plugin && (cid->sci_plugin->plg_precedence !=
PLUGIN_DEFAULT_PRECEDENCE)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, NULL,
+ "Plugin precedence (%s) reset to group precedence (%s): %d \n",
+ name ? name : "",
+ cid->sci_plugin->plg_name ? cid->sci_plugin->plg_name :
"",
+ cid->sci_plugin->plg_precedence);
+ found_precedence = cid->sci_plugin->plg_precedence;
+ }
+ }
slapi_entry_attr_set_int(e, ATTR_PLUGIN_PRECEDENCE, found_precedence);
for (ii = 0; argv && argv[ii]; ++ii) {
@@ -308,7 +349,7 @@ slapi_register_plugin_ext(
}
/* plugin_setup copies the given entry */
- plugin_setup(e, group_identity, initfunc, 0);
+ rc = plugin_setup(e, group_identity, initfunc, 0, returntext);
slapi_entry_free(e);
return rc;
@@ -406,17 +447,16 @@ plugin_call_plugins( Slapi_PBlock *pb, int whichfunction )
if(plugin_list_number!=-1 && do_op)
{
- /* We stash the pblock plugin pointer to preserve the callers context */
- struct slapdplugin *p;
- slapi_pblock_get(pb, SLAPI_PLUGIN, &p);
+ /* We stash the pblock plugin pointer to preserve the callers context */
+ struct slapdplugin *p;
+ slapi_pblock_get(pb, SLAPI_PLUGIN, &p);
/* Call the operation on the Global Plugins */
- rc= plugin_call_list(global_plugin_list[plugin_list_number], whichfunction, pb);
-
- slapi_pblock_set(pb, SLAPI_PLUGIN, p);
+ rc = plugin_call_list(global_plugin_list[plugin_list_number], whichfunction, pb);
+ slapi_pblock_set(pb, SLAPI_PLUGIN, p);
}
else
{
- /* Programmer error! or the callback is denied during startup */
+ /* Programmer error! or the callback is denied during startup */
}
return rc;
}
@@ -543,6 +583,27 @@ plugin_extended_op_oid2string( const char *oid )
return( rval );
}
+static int
+plugin_cmp_plugins(struct slapdplugin *p1, struct slapdplugin *p2)
+{
+ int rc = 0;
+
+ if( p1->plg_dn ){
+ if(p2->plg_dn && strcasecmp(p1->plg_dn, p2->plg_dn) == 0){
+ rc = 1;
+ } else if(p2->plg_id && strcasecmp(p1->plg_dn, p2->plg_id) ==
0){
+ rc = 1;
+ }
+ } else if(p1->plg_id){
+ if(p2->plg_id && strcasecmp(p1->plg_id, p2->plg_id) == 0){
+ rc = 1;
+ } else if(p2->plg_dn && strcasecmp(p2->plg_dn, p1->plg_id) ==
0){
+ rc = 1;
+ }
+ }
+
+ return rc;
+}
/*
* kexcoff: return the slapdplugin structure
@@ -761,8 +822,11 @@ typedef struct _plugin_dep_config {
char **depends_named_list;
int total_named;
char *config_area;
+ int removed;
} plugin_dep_config;
+static void plugin_free_plugin_dep_config(plugin_dep_config **config);
+
/* list of plugins which should be shutdown in reverse order */
static plugin_dep_config *global_plugin_shutdown_order = 0;
static int global_plugins_started = 0;
@@ -882,26 +946,25 @@ add_plugin_type(plugin_dep_type *head, char *type)
* attribute passed in as args - used to track dependencies
*
*/
-
int
plugin_create_stringlist( Slapi_Entry *plugin_entry, char *attr_name,
int *total_strings, char ***list)
{
Slapi_Attr *attr = 0;
- int hint =0;
+ int hint = 0;
int num_vals = 0;
int val_index = 0;
- Slapi_Value *val;
+ Slapi_Value *val = NULL;
if(0 == slapi_entry_attr_find( plugin_entry, attr_name, &attr ))
{
+
/* allocate memory for the string array */
slapi_attr_get_numvalues( attr, &num_vals);
-
if(num_vals)
{
*total_strings = num_vals;
- *list = (char **)slapi_ch_malloc(sizeof(char*) * num_vals);
+ *list = (char **)slapi_ch_calloc(num_vals + 1, sizeof(char*));
}
else
goto bail; /* if this ever happens, then they are running on a TSR-80 */
@@ -922,9 +985,427 @@ plugin_create_stringlist( Slapi_Entry *plugin_entry, char
*attr_name,
*total_strings = num_vals;
bail:
+
return num_vals;
}
+/*
+ * Remove the plugin from the DN hashtable
+ */
+static void
+plugin_remove_from_list(char *plugin_dn)
+{
+ Slapi_DN *hash_sdn;
+
+ hash_sdn = (Slapi_DN *)PL_HashTableLookup(global_plugin_dns, plugin_dn);
+ if(hash_sdn){
+ PL_HashTableRemove(global_plugin_dns, plugin_dn);
+ slapi_sdn_free(&hash_sdn);
+ }
+}
+
+/*
+ * The main plugin was successfully started, set it and its
+ * registered plugin functions as started.
+ */
+static void
+plugin_set_plugins_started(struct slapdplugin *plugin_entry)
+{
+ struct slapdplugin *plugin = NULL;
+ int type = 0;
+
+ /* look everywhere for other plugin functions with the plugin id */
+ for(type = 0; type < PLUGIN_LIST_GLOBAL_MAX; type++){
+ plugin = global_plugin_list[type];
+ while(plugin){
+ if(plugin_cmp_plugins(plugin_entry, plugin)){
+ plugin->plg_started = 1;
+ }
+ plugin = plugin->plg_next;
+ }
+ }
+}
+/*
+ * A plugin dependency changed, update the dependency list
+ */
+void
+plugin_update_dep_entries(Slapi_Entry *plugin_entry)
+{
+ entry_and_plugin_t *ep;
+
+ slapi_rwlock_wrlock(global_rwlock);
+
+ ep = dep_plugin_entries;
+ while(ep){
+ if(ep->plugin && ep->e){
+ if(slapi_sdn_compare(slapi_entry_get_sdn(ep->e), slapi_entry_get_sdn(plugin_entry))
== 0){
+ slapi_entry_free(ep->e);
+ ep->e = slapi_entry_dup(plugin_entry);
+ break;
+ }
+ }
+ ep = ep->next;
+ }
+
+ slapi_rwlock_unlock(global_rwlock);
+}
+
+/*
+ * Attempt to start a plugin that was either just added or just enabled.
+ */
+int
+plugin_start(Slapi_Entry *entry, char *returntext)
+{
+ entry_and_plugin_t *ep = dep_plugin_entries;
+ plugin_dep_config *global_tmp_list = NULL;
+ plugin_dep_config *config = NULL;
+ plugin_dep_type the_plugin_type;
+ plugin_dep_type plugin_head = 0;
+ Slapi_PBlock pb;
+ Slapi_Entry *plugin_entry;
+ struct slapdplugin *plugin;
+ char *value;
+ int plugins_started = 1;
+ int num_plg_started = 0;
+ int shutdown_index = 0;
+ int total_plugins = 0;
+ int plugin_index = 0;
+ int plugin_idx = -1;
+ int index = 0;
+ int ret = 0;
+ int i = 0;
+
+ /*
+ * Disable registered plugin functions so preops/postops/etc
+ * dont get called prior to the plugin being started (due to
+ * plugins performing ops on the DIT)
+ */
+ global_plugin_callbacks_enabled = 0;
+ global_plugins_started = 0;
+
+ /* Count the plugins so we can allocate memory for the config array */
+ while(ep){
+ if(slapi_sdn_compare(slapi_entry_get_sdn(ep->e), slapi_entry_get_sdn(entry)) == 0){
+ plugin_idx = total_plugins;
+ }
+ total_plugins++;
+ ep = ep->next;
+ }
+
+ /* allocate the config array */
+ config = (plugin_dep_config*)slapi_ch_calloc(total_plugins + 1,
sizeof(plugin_dep_config));
+
+ ep = dep_plugin_entries;
+
+ /* Collect relevant config */
+ while(ep){
+ plugin = ep->plugin;
+
+ if(plugin == 0){
+ continue;
+ }
+
+ pblock_init(&pb);
+ slapi_pblock_set( &pb, SLAPI_ARGC, &plugin->plg_argc);
+ slapi_pblock_set( &pb, SLAPI_ARGV, &plugin->plg_argv);
+
+ config[plugin_index].pb = pb;
+ config[plugin_index].e = ep->e;
+
+ /* add type */
+ plugin_entry = ep->e;
+
+ if(plugin_entry){
+ /*
+ * Pass the plugin DN in SLAPI_TARGET_SDN and the plugin entry
+ * in SLAPI_ADD_ENTRY. For this to actually work, we need to
+ * create an operation and include that in the pblock as well,
+ * because these two items are stored in the operation parameters.
+ */
+ Operation *op = internal_operation_new(SLAPI_OPERATION_ADD, 0);
+ slapi_pblock_set(&(config[plugin_index].pb), SLAPI_OPERATION, op);
+ slapi_pblock_set(&(config[plugin_index].pb), SLAPI_TARGET_SDN,
+ (void*)(slapi_entry_get_sdn_const(plugin_entry)));
+ slapi_pblock_set(&(config[plugin_index].pb), SLAPI_ADD_ENTRY,
+ plugin_entry );
+
+ /* Pass the plugin alternate config area DN in SLAPI_PLUGIN_CONFIG_AREA. */
+ value = slapi_entry_attr_get_charptr(plugin_entry, ATTR_PLUGIN_CONFIG_AREA);
+ if(value){
+ config[plugin_index].config_area = value;
+ value = NULL;
+ slapi_pblock_set(&(config[plugin_index].pb), SLAPI_PLUGIN_CONFIG_AREA,
+ config[plugin_index].config_area);
+ }
+
+ value = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype");
+ if(value){
+ add_plugin_type( &plugin_head, value);
+ config[plugin_index].type = value;
+ value = NULL;
+ }
+
+ /* now the name */
+ value = slapi_entry_attr_get_charptr(plugin_entry, "cn");
+ if(value){
+ config[plugin_index].name = value;
+ value = NULL;
+ }
+
+ config[plugin_index].plugin = plugin;
+
+ /* now add dependencies */
+ plugin_create_stringlist( plugin_entry, ATTR_PLUGIN_DEPENDS_ON_NAMED,
+ &(config[plugin_index].total_named),
&(config[plugin_index].depends_named_list));
+
+ plugin_create_stringlist( plugin_entry, ATTR_PLUGIN_DEPENDS_ON_TYPE,
+ &(config[plugin_index].total_type),
&(config[plugin_index].depends_type_list));
+ }
+ plugin_index++;
+ ep = ep->next;
+ }
+
+ /*
+ * Prepare list of shutdown order (we need nothing fancier right now
+ * than the reverse startup order) The list may include NULL entries,
+ * these will be plugins which were never started
+ */
+ shutdown_index = total_plugins - 1;
+
+ global_tmp_list = (plugin_dep_config*)slapi_ch_calloc(total_plugins,
sizeof(plugin_dep_config));
+
+ /* now resolve dependencies
+ * cycle through list, if a plugin has no dependencies then start it
+ * then remove it from the dependency lists of all other plugins
+ * and decrement the corresponding element of the plugin types array
+ * for depends_type we will need to check the array of plugin types
+ * to see if all type dependencies are at zero prior to start
+ * if one cycle fails to load any plugins we have failed, however
+ * we shall continue loading plugins in case a configuration error
+ * can correct itself
+ */
+ while(plugins_started && num_plg_started < total_plugins){
+ for(plugin_index = 0, plugins_started = 0; plugin_index < total_plugins;
plugin_index++){
+ /* perform op on plugins only once */
+ if(config[plugin_index].op_done == 0){
+ int enabled = 0;
+ int satisfied = 0;
+ int break_out = 0;
+
+ /*
+ * determine if plugin is enabled
+ * some processing is necessary even
+ * if it is not
+ */
+ if ( NULL != config[plugin_index].e && (value =
slapi_entry_attr_get_charptr(config[plugin_index].e,
+ ATTR_PLUGIN_ENABLED)) &&
+ !strcasecmp(value, "on"))
+ {
+ enabled = 1;
+ } else {
+ enabled = 0;
+ }
+ slapi_ch_free_string(&value);
+
+ /*
+ * make sure named dependencies have been satisfied
+ * that means that the list of names should contain all
+ * null entries
+ */
+ if(enabled && config[plugin_index].total_named){
+ i = 0;
+ while(break_out == 0 && i < config[plugin_index].total_named){
+ satisfied = 1;
+
+ if((config[plugin_index].depends_named_list)[i] != 0){
+ satisfied = 0;
+ break_out = 1;
+ }
+ i++;
+ }
+
+ if(!satisfied)
+ continue;
+ }
+
+ /*
+ * make sure the type dependencies have been satisfied
+ * that means for each type in the list, it's number of
+ * plugins left not started is zero
+ */
+ satisfied = 0;
+ break_out = 0;
+
+ if(enabled && config[plugin_index].total_type){
+ i = 0;
+ while(break_out == 0 && i < config[plugin_index].total_type){
+ satisfied = 1;
+ the_plugin_type = find_plugin_type(plugin_head,
(config[plugin_index].depends_type_list)[i]);
+
+ if(the_plugin_type && the_plugin_type->num_not_started != 0){
+ satisfied = 0;
+ break_out = 1;
+ }
+ i++;
+ }
+
+ if(!satisfied)
+ continue;
+ }
+
+ /**** This plugins dependencies have now been satisfied ****/
+
+ satisfied = 1; /* symbolic only */
+ config[plugin_index].entry_created = 1;
+
+ if (enabled){
+ if(plugin_index == plugin_idx){
+ /* finally, perform the op on the plugin */
+ LDAPDebug( LDAP_DEBUG_PLUGIN, "Starting %s plugin %s\n" ,
+ config[plugin_index].type, config[plugin_index].name, 0 );
+ /*
+ * Put the plugin into the temporary pblock so the startup functions have
+ * access to the real plugin for registering callbacks, task, etc.
+ */
+ slapi_pblock_set(&(config[plugin_index].pb), SLAPI_PLUGIN,
config[plugin_index].plugin);
+ ret = plugin_call_one( config[plugin_index].plugin, SLAPI_PLUGIN_START_FN,
+ &(config[plugin_index].pb));
+ pblock_done(&(config[plugin_index].pb));
+
+ if(ret){
+ /*
+ * Delete the plugin(undo everything), as we don't know how far the start
+ * function got.
+ */
+ LDAPDebug( LDAP_DEBUG_ANY, "Failed to start %s plugin %s\n" ,
+ config[plugin_index].type, config[plugin_index].name, 0 );
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Failed to start plugin
\"%s\". See errors log.",
+ config[plugin_index].name);
+ plugin_delete(entry, returntext, 1);
+ goto done;
+ } else {
+ /*
+ * Set the plugin and its registered functions as started.
+ */
+ plugin_set_plugins_started(config[plugin_index].plugin);
+ }
+ }
+
+ /* Add this plugin to the shutdown list */
+ global_tmp_list[shutdown_index] = config[plugin_index];
+ shutdown_index--;
+ global_plugins_started++;
+
+ /* remove this named plugin from other plugins lists */
+ for(i = 0; i < total_plugins; i++){
+ index = 0;
+ while(index < config[i].total_named){
+ if((config[i].depends_named_list)[index] != 0 &&
+ !slapi_UTF8CASECMP((config[i].depends_named_list)[index],
config[plugin_index].name))
+ {
+ slapi_ch_free((void**)&((config[i].depends_named_list)[index]));
+ }
+ index++;
+ }
+ }
+ } else {
+ pblock_done(&(config[plugin_index].pb));
+ }
+
+ /* decrement the type counter for this plugin type */
+ decrement_plugin_type(plugin_head, config[plugin_index].type);
+ config[plugin_index].op_done = 1;
+ num_plg_started++;
+ plugins_started = 1;
+ } /* !op_done */
+ } /* plugin loop */
+ } /* while plugins not started */
+
+ if(plugins_started == 0){
+ /* a dependency was not resolved - error */
+ LDAPDebug( LDAP_DEBUG_ANY, "Error: Failed to resolve plugin dependencies\n" ,
0, 0, 0 );
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Failed to resolve plugin
dependencies.");
+
+ /* list the plugins yet to perform op */
+ i = 0;
+ while(i < total_plugins){
+ if(config[i].op_done == 0){
+ LDAPDebug( LDAP_DEBUG_ANY, "Error: %s plugin %s is not started\n" ,
config[i].type, config[i].name, 0 );
+ plugin_remove_plugins(config[i].plugin, config[i].type);
+ }
+ i++;
+ }
+ ret = -1;
+ }
+
+done:
+ /*
+ * Free the plugin list, then rebuild it
+ */
+ if(ret == LDAP_SUCCESS){
+ /* Ok, everything went well, use the new global_shutdown list */
+ plugin_free_plugin_dep_config(&global_plugin_shutdown_order);
+ global_plugin_shutdown_order = global_tmp_list;
+ } else {
+ /*
+ * problem, undo what we've done in plugin_setup.
+ */
+ plugin_free_plugin_dep_config(&global_tmp_list);
+ }
+
+ /*
+ * need the details in config to hang around for shutdown
+ * config itself may be deleted since its contents have been
+ * copied by value to the shutdown list
+ */
+ plugin_free_plugin_dep_config(&config);
+
+ if(plugin_head){
+ plugin_dep_type next;
+ while(plugin_head){
+ next = plugin_head->next;
+ slapi_ch_free_string(&plugin_head->type);
+ slapi_ch_free((void *)&plugin_head);
+ plugin_head = next;
+ }
+ }
+
+ /* Finally enable registered plugin functions */
+ global_plugin_callbacks_enabled = 1;
+
+ return ret;
+}
+
+static void
+plugin_free_plugin_dep_config(plugin_dep_config **cfg)
+{
+ plugin_dep_config *config = *cfg;
+ int index = 0;
+ int i = 0;
+
+ if(config){
+ while( config[index].plugin ){
+ if(config[index].depends_named_list){
+ for(i = 0; i < config[index].total_named; i++){
+ slapi_ch_free((void**)&(config[index].depends_named_list)[i]);
+ }
+ slapi_ch_free((void**)&(config[index].depends_named_list));
+ }
+ if(config[index].depends_type_list){
+ for(i = 0; i < config[index].total_type; i++){
+ slapi_ch_free((void**)&(config[index].depends_type_list)[i]);
+ }
+ slapi_ch_free((void**)&(config[index].depends_type_list));
+ }
+ slapi_ch_free_string(&config[index].type);
+ slapi_ch_free_string(&config[index].name);
+ pblock_done(&config[index].pb);
+ index++;
+ }
+ slapi_ch_free((void**)&config);
+ *cfg = NULL;
+ }
+}
/*
@@ -973,22 +1454,14 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int
operation)
/* Count the plugins so we can allocate memory for the config array */
while(ep)
{
- total_plugins++;
-
- ep = ep->next;
- }
-
- /* allocate the config array */
- config = (plugin_dep_config*)slapi_ch_malloc(sizeof(plugin_dep_config) *
total_plugins);
-
- if(config)
- memset(config, 0, sizeof(plugin_dep_config) * total_plugins);
- else
- {
- ret = -1;
- goto bail;
+ total_plugins++;
+
+ ep = ep->next;
}
+ /* allocate the config array */
+ config = (plugin_dep_config*)slapi_ch_calloc(total_plugins + 1,
sizeof(plugin_dep_config));
+
ep = dep_plugin_entries;
/* Collect relevant config */
@@ -1008,8 +1481,6 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int
operation)
/* add type */
plugin_entry = ep->e;
- ep->e = NULL; /* consumed by the operation above, and eventually by the
- slapi_internal_add operation below */
if(plugin_entry)
{
@@ -1067,7 +1538,6 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int
operation)
plugin_create_stringlist( plugin_entry, "nsslapd-plugin-depends-on-type",
&(config[plugin_index].total_type),
&(config[plugin_index].depends_type_list));
}
-
plugin_index++;
ep = ep->next;
}
@@ -1078,14 +1548,7 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int
operation)
*/
shutdown_index = total_plugins - 1;
- global_plugin_shutdown_order =
(plugin_dep_config*)slapi_ch_malloc(sizeof(plugin_dep_config) * total_plugins);
- if(global_plugin_shutdown_order)
- memset(global_plugin_shutdown_order, 0, sizeof(plugin_dep_config) * total_plugins);
- else
- {
- ret = -1;
- goto bail;
- }
+ global_plugin_shutdown_order = (plugin_dep_config*)slapi_ch_calloc(total_plugins + 1,
sizeof(plugin_dep_config));
/* now resolve dependencies
* cycle through list, if a plugin has no dependencies then start it
@@ -1225,7 +1688,11 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int
operation)
/* finally, perform the op on the plugin */
LDAPDebug( LDAP_DEBUG_PLUGIN, "Starting %s plugin %s\n" ,
config[plugin_index].type, config[plugin_index].name, 0 );
-
+ /*
+ * Put the plugin into the temporary pblock so the startup functions have
+ * access to the real plugin for registering callbacks, tasks, etc.
+ */
+ slapi_pblock_set(&(config[plugin_index].pb), SLAPI_PLUGIN,
config[plugin_index].plugin);
ret = plugin_call_one( config[plugin_index].plugin, operation,
&(config[plugin_index].pb));
pblock_done(&(config[plugin_index].pb));
@@ -1234,13 +1701,16 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg,
int operation)
{
/*
* We will not exit here. If we allow plugins to load normally it is
- * possible that a configuration error (dependedncies which were not
+ * possible that a configuration error (dependencies which were not
* configured properly) can be recovered from. If there really is a
* problem then the plugin will never start and eventually it will
* trigger an exit anyway.
*/
LDAPDebug( LDAP_DEBUG_ANY, "Failed to start %s plugin %s\n" ,
config[plugin_index].type, config[plugin_index].name, 0 );
continue;
+ } else {
+ /* now set the plugin and all its registered plugin functions as started */
+ plugin_set_plugins_started(config[plugin_index].plugin);
}
/* Add this plugin to the shutdown list */
@@ -1268,8 +1738,6 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int
operation)
}
} else {
pblock_done(&(config[plugin_index].pb));
- slapi_entry_free(config[plugin_index].e);
- config[plugin_index].e = NULL;
}
/* decrement the type counter for this plugin type */
@@ -1289,66 +1757,26 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg,
int operation)
LDAPDebug( LDAP_DEBUG_ANY, "Error: Failed to resolve plugin dependencies\n" ,
0, 0, 0 );
/* list the plugins yet to perform op */
- index = 0;
-
+ i = 0;
while(i < total_plugins)
{
if(config[i].op_done == 0)
{
LDAPDebug( LDAP_DEBUG_ANY, "Error: %s plugin %s is not started\n" ,
config[i].type, config[i].name, 0 );
}
-
i++;
}
-
exit(1);
}
-
-bail:
/*
* need the details in config to hang around for shutdown
* config itself may be deleted since its contents have been
* copied by value to the shutdown list
*/
-
- if(config)
- {
- index = 0;
-
- while(index < total_plugins)
- {
-/*
- if(config[index].depends_named_list)
- {
- slapi_ch_free((void**)&(config[index].depends_named_list));
- }
-*/
- if(config[index].depends_type_list)
- {
- i = 0;
-
- while(i < config[index].total_type)
- {
- slapi_ch_free((void**)&(config[index].depends_type_list)[i]);
-
- i++;
- }
-
- slapi_ch_free((void**)&(config[index].depends_type_list));
- }
-/*
- slapi_ch_free((void**)&(config[index].name));
- slapi_ch_free((void**)&(config[index].type));
-*/
- index++;
- }
-
- slapi_ch_free((void**)&config);
- }
+ plugin_free_plugin_dep_config(&config);
/* Finally enable registered plugin functions */
-
global_plugin_callbacks_enabled = 1;
return ret;
@@ -1367,7 +1795,7 @@ bail:
void
plugin_dependency_closeall()
{
- Slapi_PBlock pb;
+ Slapi_PBlock pb;
int plugins_closed = 0;
int index = 0;
@@ -1384,15 +1812,17 @@ plugin_dependency_closeall()
*/
if(global_plugin_shutdown_order[index].name)
{
- pblock_init(&pb);
- plugin_call_one( global_plugin_shutdown_order[index].plugin, SLAPI_PLUGIN_CLOSE_FN,
&pb );
- /* set plg_closed to 1 to prevent any further plugin pre/post op function calls */
- global_plugin_shutdown_order[index].plugin->plg_closed = 1;
+ if(!global_plugin_shutdown_order[index].removed){
+ pblock_init(&pb);
+ plugin_set_stopped(global_plugin_shutdown_order[index].plugin);
+ plugin_op_all_finished(global_plugin_shutdown_order[index].plugin);
+ plugin_call_one( global_plugin_shutdown_order[index].plugin, SLAPI_PLUGIN_CLOSE_FN,
&pb);
+ /* set plg_closed to 1 to prevent any further plugin pre/post op function calls */
+ global_plugin_shutdown_order[index].plugin->plg_closed = 1;
+ }
plugins_closed++;
- slapi_entry_free(global_plugin_shutdown_order[index].e);
- global_plugin_shutdown_order[index].e = NULL;
- }
+ }
index++;
}
}
@@ -1413,7 +1843,7 @@ plugin_dependency_closeall()
void
plugin_startall(int argc, char** argv, int start_backends, int start_global)
{
- /* initialize special plugin structures */
+ /* initialize special plugin structures */
default_plugin_init ();
plugin_dependency_startall(argc, argv, "plugin startup failed\n",
SLAPI_PLUGIN_START_FN);
@@ -1470,24 +1900,54 @@ plugin_call_one (struct slapdplugin *list, int operation,
Slapi_PBlock *pb)
static int
plugin_call_func (struct slapdplugin *list, int operation, Slapi_PBlock *pb, int
call_one)
{
- /* Invoke the operation on the plugins that are registered for the subtree effected
by the operation. */
- int rc;
+ /* Invoke the operation on the plugins that are registered for the subtree effected by
the operation. */
+ int rc;
int return_value = 0;
- int count= 0;
- for (; list != NULL; list = list->plg_next)
+ int count = 0;
+ int *locked = 0;
+
+ /*
+ * Take the read lock
+ */
+ slapi_td_get_plugin_locked(&locked);
+ if(locked == 0){
+ slapi_rwlock_rdlock(global_rwlock);
+ }
+
+
+ for (; list != NULL; list = list->plg_next)
{
IFP func = NULL;
- slapi_pblock_set (pb, SLAPI_PLUGIN, list);
- set_db_default_result_handlers (pb); /* JCM: What's this do? Is it needed here? */
- if (slapi_pblock_get (pb, operation, &func) == 0 && func != NULL &&
- plugin_invoke_plugin_pb (list, operation, pb) && list->plg_closed == 0)
+ slapi_pblock_set (pb, SLAPI_PLUGIN, list);
+ set_db_default_result_handlers (pb); /* JCM: What's this do? Is it needed here? */
+ if (slapi_pblock_get (pb, operation, &func) == 0 &&
+ func != NULL &&
+ plugin_invoke_plugin_pb (list, operation, pb) &&
+ list->plg_closed == 0)
{
- char *n= list->plg_name;
- LDAPDebug( LDAP_DEBUG_TRACE, "Calling plugin '%s' #%d type %d\n",
(n==NULL?"noname":n), count, operation );
+ char *n = list->plg_name;
+
+ LDAPDebug( LDAP_DEBUG_TRACE , "Calling plugin '%s' #%d type %d\n",
(n==NULL?"noname":n), count, operation );
/* counters_to_errors_log("before plugin call"); */
- if (( rc = func (pb)) != 0 )
+
+ /*
+ * Only call the plugin function if:
+ *
+ * [1] The plugin is started, and we are NOT trying to restart it.
+ * [2] The plugin is started, and we are stopping it.
+ * [3] The plugin is stopped, and we are trying to start it.
+ *
+ * This frees up the plugins from having to check if the plugin is already started
when
+ * calling the START and CLOSE functions - prevents double starts and stops.
+ */
+ slapi_plugin_op_started(list);
+ if (((SLAPI_PLUGIN_START_FN == operation && !list->plg_started) || /*
Starting it up for the first time */
+ (SLAPI_PLUGIN_CLOSE_FN == operation && !list->plg_stopped) || /*
Shutting down, plugin has been stopped */
+ (SLAPI_PLUGIN_START_FN != operation && list->plg_started)) &&
/* Started, and not trying to start again */
+ ( rc = func (pb)) != 0 )
{
+ slapi_plugin_op_finished(list);
if (SLAPI_PLUGIN_PREOPERATION == list->plg_type ||
SLAPI_PLUGIN_INTERNAL_PREOPERATION == list->plg_type ||
SLAPI_PLUGIN_START_FN == operation )
@@ -1518,6 +1978,12 @@ plugin_call_func (struct slapdplugin *list, int operation,
Slapi_PBlock *pb, int
return_value |= rc;
}
}
+ } else {
+ if(SLAPI_PLUGIN_CLOSE_FN == operation){
+ /* successfully stopped the plugin */
+ list->plg_stopped = 1;
+ }
+ slapi_plugin_op_finished(list);
}
/* counters_to_errors_log("after plugin call"); */
}
@@ -1527,6 +1993,10 @@ plugin_call_func (struct slapdplugin *list, int operation,
Slapi_PBlock *pb, int
if(call_one)
break;
}
+ if(locked == 0){
+ slapi_rwlock_unlock(global_rwlock);
+ }
+
return( return_value );
}
@@ -1758,7 +2228,7 @@ plugin_get_type_and_list(
*type = SLAPI_PLUGIN_INDEX;
plugin_list_index= PLUGIN_LIST_INDEX;
} else {
- return( 1 ); /* unknown plugin type - pass to backend */
+ return( 1 ); /* unknown plugin type - pass to backend */
}
if (plugin_list_index >= 0)
@@ -1767,6 +2237,54 @@ plugin_get_type_and_list(
return 0;
}
+static char *
+plugin_get_type_str( int type )
+{
+ if ( type == SLAPI_PLUGIN_DATABASE){
+ return "database";
+ } else if ( type == SLAPI_PLUGIN_EXTENDEDOP){
+ return "extendedop";
+ } else if ( type == SLAPI_PLUGIN_PREOPERATION){
+ return "preoperation";
+ } else if ( type == SLAPI_PLUGIN_POSTOPERATION){
+ return "postoperation";
+ } else if ( type == SLAPI_PLUGIN_MATCHINGRULE){
+ return "matchingrule";
+ } else if ( type == SLAPI_PLUGIN_SYNTAX){
+ return "syntax";
+ } else if ( type == SLAPI_PLUGIN_ACL){
+ return "accesscontrol";
+ } else if ( type == SLAPI_PLUGIN_BEPREOPERATION){
+ return "bepreoperation";
+ } else if ( type == SLAPI_PLUGIN_BEPOSTOPERATION){
+ return "bepostoperation";
+ } else if ( type == SLAPI_PLUGIN_BETXNPREOPERATION){
+ return "betxnpreoperation";
+ } else if ( type == SLAPI_PLUGIN_BETXNPOSTOPERATION){
+ return "betxnpostoperation";
+ } else if ( type == SLAPI_PLUGIN_INTERNAL_PREOPERATION){
+ return "internalpreoperation";
+ } else if ( type == SLAPI_PLUGIN_INTERNAL_POSTOPERATION){
+ return "internalpostoperation";
+ } else if ( type == SLAPI_PLUGIN_ENTRY){
+ return "entry";
+ } else if ( type == SLAPI_PLUGIN_TYPE_OBJECT){
+ return "object";
+ } else if ( type == SLAPI_PLUGIN_PWD_STORAGE_SCHEME){
+ return "pwdstoragescheme";
+ } else if ( type == SLAPI_PLUGIN_REVER_PWD_STORAGE_SCHEME){
+ return "reverpwdstoragescheme";
+ } else if ( type == SLAPI_PLUGIN_VATTR_SP){
+ return "vattrsp";
+ } else if ( type == SLAPI_PLUGIN_LDBM_ENTRY_FETCH_STORE){
+ return "ldbmentryfetchstore";
+ } else if ( type == SLAPI_PLUGIN_INDEX){
+ return "index";
+ } else {
+ return NULL; /* unknown plugin type - pass to backend */
+ }
+}
+
static const char *
plugin_exists(const Slapi_DN *plugin_dn)
{
@@ -1781,6 +2299,52 @@ plugin_exists(const Slapi_DN *plugin_dn)
return retval;
}
+/*
+ * A plugin config change has occurred, restart the plugin (delete/add).
+ * If something goes wrong, revert to the original plugin entry.
+ */
+int
+plugin_restart(Slapi_Entry *pentryBefore, Slapi_Entry *pentryAfter)
+{
+ char returntext[SLAPI_DSE_RETURNTEXT_SIZE];
+ int rc = LDAP_SUCCESS;
+
+ /* We can not restart the critical plugins */
+ if(plugin_is_critical(pentryBefore)){
+ LDAPDebug(LDAP_DEBUG_PLUGIN, "plugin_restart: Plugin (%s) is critical to server
operation. "
+ "Any changes will not take effect until the server is restarted.\n",
+ slapi_entry_get_dn(pentryBefore),0,0);
+ return 1; /* failure - dse code will log a fatal message */
+ }
+
+ slapi_rwlock_wrlock(global_rwlock);
+
+ if(plugin_delete(pentryBefore, returntext, 1) == LDAP_SUCCESS){
+ if(plugin_add(pentryAfter, returntext, 1) == LDAP_SUCCESS){
+ LDAPDebug(LDAP_DEBUG_PLUGIN, "plugin_restart: Plugin (%s) has been
successfully "
+ "restarted after configuration change.\n",
+ slapi_entry_get_dn(pentryAfter),0,0);
+ } else {
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_restart: Plugin (%s) failed to restart after
"
+ "configuration change (%s). Reverting to original plugin
entry.\n",
+ slapi_entry_get_dn(pentryAfter), returntext, 0);
+ if(plugin_add(pentryBefore, returntext, 1) == LDAP_SUCCESS){
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_restart: Plugin (%s) failed to reload
"
+ "original plugin (%s)\n",slapi_entry_get_dn(pentryBefore),
returntext, 0);
+ }
+ rc = 1;
+ }
+ } else {
+ LDAPDebug(LDAP_DEBUG_ANY,"plugin_restart: failed to disable/stop the plugin
(%s): %s\n",
+ slapi_entry_get_dn(pentryBefore), returntext, 0);
+ rc = 1;
+ }
+
+ slapi_rwlock_unlock(global_rwlock);
+
+ return rc;
+}
+
static int
plugin_set_subtree_config(PluginTargetData *subtree_config, const char *val)
{
@@ -2063,10 +2627,11 @@ static void
plugin_free(struct slapdplugin *plugin)
{
charray_free(plugin->plg_argv);
- slapi_ch_free((void**)&plugin->plg_libpath);
- slapi_ch_free((void**)&plugin->plg_initfunc);
- slapi_ch_free((void**)&plugin->plg_name);
- slapi_ch_free((void**)&plugin->plg_dn);
+ slapi_ch_free_string(&plugin->plg_libpath);
+ slapi_ch_free_string(&plugin->plg_initfunc);
+ slapi_ch_free_string(&plugin->plg_name);
+ slapi_ch_free_string(&plugin->plg_dn);
+ slapi_counter_destroy(&plugin->plg_op_counter);
if (!plugin->plg_group)
plugin_config_cleanup(&plugin->plg_conf);
slapi_ch_free((void**)&plugin);
@@ -2124,7 +2689,7 @@ add_entry - if true, the entry will be added to the DIT using the
given
************************************/
int
plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group,
- slapi_plugin_init_fnptr p_initfunc, int add_entry)
+ slapi_plugin_init_fnptr p_initfunc, int add_entry, char *returntext)
{
int ii = 0;
char attrname[BUFSIZ];
@@ -2143,15 +2708,18 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
if (!slapi_entry_get_sdn_const(plugin_entry))
{
- LDAPDebug(LDAP_DEBUG_ANY, "Error: DN is missing from the plugin.\n",
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_setup: DN is missing from the plugin.\n",
0, 0, 0);
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Plugin is missing dn.");
return -1;
}
if ((existname = plugin_exists(slapi_entry_get_sdn_const(plugin_entry))) != NULL)
{
- LDAPDebug(LDAP_DEBUG_ANY, "Error: the plugin named %s "
- "already exists.\n", existname, 0, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_setup: the plugin named %s already exists,
"
+ "or is already setup.\n", existname, 0, 0);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
+ "the plugin named %s already exists, or is already setup.",
existname);
return -1;
}
@@ -2162,16 +2730,17 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
*/
plugin = (struct slapdplugin *)slapi_ch_calloc(1, sizeof(struct slapdplugin));
- plugin->plg_dn = slapi_ch_strdup(slapi_entry_get_dn_const(plugin_entry));
+ plugin->plg_dn = slapi_ch_strdup(slapi_entry_get_ndn(plugin_entry));
plugin->plg_closed = 0;
if (!(value = slapi_entry_attr_get_charptr(plugin_entry,
ATTR_PLUGIN_TYPE)))
{
/* error: required attribute %s missing */
- LDAPDebug(LDAP_DEBUG_ANY, "Error: required attribute %s is missing "
- "from entry \"%s\"\n", ATTR_PLUGIN_TYPE,
- slapi_entry_get_dn_const(plugin_entry), 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "Error: required attribute %s is missing from entry
\"%s\"\n",
+ ATTR_PLUGIN_TYPE, slapi_entry_get_dn_const(plugin_entry), 0);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"required attribute %s is
missing from entry",
+ ATTR_PLUGIN_TYPE);
status = -1;
goto PLUGIN_CLEANUP;
}
@@ -2182,23 +2751,23 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
if ( status != 0 ) {
/* error: unknown plugin type */
- LDAPDebug(LDAP_DEBUG_ANY, "Error: unknown plugin type \"%s\" "
- "in entry \"%s\"\n",
+ LDAPDebug(LDAP_DEBUG_ANY, "Error: unknown plugin type \"%s\" in entry
\"%s\"\n",
value, slapi_entry_get_dn_const(plugin_entry), 0);
- slapi_ch_free((void**)&value);
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "unknown plugin type
\"%s\" in entry", value);
+ slapi_ch_free_string(&value);
status = -1;
goto PLUGIN_CLEANUP;
}
- slapi_ch_free((void**)&value);
+ slapi_ch_free_string(&value);
}
if (!status &&
!(value = slapi_entry_attr_get_charptr(plugin_entry, "cn")))
{
/* error: required attribute %s missing */
- LDAPDebug(LDAP_DEBUG_ANY, "Error: required attribute %s is missing "
- "from entry \"%s\"\n", "cn",
- slapi_entry_get_dn_const(plugin_entry), 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "Error: required attribute %s is missing from entry
\"%s\"\n",
+ "cn", slapi_entry_get_dn_const(plugin_entry), 0);
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "required attribute
\"cn\" is missing from entry");
status = -1;
goto PLUGIN_CLEANUP;
}
@@ -2231,6 +2800,9 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
LDAPDebug(LDAP_DEBUG_ANY, "Error: value for attribute %s must be "
"an integer between %d and %d\n", ATTR_PLUGIN_PRECEDENCE,
PLUGIN_MIN_PRECEDENCE, PLUGIN_MAX_PRECEDENCE);
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "value for attribute %s must
be "
+ "an integer between %d and %d.", ATTR_PLUGIN_PRECEDENCE,
+ PLUGIN_MIN_PRECEDENCE, PLUGIN_MAX_PRECEDENCE);
status = -1;
slapi_ch_free((void**)&value);
goto PLUGIN_CLEANUP;
@@ -2248,9 +2820,10 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
if (!initfunc)
{
/* error: required attribute %s missing */
- LDAPDebug(LDAP_DEBUG_ANY, "Error: required attribute %s is missing "
- "from entry \"%s\"\n", ATTR_PLUGIN_INITFN,
- slapi_entry_get_dn_const(plugin_entry), 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "Error: required attribute %s is missing from entry
\"%s\"\n",
+ ATTR_PLUGIN_INITFN, slapi_entry_get_dn_const(plugin_entry), 0);
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,"required attribute %s is
missing from entry.",
+ ATTR_PLUGIN_INITFN);
status = -1;
goto PLUGIN_CLEANUP;
}
@@ -2269,9 +2842,10 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
ATTR_PLUGIN_PATH)))
{
/* error: required attribute %s missing */
- LDAPDebug(LDAP_DEBUG_ANY, "Error: required attribute %s is missing "
- "from entry \"%s\"\n", ATTR_PLUGIN_PATH,
- slapi_entry_get_dn_const(plugin_entry), 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "Error: required attribute %s is missing from entry
\"%s\"\n",
+ ATTR_PLUGIN_PATH, slapi_entry_get_dn_const(plugin_entry), 0);
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "required attribute %s is
missing from entry.",
+ ATTR_PLUGIN_PATH);
status = -1;
goto PLUGIN_CLEANUP;
}
@@ -2290,6 +2864,7 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
plugin->plg_initfunc, plugin->plg_name, 1 /* report errors */,
loadNow, loadGlobal)) == NULL)
{
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Failed to load plugin's
init function.");
status = -1;
goto PLUGIN_CLEANUP;
}
@@ -2318,6 +2893,14 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
set_plugin_config_from_entry(plugin_entry, plugin);
}
+ /*
+ * If this is a registered plugin function, then set the plugin id so we can remove
+ * this plugin later if needed.
+ */
+ if(group){
+ plugin->plg_id = group->sci_component_name;
+ }
+
/* add the plugin arguments */
value = 0;
ii = 0;
@@ -2354,13 +2937,14 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
slapi_pblock_set(&pb, SLAPI_PLUGIN_ENABLED, &enabled);
slapi_pblock_set(&pb, SLAPI_PLUGIN_CONFIG_ENTRY, plugin_entry);
+ plugin->plg_op_counter = slapi_counter_new();
if (enabled && (*initfunc)(&pb) != 0)
{
- LDAPDebug(LDAP_DEBUG_ANY, "Init function \"%s\" for
\"%s\" plugin"
- " in library \"%s\" failed\n",
- plugin->plg_initfunc, plugin->plg_name,
- plugin->plg_libpath);
+ LDAPDebug(LDAP_DEBUG_ANY, "Init function \"%s\" for
\"%s\" plugin in library \"%s\" failed\n",
+ plugin->plg_initfunc, plugin->plg_name, plugin->plg_libpath);
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Init function
\"%s\" for \"%s\" plugin in "
+ "library \"%s\"
failed.",plugin->plg_initfunc, plugin->plg_name, plugin->plg_libpath);
status = -1;
slapi_ch_free((void**)&value);
goto PLUGIN_CLEANUP;
@@ -2390,7 +2974,6 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
new_plugin_entry(&dep_plugin_entries, e_copy, plugin);
}
-
PLUGIN_CLEANUP:
if (status)
plugin_free(plugin);
@@ -2399,6 +2982,476 @@ PLUGIN_CLEANUP:
return status;
}
+/*
+ * We added a plugin, do our setup and then start the plugin. This is the same as adding
a plugin
+ * or enabling a disabled plugin.
+ */
+int
+plugin_add(Slapi_Entry *entry, char *returntext, int locked)
+{
+ int rc = LDAP_SUCCESS;
+ int td_locked = 1;
+
+ if(!locked){
+ slapi_rwlock_wrlock(global_rwlock);
+ }
+ slapi_td_set_plugin_locked(&td_locked);
+
+ if((rc = plugin_setup(entry, 0, 0, 1, returntext)) != LDAP_SUCCESS){
+ LDAPDebug(LDAP_DEBUG_PLUGIN, "plugin_add: plugin_setup failed for
(%s)\n",slapi_entry_get_dn(entry), rc, 0);
+ goto done;
+ }
+
+ if((rc = plugin_start(entry, returntext)) != LDAP_SUCCESS){
+ LDAPDebug(LDAP_DEBUG_PLUGIN, "plugin_add: plugin_start failed for
(%s)\n",slapi_entry_get_dn(entry), rc, 0);
+ goto done;
+ }
+
+done:
+ if(!locked){
+ slapi_rwlock_unlock(global_rwlock);
+ }
+ td_locked = 0;
+ slapi_td_set_plugin_locked(&td_locked);
+
+ return rc;
+}
+
+static char *
+get_dep_plugin_list(char **plugins)
+{
+ char output[1024];
+ int first_plugin = 1;
+ int len = 0;
+ int i ;
+
+ for(i = 0; plugins && plugins[i]; i++){
+ if(first_plugin){
+ PL_strncpyz(output,plugins[i], sizeof(output) - 3);
+ len += strlen(plugins[i]);
+ first_plugin = 0;
+ } else {
+ PL_strcatn(output ,sizeof(output) -3, ", ");
+ PL_strcatn(output, sizeof(output) -3, plugins[i]);
+ len += strlen(plugins[i]);
+ }
+ if(len > (sizeof(output) - 3)){
+ /*
+ * We could not print all the plugins, show that we truncated
+ * the list by adding "..."
+ */
+ PL_strcatn(output ,sizeof(output) , "...");
+ }
+ }
+
+ return slapi_ch_strdup(output);
+}
+
+/*
+ * Make sure the removal of this plugin does not breaking any existing dependencies
+ */
+static int
+plugin_delete_check_dependency(struct slapdplugin *plugin_entry, int flag, char
*returntext)
+{
+ entry_and_plugin_t *ep = dep_plugin_entries;
+ plugin_dep_config *config = NULL;
+ struct slapdplugin *plugin = NULL;
+ Slapi_Entry *pentry = NULL;
+ char *plugin_name = plugin_entry->plg_name;
+ char *plugin_type = plugin_get_type_str(plugin_entry->plg_type);
+ char **dep_plugins = NULL;
+ char *value = NULL;
+ char **list = NULL;
+ int dep_type_count = 0;
+ int type_count = 0;
+ int total_plugins = 0;
+ int plugin_index = 0;
+ int index = 0;
+ int rc = LDAP_SUCCESS;
+ int i;
+
+ while(ep){
+ total_plugins++;
+ ep = ep->next;
+ }
+
+ /* allocate the config array */
+ config = (plugin_dep_config*)slapi_ch_calloc(total_plugins + 1,
sizeof(plugin_dep_config));
+
+ ep = dep_plugin_entries;
+
+ /*
+ * Collect relevant config
+ */
+ while(ep){
+ plugin = ep->plugin;
+
+ if(plugin == 0){
+ goto next;
+ }
+
+ /*
+ * We are not concerned with disabled plugins
+ */
+ value = slapi_entry_attr_get_charptr(ep->e, ATTR_PLUGIN_ENABLED);
+ if(value){
+ if(strcasecmp(value, "off") == 0){
+ slapi_ch_free_string(&value);
+ goto next;
+ }
+ slapi_ch_free_string(&value);
+ } else {
+ goto next;
+ }
+ if(!ep->plugin){
+ goto next;
+ }
+
+ config[plugin_index].e = ep->e;
+ pentry = ep->e;
+ if(pentry){
+ config[plugin_index].plugin = plugin;
+ plugin_create_stringlist( pentry,
"nsslapd-plugin-depends-on-named",
+ &(config[plugin_index].total_named),
&(config[plugin_index].depends_named_list));
+ plugin_create_stringlist( pentry,
"nsslapd-plugin-depends-on-type",
+ &(config[plugin_index].total_type),
&(config[plugin_index].depends_type_list));
+ }
+ plugin_index++;
+next:
+ ep = ep->next;
+ }
+
+ /*
+ * Start checking every plugin for dependency issues
+ */
+ for(index = 0; index < plugin_index; index++){
+ if((plugin = config[index].plugin)){
+ /*
+ * We can skip ourselves, and our registered plugins.
+ */
+ if( plugin_cmp_plugins(plugin, plugin_entry))
+ {
+ continue;
+ }
+
+ /*
+ * Check all the plugins to see if one is depending on this plugin(name)
+ */
+ if(flag == CHECK_ALL && config[index].depends_named_list){
+ list = config[index].depends_named_list;
+ for(i = 0; list && list[i]; i++){
+ if(strcasecmp(list[i], plugin_name) == 0){
+ /* We have a dependency, we can not disable this pluign */
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete_check_dependency:
can not disable plugin(%s) due "
+ "to dependency name issues with plugin
(%s)\n",
+ plugin_name, config[index].plugin->plg_name, 0);
+ rc = -1;
+ goto free_and_return;
+ }
+ }
+ }
+ /*
+ * Check all the plugins to see if one is depending on this plugin(type).
+ */
+ if(config[index].depends_type_list){
+ list = config[index].depends_type_list;
+ for(i = 0; list && list[i]; i++){
+ if(strcasecmp(list[i], plugin_type) == 0){
+ charray_add(&dep_plugins,
slapi_ch_strdup(plugin->plg_name));
+ dep_type_count++;
+ break;
+ }
+ }
+ }
+ }
+ }
+ /*
+ * Now check the dependency type count.
+ */
+ if(dep_type_count > 0){
+ /*
+ * There are plugins that depend on this plugin type. Now, get a plugin count of
this
+ * type of plugin. If we are the only plugin of this type, we can not disable
it.
+ */
+ for(index = 0; index < plugin_index; index++){
+ if((plugin = config[index].plugin)){
+ /* Skip ourselves, and our registered plugins. */
+ if( plugin_cmp_plugins(plugin, plugin_entry))
+ {
+ continue;
+ }
+ if(plugin->plg_type == plugin_entry->plg_type){
+ /* there is at least one other plugin of this type, its ok to disable
*/
+ type_count = 1;
+ break;
+ }
+ }
+ }
+ if(type_count == 0){ /* this is the only plugin of this type - return an error
*/
+ char *plugins = get_dep_plugin_list(dep_plugins);
+
+ /*
+ * The plugin type was changed, but since other plugins currently have
dependencies,
+ * we can not dynamically apply the change. This is will most likely cause
issues
+ * at the next server startup.
+ */
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Plugin (%s) type
(%s) is needed "
+ "by other plugins(%s), it can not be dynamically
disabled/removed at this time.",
+ plugin_name, plugin_type, plugins);
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete_check_dependency: %s\n",
+ returntext, 0, 0);
+
+ slapi_ch_free_string(&plugins);
+ rc = -1;
+ }
+ }
+
+free_and_return:
+ /*
+ * Free the config list
+ */
+ charray_free(dep_plugins);
+ if(config){
+ index = 0;
+ while( config[index].plugin){
+ charray_free(config[index].depends_type_list);
+ charray_free(config[index].depends_named_list);
+ index++;
+ }
+ slapi_ch_free((void**)&config);
+ }
+
+ return rc;
+}
+
+/*
+ * Mark the plugin in the shutdown list a removed
+ */
+static void
+plugin_remove_from_shutdown(struct slapdplugin *plugin_entry)
+{
+ struct slapdplugin *plugin = NULL;
+ int index = 0;
+
+ for(;index < global_plugins_started; index++){
+ if((plugin = global_plugin_shutdown_order[index].plugin)){
+ if(global_plugin_shutdown_order[index].removed){
+ continue;
+ }
+ /* "plugin_entry" can be the main plugin for registered function
*/
+ if(plugin_cmp_plugins(plugin, plugin_entry))
+ {
+ /*
+ * We have our index, just mark it as removed. The global list gets
rewritten
+ * the next time we add or enable a plugin.
+ */
+ global_plugin_shutdown_order[index].removed = 1;
+ return;
+ }
+ }
+ }
+}
+
+/*
+ * Free the plugins that have been set to be removed.
+ */
+static void
+plugin_cleanup_list()
+{
+ struct slapdplugin *plugin = NULL;
+ entry_and_plugin_t *ep = dep_plugin_entries;
+ entry_and_plugin_t *ep_prev = NULL, *ep_next = NULL;
+
+ while(ep){
+ plugin = ep->plugin;
+ ep_next = ep->next;
+ if(plugin && plugin->plg_removed){
+ if(ep_prev){
+ ep_prev->next = ep->next;
+ } else {
+ dep_plugin_entries = ep->next;
+ }
+ slapi_entry_free(ep->e);
+ if(ep->plugin){
+ plugin_free(ep->plugin);
+ }
+ slapi_ch_free((void **)&ep);
+ } else {
+ ep_prev = ep;
+ }
+ ep = ep_next;
+ }
+}
+
+/*
+ * Look at all the plugins for any matches. Then mark the ones we need
+ * to delete. After checking all the plugins, then we free the ones that
+ * were marked to be removed.
+ */
+static int
+plugin_remove_plugins(struct slapdplugin *plugin_entry, char *plugin_type)
+{
+ struct slapdplugin *plugin = NULL;
+ struct slapdplugin *plugin_next = NULL;
+ struct slapdplugin *plugin_prev = NULL;
+ int removed = 0;
+ int type;
+
+ /* look everywhere for other plugin functions with the plugin id */
+ for(type = 0; type < PLUGIN_LIST_GLOBAL_MAX; type++){
+ plugin = global_plugin_list[type];
+ plugin_prev = NULL;
+ while(plugin){
+ plugin_next = plugin->plg_next;
+ /*
+ * Check for the two types of plugins:
+ * the main plugin, and its registered plugin functions.
+ */
+ if(plugin_cmp_plugins(plugin_entry, plugin)){
+ /*
+ * Call the close function, cleanup the hashtable & the global
shutdown list
+ */
+ Slapi_PBlock pb;
+
+ pblock_init(&pb);
+ plugin_set_stopped(plugin);
+ plugin_op_all_finished(plugin);
+ plugin_call_one( plugin, SLAPI_PLUGIN_CLOSE_FN, &pb);
+
+ if(plugin_prev){
+ plugin_prev->plg_next = plugin_next;
+ } else {
+ global_plugin_list[type] = plugin_next;
+ }
+
+ /*
+ * Remove plugin the DN hashtable, update the shutdown list,
+ * and mark the plugin for deletion
+ */
+ plugin_remove_from_list(plugin->plg_dn);
+ plugin_remove_from_shutdown(plugin);
+ plugin->plg_removed = 1;
+ plugin->plg_started = 0;
+ removed = 1;
+ } else {
+ plugin_prev = plugin;
+ }
+ plugin = plugin_next;
+ }
+ }
+ if(removed){
+ /*
+ * Now free the marked plugins, we could not do this earlier because
+ * we also needed to check for plugins registered functions. As both
+ * plugin types share the same slapi_plugin entry.
+ */
+ plugin_cleanup_list();
+ }
+
+ return removed;
+}
+
+/*
+ * We are removing a plugin from the global list. This happens when we delete a plugin,
or disable it.
+ */
+int
+plugin_delete(Slapi_Entry *plugin_entry, char *returntext, int locked)
+{
+ struct slapdplugin **plugin_list = NULL;
+ struct slapdplugin *plugin = NULL;
+ const char *plugin_dn = slapi_entry_get_dn_const(plugin_entry);
+ char *value = NULL;
+ int td_locked = 1;
+ int removed = 0;
+ int type = 0;
+ int rc = LDAP_SUCCESS;
+
+ if(!locked){
+ slapi_rwlock_wrlock(global_rwlock);
+ }
+ slapi_td_set_plugin_locked(&td_locked);
+
+ /* Critical server plugins can not be disabled */
+ if(plugin_is_critical(plugin_entry)){
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: plugin \"%s\" is
critical to server operations, and can not be disabled\n",
+ slapi_entry_get_dn_const(plugin_entry), 0, 0);
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Plugin \"%s\"
is critical to server operations, and can not "
+ "be disabled.\n",slapi_entry_get_dn_const(plugin_entry));
+ rc = -1;
+ goto done;
+ }
+
+ if (!(value = slapi_entry_attr_get_charptr(plugin_entry, ATTR_PLUGIN_TYPE))){
+ /* error: required attribute %s missing */
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: required attribute %s is missing
from entry \"%s\"\n",
+ ATTR_PLUGIN_TYPE, slapi_entry_get_dn_const(plugin_entry), 0);
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Plugin delete failed:
required attribute %s "
+ "is missing from entry.",ATTR_PLUGIN_TYPE);
+ rc = -1;
+ goto done;
+ } else {
+ rc = plugin_get_type_and_list(value, &type, &plugin_list);
+ if ( rc != 0 ) {
+ /* error: unknown plugin type */
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: unknown plugin type
\"%s\" in entry \"%s\"\n",
+ value, slapi_entry_get_dn_const(plugin_entry), 0);
+ PR_snprintf (returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Plugin delete
failed: unknown plugin type "
+ "\"%s\" in entry.",value);
+ rc = -1;
+ goto done;
+ }
+
+ /*
+ * Skip syntax/matching rule/database plugins - these can not be disabled as it
+ * could break existing schema. We allow the update to occur, but it will
+ * not take effect until the next server restart.
+ */
+ if(type == SLAPI_PLUGIN_SYNTAX || type == SLAPI_PLUGIN_MATCHINGRULE || type ==
SLAPI_PLUGIN_DATABASE){
+ removed = 1; /* avoids error check below */
+ goto done;
+ }
+
+ /*
+ * Now remove the plugin from the list and the hashtable
+ */
+ for(plugin = *plugin_list; plugin ; plugin = plugin->plg_next){
+ if(strcasecmp(plugin->plg_dn, plugin_dn) == 0){
+ /*
+ * Make sure there are no other plugins that depend on this one before
removing it
+ */
+ if(plugin_delete_check_dependency(plugin, CHECK_ALL, returntext) !=
LDAP_SUCCESS){
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: failed to
disable/delete plugin (%s)\n",
+ plugin->plg_dn,0,0);
+ rc = -1;
+ goto done;
+ }
+ removed = plugin_remove_plugins(plugin, value);
+ break;
+ }
+ }
+ }
+
+done:
+ if(!locked){
+ slapi_rwlock_unlock(global_rwlock);
+ }
+ td_locked = 0;
+ slapi_td_set_plugin_locked(&td_locked);
+
+ slapi_ch_free_string(&value);
+
+ if(!removed && rc == 0){
+ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Plugin delete failed:
could not find plugin "
+ "in the global list.");
+ LDAPDebug(LDAP_DEBUG_ANY, "plugin_delete: did not find plugin(%s) in the
global list.\n",
+ slapi_entry_get_dn_const(plugin_entry),0,0);
+ rc = -1;
+ }
+
+ return rc;
+}
+
+
/* set default configuration parameters */
static void
plugin_config_init (struct pluginconfig *config)
@@ -3275,3 +4328,74 @@ slapi_disordely_shutdown(PRBool set)
}
return (is_disordely_shutdown);
}
+
+/*
+ * Plugin operation counters
+ *
+ * Since most plugins can now be stopped and started dynamically we need
+ * to take special care when calling a close function. Since many plugins
+ * use global locks and data structures, these can not be freed/destroyed
+ * while there are active operations using them.
+ */
+
+void
+slapi_plugin_op_started(void *p)
+{
+ struct slapdplugin *plugin = (struct slapdplugin *)p;
+
+ if(plugin){
+ slapi_counter_increment(plugin->plg_op_counter);
+ }
+}
+
+void
+slapi_plugin_op_finished(void *p)
+{
+ struct slapdplugin *plugin = (struct slapdplugin *)p;
+
+ if(plugin){
+ slapi_counter_decrement(plugin->plg_op_counter);
+ }
+}
+
+/*
+ * Waits for the operation counter to hit zero
+ */
+void
+plugin_op_all_finished(struct slapdplugin *p)
+{
+ while(p && slapi_counter_get_value(p->plg_op_counter) > 0){
+ DS_Sleep(PR_MillisecondsToInterval(100));
+ }
+}
+
+void
+plugin_set_started(struct slapdplugin *p)
+{
+ p->plg_started = 1;
+ p->plg_stopped = 0;
+}
+
+void
+plugin_set_stopped(struct slapdplugin *p)
+{
+ /*
+ * We do not set "plg_stopped" here, because that is only used
+ * once the plugin has called its CLOSE function. Setting
+ * "plg_started" to 0 will prevent new operations from calling
+ * the plugin.
+ */
+ p->plg_started = 0;
+}
+
+int
+slapi_plugin_running(Slapi_PBlock *pb)
+{
+ int rc = 0;
+
+ if(pb->pb_plugin){
+ rc = pb->pb_plugin->plg_started;
+ }
+
+ return rc;
+}
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 447e1d0..760a728 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -584,6 +584,8 @@ int config_get_plugin_logging();
int config_set_connection_nocanon(const char *attrname, char *value, char *errorbuf, int
apply);
int config_set_plugin_logging(const char *attrname, char *value, char *errorbuf, int
apply);
int config_get_listen_backlog_size(void);
+int config_set_dynamic_plugins(const char *attrname, char *value, char *errorbuf, int
apply);
+int config_get_dynamic_plugins();
PLHashNumber hashNocaseString(const void *key);
PRIntn hashNocaseCompare(const void *v1, const void *v2);
@@ -712,7 +714,7 @@ int dse_search(Slapi_PBlock *pb);
int dse_modify(Slapi_PBlock *pb);
int dse_add(Slapi_PBlock *pb);
int dse_delete(Slapi_PBlock *pb);
-struct dse_callback *dse_register_callback(struct dse* pdse, int operation, int flags,
const Slapi_DN *base, int scope, const char *filter, dseCallbackFn fn, void *fn_arg);
+struct dse_callback *dse_register_callback(struct dse* pdse, int operation, int flags,
const Slapi_DN *base, int scope, const char *filter, dseCallbackFn fn, void *fn_arg,
struct slapdplugin *plugin);
void dse_remove_callback(struct dse* pdse, int operation, int flags, const Slapi_DN
*base, int scope, const char *filter, dseCallbackFn fn);
void dse_set_dont_ever_write_dse_files(void);
void dse_unset_dont_ever_write_dse_files(void);
@@ -866,9 +868,10 @@ void operation_set_type(Slapi_Operation *op, unsigned long type);
/*
* plugin.c
*/
+void global_plugin_init();
int plugin_call_plugins( Slapi_PBlock *, int );
int plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group,
- slapi_plugin_init_fnptr initfunc, int add_to_dit);
+ slapi_plugin_init_fnptr initfunc, int add_to_dit, char *returntext);
int plugin_call_exop_plugins( Slapi_PBlock *pb, char *oid );
const char *plugin_extended_op_oid2string( const char *oid );
void plugin_closeall(int close_backends, int close_globals);
@@ -884,6 +887,13 @@ void plugin_call_entryfetch_plugins(char **entrystr, uint *size);
void plugin_call_entrystore_plugins(char **entrystr, uint *size);
void plugin_print_versions(void);
void plugin_print_lists(void);
+int plugin_add(Slapi_Entry *entry, char *returntext, int locked);
+int plugin_delete(Slapi_Entry *entry, char *returntext, int locked);
+void plugin_update_dep_entries(Slapi_Entry *plugin_entry);
+int plugin_restart(Slapi_Entry *entryBefore, Slapi_Entry *entryAfter);
+void plugin_op_all_finished(struct slapdplugin *p);
+void plugin_set_stopped(struct slapdplugin *p);
+void plugin_set_started(struct slapdplugin *p);
/*
* plugin_mr.c
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
index ef4179d..a10dfae 100644
--- a/ldap/servers/slapd/result.c
+++ b/ldap/servers/slapd/result.c
@@ -1441,7 +1441,6 @@ send_specific_attrs(Slapi_Entry *e, char **attrs, Slapi_Operation
*op,
/* need to pass actual_type_name (e.g., sn;en to evaluate the ACL */
rc = encode_attr_2(pb, ber, e, values[iter], attrsonly,
actual_type_name[iter], name_to_return);
-
slapi_vattr_values_free(&(values[iter]), &(actual_type_name[iter]),
attr_free_flags);
}
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
index 40b14a9..24febad 100644
--- a/ldap/servers/slapd/schema.c
+++ b/ldap/servers/slapd/schema.c
@@ -5213,7 +5213,7 @@ init_schema_dse_ext(char *schemadir, Slapi_Backend *be,
dse_register_callback(*local_pschemadse,
DSE_OPERATION_READ, DSE_FLAG_PREOP, &schema,
LDAP_SCOPE_BASE, NULL,
- load_schema_dse, (void *)&schema_flags);
+ load_schema_dse, (void *)&schema_flags, NULL);
}
slapi_ch_free_string(&userschematmpfile);
if (NULL == schemadir)
@@ -5283,16 +5283,16 @@ init_schema_dse_ext(char *schemadir, Slapi_Backend *be,
/* register callbacks */
dse_register_callback(*local_pschemadse, SLAPI_OPERATION_SEARCH,
DSE_FLAG_PREOP,&schema, LDAP_SCOPE_BASE,
- NULL, read_schema_dse, NULL);
+ NULL, read_schema_dse, NULL, NULL);
dse_register_callback(*local_pschemadse, SLAPI_OPERATION_MODIFY,
DSE_FLAG_PREOP,&schema, LDAP_SCOPE_BASE,
- NULL, modify_schema_dse, NULL);
+ NULL, modify_schema_dse, NULL, NULL);
dse_register_callback(*local_pschemadse, SLAPI_OPERATION_DELETE,
DSE_FLAG_PREOP, &schema, LDAP_SCOPE_BASE,
- NULL,dont_allow_that,NULL);
+ NULL,dont_allow_that,NULL, NULL);
dse_register_callback(*local_pschemadse, DSE_OPERATION_WRITE,
DSE_FLAG_PREOP, &schema, LDAP_SCOPE_BASE,
- NULL, refresh_user_defined_schema, NULL);
+ NULL, refresh_user_defined_schema, NULL, NULL);
if (rc) {
if (NULL == be) { /* be is not given. select it */
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index f2ab9b3..eb52f7d 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -774,6 +774,9 @@ struct matchingRuleList {
#define ATTR_PLUGIN_LOAD_NOW "nsslapd-pluginLoadNow"
#define ATTR_PLUGIN_LOAD_GLOBAL "nsslapd-pluginLoadGlobal"
#define ATTR_PLUGIN_PRECEDENCE "nsslapd-pluginPrecedence"
+#define ATTR_PLUGIN_DEPENDS_ON_TYPE "nsslapd-plugin-depends-on-type"
+#define ATTR_PLUGIN_DEPENDS_ON_NAMED "nsslapd-plugin-depends-on-named"
+#define ATTR_PLUGIN_BE_TXN "nsslapd-pluginbetxn"
/* plugin precedence defines */
#define PLUGIN_DEFAULT_PRECEDENCE 50
@@ -838,6 +841,7 @@ struct slapdplugin {
struct slapdplugin *plg_next; /* for plugin lists */
int plg_type; /* discriminates union */
char *plg_dn; /* config dn for this plugin */
+ char *plg_id; /* plugin id, used when adding/removing plugins */
int plg_precedence; /* for plugin execution ordering */
struct slapdplugin *plg_group; /* pointer to the group to which this plugin belongs
*/
struct pluginconfig plg_conf; /* plugin configuration parameters */
@@ -845,6 +849,10 @@ struct slapdplugin {
IFP plg_start; /* start function */
IFP plg_poststart; /* poststart function */
int plg_closed; /* mark plugin as closed */
+ int plg_removed; /* mark plugin as removed/deleted */
+ PRUint64 plg_started; /* plugin is started/running */
+ PRUint64 plg_stopped; /* plugin has been fully shutdown */
+ Slapi_Counter *plg_op_counter; /* operation counter, used for shutdown */
/* NOTE: These LDIF2DB and DB2LDIF fn pointers are internal only for now.
I don't believe you can get these functions from a plug-in and
@@ -1558,6 +1566,7 @@ struct slapi_task {
TaskCallbackFn cancel; /* task has been cancelled by user */
TaskCallbackFn destructor; /* task entry is being destroyed */
int task_refcount;
+ void *origin_plugin; /* If this is a plugin create task, store the plugin
object */
PRLock *task_log_lock; /* To protect task_log to be realloced if
it's in use */
} slapi_task;
@@ -2139,6 +2148,7 @@ typedef struct _slapdEntryPoints {
#define CONFIG_CONNECTION_NOCANON "nsslapd-connection-nocanon"
#define CONFIG_PLUGIN_LOGGING "nsslapd-plugin-logging"
#define CONFIG_LISTEN_BACKLOG_SIZE "nsslapd-listen-backlog-size"
+#define CONFIG_DYNAMIC_PLUGINS "nsslapd-dynamic-plugins"
/* getenv alternative */
#define CONFIG_MALLOC_MXFAST "nsslapd-malloc-mxfast"
@@ -2402,6 +2412,7 @@ typedef struct _slapdFrontendConfig {
slapi_onoff_t connection_nocanon; /* if "on" sets LDAP_OPT_X_SASL_NOCANON */
slapi_onoff_t plugin_logging; /* log all internal plugin operations */
slapi_onoff_t ignore_time_skew;
+ slapi_onoff_t dynamic_plugins; /* allow plugins to be dynamically enabled/disabled */
#if defined(LINUX)
int malloc_mxfast; /* mallopt M_MXFAST */
int malloc_trim_threshold; /* mallopt M_TRIM_THRESHOLD */
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 63baf21..4fddc42 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5530,9 +5530,13 @@ void slapi_td_get_val(int indexType, void **value);
int slapi_td_dn_init(void);
int slapi_td_set_dn(char *dn);
void slapi_td_get_dn(char **dn);
+int slapi_td_plugin_lock_init();
+int slapi_td_set_plugin_locked(int *value);
+void slapi_td_get_plugin_locked(int **value);
/* Thread Local Storage Index Types */
#define SLAPI_TD_REQUESTOR_DN 1
+#define SLAPI_TD_PLUGIN_LIST_LOCK 2
/*
* routines for dealing with controls
@@ -5961,6 +5965,13 @@ int slapi_register_object_extension( const char *pluginname,
slapi_extension_destructor_fnptr destructor, int *objecttype,
int *extensionhandle);
+int
+slapi_unregister_object_extension(
+ const char* pluginname,
+ const char* objectname,
+ int *objecttype,
+ int *ext_index);
+
/* objects that can be extended (possible values for the objectname param.) */
#define SLAPI_EXT_CONNECTION "Connection"
#define SLAPI_EXT_OPERATION "Operation"
@@ -6507,12 +6518,14 @@ typedef int (*dseCallbackFn)(Slapi_PBlock *, Slapi_Entry *,
Slapi_Entry *,
*/
#define DSE_FLAG_PREOP 0x0001
#define DSE_FLAG_POSTOP 0x0002
+#define DSE_FLAG_PLUGIN 0x0004
/* This is the size of the returntext parameter passed to the config callback function,
which is the "char *" argument to dseCallbackFn above */
#define SLAPI_DSE_RETURNTEXT_SIZE 512 /* for use by callback functions */
int slapi_config_register_callback(int operation, int flags, const char *base, int scope,
const char *filter, dseCallbackFn fn, void *fn_arg);
+int slapi_config_register_callback_plugin(int operation, int flags, const char *base, int
scope, const char *filter, dseCallbackFn fn, void *fn_arg, Slapi_PBlock *pb);
int slapi_config_remove_callback(int operation, int flags, const char *base, int scope,
const char *filter, dseCallbackFn fn);
/******************************************************************************
@@ -6534,6 +6547,7 @@ int slapi_config_remove_callback(int operation, int flags, const
char *base, int
#define SLAPI_TASK_DESTROYING 0x01 /* queued event for destruction */
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);
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);
@@ -6573,6 +6587,17 @@ void slapi_task_log_notice_ext(Slapi_Task *task, char *format,
va_list varg);
*/
Slapi_Task *slapi_new_task(const char *dn);
+/**
+ * slapi_plugin_new_task: create a new task from within a plugin, where
+ * the task runs inside a thread. This
+ *
+ * \param dn Task DN.
+ * \param arg The function argument passed to the registered task function.
+ *
+ * \return Slapi_Task object;
+ */
+Slapi_Task *slapi_plugin_new_task(const char *dn, void *arg);
+
/* slapi_destroy_task: destroy a task
* argument:
* task: task to destroy
@@ -7825,6 +7850,36 @@ char *slapi_pw_get_scheme_name(PWScheme *pass_scheme);
*/
void slapi_free_pw_scheme(PWScheme *pass_scheme);
+/**
+ * Check if the plugin is still running/started.
+ *
+ * \param Slapi_PBlock object.
+ *
+ * \return 0 If plugin is not running.
+ * \return 1 If plugin is running.
+ */
+int slapi_plugin_running(Slapi_PBlock *pb);
+
+/**
+ * For slapi registered tasks that create their own threads. Mark that the task
+ * thread has started. This arg must be passed to the thread function.
+ *
+ * \param void *arg This is the function argument passed to the task function.
+ *
+ * \return Nothing
+ */
+void slapi_plugin_op_started(void *arg);
+
+/**
+ * For slapi registered tasks that create their own threads. Mark that the task
+ * thread has finished. This arg must be passed to the thread function.
+ *
+ * \param void *arg This is the function argument passed to the task function.
+ *
+ * \return Nothing
+ */
+void slapi_plugin_op_finished(void *arg);
+
#ifdef __cplusplus
}
#endif
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 6ca1a49..5e03bc2 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -96,7 +96,7 @@ static int shutting_down = 0;
/***********************************
* Static Function Prototypes
***********************************/
-static Slapi_Task *new_task(const char *dn);
+static Slapi_Task *new_task(const char *dn, void *plugin);
static void destroy_task(time_t when, void *arg);
static int task_modify(Slapi_PBlock *pb, Slapi_Entry *e,
Slapi_Entry *eAfter, int *returncode, char *returntext, void
*arg);
@@ -122,7 +122,13 @@ static void modify_internal_entry(char *dn, LDAPMod **mods);
Slapi_Task *
slapi_new_task(const char *dn)
{
- return new_task(dn);
+ return new_task(dn, NULL);
+}
+
+Slapi_Task *
+slapi_plugin_new_task(const char *dn, void *plugin)
+{
+ return new_task(dn, plugin);
}
/* slapi_destroy_task: destroy a task
@@ -171,6 +177,7 @@ void slapi_task_finish(Slapi_Task *task, int rc)
if (task) {
task->task_exitcode = rc;
task->task_state = SLAPI_TASK_FINISHED;
+ slapi_plugin_op_finished(task->origin_plugin);
slapi_task_status_changed(task);
}
}
@@ -448,16 +455,16 @@ int slapi_task_get_refcount(Slapi_Task *task)
return 0; /* return value not currently used */
}
-/* name is, for example, "import" */
-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)
{
- char *dn = NULL;
- Slapi_PBlock *pb = NULL;
+ Slapi_PBlock *add_pb = NULL;
Slapi_Operation *op;
LDAPMod *mods[3];
LDAPMod mod[3];
const char *objectclass[3];
const char *cnvals[2];
+ char *dn = NULL;
int ret = -1;
int x;
@@ -469,8 +476,8 @@ int slapi_task_register_handler(const char *name, dseCallbackFn func)
return ret;
}
- pb = slapi_pblock_new();
- if (pb == NULL) {
+ add_pb = slapi_pblock_new();
+ if (add_pb == NULL) {
goto out;
}
@@ -489,16 +496,16 @@ int slapi_task_register_handler(const char *name, dseCallbackFn
func)
cnvals[0] = name;
cnvals[1] = NULL;
mods[2] = NULL;
- slapi_add_internal_set_pb(pb, dn, mods, NULL,
+ slapi_add_internal_set_pb(add_pb, dn, mods, NULL,
plugin_get_default_component_id(), 0);
x = 1;
- slapi_pblock_set(pb, SLAPI_DSE_DONT_WRITE_WHEN_ADDING, &x);
+ slapi_pblock_set(add_pb, SLAPI_DSE_DONT_WRITE_WHEN_ADDING, &x);
/* Make sure these adds don't appear in the audit and change logs */
- slapi_pblock_get(pb, SLAPI_OPERATION, &op);
+ slapi_pblock_get(add_pb, SLAPI_OPERATION, &op);
operation_set_flag(op, OP_FLAG_ACTION_NOLOG);
- slapi_add_internal_pb(pb);
- slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &x);
+ slapi_add_internal_pb(add_pb);
+ slapi_pblock_get(add_pb, SLAPI_PLUGIN_INTOP_RESULT, &x);
if ((x != LDAP_SUCCESS) && (x != LDAP_ALREADY_EXISTS)) {
LDAPDebug(LDAP_DEBUG_ANY,
"Can't create task node '%s' (error %d)\n",
@@ -508,8 +515,8 @@ int slapi_task_register_handler(const char *name, dseCallbackFn func)
}
/* register add callback */
- slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP,
- dn, LDAP_SCOPE_SUBTREE, "(objectclass=*)",
func, NULL);
+ slapi_config_register_callback_plugin(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP,
+ dn, LDAP_SCOPE_SUBTREE, "(objectclass=*)",
func, NULL, plugin_pb);
/* deny modify/delete of the root task entry */
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP,
dn, LDAP_SCOPE_BASE, "(objectclass=*)",
task_deny, NULL);
@@ -520,12 +527,18 @@ int slapi_task_register_handler(const char *name, dseCallbackFn
func)
out:
slapi_ch_free_string(&dn);
- if (pb) {
- slapi_pblock_destroy(pb);
+ if (add_pb) {
+ slapi_pblock_destroy(add_pb);
}
return ret;
}
+/* name is, for example, "import" */
+int slapi_task_register_handler(const char *name, dseCallbackFn func)
+{
+ return slapi_plugin_task_register_handler(name, func, NULL);
+}
+
void slapi_task_set_destructor_fn(Slapi_Task *task, TaskCallbackFn func)
{
if (task) {
@@ -546,7 +559,7 @@ void slapi_task_set_cancel_fn(Slapi_Task *task, TaskCallbackFn func)
***********************************/
/* create a new task, fill in DN, and setup modify callback */
static Slapi_Task *
-new_task(const char *rawdn)
+new_task(const char *rawdn, void *plugin)
{
Slapi_Task *task = NULL;
char *dn = NULL;
@@ -572,6 +585,9 @@ new_task(const char *rawdn)
task->destructor = NULL;
task->cancel = NULL;
task->task_private = NULL;
+ task->origin_plugin = plugin;
+ slapi_plugin_op_started(task->origin_plugin);
+
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
task_modify, (void *)task);
slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, dn,
diff --git a/ldap/servers/slapd/thread_data.c b/ldap/servers/slapd/thread_data.c
index ead6e88..121e2d8 100644
--- a/ldap/servers/slapd/thread_data.c
+++ b/ldap/servers/slapd/thread_data.c
@@ -47,6 +47,7 @@ void td_dn_destructor(void *priv);
* Thread Local Storage Indexes
*/
static PRUintn td_requestor_dn; /* TD_REQUESTOR_DN */
+static PRUintn td_plugin_list; /* SLAPI_TD_PLUGIN_LIST_LOCK - integer set to 1 or zero
*/
/*
* Index types defined in slapi-plugin.h
@@ -78,7 +79,12 @@ slapi_td_init(int indexType)
if(PR_NewThreadPrivateIndex(&td_requestor_dn, td_dn_destructor) ==
PR_FAILURE){
return PR_FAILURE;
}
- break;
+ break;
+ case SLAPI_TD_PLUGIN_LIST_LOCK:
+ if(PR_NewThreadPrivateIndex(&td_plugin_list, NULL) == PR_FAILURE){
+ return PR_FAILURE;
+ }
+ break;
default:
return PR_FAILURE;
@@ -103,7 +109,15 @@ slapi_td_set_val(int indexType, void *value)
return PR_FAILURE;
}
break;
-
+ case SLAPI_TD_PLUGIN_LIST_LOCK:
+ if(td_plugin_list){
+ if(PR_SetThreadPrivate(td_plugin_list, value) == PR_FAILURE){
+ return PR_FAILURE;
+ }
+ } else {
+ return PR_FAILURE;
+ }
+ break;
default:
return PR_FAILURE;
}
@@ -125,6 +139,13 @@ slapi_td_get_val(int indexType, void **value)
*value = NULL;
}
break;
+ case SLAPI_TD_PLUGIN_LIST_LOCK:
+ if(td_plugin_list){
+ *value = PR_GetThreadPrivate(td_plugin_list);
+ } else {
+ *value = 0;
+ }
+ break;
default:
*value = NULL;
return;
@@ -135,6 +156,34 @@ slapi_td_get_val(int indexType, void **value)
* Wrapper Functions
*/
+/* plugin list locking */
+int
+slapi_td_plugin_lock_init()
+{
+ if(slapi_td_init(SLAPI_TD_PLUGIN_LIST_LOCK) == PR_FAILURE){
+ return PR_FAILURE;
+ }
+
+ return PR_SUCCESS;
+}
+
+int
+slapi_td_set_plugin_locked(int *value)
+{
+ if(slapi_td_set_val(SLAPI_TD_PLUGIN_LIST_LOCK, (void *)value) == PR_FAILURE){
+ return PR_FAILURE;
+ }
+
+ return PR_SUCCESS;
+}
+
+void
+slapi_td_get_plugin_locked(int **value)
+{
+ slapi_td_get_val(SLAPI_TD_PLUGIN_LIST_LOCK, (void **)value);
+}
+
+/* requestor dn */
int
slapi_td_dn_init()
{
@@ -156,7 +205,8 @@ slapi_td_set_dn(char *value)
}
void
-slapi_td_get_dn(char **value){
+slapi_td_get_dn(char **value)
+{
slapi_td_get_val(SLAPI_TD_REQUESTOR_DN, (void **)value);
}
diff --git a/ldap/servers/slapd/tools/pwenc.c b/ldap/servers/slapd/tools/pwenc.c
index 998b43a..6760be4 100644
--- a/ldap/servers/slapd/tools/pwenc.c
+++ b/ldap/servers/slapd/tools/pwenc.c
@@ -311,6 +311,7 @@ slapd_config(const char *configdir, const char *givenconfigfile)
int done = 0;
PRInt32 nr = 0;
PRFileDesc *prfd = 0;
+ char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";
char *buf = 0;
char *lastp = 0;
char *entrystr = 0;
@@ -381,11 +382,11 @@ slapd_config(const char *configdir, const char *givenconfigfile)
if ( entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "pwdstoragescheme"))
{
/* add the syntax/matching/pwd storage scheme rule plugin */
- if (plugin_setup(e, 0, 0, 1))
+ if (plugin_setup(e, 0, 0, 1, returntext))
{
fprintf(stderr,
- "The plugin entry [%s] in the configfile %s was invalid\n",
- slapi_entry_get_dn(e), configfile);
+ "The plugin entry [%s] in the configfile %s was invalid. %s\n",
+ slapi_entry_get_dn(e), configfile, returntext);
exit(1); /* yes this sucks, but who knows what else would go on if I did the right
thing */
}
else