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 14:02:00 -0700
commit2570fbb225dc0b6f0bd3794538cf33986a3a4395 (patch)
tree84edf3fbfa5e268de67bd2d2163e35adf82ba0cb
parent8632731df33fc3a91eb3cfecfb9c63d56cff23e8 (diff)
downloadds-2570fbb225dc0b6f0bd3794538cf33986a3a4395.tar.gz
ds-2570fbb225dc0b6f0bd3794538cf33986a3a4395.tar.xz
ds-2570fbb225dc0b6f0bd3794538cf33986a3a4395.zip
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 8ba8b5c3..e6f1e818 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 65de19dd..f69cb7a8 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);