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