Blame SOURCES/0030-Ticket-48010-winsync-range-retrieval-gets-only-5000-.patch

a2f18f
From bc26583d161168ce664d160592a30abbd98b9a1f Mon Sep 17 00:00:00 2001
a2f18f
From: Noriko Hosoi <nhosoi@redhat.com>
a2f18f
Date: Wed, 22 Jul 2015 09:41:46 -0700
a2f18f
Subject: [PATCH 30/30] Ticket #48010 - winsync range retrieval gets only 5000
a2f18f
 values upon initialization
a2f18f
a2f18f
Description: Search with DirSync control does not support range subtype.
a2f18f
On WS2012, it returns all the multi-valued attribute values regardless
a2f18f
of MaxValRange, but on WS2008, it cuts at the physical limit 5000.
a2f18f
This patch does not rely on the entry returned by the DirySync search.
a2f18f
a2f18f
Also, since DirSync search does not support the range subtype, removing
a2f18f
the range related code from the DirSync search.
a2f18f
a2f18f
Researched and tested by vashirov@redhat.com (Thank you, Viktor!!)
a2f18f
Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
a2f18f
a2f18f
https://fedorahosted.org/389/ticket/48010
a2f18f
(cherry picked from commit c6b211f8ea4970623f8ac1b365d040756d46bf3c)
a2f18f
(cherry picked from commit d9af22eb940353c0692b6d73cc0a2d6998311498)
a2f18f
---
a2f18f
 .../plugins/replication/windows_connection.c       | 21 ++-----
a2f18f
 ldap/servers/plugins/replication/windows_private.c | 70 ----------------------
a2f18f
 .../plugins/replication/windows_protocol_util.c    | 21 +++++--
a2f18f
 ldap/servers/plugins/replication/windowsrepl.h     |  5 --
a2f18f
 4 files changed, 21 insertions(+), 96 deletions(-)
a2f18f
a2f18f
diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c
a2f18f
index 5db43a5..a06a07e 100644
a2f18f
--- a/ldap/servers/plugins/replication/windows_connection.c
a2f18f
+++ b/ldap/servers/plugins/replication/windows_connection.c
a2f18f
@@ -821,7 +821,6 @@ send_dirsync_search(Repl_Connection *conn)
a2f18f
 		const char *old_dn = slapi_sdn_get_ndn( windows_private_get_windows_subtree(conn->agmt) );
a2f18f
 		/* LDAP_SERVER_DIRSYNC_OID requires the search base Naming Context */
a2f18f
 		char *dn = slapi_ch_strdup(strstr(old_dn, "dc="));
a2f18f
-		char **exattrs = NULL;
a2f18f
 
a2f18f
 		if (conn->supports_dirsync == 0)
a2f18f
 		{
a2f18f
@@ -847,10 +846,6 @@ send_dirsync_search(Repl_Connection *conn)
a2f18f
 
a2f18f
 		winsync_plugin_call_dirsync_search_params_cb(conn->agmt, old_dn, &dn, &scope, &filter,
a2f18f
 		                                             &attrs, &server_controls);
a2f18f
-		exattrs = windows_private_get_range_attrs(conn->agmt);
a2f18f
-		charray_merge(&attrs, exattrs, 0 /* pass in */);
a2f18f
-		slapi_ch_free((void **)&exattrs); /* strings are passed in */
a2f18f
-
a2f18f
 		LDAPDebug( LDAP_DEBUG_REPL, "Sending dirsync search request\n", 0, 0, 0 );
a2f18f
 
a2f18f
 		rc = ldap_search_ext( conn->ld, dn, scope, filter, attrs, PR_FALSE, server_controls,
a2f18f
@@ -1010,20 +1005,14 @@ Slapi_Entry * windows_conn_get_search_result(Repl_Connection *conn)
a2f18f
 			{
a2f18f
 				if (( dn = ldap_get_dn( conn->ld, res )) != NULL ) 
a2f18f
 				{
a2f18f
-					char **exattrs = NULL;
a2f18f
 					slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,"received entry from dirsync: %s\n", dn);
a2f18f
 					lm = ldap_first_entry( conn->ld, res );
a2f18f
-					e = windows_private_get_curr_entry(conn->agmt); /* if range search, e != NULL */
a2f18f
-					e = windows_LDAPMessage2Entry(e, conn, lm, 0, &exattrs);
a2f18f
+					/* 
a2f18f
+					 * we don't have to retrieve all the members here.
a2f18f
+					 * here, we have to make sure to get the entry once.
a2f18f
+					 */
a2f18f
+					e = windows_LDAPMessage2Entry(e, conn, lm, 0, NULL);
a2f18f
 					ldap_memfree(dn);
a2f18f
-					if (exattrs) {
a2f18f
-						/* some attribute returned "<attr>;range=low-high" */
a2f18f
-						windows_private_set_curr_entry(conn->agmt, e);
a2f18f
-						windows_private_set_range_attrs(conn->agmt, exattrs);
a2f18f
-					} else {
a2f18f
-						windows_private_set_curr_entry(conn->agmt, NULL);
a2f18f
-						windows_private_set_range_attrs(conn->agmt, NULL);
a2f18f
-					}
a2f18f
 				}
a2f18f
 			}
a2f18f
 			break;
a2f18f
diff --git a/ldap/servers/plugins/replication/windows_private.c b/ldap/servers/plugins/replication/windows_private.c
a2f18f
index f5cb44e..c118236 100644
a2f18f
--- a/ldap/servers/plugins/replication/windows_private.c
a2f18f
+++ b/ldap/servers/plugins/replication/windows_private.c
a2f18f
@@ -1570,76 +1570,6 @@ windows_private_set_move_action(const Repl_Agmt *ra, int value)
a2f18f
 	LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_move_action\n" );
a2f18f
 }
