summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Megginson <rmeggins@redhat.com>2008-08-27 21:47:00 +0000
committerRich Megginson <rmeggins@redhat.com>2008-08-27 21:47:00 +0000
commit446134bf3bd4d85433738bb257dba18269c32980 (patch)
tree5f97325ab901d1c2af3e699b654e945597b326d3
parent27f282f02a60818e750902ecfd748ef3521f9539 (diff)
downloadds-446134bf3bd4d85433738bb257dba18269c32980.tar.gz
ds-446134bf3bd4d85433738bb257dba18269c32980.tar.xz
ds-446134bf3bd4d85433738bb257dba18269c32980.zip
Resolves: bug 457846
Bug Description: The Windows Sync API should have plug-in points Reviewed by: nkinder (Thanks!) Fix Description: Some additional changes to the api 1) added plugin points for begin update, end update, and agreement destruction 2) added debugging code to allow a regular DS to stand in for AD 3) fixed a couple of minor memory leaks 4) added the rest of the SLAPI DSE code to the public API to allow plugins to do dynamic configuration using the SLAPI public API Platforms tested: RHEL5 Flag Day: no Doc impact: yes - plugin guide
-rw-r--r--ldap/servers/plugins/replication/windows_connection.c12
-rw-r--r--ldap/servers/plugins/replication/windows_inc_protocol.c12
-rw-r--r--ldap/servers/plugins/replication/windows_private.c78
-rw-r--r--ldap/servers/plugins/replication/windows_protocol_util.c1
-rw-r--r--ldap/servers/plugins/replication/windows_tot_protocol.c12
-rw-r--r--ldap/servers/plugins/replication/windowsrepl.h7
-rw-r--r--ldap/servers/plugins/replication/winsync-plugin.h80
-rw-r--r--ldap/servers/slapd/slapi-plugin.h14
-rw-r--r--ldap/servers/slapd/slapi-private.h13
9 files changed, 199 insertions, 30 deletions
diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c
index 32787c4c..a2c720f0 100644
--- a/ldap/servers/plugins/replication/windows_connection.c
+++ b/ldap/servers/plugins/replication/windows_connection.c
@@ -1465,12 +1465,12 @@ windows_conn_replica_supports_dirsync(Repl_Connection *conn)
LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_conn_replica_supports_dirsync\n", 0, 0, 0 );
-#ifdef WINSYNC_TEST
- /* used to fake out dirsync to think it's talking to a real ad when in fact
- it's just talking to another directory server */
- conn->supports_dirsync = 1;
- return CONN_SUPPORTS_DIRSYNC;
-#endif
+ if (getenv("WINSYNC_USE_DS")) {
+ /* used to fake out dirsync to think it's talking to a real ad when in fact
+ it's just talking to another directory server */
+ conn->supports_dirsync = 1;
+ return CONN_SUPPORTS_DIRSYNC;
+ }
if (windows_conn_connected(conn))
{
diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c
index c02e6610..e7df5a38 100644
--- a/ldap/servers/plugins/replication/windows_inc_protocol.c
+++ b/ldap/servers/plugins/replication/windows_inc_protocol.c
@@ -812,6 +812,12 @@ windows_inc_run(Private_Repl_Protocol *prp)
}
else
{
+ /* call begin incremental update callback */
+ winsync_plugin_call_begin_update_cb(prp->agmt,
+ windows_private_get_directory_subtree(prp->agmt),
+ windows_private_get_windows_subtree(prp->agmt),
+ 0 /* is_total == FALSE */);
+
rc = send_updates(prp, ruv, &num_changes_sent);
if (rc == UPDATE_NO_MORE_UPDATES)
{
@@ -874,6 +880,12 @@ windows_inc_run(Private_Repl_Protocol *prp)
if (rc == UPDATE_TIMEOUT) {
windows_conn_disconnect(prp->conn);
}
+ /* call end incremental update callback */
+ winsync_plugin_call_end_update_cb(prp->agmt,
+ windows_private_get_directory_subtree(prp->agmt),
+ windows_private_get_windows_subtree(prp->agmt),
+ 0 /* is_total == FALSE */);
+
if (rc == UPDATE_NO_MORE_UPDATES && num_changes_sent > 0)
{
if (pausetime > 0)
diff --git a/ldap/servers/plugins/replication/windows_private.c b/ldap/servers/plugins/replication/windows_private.c
index 19158668..a42d7646 100644
--- a/ldap/servers/plugins/replication/windows_private.c
+++ b/ldap/servers/plugins/replication/windows_private.c
@@ -47,8 +47,8 @@
#include "repl5.h"
#include "slap.h"
#include "slapi-plugin.h"
-#include "windowsrepl.h"
#include "winsync-plugin.h"
+#include "windowsrepl.h"
struct windowsprivate {
@@ -217,6 +217,11 @@ void windows_agreement_delete(Repl_Agmt *ra)
PR_ASSERT(dp != NULL);
+ winsync_plugin_call_destroy_agmt_cb(ra, dp->directory_subtree,
+ dp->windows_subtree);
+
+ slapi_sdn_free(&dp->directory_subtree);
+ slapi_sdn_free(&dp->windows_subtree);
slapi_filter_free(dp->directory_filter, 1);
slapi_filter_free(dp->deleted_filter, 1);
slapi_entry_free(dp->raw_entry);
@@ -538,9 +543,10 @@ LDAPControl* windows_private_dirsync_control(const Repl_Agmt *ra)
ber_printf( ber, "{iio}", dp->dirsync_flags, dp->dirsync_maxattributecount, dp->dirsync_cookie, dp->dirsync_cookie_len );
-#ifdef WINSYNC_TEST
- iscritical = PR_FALSE;
-#endif
+ /* Use a regular directory server instead of a real AD - for testing */
+ if (getenv("WINSYNC_USE_DS")) {
+ iscritical = PR_FALSE;
+ }
slapi_build_control( REPL_DIRSYNC_CONTROL_OID, ber, iscritical, &control);
ber_free(ber,1);
@@ -563,7 +569,7 @@ void windows_private_update_dirsync_control(const Repl_Agmt *ra,LDAPControl **co
Dirsync_Private *dp;
int foundDirsyncControl;
int i;
- LDAPControl *dirsync;
+ LDAPControl *dirsync = NULL;
BerElement *ber;
ber_int_t hasMoreData;
ber_int_t maxAttributeCount;
@@ -620,6 +626,7 @@ void windows_private_update_dirsync_control(const Repl_Agmt *ra,LDAPControl **co
choke:
ber_bvfree(serverCookie);
ber_free(ber,1);
+ ldap_control_free(dirsync);
}
else
{
@@ -1187,3 +1194,64 @@ winsync_plugin_call_can_add_entry_to_ad_cb(const Repl_Agmt *ra, const Slapi_Entr
return (*thefunc)(windows_private_get_api_cookie(ra), local_entry, remote_dn);
}
+
+void
+winsync_plugin_call_begin_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
+ const Slapi_DN *ad_subtree, int is_total)
+{
+ winsync_plugin_update_cb thefunc =
+ (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_BEGIN_UPDATE_CB]) ?
+ (winsync_plugin_update_cb)_WinSyncAPI[WINSYNC_PLUGIN_BEGIN_UPDATE_CB] :
+ NULL;
+
+ if (!thefunc) {
+ return;
+ }
+
+ (*thefunc)(windows_private_get_api_cookie(ra), ds_subtree, ad_subtree, is_total);
+
+ return;
+}
+
+void
+winsync_plugin_call_end_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
+ const Slapi_DN *ad_subtree, int is_total)
+{
+ winsync_plugin_update_cb thefunc =
+ (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_END_UPDATE_CB]) ?
+ (winsync_plugin_update_cb)_WinSyncAPI[WINSYNC_PLUGIN_END_UPDATE_CB] :
+ NULL;
+
+ if (!thefunc) {
+ return;
+ }
+
+ (*thefunc)(windows_private_get_api_cookie(ra), ds_subtree, ad_subtree, is_total);
+
+ return;
+}
+
+void
+winsync_plugin_call_destroy_agmt_cb(const Repl_Agmt *ra,
+ const Slapi_DN *ds_subtree,
+ const Slapi_DN *ad_subtree)
+{
+ winsync_plugin_destroy_agmt_cb thefunc =
+ (_WinSyncAPI && _WinSyncAPI[WINSYNC_PLUGIN_DESTROY_AGMT_CB]) ?
+ (winsync_plugin_destroy_agmt_cb)_WinSyncAPI[WINSYNC_PLUGIN_DESTROY_AGMT_CB] :
+ NULL;
+
+ if (thefunc) {
+ (*thefunc)(windows_private_get_api_cookie(ra), ds_subtree, ad_subtree);
+ }
+
+ return;
+}
+
+/* #define WINSYNC_TEST_IPA */
+#ifdef WINSYNC_TEST_IPA
+
+#include "ipa-winsync.c"
+#include "ipa-winsync-config.c"
+
+#endif
diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c
index b893aac2..7a915684 100644
--- a/ldap/servers/plugins/replication/windows_protocol_util.c
+++ b/ldap/servers/plugins/replication/windows_protocol_util.c
@@ -2605,6 +2605,7 @@ map_entry_dn_outbound(Slapi_Entry *e, Slapi_DN **dn, Private_Repl_Protocol *prp,
{
*dn = new_dn;
}
+ slapi_ch_free_string(&guid);
return retval;
}
diff --git a/ldap/servers/plugins/replication/windows_tot_protocol.c b/ldap/servers/plugins/replication/windows_tot_protocol.c
index 09ecbc8e..c1bca1ce 100644
--- a/ldap/servers/plugins/replication/windows_tot_protocol.c
+++ b/ldap/servers/plugins/replication/windows_tot_protocol.c
@@ -153,6 +153,12 @@ windows_tot_run(Private_Repl_Protocol *prp)
windows_private_null_dirsync_cookie(prp->agmt);
+ /* call begin total update callback */
+ winsync_plugin_call_begin_update_cb(prp->agmt,
+ windows_private_get_directory_subtree(prp->agmt),
+ windows_private_get_windows_subtree(prp->agmt),
+ 1 /* is_total == TRUE */);
+
/* get everything */
windows_dirsync_inc_run(prp);
@@ -225,6 +231,12 @@ windows_tot_run(Private_Repl_Protocol *prp)
agmt_set_consumer_ruv(prp->agmt, starting_ruv );
}
+ /* call end total update callback */
+ winsync_plugin_call_end_update_cb(prp->agmt,
+ windows_private_get_directory_subtree(prp->agmt),
+ windows_private_get_windows_subtree(prp->agmt),
+ 1 /* is_total == TRUE */);
+
done:
if (starting_ruv)
{
diff --git a/ldap/servers/plugins/replication/windowsrepl.h b/ldap/servers/plugins/replication/windowsrepl.h
index 47138656..681eba5d 100644
--- a/ldap/servers/plugins/replication/windowsrepl.h
+++ b/ldap/servers/plugins/replication/windowsrepl.h
@@ -153,6 +153,13 @@ void winsync_plugin_call_pre_ad_mod_user_mods_cb(const Repl_Agmt *ra, const Slap
void winsync_plugin_call_pre_ad_mod_group_mods_cb(const Repl_Agmt *ra, const Slapi_Entry *rawentry, const Slapi_DN *local_dn, LDAPMod * const *origmods, Slapi_DN *remote_dn, LDAPMod ***modstosend);
int winsync_plugin_call_can_add_entry_to_ad_cb(const Repl_Agmt *ra, const Slapi_Entry *local_entry, const Slapi_DN *remote_dn);
+void winsync_plugin_call_begin_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
+ const Slapi_DN *ad_subtree, int is_total);
+void winsync_plugin_call_end_update_cb(const Repl_Agmt *ra, const Slapi_DN *ds_subtree,
+ const Slapi_DN *ad_subtree, int is_total);
+void winsync_plugin_call_destroy_agmt_cb(const Repl_Agmt *ra,
+ const Slapi_DN *ds_subtree,
+ const Slapi_DN *ad_subtree);
/*
Call stack for all places where windows_LDAPMessage2Entry is called:
diff --git a/ldap/servers/plugins/replication/winsync-plugin.h b/ldap/servers/plugins/replication/winsync-plugin.h
index 882e4144..71d27819 100644
--- a/ldap/servers/plugins/replication/winsync-plugin.h
+++ b/ldap/servers/plugins/replication/winsync-plugin.h
@@ -51,11 +51,12 @@
#define WINSYNC_v1_0_GUID "CDA8F029-A3C6-4EBB-80B8-A2E183DB0481"
/*
- * The plugin will define this callback in order to initialize itself.
- * The ds subtree and the ad subtree from the sync agreement are passed in.
- * These are read only.
- * The return value is private data to the plugin that will be passed back
- * at each callback
+ * This callback is called when a winsync agreement is created.
+ * The ds_subtree and ad_subtree from the agreement are read-only.
+ * The callback can allocate some private data to return. If so
+ * the callback must define a winsync_plugin_destroy_agmt_cb so
+ * that the private data can be freed. This private data is passed
+ * to every other callback function as the void *cookie argument.
*/
typedef void * (*winsync_plugin_init_cb)(const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree);
#define WINSYNC_PLUGIN_INIT_CB 1
@@ -161,6 +162,29 @@ typedef int (*winsync_can_add_to_ad_cb)(void *cookie, const Slapi_Entry *local_e
#define WINSYNC_PLUGIN_CAN_ADD_ENTRY_TO_AD_CB 16
/*
+ * Callbacks called at begin and end of update
+ *
+ * The ds subtree and the ad subtree from the sync agreement are passed in.
+ * These are read only.
+ * is_total will be true if this is a total update, or false if this
+ * is an incremental update
+ */
+typedef void (*winsync_plugin_update_cb)(void *cookie, const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree, int is_total);
+#define WINSYNC_PLUGIN_BEGIN_UPDATE_CB 17
+#define WINSYNC_PLUGIN_END_UPDATE_CB 18
+
+/*
+ * Callbacks called when the agreement is destroyed.
+ *
+ * The ds subtree and the ad subtree from the sync agreement are passed in.
+ * These are read only.
+ * The plugin must define this function to free the cookie allocated
+ * in the init function, if any.
+ */
+typedef void (*winsync_plugin_destroy_agmt_cb)(void *cookie, const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree);
+#define WINSYNC_PLUGIN_DESTROY_AGMT_CB 19
+
+/*
The following are sample code stubs to show how to implement
a plugin which uses this api
*/
@@ -418,6 +442,47 @@ test_winsync_can_add_entry_to_ad_cb(void *cbdata, const Slapi_Entry *local_entry
return 0; /* false - do not allow entries to be added to ad */
}
+static void
+test_winsync_begin_update_cb(void *cbdata, const Slapi_DN *ds_subtree,
+ const Slapi_DN *ad_subtree, int is_total)
+{
+ slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
+ "--> test_winsync_begin_update_cb -- begin\n");
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
+ "<-- test_winsync_begin_update_cb -- end\n");
+
+ return;
+}
+
+static void
+test_winsync_end_update_cb(void *cbdata, const Slapi_DN *ds_subtree,
+ const Slapi_DN *ad_subtree, int is_total)
+{
+ slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
+ "--> test_winsync_end_update_cb -- begin\n");
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
+ "<-- test_winsync_end_update_cb -- end\n");
+
+ return;
+}
+
+static void
+test_winsync_destroy_agmt_cb(void *cbdata, const Slapi_DN *ds_subtree,
+ const Slapi_DN *ad_subtree)
+{
+ slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
+ "--> test_winsync_destroy_agmt_cb -- begin\n");
+
+ /* free(cbdata); */
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, test_winsync_plugin_name,
+ "<-- test_winsync_destroy_agmt_cb -- end\n");
+
+ return;
+}
+
/**
* Plugin identifiers
*/
@@ -447,7 +512,10 @@ static void *test_winsync_api[] = {
test_winsync_get_new_ds_group_dn_cb,
test_winsync_pre_ad_mod_user_mods_cb,
test_winsync_pre_ad_mod_group_mods_cb,
- test_winsync_can_add_entry_to_ad_cb
+ test_winsync_can_add_entry_to_ad_cb,
+ test_winsync_begin_update_cb,
+ test_winsync_end_update_cb,
+ test_winsync_destroy_agmt_cb
};
static int
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 8b38b19e..396150a5 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -1256,6 +1256,20 @@ typedef int (*dseCallbackFn)(Slapi_PBlock *, Slapi_Entry *, Slapi_Entry *,
#define SLAPI_DSE_CALLBACK_ERROR (-1)
#define SLAPI_DSE_CALLBACK_DO_NOT_APPLY (0)
+/*
+ * Flags for slapi_config_register_callback() and
+ * slapi_config_remove_callback()
+ */
+#define DSE_FLAG_PREOP 0x0001
+#define DSE_FLAG_POSTOP 0x0002
+
+/* 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_remove_callback(int operation, int flags, const char *base, int scope, const char *filter, dseCallbackFn fn);
+
/******************************************************************************
* Online tasks interface (to support import, export, etc)
* After some cleanup, we could consider making these public.
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 49a8fbb9..3a06f4aa 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -1069,19 +1069,6 @@ int slapi_uniqueIDGenerateFromNameString(char **uId,
* JCMREPL - Added for the replication plugin.
*/
-/*
- * Flags for slapi_config_register_callback() and
- * slapi_config_remove_callback()
- */
-#define DSE_FLAG_PREOP 0x0001
-#define DSE_FLAG_POSTOP 0x0002
-
-/* 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_remove_callback(int operation, int flags, const char *base, int scope, const char *filter, dseCallbackFn fn);
int config_is_slapd_lite( void );
void schema_expand_objectclasses_nolock( Slapi_Entry *e );