in src/qpid/acl/AclData.cpp [159:360]
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);
}
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_MAXPAGESLOWERLIMIT:
case acl::SPECPROP_MAXPAGESUPPERLIMIT:
lookupParamItr = params->find(PROP_MAXPAGES);
break;
case acl::SPECPROP_MAXPAGEFACTORLOWERLIMIT:
case acl::SPECPROP_MAXPAGEFACTORUPPERLIMIT:
lookupParamItr = params->find(PROP_MAXPAGEFACTOR);
break;
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:
case acl::SPECPROP_MAXPAGESUPPERLIMIT:
case acl::SPECPROP_MAXPAGEFACTORUPPERLIMIT:
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:
case acl::SPECPROP_MAXPAGESLOWERLIMIT:
case acl::SPECPROP_MAXPAGEFACTORLOWERLIMIT:
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));
} else {
// This rule did not match the requested lookup and
// does not contribute to an ACL decision.
}
return match;
}