You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2013/06/28 18:11:56 UTC
svn commit: r1497827 - in /qpid/trunk/qpid/cpp/src/qpid/acl: AclData.cpp
AclData.h
Author: chug
Date: Fri Jun 28 16:11:55 2013
New Revision: 1497827
URL: http://svn.apache.org/r1497827
Log:
NO-JIRA: Refactor AclData to extract two deeply nested functions. Fix parens.
Modified:
qpid/trunk/qpid/cpp/src/qpid/acl/AclData.cpp
qpid/trunk/qpid/cpp/src/qpid/acl/AclData.h
Modified: qpid/trunk/qpid/cpp/src/qpid/acl/AclData.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/acl/AclData.cpp?rev=1497827&r1=1497826&r2=1497827&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/acl/AclData.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/acl/AclData.cpp Fri Jun 28 16:11:55 2013
@@ -24,772 +24,741 @@
namespace qpid {
namespace acl {
- //
- // Instantiate the keyword strings
- //
- const std::string AclData::ACL_KEYWORD_USER_SUBST = "${user}";
- const std::string AclData::ACL_KEYWORD_DOMAIN_SUBST = "${domain}";
- const std::string AclData::ACL_KEYWORD_USERDOMAIN_SUBST = "${userdomain}";
- const std::string AclData::ACL_KEYWORD_ALL = "all";
- const std::string AclData::ACL_KEYWORD_ACL = "acl";
- const std::string AclData::ACL_KEYWORD_GROUP = "group";
- const std::string AclData::ACL_KEYWORD_QUOTA = "quota";
- const std::string AclData::ACL_KEYWORD_QUOTA_CONNECTIONS = "connections";
- const std::string AclData::ACL_KEYWORD_QUOTA_QUEUES = "queues";
- const char AclData::ACL_SYMBOL_WILDCARD = '*';
- const std::string AclData::ACL_KEYWORD_WILDCARD = "*";
- const char AclData::ACL_SYMBOL_LINE_CONTINUATION = '\\';
- const std::string AclData::ACL_KEYWORD_DEFAULT_EXCHANGE = "amq.default";
-
- //
- // constructor
- //
- AclData::AclData():
- decisionMode(qpid::acl::DENY),
- transferAcl(false),
- aclSource("UNKNOWN"),
- connQuotaRulesExist(false),
- connQuotaRuleSettings(new quotaRuleSet),
- queueQuotaRulesExist(false),
- queueQuotaRuleSettings(new quotaRuleSet)
- {
- for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++)
- {
- actionList[cnt]=0;
- }
- }
-
-
- //
- // clear
- //
- void AclData::clear ()
- {
- for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++)
- {
- if (actionList[cnt])
- {
- for (unsigned int cnt1=0; cnt1< qpid::acl::OBJECTSIZE; cnt1++)
- delete actionList[cnt][cnt1];
+//
+// Instantiate the keyword strings
+//
+const std::string AclData::ACL_KEYWORD_USER_SUBST = "${user}";
+const std::string AclData::ACL_KEYWORD_DOMAIN_SUBST = "${domain}";
+const std::string AclData::ACL_KEYWORD_USERDOMAIN_SUBST = "${userdomain}";
+const std::string AclData::ACL_KEYWORD_ALL = "all";
+const std::string AclData::ACL_KEYWORD_ACL = "acl";
+const std::string AclData::ACL_KEYWORD_GROUP = "group";
+const std::string AclData::ACL_KEYWORD_QUOTA = "quota";
+const std::string AclData::ACL_KEYWORD_QUOTA_CONNECTIONS = "connections";
+const std::string AclData::ACL_KEYWORD_QUOTA_QUEUES = "queues";
+const char AclData::ACL_SYMBOL_WILDCARD = '*';
+const std::string AclData::ACL_KEYWORD_WILDCARD = "*";
+const char AclData::ACL_SYMBOL_LINE_CONTINUATION = '\\';
+const std::string AclData::ACL_KEYWORD_DEFAULT_EXCHANGE = "amq.default";
+
+//
+// constructor
+//
+AclData::AclData():
+ decisionMode(qpid::acl::DENY),
+ transferAcl(false),
+ aclSource("UNKNOWN"),
+ connQuotaRulesExist(false),
+ connQuotaRuleSettings(new quotaRuleSet),
+ queueQuotaRulesExist(false),
+ queueQuotaRuleSettings(new quotaRuleSet)
+{
+ for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++) {
+ actionList[cnt]=0;
+ }
+}
+
+
+//
+// clear
+//
+void AclData::clear ()
+{
+ for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++) {
+ if (actionList[cnt]) {
+ for (unsigned int cnt1=0; cnt1< qpid::acl::OBJECTSIZE; cnt1++) {
+ delete actionList[cnt][cnt1];
}
- delete[] actionList[cnt];
}
- transferAcl = false;
- connQuotaRulesExist = false;
- connQuotaRuleSettings->clear();
- queueQuotaRulesExist = false;
- queueQuotaRuleSettings->clear();
+ delete[] actionList[cnt];
}
-
-
- //
- // matchProp
- //
- // Compare a rule's property name with a lookup name,
- // The rule's name may contain a trailing '*' to specify a wildcard match.
- //
- bool AclData::matchProp(const std::string& ruleStr,
- const std::string& lookupStr)
- {
- // allow wildcard on the end of rule strings...
- if (ruleStr.data()[ruleStr.size()-1]==ACL_SYMBOL_WILDCARD)
- {
- return ruleStr.compare(0,
- ruleStr.size()-1,
- lookupStr,
- 0,
- ruleStr.size()-1 ) == 0;
- }
- else
- {
- return ruleStr.compare(lookupStr) == 0;
- }
- }
-
-
- //
- // lookup
- //
- // The ACL main business logic function of matching rules and declaring
- // an allow or deny result.
- //
- AclResult AclData::lookup(
- const std::string& id,
- const Action& action,
- const ObjectType& objType,
- const std::string& name,
- std::map<Property, std::string>* params)
- {
- QPID_LOG(debug, "ACL: Lookup for id:" << id
- << " action:" << AclHelper::getActionStr((Action) action)
- << " objectType:" << AclHelper::getObjectTypeStr((ObjectType) objType)
- << " name:" << name
- << " with params " << AclHelper::propertyMapToString(params));
-
- // A typical log looks like:
- // ACL: Lookup for id:bob@QPID action:create objectType:queue name:q2
- // with params { durable=false passive=false autodelete=false
- // exclusive=false alternate= policytype= maxqueuesize=0
- // maxqueuecount=0 }
-
- // Default result is blanket decision mode for the entire ACL list.
- AclResult aclresult = decisionMode;
-
- // Test for lists of rules at the intersection of the Action & Object
- if (actionList[action] && actionList[action][objType])
- {
- // Find the list of rules for this actorId
- AclData::actObjItr itrRule = actionList[action][objType]->find(id);
-
- // If individual actorId not found then find a rule set for '*'.
- if (itrRule == actionList[action][objType]->end())
- itrRule = actionList[action][objType]->find(ACL_KEYWORD_WILDCARD);
-
- if (itrRule != actionList[action][objType]->end())
- {
- // A list of rules exists for this actor/action/object tuple.
- // Iterate the rule set to search for a matching rule.
- ruleSetItr rsItr = itrRule->second.end();
- for (int cnt = itrRule->second.size(); cnt != 0; cnt--)
- {
- rsItr--;
-
- QPID_LOG(debug, "ACL: checking rule " << rsItr->toString());
-
- bool match = true;
- bool limitChecked = true;
-
- // Iterate this rule's properties. A 'match' is true when
- // all of the rule's properties are found to be satisfied
- // in the lookup param list. The lookup may specify things
- // (they usually do) that are not in the rule properties but
- // these things don't interfere with the rule match.
-
- for (specPropertyMapItr rulePropMapItr = rsItr->props.begin();
- (rulePropMapItr != rsItr->props.end()) && match;
- rulePropMapItr++)
- {
- // The rule property map's NAME property is given in
- // the calling args and not in the param map.
- if (rulePropMapItr->first == acl::SPECPROP_NAME)
- {
- // substitute user name into object name
- bool result;
- if (rsItr->ruleHasUserSub[PROP_NAME]) {
- std::string sName(rulePropMapItr->second);
- substituteUserId(sName, id);
- result = matchProp(sName, name);
- } else {
- result = matchProp(rulePropMapItr->second, name);
- }
-
- if (result)
- {
- QPID_LOG(debug, "ACL: lookup name '" << name
- << "' matched with rule name '"
- << rulePropMapItr->second << "'");
- }
- else
- {
- match = false;
- QPID_LOG(debug, "ACL: lookup name '" << name
- << "' didn't match with rule name '"
- << rulePropMapItr->second << "'");
- }
- }
- else
- {
- if (params)
- {
- // The rule's property map non-NAME properties
- // found in the lookup's params list.
- // In some cases the param's index is not the same
- // as rule's index.
- propertyMapItr lookupParamItr;
- switch (rulePropMapItr->first)
- {
- case acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT:
- case acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT:
- lookupParamItr = params->find(PROP_MAXQUEUECOUNT);
- break;
-
- case acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT:
- case acl::SPECPROP_MAXQUEUESIZELOWERLIMIT:
- lookupParamItr = params->find(PROP_MAXQUEUESIZE);
- break;
-
- case acl::SPECPROP_MAXFILECOUNTUPPERLIMIT:
- case acl::SPECPROP_MAXFILECOUNTLOWERLIMIT:
- lookupParamItr = params->find(PROP_MAXFILECOUNT);
- break;
-
- case acl::SPECPROP_MAXFILESIZEUPPERLIMIT:
- case acl::SPECPROP_MAXFILESIZELOWERLIMIT:
- lookupParamItr = params->find(PROP_MAXFILESIZE);
- break;
-
- default:
- lookupParamItr = params->find((Property)rulePropMapItr->first);
- break;
- };
-
- if (lookupParamItr == params->end())
- {
- // Now the rule has a specified property
- // that does not exist in the caller's
- // lookup params list.
- // This rule does not match.
- match = false;
- QPID_LOG(debug, "ACL: lookup parameter map doesn't contain the rule property '"
- << AclHelper::getPropertyStr(rulePropMapItr->first) << "'");
- }
- else
- {
- // Now account for the business of rules
- // whose property indexes are mismatched.
- switch (rulePropMapItr->first)
- {
- case acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT:
- case acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT:
- case acl::SPECPROP_MAXFILECOUNTUPPERLIMIT:
- case acl::SPECPROP_MAXFILESIZEUPPERLIMIT:
- limitChecked &=
- compareInt(
- rulePropMapItr->first,
- boost::lexical_cast<std::string>(rulePropMapItr->second),
- boost::lexical_cast<std::string>(lookupParamItr->second),
- true);
- break;
-
- case acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT:
- case acl::SPECPROP_MAXQUEUESIZELOWERLIMIT:
- case acl::SPECPROP_MAXFILECOUNTLOWERLIMIT:
- case acl::SPECPROP_MAXFILESIZELOWERLIMIT:
- limitChecked &=
- compareInt(
- rulePropMapItr->first,
- boost::lexical_cast<std::string>(rulePropMapItr->second),
- boost::lexical_cast<std::string>(lookupParamItr->second),
- false);
- break;
-
- default:
- bool result;
- if ((SPECPROP_ALTERNATE == rulePropMapItr->first && rsItr->ruleHasUserSub[PROP_ALTERNATE]) ||
- (SPECPROP_QUEUENAME == rulePropMapItr->first && rsItr->ruleHasUserSub[PROP_QUEUENAME]))
- {
- // These properties are allowed to have username substitution
- std::string sName(rulePropMapItr->second);
- substituteUserId(sName, id);
- result = matchProp(sName, lookupParamItr->second);
- }
- else if (SPECPROP_ROUTINGKEY == rulePropMapItr->first)
- {
- // Routing key is allowed to have username substitution
- // and it gets topic exchange matching
- if (rsItr->ruleHasUserSub[PROP_ROUTINGKEY])
- {
- std::string sKey(lookupParamItr->second);
- substituteKeywords(sKey, id);
- result = rsItr->matchRoutingKey(sKey);
- }
- else
- {
- result = rsItr->matchRoutingKey(lookupParamItr->second);
- }
- }
- else
- {
- // Rules without substitution
- result = matchProp(rulePropMapItr->second, lookupParamItr->second);
- }
-
- if (result)
- {
- QPID_LOG(debug, "ACL: the pair("
- << AclHelper::getPropertyStr(lookupParamItr->first)
- << "," << lookupParamItr->second
- << ") given in lookup matched the pair("
- << AclHelper::getPropertyStr(rulePropMapItr->first) << ","
- << rulePropMapItr->second
- << ") given in the rule");
- }
- else
- {
- match = false;
- QPID_LOG(debug, "ACL: the pair("
- << AclHelper::getPropertyStr(lookupParamItr->first)
- << "," << lookupParamItr->second
- << ") given in lookup doesn't match the pair("
- << AclHelper::getPropertyStr(rulePropMapItr->first)
- << "," << rulePropMapItr->second
- << ") given in the rule");
- }
- break;
- };
- }
- }
- else
- {
- // params don't exist.
- }
- }
- }
- if (match)
- {
- aclresult = rsItr->ruleMode;
- if (!limitChecked)
- {
- // Now a lookup matched all rule properties but one
- // of the numeric limit checks has failed.
- // Demote allow rules to corresponding deny rules.
- switch (aclresult)
- {
- case acl::ALLOW:
- aclresult = acl::DENY;
- break;
- case acl::ALLOWLOG:
- aclresult = acl::DENYLOG;
- break;
- default:
- break;
- };
- }
- QPID_LOG(debug,"ACL: Successful match, the decision is:"
- << AclHelper::getAclResultStr(aclresult));
- return aclresult;
- }
- else
- {
- // This rule did not match the requested lookup and
- // does not contribute to an ACL decision.
- }
- }
- }
- else
- {
- // The Action-Object list has entries but not for this actorId
- // nor for *.
+ transferAcl = false;
+ connQuotaRulesExist = false;
+ connQuotaRuleSettings->clear();
+ queueQuotaRulesExist = false;
+ queueQuotaRuleSettings->clear();
+}
+
+
+//
+// matchProp
+//
+// Compare a rule's property name with a lookup name,
+// The rule's name may contain a trailing '*' to specify a wildcard match.
+//
+bool AclData::matchProp(const std::string& ruleStr,
+ const std::string& lookupStr)
+{
+ // allow wildcard on the end of rule strings...
+ if (ruleStr.data()[ruleStr.size()-1]==ACL_SYMBOL_WILDCARD) {
+ return ruleStr.compare(0,
+ ruleStr.size()-1,
+ lookupStr,
+ 0,
+ ruleStr.size()-1 ) == 0;
+ } else {
+ return ruleStr.compare(lookupStr) == 0;
+ }
+}
+
+
+//
+// lookupMatchRule
+//
+// Check a single rule and if it's a match return the decision
+//
+bool AclData::lookupMatchRule(
+ const ruleSetItr& rsItr,
+ const std::string& id,
+ const std::string& name,
+ const std::map<Property, std::string>* params,
+ AclResult& aclresult)
+{
+ QPID_LOG(debug, "ACL: checking rule " << rsItr->toString());
+
+ bool match = true;
+ bool limitChecked = true;
+
+ // Iterate this rule's properties. A 'match' is true when
+ // all of the rule's properties are found to be satisfied
+ // in the lookup param list. The lookup may specify things
+ // (they usually do) that are not in the rule properties but
+ // these things don't interfere with the rule match.
+
+ for (specPropertyMapItr rulePropMapItr = rsItr->props.begin();
+ (rulePropMapItr != rsItr->props.end()) && match;
+ rulePropMapItr++) {
+ // The rule property map's NAME property is given in
+ // the calling args and not in the param map.
+ if (rulePropMapItr->first == acl::SPECPROP_NAME)
+ {
+ // substitute user name into object name
+ bool result;
+ if (rsItr->ruleHasUserSub[PROP_NAME]) {
+ std::string sName(rulePropMapItr->second);
+ substituteUserId(sName, id);
+ result = matchProp(sName, name);
+ } else {
+ result = matchProp(rulePropMapItr->second, name);
}
- }
- else
- {
- // The Action-Object list has no entries.
- }
-
- QPID_LOG(debug,"ACL: No successful match, defaulting to the decision mode "
- << AclHelper::getAclResultStr(aclresult));
- return aclresult;
- }
+ if (result) {
+ QPID_LOG(debug, "ACL: lookup name '" << name
+ << "' matched with rule name '"
+ << rulePropMapItr->second << "'");
+ } else {
+ match = false;
+ QPID_LOG(debug, "ACL: lookup name '" << name
+ << "' didn't match with rule name '"
+ << rulePropMapItr->second << "'");
+ }
+ } else {
+ if (params) {
+ // The rule's property map non-NAME properties
+ // found in the lookup's params list.
+ // In some cases the param's index is not the same
+ // as rule's index.
+ propertyMapItr lookupParamItr;
+ switch (rulePropMapItr->first) {
+ case acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT:
+ case acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT:
+ lookupParamItr = params->find(PROP_MAXQUEUECOUNT);
+ break;
+
+ case acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT:
+ case acl::SPECPROP_MAXQUEUESIZELOWERLIMIT:
+ lookupParamItr = params->find(PROP_MAXQUEUESIZE);
+ break;
+
+ case acl::SPECPROP_MAXFILECOUNTUPPERLIMIT:
+ case acl::SPECPROP_MAXFILECOUNTLOWERLIMIT:
+ lookupParamItr = params->find(PROP_MAXFILECOUNT);
+ break;
+
+ case acl::SPECPROP_MAXFILESIZEUPPERLIMIT:
+ case acl::SPECPROP_MAXFILESIZELOWERLIMIT:
+ lookupParamItr = params->find(PROP_MAXFILESIZE);
+ break;
+
+ default:
+ lookupParamItr = params->find((Property)rulePropMapItr->first);
+ break;
+ };
+
+ if (lookupParamItr == params->end()) {
+ // Now the rule has a specified property
+ // that does not exist in the caller's
+ // lookup params list.
+ // This rule does not match.
+ match = false;
+ QPID_LOG(debug, "ACL: lookup parameter map doesn't contain the rule property '"
+ << AclHelper::getPropertyStr(rulePropMapItr->first) << "'");
+ } else {
+ // Now account for the business of rules
+ // whose property indexes are mismatched.
+ switch (rulePropMapItr->first) {
+ case acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT:
+ case acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT:
+ case acl::SPECPROP_MAXFILECOUNTUPPERLIMIT:
+ case acl::SPECPROP_MAXFILESIZEUPPERLIMIT:
+ limitChecked &=
+ compareInt(
+ rulePropMapItr->first,
+ boost::lexical_cast<std::string>(rulePropMapItr->second),
+ boost::lexical_cast<std::string>(lookupParamItr->second),
+ true);
+ break;
+
+ case acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT:
+ case acl::SPECPROP_MAXQUEUESIZELOWERLIMIT:
+ case acl::SPECPROP_MAXFILECOUNTLOWERLIMIT:
+ case acl::SPECPROP_MAXFILESIZELOWERLIMIT:
+ limitChecked &=
+ compareInt(
+ rulePropMapItr->first,
+ boost::lexical_cast<std::string>(rulePropMapItr->second),
+ boost::lexical_cast<std::string>(lookupParamItr->second),
+ false);
+ break;
- //
- // lookup
- //
- // The ACL main business logic function of matching rules and declaring
- // an allow or deny result. This lookup is the fastpath per-message
- // lookup to verify if a user is allowed to publish to an exchange with
- // a given key.
- //
- AclResult AclData::lookup(
- const std::string& id,
- const Action& action,
- const ObjectType& objType,
- const std::string& /*Exchange*/ name,
- const std::string& routingKey)
- {
-
- QPID_LOG(debug, "ACL: Lookup for id:" << id
- << " action:" << AclHelper::getActionStr((Action) action)
- << " objectType:" << AclHelper::getObjectTypeStr((ObjectType) objType)
- << " exchange name:" << name
- << " with routing key " << routingKey);
-
- AclResult aclresult = decisionMode;
-
- if (actionList[action] && actionList[action][objType]){
- AclData::actObjItr itrRule = actionList[action][objType]->find(id);
-
- if (itrRule == actionList[action][objType]->end())
- itrRule = actionList[action][objType]->find(ACL_KEYWORD_WILDCARD);
-
- if (itrRule != actionList[action][objType]->end() )
- {
- // Found a rule list for this user-action-object set.
- // Search the rule list for a matching rule.
- ruleSetItr rsItr = itrRule->second.end();
- for (int cnt = itrRule->second.size(); cnt != 0; cnt--)
- {
- rsItr--;
-
- QPID_LOG(debug, "ACL: checking rule " << rsItr->toString());
-
- // Search on exchange name and routing key only if specfied in rule.
- bool match =true;
- if (rsItr->pubExchNameInRule)
- {
- // substitute user name into object name
+ default:
bool result;
-
- if (rsItr->ruleHasUserSub[PROP_NAME]) {
- std::string sName(rsItr->pubExchName);
+ if ((SPECPROP_ALTERNATE == rulePropMapItr->first && rsItr->ruleHasUserSub[PROP_ALTERNATE]) ||
+ (SPECPROP_QUEUENAME == rulePropMapItr->first && rsItr->ruleHasUserSub[PROP_QUEUENAME])) {
+ // These properties are allowed to have username substitution
+ std::string sName(rulePropMapItr->second);
substituteUserId(sName, id);
- result = matchProp(sName, name);
- }
- else if (rsItr->pubExchNameMatchesBlank)
- {
- result = name.empty();
- }
- else
- {
- result = matchProp(rsItr->pubExchName, name);
- }
-
- if (result)
- {
- QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup exchange name '"
- << name << "' matched with rule name '"
- << rsItr->pubExchName << "'");
- }
- else
- {
- match= false;
- QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup exchange name '"
- << name << "' did not match with rule name '"
- << rsItr->pubExchName << "'");
- }
- }
-
- if (match && rsItr->pubRoutingKeyInRule)
- {
- if ((routingKey.find(ACL_KEYWORD_USER_SUBST, 0) != std::string::npos) ||
- (routingKey.find(ACL_KEYWORD_DOMAIN_SUBST, 0) != std::string::npos) ||
- (routingKey.find(ACL_KEYWORD_USERDOMAIN_SUBST, 0) != std::string::npos))
- {
- // The user is not allowed to present a routing key with the substitution key in it
- QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum <<
- " User-specified routing key has substitution wildcard:" << routingKey
- << ". Rule match prohibited.");
- match = false;
- }
- else
- {
- bool result;
+ result = matchProp(sName, lookupParamItr->second);
+ } else if (SPECPROP_ROUTINGKEY == rulePropMapItr->first) {
+ // Routing key is allowed to have username substitution
+ // and it gets topic exchange matching
if (rsItr->ruleHasUserSub[PROP_ROUTINGKEY]) {
- std::string sKey(routingKey);
+ std::string sKey(lookupParamItr->second);
substituteKeywords(sKey, id);
result = rsItr->matchRoutingKey(sKey);
} else {
- result = rsItr->matchRoutingKey(routingKey);
- }
-
- if (result)
- {
- QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
- << routingKey << "' matched with rule routing key '"
- << rsItr->pubRoutingKey << "'");
- }
- else
- {
- QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
- << routingKey << "' did not match with rule routing key '"
- << rsItr->pubRoutingKey << "'");
- match = false;
+ result = rsItr->matchRoutingKey(lookupParamItr->second);
}
+ } else {
+ // Rules without substitution
+ result = matchProp(rulePropMapItr->second, lookupParamItr->second);
}
- }
- if (match){
- aclresult = rsItr->ruleMode;
- QPID_LOG(debug,"ACL: Rule: " << rsItr->rawRuleNum << " Successful match, the decision is:"
- << AclHelper::getAclResultStr(aclresult));
- return aclresult;
- }
+ if (result) {
+ QPID_LOG(debug, "ACL: the pair("
+ << AclHelper::getPropertyStr(lookupParamItr->first)
+ << "," << lookupParamItr->second
+ << ") given in lookup matched the pair("
+ << AclHelper::getPropertyStr(rulePropMapItr->first) << ","
+ << rulePropMapItr->second
+ << ") given in the rule");
+ } else {
+ match = false;
+ QPID_LOG(debug, "ACL: the pair("
+ << AclHelper::getPropertyStr(lookupParamItr->first)
+ << "," << lookupParamItr->second
+ << ") given in lookup doesn't match the pair("
+ << AclHelper::getPropertyStr(rulePropMapItr->first)
+ << "," << rulePropMapItr->second
+ << ") given in the rule");
+ }
+ break;
+ };
}
+ } else {
+ // params don't exist.
}
}
- QPID_LOG(debug,"ACL: No successful match, defaulting to the decision mode "
- << AclHelper::getAclResultStr(aclresult));
- return aclresult;
-
- }
-
-
-
- //
- //
- //
- void AclData::setConnQuotaRuleSettings (
- bool rulesExist, boost::shared_ptr<quotaRuleSet> quotaPtr)
- {
- connQuotaRulesExist = rulesExist;
- connQuotaRuleSettings = quotaPtr;
}
-
-
- //
- // getConnQuotaForUser
- //
- // Return the true or false value of connQuotaRulesExist,
- // indicating whether any kind of lookup was done or not.
- //
- // When lookups are performed return the result value of
- // 1. The user's setting else
- // 2. The 'all' user setting else
- // 3. Zero
- // When lookups are not performed then return a result value of Zero.
- //
- bool AclData::getConnQuotaForUser(const std::string& theUserName,
- uint16_t* theResult) const {
- if (connQuotaRulesExist) {
- // look for this user explicitly
- quotaRuleSetItr nameItr = (*connQuotaRuleSettings).find(theUserName);
- if (nameItr != (*connQuotaRuleSettings).end()) {
- QPID_LOG(trace, "ACL: Connection quota for user " << theUserName
- << " explicitly set to : " << (*nameItr).second);
- *theResult = (*nameItr).second;
- } else {
- // Look for the 'all' user
- nameItr = (*connQuotaRuleSettings).find(ACL_KEYWORD_ALL);
- if (nameItr != (*connQuotaRuleSettings).end()) {
- QPID_LOG(trace, "ACL: Connection quota for user " << theUserName
- << " chosen through value for 'all' : " << (*nameItr).second);
- *theResult = (*nameItr).second;
- } else {
- // Neither userName nor "all" found.
- QPID_LOG(trace, "ACL: Connection quota for user " << theUserName
- << " absent in quota settings. Return value : 0");
- *theResult = 0;
+ if (match) {
+ aclresult = rsItr->ruleMode;
+ if (!limitChecked) {
+ // Now a lookup matched all rule properties but one
+ // of the numeric limit checks has failed.
+ // Demote allow rules to corresponding deny rules.
+ switch (aclresult) {
+ case acl::ALLOW:
+ aclresult = acl::DENY;
+ break;
+ case acl::ALLOWLOG:
+ aclresult = acl::DENYLOG;
+ break;
+ default:
+ break;
+ };
+ }
+ QPID_LOG(debug,"ACL: Successful match, the decision is:"
+ << AclHelper::getAclResultStr(aclresult));
+ } else {
+ // This rule did not match the requested lookup and
+ // does not contribute to an ACL decision.
+ }
+ return match;
+}
+
+//
+// lookup - general ACL lookup
+//
+// The ACL main business logic function of matching rules and declaring
+// an allow or deny result.
+//
+AclResult AclData::lookup(
+ const std::string& id,
+ const Action& action,
+ const ObjectType& objType,
+ const std::string& name,
+ std::map<Property, std::string>* params)
+{
+ QPID_LOG(debug, "ACL: Lookup for id:" << id
+ << " action:" << AclHelper::getActionStr((Action) action)
+ << " objectType:" << AclHelper::getObjectTypeStr((ObjectType) objType)
+ << " name:" << name
+ << " with params " << AclHelper::propertyMapToString(params));
+
+ // A typical log looks like:
+ // ACL: Lookup for id:bob@QPID action:create objectType:queue name:q2
+ // with params { durable=false passive=false autodelete=false
+ // exclusive=false alternate= policytype= maxqueuesize=0
+ // maxqueuecount=0 }
+
+ // Default result is blanket decision mode for the entire ACL list.
+ AclResult aclresult = decisionMode;
+
+ // Test for lists of rules at the intersection of the Action & Object
+ if (actionList[action] && actionList[action][objType]) {
+ // Find the list of rules for this actorId
+ AclData::actObjItr itrRule = actionList[action][objType]->find(id);
+
+ // If individual actorId not found then find a rule set for '*'.
+ if (itrRule == actionList[action][objType]->end()) {
+ itrRule = actionList[action][objType]->find(ACL_KEYWORD_WILDCARD);
+ }
+ if (itrRule != actionList[action][objType]->end()) {
+ // A list of rules exists for this actor/action/object tuple.
+ // Iterate the rule set to search for a matching rule.
+ ruleSetItr rsItr = itrRule->second.end();
+ for (int cnt = itrRule->second.size(); cnt != 0; cnt--) {
+ rsItr--;
+ if (lookupMatchRule(rsItr, id, name, params, aclresult)) {
+ return aclresult;
}
}
} else {
- // Rules do not exist
- QPID_LOG(trace, "ACL: Connection quota for user " << theUserName
- << " unavailable; quota settings are not specified. Return value : 0");
- *theResult = 0;
+ // The Action-Object list has entries but not for this actorId
+ // nor for *.
}
- return connQuotaRulesExist;
+ } else {
+ // The Action-Object list has no entries.
}
- //
- //
- //
- void AclData::setQueueQuotaRuleSettings (
- bool rulesExist, boost::shared_ptr<quotaRuleSet> quotaPtr)
- {
- queueQuotaRulesExist = rulesExist;
- queueQuotaRuleSettings = quotaPtr;
+ QPID_LOG(debug,"ACL: No successful match, defaulting to the decision mode "
+ << AclHelper::getAclResultStr(aclresult));
+ return aclresult;
+}
+
+
+//
+// lookupMatchPublishExchangeRule
+//
+// check a single publish exchange rule
+//
+bool AclData::lookupMatchPublishExchangeRule(
+ const ruleSetItr& rsItr,
+ const std::string& id,
+ const std::string& name,
+ const std::string& routingKey,
+ AclResult& aclresult)
+{
+ QPID_LOG(debug, "ACL: checking rule " << rsItr->toString());
+
+ // Search on exchange name and routing key only if specfied in rule.
+ bool match =true;
+ if (rsItr->pubExchNameInRule) {
+ // substitute user name into object name
+ bool result;
+
+ if (rsItr->ruleHasUserSub[PROP_NAME]) {
+ std::string sName(rsItr->pubExchName);
+ substituteUserId(sName, id);
+ result = matchProp(sName, name);
+ }
+ else if (rsItr->pubExchNameMatchesBlank) {
+ result = name.empty();
+ } else {
+ result = matchProp(rsItr->pubExchName, name);
+ }
+
+ if (result) {
+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup exchange name '"
+ << name << "' matched with rule name '"
+ << rsItr->pubExchName << "'");
+ } else {
+ match= false;
+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup exchange name '"
+ << name << "' did not match with rule name '"
+ << rsItr->pubExchName << "'");
+ }
}
+ if (match && rsItr->pubRoutingKeyInRule) {
+ if ((routingKey.find(ACL_KEYWORD_USER_SUBST, 0) != std::string::npos) ||
+ (routingKey.find(ACL_KEYWORD_DOMAIN_SUBST, 0) != std::string::npos) ||
+ (routingKey.find(ACL_KEYWORD_USERDOMAIN_SUBST, 0) != std::string::npos)) {
+ // The user is not allowed to present a routing key with the substitution key in it
+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum <<
+ " User-specified routing key has substitution wildcard:" << routingKey
+ << ". Rule match prohibited.");
+ match = false;
+ } else {
+ bool result;
+ if (rsItr->ruleHasUserSub[PROP_ROUTINGKEY]) {
+ std::string sKey(routingKey);
+ substituteKeywords(sKey, id);
+ result = rsItr->matchRoutingKey(sKey);
+ } else {
+ result = rsItr->matchRoutingKey(routingKey);
+ }
- //
- // getQueueQuotaForUser
- //
- // Return the true or false value of queueQuotaRulesExist,
- // indicating whether any kind of lookup was done or not.
- //
- // When lookups are performed return the result value of
- // 1. The user's setting else
- // 2. The 'all' user setting else
- // 3. Zero
- // When lookups are not performed then return a result value of Zero.
- //
- bool AclData::getQueueQuotaForUser(const std::string& theUserName,
- uint16_t* theResult) const {
- if (queueQuotaRulesExist) {
- // look for this user explicitly
- quotaRuleSetItr nameItr = (*queueQuotaRuleSettings).find(theUserName);
- if (nameItr != (*queueQuotaRuleSettings).end()) {
- QPID_LOG(trace, "ACL: Queue quota for user " << theUserName
- << " explicitly set to : " << (*nameItr).second);
- *theResult = (*nameItr).second;
+ if (result) {
+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
+ << routingKey << "' matched with rule routing key '"
+ << rsItr->pubRoutingKey << "'");
} else {
- // Look for the 'all' user
- nameItr = (*queueQuotaRuleSettings).find(ACL_KEYWORD_ALL);
- if (nameItr != (*queueQuotaRuleSettings).end()) {
- QPID_LOG(trace, "ACL: Queue quota for user " << theUserName
- << " chosen through value for 'all' : " << (*nameItr).second);
- *theResult = (*nameItr).second;
- } else {
- // Neither userName nor "all" found.
- QPID_LOG(trace, "ACL: Queue quota for user " << theUserName
- << " absent in quota settings. Return value : 0");
- *theResult = 0;
- }
+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
+ << routingKey << "' did not match with rule routing key '"
+ << rsItr->pubRoutingKey << "'");
+ match = false;
}
- } else {
- // Rules do not exist
- QPID_LOG(trace, "ACL: Queue quota for user " << theUserName
- << " unavailable; quota settings are not specified. Return value : 0");
- *theResult = 0;
}
- return queueQuotaRulesExist;
}
+ if (match) {
+ aclresult = rsItr->ruleMode;
+ QPID_LOG(debug,"ACL: Rule: " << rsItr->rawRuleNum << " Successful match, the decision is:"
+ << AclHelper::getAclResultStr(aclresult));
+ }
+ return match;
+}
+
+//
+// lookup - special PUBLISH EXCHANGE lookup
+//
+// The ACL main business logic function of matching rules and declaring
+// an allow or deny result. This lookup is the fastpath per-message
+// lookup to verify if a user is allowed to publish to an exchange with
+// a given key.
+//
+AclResult AclData::lookup(
+ const std::string& id,
+ const Action& action,
+ const ObjectType& objType,
+ const std::string& /*Exchange*/ name,
+ const std::string& routingKey)
+{
+
+ QPID_LOG(debug, "ACL: Lookup for id:" << id
+ << " action:" << AclHelper::getActionStr((Action) action)
+ << " objectType:" << AclHelper::getObjectTypeStr((ObjectType) objType)
+ << " exchange name:" << name
+ << " with routing key " << routingKey);
+
+ AclResult aclresult = decisionMode;
+
+ if (actionList[action] && actionList[action][objType]){
+ AclData::actObjItr itrRule = actionList[action][objType]->find(id);
+
+ if (itrRule == actionList[action][objType]->end()) {
+ itrRule = actionList[action][objType]->find(ACL_KEYWORD_WILDCARD);
+ }
+ if (itrRule != actionList[action][objType]->end() ) {
+ // Found a rule list for this user-action-object set.
+ // Search the rule list for a matching rule.
+ ruleSetItr rsItr = itrRule->second.end();
+ for (int cnt = itrRule->second.size(); cnt != 0; cnt--) {
+ rsItr--;
- //
- //
- //
- AclData::~AclData()
- {
- clear();
+ if (lookupMatchPublishExchangeRule(rsItr, id, name, routingKey, aclresult)) {
+ return aclresult;
+ }
+ }
+ }
}
+ QPID_LOG(debug,"ACL: No successful match, defaulting to the decision mode "
+ << AclHelper::getAclResultStr(aclresult));
+ return aclresult;
+
+}
- //
- // Limit check an int limit
- //
- bool AclData::compareInt(const qpid::acl::SpecProperty theProperty,
- const std::string theAclValue,
- const std::string theLookupValue,
- bool theMaxFlag)
- {
- uint64_t aclRuleValue (0);
- uint64_t lookupValue (0);
-
- QPID_LOG(debug, "ACL: "
- << (theMaxFlag ? "Upper" : "Lower") << "-limit comparison for property "
- << AclHelper::getPropertyStr(theProperty)
- << ". Success if lookup(" << theLookupValue
- << ") "
- << (theMaxFlag ? "<=" : ">=") << " rule(" << theAclValue << ")");
-
- try
- {
- aclRuleValue = boost::lexical_cast<uint64_t>(theAclValue);
- }
- catch(const boost::bad_lexical_cast&)
- {
- assert (false);
- return false;
- }
-
- if (aclRuleValue == 0)
- {
- QPID_LOG(debug, "ACL: Comparison is always true when ACL rule value is zero");
- return true;
- }
- try
- {
- lookupValue = boost::lexical_cast<uint64_t>(theLookupValue);
- }
- catch(const boost::bad_lexical_cast&)
- {
- QPID_LOG(error,"ACL: Illegal value given in lookup for property '"
- << AclHelper::getPropertyStr(theProperty)
- << "' : " << theLookupValue);
- return false;
+//
+//
+//
+void AclData::setConnQuotaRuleSettings (
+ bool rulesExist, boost::shared_ptr<quotaRuleSet> quotaPtr)
+{
+ connQuotaRulesExist = rulesExist;
+ connQuotaRuleSettings = quotaPtr;
+}
+
+
+//
+// getConnQuotaForUser
+//
+// Return the true or false value of connQuotaRulesExist,
+// indicating whether any kind of lookup was done or not.
+//
+// When lookups are performed return the result value of
+// 1. The user's setting else
+// 2. The 'all' user setting else
+// 3. Zero
+// When lookups are not performed then return a result value of Zero.
+//
+bool AclData::getConnQuotaForUser(const std::string& theUserName,
+ uint16_t* theResult) const {
+ if (connQuotaRulesExist) {
+ // look for this user explicitly
+ quotaRuleSetItr nameItr = (*connQuotaRuleSettings).find(theUserName);
+ if (nameItr != (*connQuotaRuleSettings).end()) {
+ QPID_LOG(trace, "ACL: Connection quota for user " << theUserName
+ << " explicitly set to : " << (*nameItr).second);
+ *theResult = (*nameItr).second;
+ } else {
+ // Look for the 'all' user
+ nameItr = (*connQuotaRuleSettings).find(ACL_KEYWORD_ALL);
+ if (nameItr != (*connQuotaRuleSettings).end()) {
+ QPID_LOG(trace, "ACL: Connection quota for user " << theUserName
+ << " chosen through value for 'all' : " << (*nameItr).second);
+ *theResult = (*nameItr).second;
+ } else {
+ // Neither userName nor "all" found.
+ QPID_LOG(trace, "ACL: Connection quota for user " << theUserName
+ << " absent in quota settings. Return value : 0");
+ *theResult = 0;
+ }
}
-
- bool result =
- (theMaxFlag ? lookupValue > aclRuleValue : lookupValue < aclRuleValue);
- if ( result )
- {
- QPID_LOG(debug, "ACL: Limit exceeded for property '"
- << AclHelper::getPropertyStr(theProperty) << "'");
- return false;
+ } else {
+ // Rules do not exist
+ QPID_LOG(trace, "ACL: Connection quota for user " << theUserName
+ << " unavailable; quota settings are not specified. Return value : 0");
+ *theResult = 0;
+ }
+ return connQuotaRulesExist;
+}
+
+//
+//
+//
+void AclData::setQueueQuotaRuleSettings (
+ bool rulesExist, boost::shared_ptr<quotaRuleSet> quotaPtr)
+{
+ queueQuotaRulesExist = rulesExist;
+ queueQuotaRuleSettings = quotaPtr;
+}
+
+
+//
+// getQueueQuotaForUser
+//
+// Return the true or false value of queueQuotaRulesExist,
+// indicating whether any kind of lookup was done or not.
+//
+// When lookups are performed return the result value of
+// 1. The user's setting else
+// 2. The 'all' user setting else
+// 3. Zero
+// When lookups are not performed then return a result value of Zero.
+//
+bool AclData::getQueueQuotaForUser(const std::string& theUserName,
+ uint16_t* theResult) const {
+ if (queueQuotaRulesExist) {
+ // look for this user explicitly
+ quotaRuleSetItr nameItr = (*queueQuotaRuleSettings).find(theUserName);
+ if (nameItr != (*queueQuotaRuleSettings).end()) {
+ QPID_LOG(trace, "ACL: Queue quota for user " << theUserName
+ << " explicitly set to : " << (*nameItr).second);
+ *theResult = (*nameItr).second;
+ } else {
+ // Look for the 'all' user
+ nameItr = (*queueQuotaRuleSettings).find(ACL_KEYWORD_ALL);
+ if (nameItr != (*queueQuotaRuleSettings).end()) {
+ QPID_LOG(trace, "ACL: Queue quota for user " << theUserName
+ << " chosen through value for 'all' : " << (*nameItr).second);
+ *theResult = (*nameItr).second;
+ } else {
+ // Neither userName nor "all" found.
+ QPID_LOG(trace, "ACL: Queue quota for user " << theUserName
+ << " absent in quota settings. Return value : 0");
+ *theResult = 0;
+ }
}
-
- return true;
+ } else {
+ // Rules do not exist
+ QPID_LOG(trace, "ACL: Queue quota for user " << theUserName
+ << " unavailable; quota settings are not specified. Return value : 0");
+ *theResult = 0;
+ }
+ return queueQuotaRulesExist;
+}
+
+
+//
+//
+//
+AclData::~AclData()
+{
+ clear();
+}
+
+
+//
+// Limit check an int limit
+//
+bool AclData::compareInt(const qpid::acl::SpecProperty theProperty,
+ const std::string theAclValue,
+ const std::string theLookupValue,
+ bool theMaxFlag)
+{
+ uint64_t aclRuleValue (0);
+ uint64_t lookupValue (0);
+
+ QPID_LOG(debug, "ACL: "
+ << (theMaxFlag ? "Upper" : "Lower") << "-limit comparison for property "
+ << AclHelper::getPropertyStr(theProperty)
+ << ". Success if lookup(" << theLookupValue
+ << ") "
+ << (theMaxFlag ? "<=" : ">=") << " rule(" << theAclValue << ")");
+
+ try {
+ aclRuleValue = boost::lexical_cast<uint64_t>(theAclValue);
+ }
+ catch(const boost::bad_lexical_cast&) {
+ assert (false);
+ return false;
}
- const std::string DOMAIN_SEPARATOR("@");
- const std::string PERIOD(".");
- const std::string UNDERSCORE("_");
- //
- // substituteString
- // Given a name string from an Acl rule, substitute the replacement into it
- // wherever the placeholder directs.
- //
- void AclData::substituteString(std::string& targetString,
- const std::string& placeholder,
- const std::string& replacement)
- {
- assert (!placeholder.empty());
- if (placeholder.empty())
- return;
- size_t start_pos(0);
- while((start_pos = targetString.find(placeholder, start_pos)) != std::string::npos)
- {
- targetString.replace(start_pos, placeholder.length(), replacement);
- start_pos += replacement.length();
- }
+ if (aclRuleValue == 0) {
+ QPID_LOG(debug, "ACL: Comparison is always true when ACL rule value is zero");
+ return true;
}
-
- //
- // normalizeUserId
- // Given a name string return it in a form usable as topic keys:
- // change "@" and "." to "_".
- //
- std::string AclData::normalizeUserId(const std::string& userId)
- {
- std::string normalId(userId);
- substituteString(normalId, DOMAIN_SEPARATOR, UNDERSCORE);
- substituteString(normalId, PERIOD, UNDERSCORE);
- return normalId;
+ try {
+ lookupValue = boost::lexical_cast<uint64_t>(theLookupValue);
}
-
-
- //
- // substituteUserId
- // Given an Acl rule and an authenticated userId
- // do the keyword substitutions on the rule.
- //
- void AclData::substituteUserId(std::string& ruleString,
- const std::string& userId)
- {
- size_t locDomSeparator(0);
- std::string user("");
- std::string domain("");
- std::string userdomain = normalizeUserId(userId);
-
- locDomSeparator = userId.find(DOMAIN_SEPARATOR);
- if (std::string::npos == locDomSeparator) {
- // "@" not found. There's just a user name
- user = normalizeUserId(userId);
- } else {
- // "@" found, split the names. Domain may be blank.
- user = normalizeUserId(userId.substr(0,locDomSeparator));
- domain = normalizeUserId(userId.substr(locDomSeparator+1));
- }
-
- substituteString(ruleString, ACL_KEYWORD_USER_SUBST, user);
- substituteString(ruleString, ACL_KEYWORD_DOMAIN_SUBST, domain);
- substituteString(ruleString, ACL_KEYWORD_USERDOMAIN_SUBST, userdomain);
+ catch(const boost::bad_lexical_cast&) {
+ QPID_LOG(error,"ACL: Illegal value given in lookup for property '"
+ << AclHelper::getPropertyStr(theProperty)
+ << "' : " << theLookupValue);
+ return false;
}
-
- //
- // substituteKeywords
- // Given an Acl rule and an authenticated userId
- // do reverse keyword substitutions on the rule.
- // That is, replace the normalized name in the rule string with
- // the keyword that represents it. This stragegy is used for
- // topic key lookups where the keyword string proper is in the
- // topic key search tree.
- //
- void AclData::substituteKeywords(std::string& ruleString,
- const std::string& userId)
- {
- size_t locDomSeparator(0);
- std::string user("");
- std::string domain("");
- std::string userdomain = normalizeUserId(userId);
-
- locDomSeparator = userId.find(DOMAIN_SEPARATOR);
- if (std::string::npos == locDomSeparator) {
- // "@" not found. There's just a user name
- user = normalizeUserId(userId);
- } else {
- // "@" found, split the names
- user = normalizeUserId(userId.substr(0,locDomSeparator));
- domain = normalizeUserId(userId.substr(locDomSeparator+1));
- }
- std::string oRule(ruleString);
- substituteString(ruleString, userdomain, ACL_KEYWORD_USERDOMAIN_SUBST);
- substituteString(ruleString, user, ACL_KEYWORD_USER_SUBST);
- substituteString(ruleString, domain, ACL_KEYWORD_DOMAIN_SUBST);
- }
+ bool result =
+ (theMaxFlag ? lookupValue > aclRuleValue : lookupValue < aclRuleValue);
+ if ( result ) {
+ QPID_LOG(debug, "ACL: Limit exceeded for property '"
+ << AclHelper::getPropertyStr(theProperty) << "'");
+ return false;
+ }
+
+ return true;
+}
+
+const std::string DOMAIN_SEPARATOR("@");
+const std::string PERIOD(".");
+const std::string UNDERSCORE("_");
+//
+// substituteString
+// Given a name string from an Acl rule, substitute the replacement into it
+// wherever the placeholder directs.
+//
+void AclData::substituteString(std::string& targetString,
+ const std::string& placeholder,
+ const std::string& replacement)
+{
+ assert (!placeholder.empty());
+ if (placeholder.empty()) {
+ return;
+ }
+ size_t start_pos(0);
+ while((start_pos = targetString.find(placeholder, start_pos)) != std::string::npos) {
+ targetString.replace(start_pos, placeholder.length(), replacement);
+ start_pos += replacement.length();
+ }
+}
+
+
+//
+// normalizeUserId
+// Given a name string return it in a form usable as topic keys:
+// change "@" and "." to "_".
+//
+std::string AclData::normalizeUserId(const std::string& userId)
+{
+ std::string normalId(userId);
+ substituteString(normalId, DOMAIN_SEPARATOR, UNDERSCORE);
+ substituteString(normalId, PERIOD, UNDERSCORE);
+ return normalId;
+}
+
+
+//
+// substituteUserId
+// Given an Acl rule and an authenticated userId
+// do the keyword substitutions on the rule.
+//
+void AclData::substituteUserId(std::string& ruleString,
+ const std::string& userId)
+{
+ size_t locDomSeparator(0);
+ std::string user("");
+ std::string domain("");
+ std::string userdomain = normalizeUserId(userId);
+
+ locDomSeparator = userId.find(DOMAIN_SEPARATOR);
+ if (std::string::npos == locDomSeparator) {
+ // "@" not found. There's just a user name
+ user = normalizeUserId(userId);
+ } else {
+ // "@" found, split the names. Domain may be blank.
+ user = normalizeUserId(userId.substr(0,locDomSeparator));
+ domain = normalizeUserId(userId.substr(locDomSeparator+1));
+ }
+
+ substituteString(ruleString, ACL_KEYWORD_USER_SUBST, user);
+ substituteString(ruleString, ACL_KEYWORD_DOMAIN_SUBST, domain);
+ substituteString(ruleString, ACL_KEYWORD_USERDOMAIN_SUBST, userdomain);
+}
+
+
+//
+// substituteKeywords
+// Given an Acl rule and an authenticated userId
+// do reverse keyword substitutions on the rule.
+// That is, replace the normalized name in the rule string with
+// the keyword that represents it. This stragegy is used for
+// topic key lookups where the keyword string proper is in the
+// topic key search tree.
+//
+void AclData::substituteKeywords(std::string& ruleString,
+ const std::string& userId)
+{
+ size_t locDomSeparator(0);
+ std::string user("");
+ std::string domain("");
+ std::string userdomain = normalizeUserId(userId);
+
+ locDomSeparator = userId.find(DOMAIN_SEPARATOR);
+ if (std::string::npos == locDomSeparator) {
+ // "@" not found. There's just a user name
+ user = normalizeUserId(userId);
+ } else {
+ // "@" found, split the names
+ user = normalizeUserId(userId.substr(0,locDomSeparator));
+ domain = normalizeUserId(userId.substr(locDomSeparator+1));
+ }
+ std::string oRule(ruleString);
+ substituteString(ruleString, userdomain, ACL_KEYWORD_USERDOMAIN_SUBST);
+ substituteString(ruleString, user, ACL_KEYWORD_USER_SUBST);
+ substituteString(ruleString, domain, ACL_KEYWORD_DOMAIN_SUBST);
+}
}}
Modified: qpid/trunk/qpid/cpp/src/qpid/acl/AclData.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/acl/AclData.h?rev=1497827&r1=1497826&r2=1497827&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/acl/AclData.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/acl/AclData.h Fri Jun 28 16:11:55 2013
@@ -205,6 +205,20 @@ public:
private:
+ inline bool lookupMatchRule(
+ const ruleSetItr& rsItr,
+ const std::string& id,
+ const std::string& name,
+ const std::map<Property, std::string>* params,
+ AclResult& aclresult);
+
+ inline bool lookupMatchPublishExchangeRule(
+ const ruleSetItr& rsItr,
+ const std::string& id,
+ const std::string& name,
+ const std::string& routingKey,
+ AclResult& aclresult);
+
bool compareInt(const qpid::acl::SpecProperty theProperty,
const std::string theAclValue,
const std::string theLookupValue,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org