andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From c90503a6a5bbb07dda929ef689e153354b4ac067 Mon Sep 17 00:00:00 2001
dc8c34
From: Nathan Kinder <nkinder@redhat.com>
dc8c34
Date: Wed, 11 Sep 2013 18:23:14 -0700
dc8c34
Subject: [PATCH 406/410] Ticket 449 - Allow macro aci keywords to be
dc8c34
 case-insensitive
dc8c34
dc8c34
This allows the macro aci keywords ($attr and $dn) to be
dc8c34
case-insensitive.  We were allowing the keywords to be set
dc8c34
regardless of case, but we were only processing them properly
dc8c34
if they were lowercase.  This patch makes the processing
dc8c34
case-insensitive as well.
dc8c34
dc8c34
I also added validation of the attribute name that is appended
dc8c34
to the $attr keyword.  We previously performed no validation.  The
dc8c34
patch ensures that the attribute name is legal per RFC 4512, but
dc8c34
we don't check if it is defined in the schema.  This will allow an
dc8c34
aci to be set prior to adding the attribute to the schema.  It
dc8c34
also allows attributes that are used in an extensibleObject entry
dc8c34
to work properly with macro acis.
dc8c34
dc8c34
(cherry picked from commit 95214606df95deb1cf9a30044fe64f780c030b34)
dc8c34
(cherry picked from commit 9b959b91c2e08d0681097e158525ef484544a214)
dc8c34
dc8c34
(cherry picked from commit d91bcdf8dd51feff96e4a4796f00d6409c187620)
dc8c34
---
dc8c34
 ldap/servers/plugins/acl/acllas.c   | 34 ++++++++++-----------
dc8c34
 ldap/servers/plugins/acl/aclparse.c | 59 +++++++++++++++++++++++++++++++------
dc8c34
 ldap/servers/plugins/acl/aclutil.c  |  6 ++--
dc8c34
 3 files changed, 70 insertions(+), 29 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
