From fddf90faf5f0722653811957eb1e1870e487a1aa Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Tue, 21 May 2013 12:16:52 -0700 Subject: [PATCH 55/99] Ticket #47327 - error syncing group if group member user is not synced Bug description: Windows Sync synchronizes member attributes in a group entry if the member entry itself is synchronized. The entries in the sync scope are basically to be synchronized. But there is an exception such as a container in the scope is not synchronized due to the objecttype constraints. Such an unsync'ed entry could have users in it. Users are the target of Windows Sync. But since the parent container is not synch- ronized, the users in the container are not, neither. If a group contains such special user as a member, synchronization failed there and the other normal members are failed to get synchronized. Fix description: Windows Sync has a helper function is_subject_of_agreement_remote, which checks if the entry is in the scope to be synchronized. This patch adds the check if the checking entry's parent locally exists in the DS. If it does not exist, it considers the entry is out of scope. AD strictly checks if the entry exists prior to adding it to a group entry as a member. That is, a member to be added is supposed to be in the server, as well as its parent is. With this change, the AD user which is not synchronized to the DS is just skipped to add to the group in the DS in the same manner as an user out of scope is. https://fedorahosted.org/389/ticket/47327 Reviewed by Rich (Thanks!!) (cherry picked from commit 9b0834c07888aa1ee88b52141460a3b4e80d1962) (cherry picked from commit ec592bb9b320a74c1525671770b63294a8e7f64a) --- .../plugins/replication/windows_protocol_util.c | 35 +++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c index d831fa0..1bafa9a 100644 --- a/ldap/servers/plugins/replication/windows_protocol_util.c +++ b/ldap/servers/plugins/replication/windows_protocol_util.c @@ -3799,8 +3799,11 @@ map_entry_dn_inbound_ext(Slapi_Entry *e, Slapi_DN **dn, const Repl_Agmt *ra, int windows_private_get_windows_subtree(ra)); } } - new_dn = slapi_sdn_new_dn_byval(new_dn_string); - PR_smprintf_free(new_dn_string); + /* + * new_dn_string is created by slapi_create_dn_string, + * which is normalized. Thus, we can use _normdn_. + */ + new_dn = slapi_sdn_new_normdn_passin(new_dn_string); slapi_ch_free_string(&container_str); /* Clear any earlier error */ retval = 0; @@ -3895,6 +3898,7 @@ is_subject_of_agreement_remote(Slapi_Entry *e, const Repl_Agmt *ra) int retval = 0; int is_in_subtree = 0; const Slapi_DN *agreement_subtree = NULL; + const Slapi_DN *sdn; /* First test for the sync'ed subtree */ agreement_subtree = windows_private_get_windows_subtree(ra); @@ -3902,10 +3906,33 @@ is_subject_of_agreement_remote(Slapi_Entry *e, const Repl_Agmt *ra) { goto error; } - is_in_subtree = slapi_sdn_scope_test(slapi_entry_get_sdn_const(e), agreement_subtree, LDAP_SCOPE_SUBTREE); + sdn = slapi_entry_get_sdn_const(e); + is_in_subtree = slapi_sdn_scope_test(sdn, agreement_subtree, LDAP_SCOPE_SUBTREE); if (is_in_subtree) { - retval = 1; + Slapi_DN psdn = {0}; + Slapi_Entry *pentry = NULL; + /* + * Check whether the parent of the entry exists or not. + * If it does not, treat the entry e is out of scope. + * For instance, agreement_subtree is cn=USER, + * cn=container,cn=USER, is not synchronized. + * If 'e' is uid=test,cn=container,cn=USER,, + * the entry is not synchronized, either. We treat + * 'e' as out of scope. + */ + slapi_sdn_get_parent(sdn, &psdn); + if (0 == slapi_sdn_compare(&psdn, agreement_subtree)) { + retval = 1; + } else { + /* If parent entry is not local, the entry is out of scope */ + int rc = windows_get_local_entry(&psdn, &pentry); + if ((0 == rc) && pentry) { + retval = 1; + slapi_entry_free(pentry); + } + } + slapi_sdn_done(&psdn); } error: return retval; -- 1.8.1.4