816ad1
From 73dd295434a03be28531cea40fde041ce7bd2d7e Mon Sep 17 00:00:00 2001
816ad1
From: Mark Reynolds <mreynolds@redhat.com>
816ad1
Date: Tue, 13 Feb 2018 10:35:35 -0500
816ad1
Subject: [PATCH] Ticket 49545 - final substring extended filter search returns
816ad1
  invalid result
816ad1
816ad1
Bug Description:
816ad1
	During a search (using extended filter with final substring), the server
816ad1
	checks the filter before returning the matching entries.
816ad1
	When checking the attribute value against the filter, it
816ad1
	uses the wrong value.
816ad1
816ad1
Fix Description:
816ad1
	Make suree it uses the right portion of the attribute value, in order
816ad1
	to generate the keys to compare.
816ad1
816ad1
https://pagure.io/389-ds-base/issue/49545
816ad1
816ad1
Reviewed by: Ludwig Krispenz
816ad1
---
816ad1
 ldap/servers/plugins/collation/orfilter.c | 20 ++++++++++++++++++--
816ad1
 1 file changed, 18 insertions(+), 2 deletions(-)
816ad1
816ad1
diff --git a/ldap/servers/plugins/collation/orfilter.c b/ldap/servers/plugins/collation/orfilter.c
816ad1
index 866936afe..8f10f81b6 100644
816ad1
--- a/ldap/servers/plugins/collation/orfilter.c
816ad1
+++ b/ldap/servers/plugins/collation/orfilter.c
816ad1
@@ -180,17 +180,33 @@ ss_filter_match (or_filter_t* or, struct berval** vals)
816ad1
 	    } else {		/* final */
816ad1
 		auto size_t attempts = MAX_CHAR_COMBINING;
816ad1
 		auto char* limit = v.bv_val;
816ad1
+                auto char *end;
816ad1
 		auto struct berval** vkeys;
816ad1
 		auto struct berval* vals[2];
816ad1
 		auto struct berval key;
816ad1
+
816ad1
 		rc = -1;
816ad1
 		vals[0] = &v;
816ad1
 		vals[1] = NULL;
816ad1
 		key.bv_val = (*k)->bv_val;
816ad1
 		key.bv_len = (*k)->bv_len - 1;
816ad1
-		v.bv_val = (*vals)->bv_val + (*vals)->bv_len;
816ad1
+                /* In the following lines it will loop to find
816ad1
+                 * if the end of the attribute value matches the 'final' of the filter
816ad1
+                 * Short summary:
816ad1
+                 * vals contains the attribute value :for example "hello world"
816ad1
+                 * key contain the key generated from the indexing of final part of the filter.
816ad1
+                 * for example filter=(<attribut>=*ld), so key contains the indexing("ld").
816ad1
+                 * 
816ad1
+                 * The loop will iterate over the attribute value (vals) from the end of string
816ad1
+                 * to the begining. So it will try to index('d'), index('ld'), index('rld'), index('orld')...
816ad1
+                 * 
816ad1
+                 * At each iteration if the key generated from indexing the portion of vals, matches 
816ad1
+                 * the key generate from the final part of the filter, then the loop stops => we are done
816ad1
+                 */
816ad1
+                end = v.bv_val + v.bv_len - 1;
816ad1
+                v.bv_val = end;
816ad1
 		while(1) {
816ad1
-		    v.bv_len = (*vals)->bv_len - (v.bv_val - (*vals)->bv_val);
816ad1
+                    v.bv_len = end - v.bv_val + 1;
816ad1
 		    vkeys = ix->ix_index (ix, vals, NULL);
816ad1
 		    if (vkeys && vkeys[0]) {
816ad1
 			auto const struct berval* vkey = vkeys[0];
816ad1
-- 
816ad1
2.13.6
816ad1