summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2010-07-09 10:23:51 -0700
committerNathan Kinder <nkinder@redhat.com>2010-07-09 10:23:51 -0700
commitf1d509ec6f97fced6ad06b0fbe458444cd444825 (patch)
tree984765b981c37de3aa75d5470a411a2c02ae998f
parente9a26dca776e3d812ae634fb6d3f2836499d7356 (diff)
Bug 612242 - membership change on DS does not show on AD
When a change was made to a DN mapped attribute in DS (such as uniqueMember in a group entry), we may end up searching for the entries that those values point to in AD when winsync is being used. We were overwriting the "raw entry" pointer every time we searched for an entry in AD. The raw entry is intended to point to the entry that the original modification was made to, not the entry that a DN mapped attribute value points to. The fix is to add a flag that will force the raw entry to be kept when we search for an entry in AD. We set this flag when we search for entries that are pointed to be DN mapped attribute values and reset it when we are finished. This results in the raw entry being the actual entry that is the target of the operation we are syncing.
-rw-r--r--ldap/servers/plugins/replication/windows_private.c42
-rw-r--r--ldap/servers/plugins/replication/windows_protocol_util.c7
-rw-r--r--ldap/servers/plugins/replication/windowsrepl.h2
3 files changed, 49 insertions, 2 deletions
diff --git a/ldap/servers/plugins/replication/windows_private.c b/ldap/servers/plugins/replication/windows_private.c
index d6f8e51e..d855b85b 100644
--- a/ldap/servers/plugins/replication/windows_private.c
+++ b/ldap/servers/plugins/replication/windows_private.c
@@ -72,6 +72,7 @@ struct windowsprivate {
Slapi_Filter *directory_filter; /* Used for checking if local entries need to be sync'd to AD */
Slapi_Filter *deleted_filter; /* Used for checking if an entry is an AD tombstone */
Slapi_Entry *raw_entry; /* "raw" un-schema processed last entry read from AD */
+ int keep_raw_entry; /* flag to control when the raw entry is set */
void *api_cookie; /* private data used by api callbacks */
time_t sync_interval; /* how often to run the dirsync search, in seconds */
};
@@ -845,12 +846,49 @@ void windows_private_set_raw_entry(const Repl_Agmt *ra, Slapi_Entry *e)
dp = (Dirsync_Private *) agmt_get_priv(ra);
PR_ASSERT (dp);
- slapi_entry_free(dp->raw_entry);
- dp->raw_entry = e;
+ /* If the keep raw entry flag is set, just free the passed
+ * in entry and leave the current raw entry in place. */
+ if (windows_private_get_keep_raw_entry(ra)) {
+ slapi_entry_free(e);
+ } else {
+ slapi_entry_free(dp->raw_entry);
+ dp->raw_entry = e;
+ }
LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_raw_entry\n" );
}
+/* Setting keep to 1 will cause the current raw entry to remain, even if
+ * windows_private_set_raw_entry() is called. This behavior will persist
+ * until this flag is set back to 0. */
+void windows_private_set_keep_raw_entry(const Repl_Agmt *ra, int keep)
+{
+ Dirsync_Private *dp;
+
+ LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_keep_raw_entry\n" );
+
+ dp = (Dirsync_Private *) agmt_get_priv(ra);
+ PR_ASSERT (dp);
+
+ dp->keep_raw_entry = keep;
+
+ LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_keep_raw_entry\n" );
+}
+
+int windows_private_get_keep_raw_entry(const Repl_Agmt *ra)
+{
+ Dirsync_Private *dp;
+
+ LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_keep_raw_entry\n" );
+
+ dp = (Dirsync_Private *) agmt_get_priv(ra);
+ PR_ASSERT (dp);
+
+ LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_keep_raw_entry\n" );
+
+ return dp->keep_raw_entry;
+}
+
void *windows_private_get_api_cookie(const Repl_Agmt *ra)
{
Dirsync_Private *dp;
diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c
index 3c6b4d4c..a3d00772 100644
--- a/ldap/servers/plugins/replication/windows_protocol_util.c
+++ b/ldap/servers/plugins/replication/windows_protocol_util.c
@@ -406,6 +406,10 @@ map_dn_values(Private_Repl_Protocol *prp,Slapi_ValueSet *original_values, Slapi_
Slapi_Value *original_value = NULL;
int retval = 0;
int i = 0;
+
+ /* Set the keep raw entry flag to avoid overwriting the existing raw entry. */
+ windows_private_set_keep_raw_entry(prp->agmt, 1);
+
/* For each value: */
i= slapi_valueset_first_value(original_values,&original_value);
while ( i != -1 ) {
@@ -531,6 +535,9 @@ map_dn_values(Private_Repl_Protocol *prp,Slapi_ValueSet *original_values, Slapi_
{
*mapped_values = new_vs;
}
+
+ /* Restore the keep raw entry flag. */
+ windows_private_set_keep_raw_entry(prp->agmt, 0);
}
static void
diff --git a/ldap/servers/plugins/replication/windowsrepl.h b/ldap/servers/plugins/replication/windowsrepl.h
index 3d216e05..f4137461 100644
--- a/ldap/servers/plugins/replication/windowsrepl.h
+++ b/ldap/servers/plugins/replication/windowsrepl.h
@@ -78,6 +78,8 @@ const char* windows_private_get_purl(const Repl_Agmt *ra);
Slapi_Entry *windows_private_get_raw_entry(const Repl_Agmt *ra);
/* this is passin - windows_private owns the pointer, not a copy */
void windows_private_set_raw_entry(const Repl_Agmt *ra, Slapi_Entry *e);
+void windows_private_set_keep_raw_entry(const Repl_Agmt *ra, int keep);
+int windows_private_get_keep_raw_entry(const Repl_Agmt *ra);
void *windows_private_get_api_cookie(const Repl_Agmt *ra);
void windows_private_set_api_cookie(Repl_Agmt *ra, void *cookie);
time_t windows_private_get_sync_interval(const Repl_Agmt *ra);