|
|
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 |
|