andykimpe / rpms / 389-ds-base

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