summaryrefslogtreecommitdiffstats
path: root/ldap
diff options
context:
space:
mode:
Diffstat (limited to 'ldap')
-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 );