andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From d85b13bbe064c7783ec4d85d29f07abd59723f50 Mon Sep 17 00:00:00 2001
dc8c34
From: Ludwig Krispenz <lkrispen@redhat.com>
dc8c34
Date: Tue, 12 May 2015 10:07:24 +0200
dc8c34
Subject: [PATCH 350/363] Ticket 48175 - Avoid using regex in ACL if possible
dc8c34
dc8c34
Bug Description:  aci code uses regex to do substring matching for targets
dc8c34
                  but this is a huge overhead for a simple sequence of
dc8c34
                  string matching
dc8c34
dc8c34
Fix Description:   directly do the str match for the initial, any, final
dc8c34
                   parts of the filter
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/48175
dc8c34
dc8c34
Reviewed by: Noriko, thanks
dc8c34
dc8c34
(cherry picked from commit 6024a7731c1888668f1efc163fb55e118a373366)
dc8c34
---
dc8c34
 ldap/servers/plugins/acl/acl.c | 121 ++++++++++-------------------------------
dc8c34
 1 file changed, 30 insertions(+), 91 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
dc8c34
index 6edc367..3b0a7ce 100644
dc8c34
--- a/ldap/servers/plugins/acl/acl.c
dc8c34
+++ b/ldap/servers/plugins/acl/acl.c
dc8c34
@@ -3209,119 +3209,58 @@ acl__TestRights(Acl_PBlock *aclpb,int access, char **right, char ** map_generic,
dc8c34
 int
dc8c34
 acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
dc8c34
 {
dc8c34
-	int 		i, rc, len;
dc8c34
-	char 		*p = NULL;
dc8c34
-	char		*end, *realval, *tmp;
dc8c34
-	char 		pat[BUFSIZ];
dc8c34
-	char 		buf[BUFSIZ];
dc8c34
+	int i, len, tlen;
dc8c34
+	char 		*p = str;
dc8c34
 	char		*type, *initial, *final;
dc8c34
 	char		**any;
dc8c34
-	Slapi_Regex	*re = NULL;
dc8c34
-	const char  *re_result = NULL;
dc8c34
 
dc8c34
 	if ( 0 != slapi_filter_get_subfilt ( f, &type, &initial, &any, &final ) ) {
dc8c34
 		return (ACL_FALSE);
dc8c34
 	}
dc8c34
 
dc8c34
-	/* convert the input to lower. */
dc8c34
-	for (p = str; *p; p++)
dc8c34
-		*p = TOLOWER ( *p );
dc8c34
-
dc8c34
-	/* construct a regular expression corresponding to the filter: */
dc8c34
-	pat[0] = '\0';
dc8c34
-	p = pat;
dc8c34
-	end = pat + sizeof(pat) - 2; /* leave room for null */
dc8c34
-
dc8c34
-
dc8c34
+	/* this assumes that str and the filter components are already
dc8c34
+	 * normalized. If not, it shoul be done
dc8c34
+	 */
dc8c34
 	if ( initial != NULL) {
dc8c34
-		strcpy (p, "^");
dc8c34
-		p = strchr (p, '\0');
dc8c34
-
dc8c34
-		/* 2 * in case every char is special */
dc8c34
-		if (p + 2 * strlen ( initial ) > end) {
dc8c34
-			slapi_log_error (SLAPI_LOG_ACL, plugin_name, 
dc8c34
-				"not enough pattern space\n");
dc8c34
-
dc8c34
-			return (ACL_ERR);
dc8c34
-		}
dc8c34
-
dc8c34
-		if (!exact_match) {
dc8c34
-			strcpy (p, ".*");
dc8c34
-			p = strchr (p, '\0');
dc8c34
+		len = strlen(initial);
dc8c34
+		if (exact_match) {
dc8c34
+			int rc = strncmp(p, initial, len);
dc8c34
+			if (rc) {
dc8c34
+				return ACL_FALSE;
dc8c34
+			} else {
dc8c34
+				p += len;
dc8c34
+			}  
dc8c34
+		} else {
dc8c34
+			p = strstr(p, initial);
dc8c34
+			if (p) {
dc8c34
+				p += len;
dc8c34
+			} else {
dc8c34
+				return ACL_FALSE;
dc8c34
+			}
dc8c34
 		}
dc8c34
-		acl_strcpy_special (p, initial);
dc8c34
-		p = strchr (p, '\0');
dc8c34
 	}
dc8c34
 
dc8c34
 	if ( any != NULL) {
dc8c34
 		for (i = 0;  any && any[i] != NULL; i++) {
dc8c34
-			/* ".*" + value */
dc8c34
-			if (p + 2 * strlen ( any[i]) + 2 > end) {
dc8c34
-				slapi_log_error (SLAPI_LOG_ACL, plugin_name,
dc8c34
-					"not enough pattern space\n");
dc8c34
-				return (ACL_ERR);
dc8c34
+			p = strstr(p, any[i]);
dc8c34
+			if (p) {
dc8c34
+				p += strlen(any[i]);
dc8c34
+			} else {
dc8c34
+				return ACL_FALSE;
dc8c34
 			}
dc8c34
-
dc8c34
-			strcpy (p, ".*");
dc8c34
-			p = strchr (p, '\0');
dc8c34
-			acl_strcpy_special (p, any[i]);
dc8c34
-			p = strchr (p, '\0');
dc8c34
 		}
dc8c34
 	}
dc8c34
 
dc8c34
 
dc8c34
 	if ( final != NULL) {
dc8c34
-		/* ".*" + value */
dc8c34
-		if (p + 2 * strlen ( final ) + 2 > end) {
dc8c34
-			slapi_log_error (SLAPI_LOG_ACL, plugin_name, 
dc8c34
-				"not enough pattern space\n");
dc8c34
-			return (ACL_ERR);
dc8c34
-		}
dc8c34
-	
dc8c34
-		strcpy (p, ".*");
dc8c34
-		p = strchr (p, '\0');
dc8c34
-		acl_strcpy_special (p, final);
dc8c34
-		p = strchr (p, '\0');
dc8c34
-		strcpy (p, "$");
dc8c34
+		len = strlen(final);
dc8c34
+		tlen = strlen(p);
dc8c34
+		if (len > tlen) return ACL_FALSE;
dc8c34
+		if (strcmp(p+tlen-len, final)) return ACL_FALSE;
dc8c34
 	}
dc8c34
 
dc8c34
-	/* see if regex matches with the input string */
dc8c34
-	tmp = NULL;
dc8c34
-	len = strlen(str);
dc8c34
-
dc8c34
-	if (len < sizeof(buf)) {
dc8c34
-		strcpy (buf, str);
dc8c34
-		realval = buf;
dc8c34
-	} else {
dc8c34
-		tmp = (char*) slapi_ch_malloc (len + 1);
dc8c34
-		strcpy (tmp, str);
dc8c34
-		realval = tmp;
dc8c34
-	}
dc8c34
+	return ACL_TRUE;
dc8c34
 
dc8c34
-	/* What we have built is a regular pattaren expression.
dc8c34
-	** Now we will compile the pattern and compare wth the string to
dc8c34
-	** see if the input string matches with the patteren or not.
dc8c34
-	*/
dc8c34
-	re = slapi_re_comp( pat, &re_result );
dc8c34
-	if (NULL == re) {
dc8c34
-		slapi_log_error (SLAPI_LOG_ACL, plugin_name, 
dc8c34
-			"acl_match_substring:re_comp failed (%s)\n", re_result?re_result:"unknown");
dc8c34
-		return (ACL_ERR);
dc8c34
-	}
dc8c34
-
dc8c34
-	/* slapi_re_exec() returns 1 if the string p1 matches the last compiled
dc8c34
-	** regular expression, 0 if the string p1 failed to match 
dc8c34
-	*/
dc8c34
-	rc = slapi_re_exec( re, realval, -1 /* no timelimit */ );
dc8c34
-
dc8c34
-	slapi_re_free(re);
dc8c34
-	slapi_ch_free ( (void **) &tmp );
dc8c34
-
dc8c34
-	if (rc == 1) {
dc8c34
-		return ACL_TRUE;
dc8c34
-	} else {
dc8c34
-		return ACL_FALSE;
dc8c34
-	}
dc8c34
 }
dc8c34
 /***************************************************************************
dc8c34
 *
dc8c34
-- 
dc8c34
2.4.3
dc8c34