dc8c34
index a0cc53d..7f4f69c 100644
dc8c34
--- a/ldap/servers/plugins/acl/acllas.c
dc8c34
+++ b/ldap/servers/plugins/acl/acllas.c
dc8c34
@@ -584,9 +584,9 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
dc8c34
 		} else {
dc8c34
 			/* URL format */
dc8c34
 			
dc8c34
-			if ((strstr (user, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
-				(strstr (user, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) ||
dc8c34
-				(strstr (user, ACL_RULE_MACRO_ATTR_KEY) != NULL)) {			
dc8c34
+			if ((strcasestr (user, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
+				(strcasestr (user, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) ||
dc8c34
+				(strcasestr (user, ACL_RULE_MACRO_ATTR_KEY) != NULL)) {			
dc8c34
 				
dc8c34
 				matched = aclutil_evaluate_macro( s_user, &lasinfo,
dc8c34
 													ACL_EVAL_USER);
dc8c34
@@ -856,9 +856,9 @@ DS_LASGroupDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
dc8c34
 					"Group not evaluated(%s)\n", groupName);
dc8c34
 			break;
dc8c34
 		} else {			
dc8c34
-			if ((strstr (groupName, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
-				(strstr (groupName, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) ||
dc8c34
-				(strstr (groupName, ACL_RULE_MACRO_ATTR_KEY) != NULL)) {			
dc8c34
+			if ((strcasestr (groupName, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
+				(strcasestr (groupName, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) ||
dc8c34
+				(strcasestr (groupName, ACL_RULE_MACRO_ATTR_KEY) != NULL)) {			
dc8c34
 				matched = aclutil_evaluate_macro( groupName, &lasinfo,
dc8c34
 													ACL_EVAL_GROUP);
dc8c34
 				slapi_log_error ( SLAPI_LOG_ACL, plugin_name,
dc8c34
@@ -1075,9 +1075,9 @@ DS_LASRoleDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
dc8c34
 		} else {
dc8c34
 
dc8c34
 			/* Take care of param strings */
dc8c34
-			if ((strstr (role, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
-				(strstr (role, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) ||
dc8c34
-				(strstr (role, ACL_RULE_MACRO_ATTR_KEY) != NULL)) {			
dc8c34
+			if ((strcasestr (role, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
+				(strcasestr (role, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) ||
dc8c34
+				(strcasestr (role, ACL_RULE_MACRO_ATTR_KEY) != NULL)) {			
dc8c34
 				
dc8c34
 				matched = aclutil_evaluate_macro( role, &lasinfo,
dc8c34
 													ACL_EVAL_ROLE);
dc8c34
@@ -2594,9 +2594,9 @@ DS_LASGroupDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
dc8c34
 
dc8c34
 		/* In this case "grppupdnattr="ldap:///base??attr" */
dc8c34
 
dc8c34
-		if ((strstr (attrName, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
-			(strstr (attrName, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) ||
dc8c34
-			(strstr (attrName, ACL_RULE_MACRO_ATTR_KEY) != NULL)) {			
dc8c34
+		if ((strcasestr (attrName, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
+			(strcasestr (attrName, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) ||
dc8c34
+			(strcasestr (attrName, ACL_RULE_MACRO_ATTR_KEY) != NULL)) {			
dc8c34
 				
dc8c34
 				matched = aclutil_evaluate_macro( attrName, &lasinfo,
dc8c34
 													ACL_EVAL_GROUPDNATTR);
dc8c34
@@ -4162,12 +4162,12 @@ acllas_replace_dn_macro( char *rule, char *matched_val, lasInfo *lasinfo) {
dc8c34
 	int has_macro_levels = 0;
dc8c34
 	
dc8c34
 	/* Determine what the rule's got once */
dc8c34
-	if ( strstr(rule, ACL_RULE_MACRO_DN_KEY) != NULL) {
dc8c34
+	if ( strcasestr(rule, ACL_RULE_MACRO_DN_KEY) != NULL) {
dc8c34
 		/* ($dn) exists */
dc8c34
 		has_macro_dn = 1;
dc8c34
 	}
dc8c34
 
dc8c34
-	if ( strstr(rule, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) {
dc8c34
+	if ( strcasestr(rule, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL) {
dc8c34
 		/* [$dn] exists */
dc8c34
 		has_macro_levels = 1;
dc8c34
 	}
dc8c34
@@ -4271,7 +4271,7 @@ acllas_replace_attr_macro( char *rule, lasInfo *lasinfo)
dc8c34
 	int l;
dc8c34
 	Slapi_Attr *attr = NULL;
dc8c34
 	
dc8c34
-	str = strstr(rule, ACL_RULE_MACRO_ATTR_KEY);
dc8c34
+	str = strcasestr(rule, ACL_RULE_MACRO_ATTR_KEY);
dc8c34
 	if ( str == NULL ) {
dc8c34
 
dc8c34
 		charray_add(&a, slapi_ch_strdup(rule));
dc8c34
@@ -4280,7 +4280,7 @@ acllas_replace_attr_macro( char *rule, lasInfo *lasinfo)
dc8c34
 	} else {
dc8c34
 	
dc8c34
 		working_rule = slapi_ch_strdup(rule);
dc8c34
-		str = strstr(working_rule, ACL_RULE_MACRO_ATTR_KEY);
dc8c34
+		str = strcasestr(working_rule, ACL_RULE_MACRO_ATTR_KEY);
dc8c34
 		charray_add(&working_list, working_rule );
dc8c34
 		
dc8c34
 		while( str != NULL) {
dc8c34
@@ -4378,7 +4378,7 @@ acllas_replace_attr_macro( char *rule, lasInfo *lasinfo)
dc8c34
 			slapi_ch_free_string(&macro_str);
dc8c34
 			slapi_ch_free_string(&macro_attr_name);
dc8c34
 			
dc8c34
-			str = strstr(working_rule, ACL_RULE_MACRO_ATTR_KEY);
dc8c34
+			str = strcasestr(working_rule, ACL_RULE_MACRO_ATTR_KEY);
dc8c34
 		
dc8c34
         }/* while */
dc8c34
 		
dc8c34
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
dc8c34
index 098b5f7..12117d4 100644
dc8c34
--- a/ldap/servers/plugins/acl/aclparse.c
dc8c34
+++ b/ldap/servers/plugins/acl/aclparse.c
dc8c34
@@ -276,8 +276,8 @@ __aclp__parse_aci(char *str, aci_t  *aci_item, char **errbuf)
dc8c34
 			 * have a target and it must have a macro.
dc8c34
 			*/
dc8c34
 		
dc8c34
-			if ((strstr(str, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
-			    (strstr(str, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL)) {
dc8c34
+			if ((strcasestr(str, ACL_RULE_MACRO_DN_KEY) != NULL) ||
dc8c34
+			    (strcasestr(str, ACL_RULE_MACRO_DN_LEVELS_KEY) != NULL)) {
dc8c34
 			
dc8c34
 				/* Must have a targetmacro */
dc8c34
 				if ( !(aci_item->aci_type & ACI_TARGET_MACRO_DN)) {
dc8c34
@@ -465,6 +465,8 @@ __aclp__sanity_check_acltxt (aci_t *aci_item, char *str)
dc8c34
 	char				*newstr = NULL;
dc8c34
 	char				*word;
dc8c34
 	char				*next;
dc8c34
+	const char      *brkstr = " ;";
dc8c34
+	int             checkversion = 0;
dc8c34
 
dc8c34
 	memset (&errp, 0, sizeof(NSErr_t));
dc8c34
 	newstr = str;
dc8c34
@@ -484,13 +486,52 @@ __aclp__sanity_check_acltxt (aci_t *aci_item, char *str)
dc8c34
 	}
dc8c34
 
dc8c34
 	newstr = slapi_ch_strdup (str);
dc8c34
-	next = NULL;
dc8c34
-	word = ldap_utf8strtok_r(newstr, " ", &next;;
dc8c34
-	if (strcasecmp (word, "version") == 0) {
dc8c34
-		word = ldap_utf8strtok_r(NULL, " ", &next;;
dc8c34
-		if (atoi(word) != 3) {
dc8c34
-			slapi_ch_free ( (void **) &newstr );
dc8c34
-			return ACL_INCORRECT_ACI_VERSION;
dc8c34
+	for (word = ldap_utf8strtok_r(newstr, brkstr, &next;; word;
dc8c34
+	     word = ldap_utf8strtok_r(NULL, brkstr, &next)) {
dc8c34
+		if (0 == strcasecmp(word, "version")) {
dc8c34
+			checkversion = 1;
dc8c34
+		} else if (checkversion) {
dc8c34
+			checkversion = 0;
dc8c34
+			if ('3' != *word) {
dc8c34
+				slapi_ch_free ( (void **) &newstr );
dc8c34
+				return ACL_INCORRECT_ACI_VERSION;
dc8c34
+			}
dc8c34
+		} else if ((s = strstr(word, "($")) || (s = strstr(word, "[$"))) {
dc8c34
+			int attr_macro = -1;
dc8c34
+
dc8c34
+			/* See if this is a valid macro keyword. */
dc8c34
+			if ((0 != strncasecmp(s, ACL_RULE_MACRO_DN_KEY,
dc8c34
+			                      sizeof(ACL_RULE_MACRO_DN_KEY) - 1)) &&
dc8c34
+			    (0 != strncasecmp(s, ACL_RULE_MACRO_DN_LEVELS_KEY,
dc8c34
+			                      sizeof(ACL_RULE_MACRO_DN_LEVELS_KEY) - 1)) &&
dc8c34
+			    (0 != (attr_macro = strncasecmp(s, ACL_RULE_MACRO_ATTR_KEY,
dc8c34
+			                      sizeof(ACL_RULE_MACRO_ATTR_KEY) - 1)))) {
dc8c34
+				slapi_ch_free ( (void **) &newstr );
dc8c34
+				return ACL_SYNTAX_ERR;
dc8c34
+			}
dc8c34
+
dc8c34
+			/* For the $attr macro, validate that the attribute name is
dc8c34
+			 * legal per RFC 4512. */
dc8c34
+			if (attr_macro == 0) {
dc8c34
+				int start = 1;
dc8c34
+				char *p = NULL;
dc8c34
+
dc8c34
+				for (p = s + sizeof(ACL_RULE_MACRO_ATTR_KEY) - 1;
dc8c34
+					p && *p && *p != ')'; p++) {
dc8c34
+					if (start) {
dc8c34
+						if (!isalpha(*p)) {
dc8c34
+							slapi_ch_free ( (void **) &newstr );
dc8c34
+							return ACL_SYNTAX_ERR;
dc8c34
+						}
dc8c34
+						start = 0;
dc8c34
+					} else {
dc8c34
+						if (!(isalnum(*p) || (*p == '-'))) {
dc8c34
+							slapi_ch_free ( (void **) &newstr );
dc8c34
+							return ACL_SYNTAX_ERR;
dc8c34
+						}
dc8c34
+					}
dc8c34
+				}
dc8c34
+			}
dc8c34
 		}
dc8c34
 	} 
dc8c34
 	slapi_ch_free ( (void **) &newstr );
dc8c34
diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c
dc8c34
index 4f81bc0..03661f2 100644
dc8c34
--- a/ldap/servers/plugins/acl/aclutil.c
dc8c34
+++ b/ldap/servers/plugins/acl/aclutil.c
dc8c34
@@ -1247,7 +1247,7 @@ acl_replace_str(char * s, char *substr, char* replace_with_str) {
dc8c34
 		char *working_s, *suffix, *prefix, *patched;
dc8c34
 		int replace_with_len, substr_len, prefix_len, suffix_len;
dc8c34
 
dc8c34
-		if (strstr(s, substr) == NULL) {
dc8c34
+		if (strcasestr(s, substr) == NULL) {
dc8c34
 			return(slapi_ch_strdup(s));
dc8c34
 		} else {
dc8c34
 
dc8c34
@@ -1257,7 +1257,7 @@ acl_replace_str(char * s, char *substr, char* replace_with_str) {
dc8c34
 		
dc8c34
 			working_s = slapi_ch_strdup(s);	
dc8c34
 			prefix = working_s;
dc8c34
-			str = strstr(prefix, substr);
dc8c34
+			str = strcasestr(prefix, substr);
dc8c34
 			
dc8c34
 			while (str != NULL) {
dc8c34
 				
dc8c34
@@ -1284,7 +1284,7 @@ acl_replace_str(char * s, char *substr, char* replace_with_str) {
dc8c34
 
dc8c34
 				working_s = patched;
dc8c34
 				prefix = working_s;
dc8c34
-				str = strstr(prefix, substr);		
dc8c34
+				str = strcasestr(prefix, substr);		
dc8c34
 				
dc8c34
 			}
dc8c34
 
dc8c34
-- 
dc8c34
2.4.11
dc8c34