a2f18f
 
a2f18f
-/* Get entry being retrieved; used for the range retrieval */
a2f18f
-Slapi_Entry *
a2f18f
-windows_private_get_curr_entry(const Repl_Agmt *ra)
a2f18f
-{
a2f18f
-	Dirsync_Private *dp;
a2f18f
-
a2f18f
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_curr_entry\n" );
a2f18f
-
a2f18f
-	PR_ASSERT(ra);
a2f18f
-
a2f18f
-	dp = (Dirsync_Private *) agmt_get_priv(ra);
a2f18f
-	PR_ASSERT (dp);
a2f18f
-
a2f18f
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_curr_entry\n" );
a2f18f
-
a2f18f
-	return dp->curr_entry;	
a2f18f
-}
a2f18f
-
a2f18f
-/* Set entry being retrieved; used for the range retrieval */
a2f18f
-void
a2f18f
-windows_private_set_curr_entry(const Repl_Agmt *ra, Slapi_Entry *e)
a2f18f
-{
a2f18f
-	Dirsync_Private *dp;
a2f18f
-
a2f18f
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_curr_entry\n" );
a2f18f
-
a2f18f
-	PR_ASSERT(ra);
a2f18f
-
a2f18f
-	dp = (Dirsync_Private *) agmt_get_priv(ra);
a2f18f
-	PR_ASSERT (dp);
a2f18f
-	dp->curr_entry = e;
a2f18f
-
a2f18f
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_curr_entry\n" );
a2f18f
-}
a2f18f
-
a2f18f
-/* Get next range retrieval attributes */
a2f18f
-char **
a2f18f
-windows_private_get_range_attrs(const Repl_Agmt *ra)
a2f18f
-{
a2f18f
-	Dirsync_Private *dp;
a2f18f
-
a2f18f
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_range_attrs\n" );
a2f18f
-
a2f18f
-	PR_ASSERT(ra);
a2f18f
-
a2f18f
-	dp = (Dirsync_Private *) agmt_get_priv(ra);
a2f18f
-	PR_ASSERT (dp);
a2f18f
-
a2f18f
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_range_attrs\n" );
a2f18f
-
a2f18f
-	return dp->range_attrs;	
a2f18f
-}
a2f18f
-
a2f18f
-/* Set next range retrieval attributes */
a2f18f
-void
a2f18f
-windows_private_set_range_attrs(const Repl_Agmt *ra, char **attrs)
a2f18f
-{
a2f18f
-	Dirsync_Private *dp;
a2f18f
-
a2f18f
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_move_action\n" );
a2f18f
-
a2f18f
-	PR_ASSERT(ra);
a2f18f
-
a2f18f
-	dp = (Dirsync_Private *) agmt_get_priv(ra);
a2f18f
-	PR_ASSERT (dp);
a2f18f
-	dp->range_attrs = attrs;
a2f18f
-
a2f18f
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_move_action\n" );
a2f18f
-}
a2f18f
-
a2f18f
 static PRCallOnceType winsync_callOnce = {0,0};
a2f18f
 
