diff options
-rw-r--r-- | cpp/src/qpid/acl/Acl.cpp | 28 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclData.cpp | 398 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclData.h | 56 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclReader.cpp | 6 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclReader.h | 15 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclValidator.cpp | 16 | ||||
-rw-r--r-- | cpp/src/qpid/acl/AclValidator.h | 6 | ||||
-rw-r--r-- | cpp/src/qpid/broker/AclModule.h | 138 | ||||
-rw-r--r-- | cpp/src/qpid/broker/ConnectionHandler.h | 1 | ||||
-rw-r--r-- | cpp/src/qpid/broker/SemanticState.h | 1 | ||||
-rwxr-xr-x | cpp/src/tests/acl.py | 212 |
11 files changed, 651 insertions, 226 deletions
diff --git a/cpp/src/qpid/acl/Acl.cpp b/cpp/src/qpid/acl/Acl.cpp index 7e7f8e4d49..a4cc24cc65 100644 --- a/cpp/src/qpid/acl/Acl.cpp +++ b/cpp/src/qpid/acl/Acl.cpp @@ -67,10 +67,10 @@ Acl::Acl (AclValues& av, Broker& b): aclValues(av), broker(&b), transferAcl(fals } bool Acl::authorise( - const std::string& id, - const Action& action, - const ObjectType& objType, - const std::string& name, + const std::string& id, + const Action& action, + const ObjectType& objType, + const std::string& name, std::map<Property, std::string>* params) { boost::shared_ptr<AclData> dataLocal; @@ -88,7 +88,7 @@ bool Acl::authorise( bool Acl::authorise( const std::string& id, - const Action& action, + const Action& action, const ObjectType& objType, const std::string& ExchangeName, const std::string& RoutingKey) @@ -107,10 +107,10 @@ bool Acl::authorise( bool Acl::result( - const AclResult& aclreslt, + const AclResult& aclreslt, const std::string& id, - const Action& action, - const ObjectType& objType, + const Action& action, + const ObjectType& objType, const std::string& name) { bool result(false); @@ -118,8 +118,10 @@ bool Acl::result( switch (aclreslt) { case ALLOWLOG: - QPID_LOG(info, "ACL Allow id:" << id <<" action:" << AclHelper::getActionStr(action) << - " ObjectType:" << AclHelper::getObjectTypeStr(objType) << " Name:" << name ); + QPID_LOG(info, "ACL Allow id:" << id + << " action:" << AclHelper::getActionStr(action) + << " ObjectType:" << AclHelper::getObjectTypeStr(objType) + << " Name:" << name ); agent->raiseEvent(_qmf::EventAllow(id, AclHelper::getActionStr(action), AclHelper::getObjectTypeStr(objType), name, types::Variant::Map())); @@ -129,8 +131,10 @@ bool Acl::result( break; case DENYLOG: - QPID_LOG(info, "ACL Deny id:" << id << " action:" << AclHelper::getActionStr(action) << - " ObjectType:" << AclHelper::getObjectTypeStr(objType) << " Name:" << name); + QPID_LOG(info, "ACL Deny id:" << id + << " action:" << AclHelper::getActionStr(action) + << " ObjectType:" << AclHelper::getObjectTypeStr(objType) + << " Name:" << name); agent->raiseEvent(_qmf::EventDeny(id, AclHelper::getActionStr(action), AclHelper::getObjectTypeStr(objType), name, types::Variant::Map())); diff --git a/cpp/src/qpid/acl/AclData.cpp b/cpp/src/qpid/acl/AclData.cpp index 96d9ef9c6e..30e4b67dcc 100644 --- a/cpp/src/qpid/acl/AclData.cpp +++ b/cpp/src/qpid/acl/AclData.cpp @@ -24,17 +24,30 @@ namespace qpid { namespace acl { - AclData::AclData():decisionMode(qpid::acl::DENY),transferAcl(false),aclSource("UNKNOWN") + // + // constructor + // + AclData::AclData(): + decisionMode(qpid::acl::DENY), + transferAcl(false), + aclSource("UNKNOWN") { - for (unsigned int cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++){ + 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 cnt=0; cnt< qpid::acl::ACTIONSIZE; cnt++) + { + if (actionList[cnt]) + { for (unsigned int cnt1=0; cnt1< qpid::acl::OBJECTSIZE; cnt1++) delete actionList[cnt][cnt1]; } @@ -42,23 +55,45 @@ namespace acl { } } - bool AclData::matchProp(const std::string & src, const std::string& src1) + + // + // matchProp + // + // Compare a rule's property name with a lookup name, + // The rule's name may contains a trailing '*' to specify a wildcard match. + // + bool AclData::matchProp(const std::string& ruleStr, + const std::string& lookupStr) { - // allow wildcard on the end of strings... - if (src.data()[src.size()-1]=='*') { - return (src.compare(0, src.size()-1, src1, 0,src.size()-1 ) == 0); - } else { - return (src.compare(src1)==0) ; + // allow wildcard on the end of rule strings... + if (ruleStr.data()[ruleStr.size()-1]=='*') + { + return ruleStr.compare(0, + ruleStr.size()-1, + lookupStr, + 0, + ruleStr.size()-1 ) == 0; + } + else + { + return ruleStr.compare(lookupStr) == 0; } } - AclResult AclData::lookup( - const std::string& id, - const Action& action, - const ObjectType& objType, - const std::string& name, - std::map<Property, std::string>* params) { + // + // 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) @@ -66,13 +101,15 @@ namespace acl { << " 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 } + // 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 and the Object + // 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 @@ -96,70 +133,118 @@ namespace acl { bool match = true; bool limitChecked = true; - // Iterate this rule's properties - for (propertyMapItr rulePropMapItr = rsItr->props.begin(); - (rulePropMapItr != rsItr->props.end()) && match; - rulePropMapItr++) + // 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 property map's NAME property is handled specially - if (rulePropMapItr->first == acl::PROP_NAME) + // 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) { if (matchProp(rulePropMapItr->second, name)) { QPID_LOG(debug, "ACL: lookup name '" << name - << "' matched with rule name '" << rulePropMapItr->second << "'"); + << "' matched with rule name '" + << rulePropMapItr->second << "'"); } else { match = false; QPID_LOG(debug, "ACL: lookup name '" << name - << "' didn't match with rule name '" << rulePropMapItr->second << "'"); + << "' didn't match with rule name '" + << rulePropMapItr->second << "'"); } } else { if (params) { - // The rule's property map non-NAME properties are - // to be found in the lookup's params list - propertyMapItr lookupParamItr = params->find(rulePropMapItr->first); + // 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; + + 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. + // 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) << "'"); + << AclHelper::getPropertyStr(rulePropMapItr->first) << "'"); } else { - if ( rulePropMapItr->first == acl::PROP_QUEUEMAXCOUNT || rulePropMapItr->first == acl::PROP_QUEUEMAXSIZE ) - { - assert ( rulePropMapItr->first == lookupParamItr->first ); - limitChecked &= compareIntMax(rulePropMapItr->first, - boost::lexical_cast<std::string>(rulePropMapItr->second), - boost::lexical_cast<std::string>(lookupParamItr->second)); - } - else + // Now account for the business of rules + // whose property indexes are mismatched. + switch (rulePropMapItr->first) { + case acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT: + case acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT: + limitChecked &= + compareIntMax( + rulePropMapItr->first, + boost::lexical_cast<std::string>(rulePropMapItr->second), + boost::lexical_cast<std::string>(lookupParamItr->second)); + break; + + case acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT: + case acl::SPECPROP_MAXQUEUESIZELOWERLIMIT: + limitChecked &= + compareIntMin( + rulePropMapItr->first, + boost::lexical_cast<std::string>(rulePropMapItr->second), + boost::lexical_cast<std::string>(lookupParamItr->second)); + break; + + default: if (matchProp(rulePropMapItr->second, lookupParamItr->second)) { QPID_LOG(debug, "ACL: the pair(" - << AclHelper::getPropertyStr(lookupParamItr->first) << "," << lookupParamItr->second + << AclHelper::getPropertyStr(lookupParamItr->first) + << "," << lookupParamItr->second << ") given in lookup matched the pair(" - << AclHelper::getPropertyStr(rulePropMapItr->first) << "," << rulePropMapItr->second + << 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 + << AclHelper::getPropertyStr(lookupParamItr->first) + << "," << lookupParamItr->second << ") given in lookup doesn't match the pair(" - << AclHelper::getPropertyStr(rulePropMapItr->first) << "," << rulePropMapItr->second + << AclHelper::getPropertyStr(rulePropMapItr->first) + << "," << rulePropMapItr->second << ") given in the rule"); } - } + break; + }; } } else @@ -173,49 +258,67 @@ namespace acl { aclresult = rsItr->ruleMode; if (!limitChecked) { - // Now a lookup matched all rule properties but one of the numeric - // limits has failed. This has the effect of demoting an allow to a deny. - if (aclresult == acl::ALLOW) - { - aclresult = acl::DENY; - } - else + // 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) { - if (aclresult == acl::ALLOWLOG) - { - aclresult = acl::DENYLOG; - } - } + 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)); + QPID_LOG(debug,"ACL: Successful match, the decision is:" + << AclHelper::getAclResultStr(aclresult)); return aclresult; } else { - // this rule did not match the requested lookup + // 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 *. + // The Action-Object list has entries but not for this actorId + // nor for *. } } else { - // The Action-Object list has no entries + // The Action-Object list has no entries. } - QPID_LOG(debug,"ACL: No successful match, defaulting to the decision mode " << AclHelper::getAclResultStr(aclresult)); + QPID_LOG(debug,"ACL: No successful match, defaulting to the decision mode " + << AclHelper::getAclResultStr(aclresult)); return aclresult; } - AclResult AclData::lookup(const std::string& id, const Action& action, const ObjectType& objType, - const std::string& /*Exchange*/ name, const std::string& RoutingKey) + + // + // 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& /*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 + 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; @@ -226,89 +329,126 @@ namespace acl { if (itrRule == actionList[action][objType]->end()) itrRule = actionList[action][objType]->find("*"); - if (itrRule != actionList[action][objType]->end() ) { - + if (itrRule != actionList[action][objType]->end() ) + { //loop the vector ruleSetItr rsItr = itrRule->second.end(); - for (int cnt = itrRule->second.size(); cnt != 0; cnt--) { + for (int cnt = itrRule->second.size(); cnt != 0; cnt--) + { rsItr--; // loop the names looking for match bool match =true; - for (propertyMapItr pMItr = rsItr->props.begin(); (pMItr != rsItr->props.end()) && match; pMItr++) + for (specPropertyMapItr pMItr = rsItr->props.begin(); + (pMItr != rsItr->props.end()) && match; + pMItr++) { //match name is exists first - if (pMItr->first == acl::PROP_NAME){ - if (matchProp(pMItr->second, name)){ - QPID_LOG(debug, "ACL: lookup exchange name '" << name << "' matched with rule name '" + switch (pMItr->first) + { + case acl::SPECPROP_NAME: + if (matchProp(pMItr->second, name)) + { + QPID_LOG(debug, "ACL: lookup exchange name '" + << name << "' matched with rule name '" << pMItr->second << "'"); - }else{ + } + else + { match= false; - QPID_LOG(debug, "ACL: lookup exchange name '" << name << "' didn't match with rule name '" + QPID_LOG(debug, "ACL: lookup exchange name '" + << name << "' did not match with rule name '" << pMItr->second << "'"); - } - }else if (pMItr->first == acl::PROP_ROUTINGKEY){ - if (matchProp(pMItr->second, RoutingKey)){ - QPID_LOG(debug, "ACL: lookup key name '" << name << "' matched with rule routing key '" + } + break; + + case acl::SPECPROP_ROUTINGKEY: + if (matchProp(pMItr->second, RoutingKey)) + { + QPID_LOG(debug, "ACL: lookup key name '" + << name << "' matched with rule routing key '" << pMItr->second << "'"); - }else{ + } + else + { match= false; - QPID_LOG(debug, "ACL: lookup key name '" << name << "' didn't match with routing key '" + QPID_LOG(debug, "ACL: lookup key name '" + << name << "' did not match with rule routing key '" << pMItr->second << "'"); - } - } + } + break; + + default: + // Don't care + break; + }; } if (match){ aclresult = rsItr->ruleMode; - QPID_LOG(debug,"ACL: Successful match, the decision is:" << AclHelper::getAclResultStr(aclresult)); + QPID_LOG(debug,"ACL: Successful match, the decision is:" + << AclHelper::getAclResultStr(aclresult)); return aclresult; } } } } - QPID_LOG(debug,"ACL: No successful match, defaulting to the decision mode " << AclHelper::getAclResultStr(aclresult)); + QPID_LOG(debug,"ACL: No successful match, defaulting to the decision mode " + << AclHelper::getAclResultStr(aclresult)); return aclresult; } + // + // + // AclData::~AclData() { clear(); } - bool AclData::compareIntMax(const qpid::acl::Property theProperty, - const std::string theAclValue, - const std::string theLookupValue) { + + // + // Limit check a MAX int limit + // + bool AclData::compareIntMax(const qpid::acl::SpecProperty theProperty, + const std::string theAclValue, + const std::string theLookupValue) + { uint64_t aclMax (0); uint64_t paramMax (0); - try { + try + { aclMax = boost::lexical_cast<uint64_t>(theAclValue); - } catch(const boost::bad_lexical_cast&) { + } + catch(const boost::bad_lexical_cast&) + { assert (false); return false; } - try { + try + { paramMax = boost::lexical_cast<uint64_t>(theLookupValue); - } catch(const boost::bad_lexical_cast&) { - QPID_LOG(error,"ACL: Error evaluating rule. " << - "Illegal value given in lookup for property '" << - AclHelper::getPropertyStr(theProperty) << "' : " << - theLookupValue); + } + catch(const boost::bad_lexical_cast&) + { + QPID_LOG(error,"ACL: Error evaluating rule. " + << "Illegal value given in lookup for property '" + << AclHelper::getPropertyStr(theProperty) + << "' : " << theLookupValue); return false; } - QPID_LOG(debug, "ACL: Numeric comparison for property " << - AclHelper::getPropertyStr(theProperty) << - " (value given in lookup = " << - theLookupValue << - ", value give in rule = " << - theAclValue << " )"); + QPID_LOG(debug, "ACL: Numeric greater-than comparison for property " + << AclHelper::getPropertyStr(theProperty) + << " (value given in lookup = " << theLookupValue + << ", value give in rule = " << theAclValue << " )"); - if (( aclMax ) && ( paramMax == 0 || paramMax > aclMax)){ + if (( aclMax ) && ( paramMax == 0 || paramMax > aclMax)) + { QPID_LOG(debug, "ACL: Max limit exceeded for property '" << AclHelper::getPropertyStr(theProperty) << "'"); return false; @@ -316,4 +456,54 @@ namespace acl { return true; } + + + // + // limit check a MIN int limit + // + bool AclData::compareIntMin(const qpid::acl::SpecProperty theProperty, + const std::string theAclValue, + const std::string theLookupValue) + { + uint64_t aclMin (0); + uint64_t paramMin (0); + + try + { + aclMin = boost::lexical_cast<uint64_t>(theAclValue); + } + catch(const boost::bad_lexical_cast&) + { + assert (false); + return false; + } + + try + { + paramMin = boost::lexical_cast<uint64_t>(theLookupValue); + } + catch(const boost::bad_lexical_cast&) + { + QPID_LOG(error,"ACL: Error evaluating rule. " + << "Illegal value given in lookup for property '" + << AclHelper::getPropertyStr(theProperty) + << "' : " << theLookupValue); + return false; + } + + QPID_LOG(debug, "ACL: Numeric less-than comparison for property " + << AclHelper::getPropertyStr(theProperty) + << " (value given in lookup = " << theLookupValue + << ", value give in rule = " << theAclValue << " )"); + + if (( aclMin ) && ( paramMin == 0 || paramMin < aclMin)) + { + QPID_LOG(debug, "ACL: Min limit exceeded for property '" + << AclHelper::getPropertyStr(theProperty) << "'"); + return false; + } + + return true; + } + }} diff --git a/cpp/src/qpid/acl/AclData.h b/cpp/src/qpid/acl/AclData.h index 7757fac0db..751062817b 100644 --- a/cpp/src/qpid/acl/AclData.h +++ b/cpp/src/qpid/acl/AclData.h @@ -34,15 +34,28 @@ public: typedef std::map<qpid::acl::Property, std::string> propertyMap; typedef propertyMap::const_iterator propertyMapItr; - + + typedef std::map<qpid::acl::SpecProperty, std::string> specPropertyMap; + typedef specPropertyMap::const_iterator specPropertyMapItr; + + // + // rule + // + // Created by AclReader and stored in a ruleSet vector for subsequent + // run-time lookup matching and allow/deny decisions. + // RuleSet vectors are indexed by Action-Object-actorId so these + // attributes are not part of a rule. + // A single ACL file entry may create many rule entries in + // many ruleset vectors. + // struct rule { int rawRuleNum; // rule number in ACL file qpid::acl::AclResult ruleMode; // combined allow/deny log/nolog - propertyMap props; + specPropertyMap props; // - rule (int ruleNum, qpid::acl::AclResult res, propertyMap& p) : + rule (int ruleNum, qpid::acl::AclResult res, specPropertyMap& p) : rawRuleNum(ruleNum), ruleMode(res), props(p) @@ -53,13 +66,18 @@ public: ruleStr << "[rule " << rawRuleNum << " ruleMode = " << AclHelper::getAclResultStr(ruleMode) << " props{"; - for (propertyMapItr pMItr = props.begin(); pMItr != props.end(); pMItr++) { - ruleStr << " " << AclHelper::getPropertyStr((Property) pMItr-> first) << "=" << pMItr->second; + for (specPropertyMapItr pMItr = props.begin(); + pMItr != props.end(); + pMItr++) { + ruleStr << " " + << AclHelper::getPropertyStr((SpecProperty) pMItr-> first) + << "=" << pMItr->second; } ruleStr << " }]"; return ruleStr.str(); } }; + typedef std::vector<rule> ruleSet; typedef ruleSet::const_iterator ruleSetItr; typedef std::map<std::string, ruleSet > actionObject; // user @@ -73,18 +91,18 @@ public: std::string aclSource; AclResult lookup( - const std::string& id, - const Action& action, - const ObjectType& objType, - const std::string& name, + const std::string& id, // actor id + const Action& action, + const ObjectType& objType, + const std::string& name, // object name std::map<Property, std::string>* params=0); AclResult lookup( - const std::string& id, - const Action& action, - const ObjectType& objType, - const std::string& ExchangeName, - const std::string& RoutingKey); + const std::string& id, // actor id + const Action& action, + const ObjectType& objType, + const std::string& ExchangeName, + const std::string& RoutingKey); bool matchProp(const std::string & src, const std::string& src1); void clear (); @@ -93,9 +111,13 @@ public: virtual ~AclData(); private: - bool compareIntMax(const qpid::acl::Property theProperty, - const std::string theAclValue, - const std::string theLookupValue); + bool compareIntMax(const qpid::acl::SpecProperty theProperty, + const std::string theAclValue, + const std::string theLookupValue); + + bool compareIntMin(const qpid::acl::SpecProperty theProperty, + const std::string theAclValue, + const std::string theLookupValue); }; }} // namespace qpid::acl diff --git a/cpp/src/qpid/acl/AclReader.cpp b/cpp/src/qpid/acl/AclReader.cpp index 48c25b7757..80debf1bd1 100644 --- a/cpp/src/qpid/acl/AclReader.cpp +++ b/cpp/src/qpid/acl/AclReader.cpp @@ -49,7 +49,7 @@ namespace acl { objStatus = ALL; } - bool AclReader::aclRule::addProperty(const Property p, const std::string v) { + bool AclReader::aclRule::addProperty(const SpecProperty p, const std::string v) { return props.insert(propNvPair(p, v)).second; } @@ -463,9 +463,9 @@ namespace acl { << propNvp.first << "\". (Must be name=value)"; return false; } - Property prop; + SpecProperty prop; try { - prop = AclHelper::getProperty(propNvp.first); + prop = AclHelper::getSpecProperty(propNvp.first); } catch (...) { errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber << ", Unknown property \"" << propNvp.first << "\"."; diff --git a/cpp/src/qpid/acl/AclReader.h b/cpp/src/qpid/acl/AclReader.h index 7b1df079eb..beeedf953a 100644 --- a/cpp/src/qpid/acl/AclReader.h +++ b/cpp/src/qpid/acl/AclReader.h @@ -42,10 +42,15 @@ class AclReader { typedef groupMap::const_iterator gmCitr; typedef std::pair<gmCitr, bool> gmRes; - typedef std::pair<Property, std::string> propNvPair; - typedef std::map<Property, std::string> propMap; - typedef propMap::const_iterator pmCitr; - + typedef std::pair<SpecProperty, std::string> propNvPair; + typedef std::map<SpecProperty, std::string> propMap; + typedef propMap::const_iterator pmCitr; + + // + // aclRule + // + // A temporary rule created during ACL file processing. + // class aclRule { public: enum objectStatus {NONE, VALUE, ALL}; @@ -62,7 +67,7 @@ class AclReader { aclRule(const AclResult r, const std::string n, const groupMap& groups, const Action a); void setObjectType(const ObjectType o); void setObjectTypeAll(); - bool addProperty(const Property p, const std::string v); + bool addProperty(const SpecProperty p, const std::string v); bool validate(const AclHelper::objectMapPtr& validationMap); std::string toString(); // debug aid private: diff --git a/cpp/src/qpid/acl/AclValidator.cpp b/cpp/src/qpid/acl/AclValidator.cpp index 2226623109..d9ce3734ea 100644 --- a/cpp/src/qpid/acl/AclValidator.cpp +++ b/cpp/src/qpid/acl/AclValidator.cpp @@ -78,17 +78,25 @@ namespace acl { } AclValidator::AclValidator(){ - validators.insert(Validator(acl::PROP_QUEUEMAXSIZE, + validators.insert(Validator(acl::SPECPROP_MAXQUEUESIZELOWERLIMIT, boost::shared_ptr<PropertyType>( new IntPropertyType(0,std::numeric_limits<int64_t>::max())))); - validators.insert(Validator(acl::PROP_QUEUEMAXCOUNT, + validators.insert(Validator(acl::SPECPROP_MAXQUEUESIZEUPPERLIMIT, boost::shared_ptr<PropertyType>( new IntPropertyType(0,std::numeric_limits<int64_t>::max())))); + validators.insert(Validator(acl::SPECPROP_MAXQUEUECOUNTLOWERLIMIT, + boost::shared_ptr<PropertyType>( + new IntPropertyType(0,std::numeric_limits<int64_t>::max())))); + + validators.insert(Validator(acl::SPECPROP_MAXQUEUECOUNTUPPERLIMIT, + boost::shared_ptr<PropertyType>( + new IntPropertyType(0,std::numeric_limits<int64_t>::max())))); + std::string policyTypes[] = {"ring", "ring_strict", "flow_to_disk", "reject"}; std::vector<std::string> v(policyTypes, policyTypes + sizeof(policyTypes) / sizeof(std::string)); - validators.insert(Validator(acl::PROP_POLICYTYPE, + validators.insert(Validator(acl::SPECPROP_POLICYTYPE, boost::shared_ptr<PropertyType>( new EnumPropertyType(v)))); @@ -129,7 +137,7 @@ namespace acl { boost::bind(&AclValidator::validateProperty, this, _1)); } - void AclValidator::validateProperty(std::pair<const qpid::acl::Property, std::string>& prop){ + void AclValidator::validateProperty(std::pair<const qpid::acl::SpecProperty, std::string>& prop){ ValidatorItr itr = validators.find(prop.first); if (itr != validators.end()){ QPID_LOG(debug,"ACL: Found validator for property '" << acl::AclHelper::getPropertyStr(itr->first) diff --git a/cpp/src/qpid/acl/AclValidator.h b/cpp/src/qpid/acl/AclValidator.h index 966e5d326b..414f6181d2 100644 --- a/cpp/src/qpid/acl/AclValidator.h +++ b/cpp/src/qpid/acl/AclValidator.h @@ -62,8 +62,8 @@ class AclValidator { virtual std::string allowedValues(); }; - typedef std::pair<acl::Property,boost::shared_ptr<PropertyType> > Validator; - typedef std::map<acl::Property,boost::shared_ptr<PropertyType> > ValidatorMap; + typedef std::pair<acl::SpecProperty,boost::shared_ptr<PropertyType> > Validator; + typedef std::map<acl::SpecProperty,boost::shared_ptr<PropertyType> > ValidatorMap; typedef ValidatorMap::iterator ValidatorItr; ValidatorMap validators; @@ -72,7 +72,7 @@ public: void validateRuleSet(std::pair<const std::string, qpid::acl::AclData::ruleSet>& rules); void validateRule(qpid::acl::AclData::rule& rule); - void validateProperty(std::pair<const qpid::acl::Property, std::string>& prop); + void validateProperty(std::pair<const qpid::acl::SpecProperty, std::string>& prop); void validate(boost::shared_ptr<AclData> d); AclValidator(); ~AclValidator(); diff --git a/cpp/src/qpid/broker/AclModule.h b/cpp/src/qpid/broker/AclModule.h index ee6acae3d8..a168fe6f90 100644 --- a/cpp/src/qpid/broker/AclModule.h +++ b/cpp/src/qpid/broker/AclModule.h @@ -34,8 +34,9 @@ namespace acl { // Interface enumerations. // These enumerations define enum lists and implied text strings - // to match. They are used in two places: - // 1. In the ACL specifications in the ACL file. + // to match. They are used in two areas: + // 1. In the ACL specifications in the ACL file, file parsing, and + // internal rule storage. // 2. In the authorize interface in the rest of the broker where // code requests the ACL module to authorize an action. @@ -61,25 +62,7 @@ namespace acl { ACT_UPDATE, ACTIONSIZE }; // ACTIONSIZE must be last in list - // Property used in ACL spec file - enum SpecProperty { - SPECPROP_NAME, - SPECPROP_DURABLE, - SPECPROP_OWNER, - SPECPROP_ROUTINGKEY, - SPECPROP_PASSIVE, - SPECPROP_AUTODELETE, - SPECPROP_EXCLUSIVE, - SPECPROP_TYPE, - SPECPROP_ALTERNATE, - SPECPROP_QUEUENAME, - SPECPROP_SCHEMAPACKAGE, - SPECPROP_SCHEMACLASS, - SPECPROP_POLICYTYPE, - SPECPROP_MAXQUEUESIZE, - SPECPROP_MAXQUEUECOUNT }; - - // Property used in ACL authroize interface + // Property used in ACL authorize interface enum Property { PROP_NAME, PROP_DURABLE, @@ -94,10 +77,33 @@ namespace acl { PROP_SCHEMAPACKAGE, PROP_SCHEMACLASS, PROP_POLICYTYPE, - PROP_QUEUEMAXSIZE, - PROP_QUEUEMAXCOUNT }; + PROP_MAXQUEUESIZE, + PROP_MAXQUEUECOUNT }; - // AclResult shared between ACL spec and ACL authorise interface + // Property used in ACL spec file + // Note for properties common to file processing/rule storage and to + // broker rule lookups the identical enum values are used. + enum SpecProperty { + SPECPROP_NAME = PROP_NAME, + SPECPROP_DURABLE = PROP_DURABLE, + SPECPROP_OWNER = PROP_OWNER, + SPECPROP_ROUTINGKEY = PROP_ROUTINGKEY, + SPECPROP_PASSIVE = PROP_PASSIVE, + SPECPROP_AUTODELETE = PROP_AUTODELETE, + SPECPROP_EXCLUSIVE = PROP_EXCLUSIVE, + SPECPROP_TYPE = PROP_TYPE, + SPECPROP_ALTERNATE = PROP_ALTERNATE, + SPECPROP_QUEUENAME = PROP_QUEUENAME, + SPECPROP_SCHEMAPACKAGE = PROP_SCHEMAPACKAGE, + SPECPROP_SCHEMACLASS = PROP_SCHEMACLASS, + SPECPROP_POLICYTYPE = PROP_POLICYTYPE, + + SPECPROP_MAXQUEUESIZELOWERLIMIT, + SPECPROP_MAXQUEUESIZEUPPERLIMIT, + SPECPROP_MAXQUEUECOUNTLOWERLIMIT, + SPECPROP_MAXQUEUECOUNTUPPERLIMIT }; + +// AclResult shared between ACL spec and ACL authorise interface enum AclResult { ALLOW, ALLOWLOG, @@ -114,23 +120,25 @@ namespace broker { public: - // efficienty turn off ACL on message transfer. + // Some ACLs are invoked on every message transfer. + // doTransferAcl pervents time consuming ACL calls on a per-message basis. virtual bool doTransferAcl()=0; virtual bool authorise( - const std::string& id, - const acl::Action& action, - const acl::ObjectType& objType, - const std::string& name, + const std::string& id, + const acl::Action& action, + const acl::ObjectType& objType, + const std::string& name, std::map<acl::Property, std::string>* params=0)=0; virtual bool authorise( - const std::string& id, - const acl::Action& action, - const acl::ObjectType& objType, - const std::string& ExchangeName, - const std::string& RoutingKey)=0; - // create specilied authorise methods for cases that need faster matching as needed. + const std::string& id, + const acl::Action& action, + const acl::ObjectType& objType, + const std::string& ExchangeName, + const std::string& RoutingKey)=0; + + // Add specialized authorise() methods as required. virtual ~AclModule() {}; }; @@ -202,8 +210,8 @@ namespace acl { if (str.compare("schemapackage") == 0) return PROP_SCHEMAPACKAGE; if (str.compare("schemaclass") == 0) return PROP_SCHEMACLASS; if (str.compare("policytype") == 0) return PROP_POLICYTYPE; - if (str.compare("maxqueuesize") == 0) return PROP_QUEUEMAXSIZE; - if (str.compare("maxqueuecount") == 0) return PROP_QUEUEMAXCOUNT; + if (str.compare("maxqueuesize") == 0) return PROP_MAXQUEUESIZE; + if (str.compare("maxqueuecount") == 0) return PROP_MAXQUEUECOUNT; throw str; } static inline std::string getPropertyStr(const Property p) { @@ -221,8 +229,8 @@ namespace acl { case PROP_SCHEMAPACKAGE: return "schemapackage"; case PROP_SCHEMACLASS: return "schemaclass"; case PROP_POLICYTYPE: return "policytype"; - case PROP_QUEUEMAXSIZE: return "maxqueuesize"; - case PROP_QUEUEMAXCOUNT: return "maxqueuecount"; + case PROP_MAXQUEUESIZE: return "maxqueuesize"; + case PROP_MAXQUEUECOUNT: return "maxqueuecount"; default: assert(false); // should never get here } return ""; @@ -241,11 +249,16 @@ namespace acl { if (str.compare("schemapackage") == 0) return SPECPROP_SCHEMAPACKAGE; if (str.compare("schemaclass") == 0) return SPECPROP_SCHEMACLASS; if (str.compare("policytype") == 0) return SPECPROP_POLICYTYPE; - if (str.compare("queuemaxsize") == 0) return SPECPROP_MAXQUEUESIZE; - if (str.compare("queuemaxcount") == 0) return SPECPROP_MAXQUEUECOUNT; + if (str.compare("queuemaxsizelowerlimit") == 0) return SPECPROP_MAXQUEUESIZELOWERLIMIT; + if (str.compare("queuemaxsizeupperlimit") == 0) return SPECPROP_MAXQUEUESIZEUPPERLIMIT; + if (str.compare("queuemaxcountlowerlimit") == 0) return SPECPROP_MAXQUEUECOUNTLOWERLIMIT; + if (str.compare("queuemaxcountupperlimit") == 0) return SPECPROP_MAXQUEUECOUNTUPPERLIMIT; + // Allow old names in ACL file as aliases for newly-named properties + if (str.compare("maxqueuesize") == 0) return SPECPROP_MAXQUEUESIZEUPPERLIMIT; + if (str.compare("maxqueuecount") == 0) return SPECPROP_MAXQUEUECOUNTUPPERLIMIT; throw str; } - static inline std::string getSpecPropertyStr(const SpecProperty p) { + static inline std::string getPropertyStr(const SpecProperty p) { switch (p) { case SPECPROP_NAME: return "name"; case SPECPROP_DURABLE: return "durable"; @@ -260,8 +273,10 @@ namespace acl { case SPECPROP_SCHEMAPACKAGE: return "schemapackage"; case SPECPROP_SCHEMACLASS: return "schemaclass"; case SPECPROP_POLICYTYPE: return "policytype"; - case SPECPROP_MAXQUEUESIZE: return "queuemaxsize"; - case SPECPROP_MAXQUEUECOUNT: return "queuemaxcount"; + case SPECPROP_MAXQUEUESIZELOWERLIMIT: return "queuemaxsizelowerlimit"; + case SPECPROP_MAXQUEUESIZEUPPERLIMIT: return "queuemaxsizeupperlimit"; + case SPECPROP_MAXQUEUECOUNTLOWERLIMIT: return "queuemaxcountlowerlimit"; + case SPECPROP_MAXQUEUECOUNTUPPERLIMIT: return "queuemaxcountupperlimit"; default: assert(false); // should never get here } return ""; @@ -298,7 +313,8 @@ namespace acl { typedef std::map<SpecProperty, std::string> specPropMap; typedef specPropMap::const_iterator specPropMapItr; - // This map contains the legal combinations of object/action/properties found in an ACL file + // This map contains the legal combinations of object/action/properties + // found in an ACL file static void loadValidationMap(objectMapPtr& map) { if (!map.get()) return; map->clear(); @@ -339,8 +355,8 @@ namespace acl { p4->insert(PROP_EXCLUSIVE); p4->insert(PROP_AUTODELETE); p4->insert(PROP_POLICYTYPE); - p4->insert(PROP_QUEUEMAXSIZE); - p4->insert(PROP_QUEUEMAXCOUNT); + p4->insert(PROP_MAXQUEUESIZE); + p4->insert(PROP_MAXQUEUECOUNT); actionMapPtr a1(new actionMap); a1->insert(actionPair(ACT_ACCESS, p0)); @@ -370,32 +386,28 @@ namespace acl { map->insert(objectPair(OBJ_METHOD, a4)); } - static std::string propertyMapToString(const std::map<Property, std::string>* params) { + // + // properyMapToString + // + template <typename T> + static std::string propertyMapToString( + const std::map<T, std::string>* params) + { std::ostringstream ss; ss << "{"; if (params) { - for (propMapItr pMItr = params->begin(); pMItr != params->end(); pMItr++) { - ss << " " << getPropertyStr((Property) pMItr-> first) - << "=" << pMItr->second; - } - } - ss << " }"; - return ss.str(); - } - static std::string specPropertyMapToString(const std::map<SpecProperty, std::string>* params) { - std::ostringstream ss; - ss << "{"; - if (params) - { - for (specPropMapItr pMItr = params->begin(); pMItr != params->end(); pMItr++) { - ss << " " << getSpecPropertyStr((SpecProperty) pMItr-> first) + for (typename std::map<T, std::string>::const_iterator + pMItr = params->begin(); pMItr != params->end(); pMItr++) + { + ss << " " << getPropertyStr((T) pMItr-> first) << "=" << pMItr->second; } } ss << " }"; return ss.str(); } + }; diff --git a/cpp/src/qpid/broker/ConnectionHandler.h b/cpp/src/qpid/broker/ConnectionHandler.h index 05c5f00c57..2e25543308 100644 --- a/cpp/src/qpid/broker/ConnectionHandler.h +++ b/cpp/src/qpid/broker/ConnectionHandler.h @@ -35,7 +35,6 @@ #include "qpid/framing/ProtocolInitiation.h" #include "qpid/framing/ProtocolVersion.h" #include "qpid/Exception.h" -#include "qpid/broker/AclModule.h" #include "qpid/sys/SecurityLayer.h" diff --git a/cpp/src/qpid/broker/SemanticState.h b/cpp/src/qpid/broker/SemanticState.h index 5a83fd0fb3..f7c9760821 100644 --- a/cpp/src/qpid/broker/SemanticState.h +++ b/cpp/src/qpid/broker/SemanticState.h @@ -39,7 +39,6 @@ #include "qpid/sys/AggregateOutput.h" #include "qpid/sys/Mutex.h" #include "qpid/sys/AtomicValue.h" -#include "qpid/broker/AclModule.h" #include "qmf/org/apache/qpid/broker/Subscription.h" #include <list> diff --git a/cpp/src/tests/acl.py b/cpp/src/tests/acl.py index 601f216b52..5db3bfe85a 100755 --- a/cpp/src/tests/acl.py +++ b/cpp/src/tests/acl.py @@ -127,6 +127,30 @@ class ACLTests(TestBase010): self.fail("ACL should deny queue bind request"); except qpid.session.SessionException, e: self.assertEqual(403,e.args[0].error_code) + + + def test_allow_mode_with_specfic_allow_override(self): + """ + Specific allow overrides a general deny + """ + aclf = self.get_acl_file() + aclf.write('group admins bob@QPID joe@QPID \n') + aclf.write('acl allow bob@QPID create queue \n') + aclf.write('acl deny admins create queue \n') + aclf.write('acl allow all all') + aclf.close() + + result = self.reload_acl() + if (result.text.find("format error",0,len(result.text)) != -1): + self.fail(result) + + session = self.get_session('bob','bob') + + try: + session.queue_declare(queue='zed') + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow create queue request"); #===================================== @@ -179,7 +203,7 @@ class ACLTests(TestBase010): if (result.text.find("Non-continuation line must start with \"group\" or \"acl\"",0,len(result.text)) == -1): self.fail(result) - def test_llegal_extension_lines(self): + def test_illegal_extension_lines(self): """ Test proper extention lines """ @@ -255,18 +279,20 @@ class ACLTests(TestBase010): if (result.text != expected): self.fail(result) - def test_illegal_queue_size(self): + def test_illegal_queuemaxsize_upper_limit_spec(self): """ Test illegal queue policy """ - + # + # Use maxqueuesize + # aclf = self.get_acl_file() aclf.write('acl deny bob@QPID create queue name=q2 maxqueuesize=-1\n') aclf.write('acl allow all all') aclf.close() result = self.reload_acl() - expected = "-1 is not a valid value for 'maxqueuesize', " \ + expected = "-1 is not a valid value for 'queuemaxsizeupperlimit', " \ "values should be between 0 and 9223372036854775807"; if (result.text != expected): self.fail(result) @@ -277,24 +303,53 @@ class ACLTests(TestBase010): aclf.close() result = self.reload_acl() - expected = "9223372036854775808 is not a valid value for 'maxqueuesize', " \ + expected = "9223372036854775808 is not a valid value for 'queuemaxsizeupperlimit', " \ "values should be between 0 and 9223372036854775807"; if (result.text != expected): self.fail(result) + # + # Use queuemaxsizeupperlimit + # + aclf = self.get_acl_file() + aclf.write('acl deny bob@QPID create queue name=q2 queuemaxsizeupperlimit=-1\n') + aclf.write('acl allow all all') + aclf.close() + + result = self.reload_acl() + expected = "-1 is not a valid value for 'queuemaxsizeupperlimit', " \ + "values should be between 0 and 9223372036854775807"; + if (result.text != expected): + self.fail(result) - def test_illegal_queue_count(self): + aclf = self.get_acl_file() + aclf.write('acl deny bob@QPID create queue name=q2 queuemaxsizeupperlimit=9223372036854775808\n') + aclf.write('acl allow all all') + aclf.close() + + result = self.reload_acl() + expected = "9223372036854775808 is not a valid value for 'queuemaxsizeupperlimit', " \ + "values should be between 0 and 9223372036854775807"; + if (result.text != expected): + self.fail(result) + + + + def test_illegal_queuemaxcount_upper_limit_spec(self): """ Test illegal queue policy """ - + # + # Use maxqueuecount + # + aclf = self.get_acl_file() aclf.write('acl deny bob@QPID create queue name=q2 maxqueuecount=-1\n') aclf.write('acl allow all all') aclf.close() result = self.reload_acl() - expected = "-1 is not a valid value for 'maxqueuecount', " \ + expected = "-1 is not a valid value for 'queuemaxcountupperlimit', " \ "values should be between 0 and 9223372036854775807"; if (result.text != expected): self.fail(result) @@ -305,7 +360,88 @@ class ACLTests(TestBase010): aclf.close() result = self.reload_acl() - expected = "9223372036854775808 is not a valid value for 'maxqueuecount', " \ + expected = "9223372036854775808 is not a valid value for 'queuemaxcountupperlimit', " \ + "values should be between 0 and 9223372036854775807"; + if (result.text != expected): + self.fail(result) + + # + # use maxqueuecountupperlimit + # + aclf = self.get_acl_file() + aclf.write('acl deny bob@QPID create queue name=q2 queuemaxcountupperlimit=-1\n') + aclf.write('acl allow all all') + aclf.close() + + result = self.reload_acl() + expected = "-1 is not a valid value for 'queuemaxcountupperlimit', " \ + "values should be between 0 and 9223372036854775807"; + if (result.text != expected): + self.fail(result) + + aclf = self.get_acl_file() + aclf.write('acl deny bob@QPID create queue name=q2 queuemaxcountupperlimit=9223372036854775808\n') + aclf.write('acl allow all all') + aclf.close() + + result = self.reload_acl() + expected = "9223372036854775808 is not a valid value for 'queuemaxcountupperlimit', " \ + "values should be between 0 and 9223372036854775807"; + if (result.text != expected): + self.fail(result) + + + def test_illegal_queuemaxsize_lower_limit_spec(self): + """ + Test illegal queue policy + """ + aclf = self.get_acl_file() + aclf.write('acl deny bob@QPID create queue name=q2 queuemaxsizelowerlimit=-1\n') + aclf.write('acl allow all all') + aclf.close() + + result = self.reload_acl() + expected = "-1 is not a valid value for 'queuemaxsizelowerlimit', " \ + "values should be between 0 and 9223372036854775807"; + if (result.text != expected): + self.fail(result) + + aclf = self.get_acl_file() + aclf.write('acl deny bob@QPID create queue name=q2 queuemaxsizelowerlimit=9223372036854775808\n') + aclf.write('acl allow all all') + aclf.close() + + result = self.reload_acl() + expected = "9223372036854775808 is not a valid value for 'queuemaxsizelowerlimit', " \ + "values should be between 0 and 9223372036854775807"; + if (result.text != expected): + self.fail(result) + + + + def test_illegal_queuemaxcount_lower_limit_spec(self): + """ + Test illegal queue policy + """ + + aclf = self.get_acl_file() + aclf.write('acl deny bob@QPID create queue name=q2 queuemaxcountlowerlimit=-1\n') + aclf.write('acl allow all all') + aclf.close() + + result = self.reload_acl() + expected = "-1 is not a valid value for 'queuemaxcountlowerlimit', " \ + "values should be between 0 and 9223372036854775807"; + if (result.text != expected): + self.fail(result) + + aclf = self.get_acl_file() + aclf.write('acl deny bob@QPID create queue name=q2 queuemaxcountlowerlimit=9223372036854775808\n') + aclf.write('acl allow all all') + aclf.close() + + result = self.reload_acl() + expected = "9223372036854775808 is not a valid value for 'queuemaxcountlowerlimit', " \ "values should be between 0 and 9223372036854775807"; if (result.text != expected): self.fail(result) @@ -427,10 +563,11 @@ class ACLTests(TestBase010): aclf.write('acl allow bob@QPID create queue name=q2 exclusive=true policytype=ring\n') aclf.write('acl allow bob@QPID access queue name=q3\n') aclf.write('acl allow bob@QPID purge queue name=q3\n') - aclf.write('acl allow bob@QPID create queue name=q3\n') - aclf.write('acl allow bob@QPID create queue name=q4\n') - aclf.write('acl allow bob@QPID delete queue name=q4\n') - aclf.write('acl allow bob@QPID create queue name=q5 maxqueuesize=1000 maxqueuecount=100\n') + aclf.write('acl allow bob@QPID create queue name=q3\n') + aclf.write('acl allow bob@QPID create queue name=q4\n') + aclf.write('acl allow bob@QPID delete queue name=q4\n') + aclf.write('acl allow bob@QPID create queue name=q5 maxqueuesize=1000 maxqueuecount=100\n') + aclf.write('acl allow bob@QPID create queue name=q6 queuemaxsizelowerlimit=50 queuemaxsizeupperlimit=100 queuemaxcountlowerlimit=50 queuemaxcountupperlimit=100\n') aclf.write('acl allow anonymous all all\n') aclf.write('acl deny all all') aclf.close() @@ -482,6 +619,55 @@ class ACLTests(TestBase010): try: queue_options = {} + queue_options["qpid.max_count"] = 49 + queue_options["qpid.max_size"] = 100 + session.queue_declare(queue="q6", arguments=queue_options) + self.fail("ACL should deny queue create request with name=q6 maxqueuesize=100 maxqueuecount=49"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + queue_options = {} + queue_options["qpid.max_count"] = 101 + queue_options["qpid.max_size"] = 100 + session.queue_declare(queue="q6", arguments=queue_options) + self.fail("ACL should allow queue create request with name=q6 maxqueuesize=100 maxqueuecount=101"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + queue_options = {} + queue_options["qpid.max_count"] = 100 + queue_options["qpid.max_size"] = 49 + session.queue_declare(queue="q6", arguments=queue_options) + self.fail("ACL should deny queue create request with name=q6 maxqueuesize=49 maxqueuecount=100"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + queue_options = {} + queue_options["qpid.max_count"] = 100 + queue_options["qpid.max_size"] =101 + session.queue_declare(queue="q6", arguments=queue_options) + self.fail("ACL should deny queue create request with name=q6 maxqueuesize=101 maxqueuecount=100"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + queue_options = {} + queue_options["qpid.max_count"] = 50 + queue_options["qpid.max_size"] = 50 + session.queue_declare(queue="q6", arguments=queue_options) + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request with name=q6 maxqueuesize=50 maxqueuecount=50"); + + try: + queue_options = {} queue_options["qpid.policy_type"] = "ring" session.queue_declare(queue="q2", exclusive=True, arguments=queue_options) except qpid.session.SessionException, e: |