Blame SOURCES/0006-Ticket-449-Allow-macro-aci-keywords-to-be-case-insen.patch

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