diff options
author | Nathan Kinder <nkinder@redhat.com> | 2010-07-09 10:23:51 -0700 |
---|---|---|
committer | Nathan Kinder <nkinder@redhat.com> | 2010-07-09 14:02:00 -0700 |
commit | 2570fbb225dc0b6f0bd3794538cf33986a3a4395 (patch) | |
tree | 84edf3fbfa5e268de67bd2d2163e35adf82ba0cb | |
parent | 8632731df33fc3a91eb3cfecfb9c63d56cff23e8 (diff) | |
download | ds-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.c | 42 | ||||
-rw-r--r-- | ldap/servers/plugins/replication/windows_protocol_util.c | 7 | ||||
-rw-r--r-- | ldap/servers/plugins/replication/windowsrepl.h | 2 |
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); |