a2f18f
 struct winsync_plugin {
a2f18f
diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c
a2f18f
index 6bf20b7..4cfa20d 100644
a2f18f
--- a/ldap/servers/plugins/replication/windows_protocol_util.c
a2f18f
+++ b/ldap/servers/plugins/replication/windows_protocol_util.c
a2f18f
@@ -5847,6 +5847,9 @@ windows_process_dirsync_entry(Private_Repl_Protocol *prp,Slapi_Entry *e, int is_
a2f18f
 		/* Is this entry one we should be interested in ? */
a2f18f
 		if (is_subject_of_agreement_remote(e,prp->agmt)) 
a2f18f
 		{
a2f18f
+			ConnResult cres = 0;
a2f18f
+			const char *searchbase = slapi_entry_get_dn_const(e);
a2f18f
+			char *filter = "(objectclass=*)";
a2f18f
 retry:
a2f18f
 			/* First make its local DN */
a2f18f
 			rc = map_entry_dn_inbound(e, &local_sdn, prp->agmt);
a2f18f
@@ -5902,7 +5905,19 @@ retry:
a2f18f
 					/* If it doesn't exist, try to make it */
a2f18f
 					if (add_local_entry_allowed(prp,e))
a2f18f
 					{
a2f18f
-						windows_create_local_entry(prp,e,local_sdn);
a2f18f
+						found_entry = NULL;
a2f18f
+						/* 
a2f18f
+						 * BZ 1172037: Search with DirSync Control does not return the range subtype.
a2f18f
+						 * Re-search the entry to get all the attribute values over hard limit MaxValRange
a2f18f
+						 * on 2008R2.  Note: 2012R2 does not have the hard limit.
a2f18f
+						 * If we stop supporting 2008R2, this windows_search_entry_ext call can be removed.
a2f18f
+						 */
a2f18f
+						cres = windows_search_entry_ext(prp->conn, (char*)searchbase, 
a2f18f
+						                                filter, &found_entry, NULL, LDAP_SCOPE_BASE);
a2f18f
+						if (found_entry) {
a2f18f
+							e = found_entry;
a2f18f
+						}
a2f18f
+						windows_create_local_entry(prp, e, local_sdn);
a2f18f
 					} else
a2f18f
 					{
a2f18f
 						slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,"%s: windows_process_dirsync_entry: not allowed to add entry %s.\n",agmt_get_long_name(prp->agmt)
a2f18f
@@ -5918,10 +5933,6 @@ retry:
a2f18f
 			 	 * We search Windows with the dn and retry using the found 
a2f18f
 				 * entry.
a2f18f
 			 	 */
a2f18f
-				ConnResult cres = 0;
a2f18f
-				const char *searchbase = slapi_entry_get_dn_const(e);
a2f18f
-				char *filter = "(objectclass=*)";
a2f18f
-
a2f18f
 				retried = 1;
a2f18f
 				cres = windows_search_entry_ext(prp->conn, (char*)searchbase, 
a2f18f
 												filter, &found_entry, NULL, LDAP_SCOPE_BASE);
a2f18f
diff --git a/ldap/servers/plugins/replication/windowsrepl.h b/ldap/servers/plugins/replication/windowsrepl.h
a2f18f
index fd80212..66f4804 100644
a2f18f
--- a/ldap/servers/plugins/replication/windowsrepl.h
a2f18f
+++ b/ldap/servers/plugins/replication/windowsrepl.h
a2f18f
@@ -66,11 +66,6 @@ void windows_private_set_one_way(const Repl_Agmt *ra, PRBool value);
a2f18f
 int windows_private_get_move_action(const Repl_Agmt *ra);
a2f18f
 void windows_private_set_move_action(const Repl_Agmt *ra, int value);
a2f18f
 
a2f18f
-Slapi_Entry *windows_private_get_curr_entry(const Repl_Agmt *ra);
a2f18f
-void windows_private_set_curr_entry(const Repl_Agmt *ra, Slapi_Entry *e);
a2f18f
-char **windows_private_get_range_attrs(const Repl_Agmt *ra);
a2f18f
-void windows_private_set_range_attrs(const Repl_Agmt *ra, char **attrs);
a2f18f
-
a2f18f
 void windows_private_set_directory_userfilter(const Repl_Agmt *ra, char *filter);
a2f18f
 void windows_private_set_windows_userfilter(const Repl_Agmt *ra, char *filter);
a2f18f
 const char* windows_private_get_directory_userfilter(const Repl_Agmt *ra);
a2f18f
-- 
a2f18f
1.9.3
a2f18f