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 2012/08/24 17:24:07 UTC
svn commit: r1376961 - in /qpid/trunk/qpid/cpp/src: ./ qpid/acl/
qpid/broker/ tests/
Author: chug
Date: Fri Aug 24 15:24:07 2012
New Revision: 1376961
URL: http://svn.apache.org/viewvc?rev=1376961&view=rev
Log:
QPID-2393 Limit number of queues per user.
Merge work from branches/qpid-2393
This scheme works for old HA as long as cluster members run with the same --max-queues-per-user setting.
Added:
qpid/trunk/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp
- copied unchanged from r1376954, qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp
qpid/trunk/qpid/cpp/src/qpid/acl/AclResourceCounter.h
- copied unchanged from r1376954, qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.h
Modified:
qpid/trunk/qpid/cpp/src/CMakeLists.txt (contents, props changed)
qpid/trunk/qpid/cpp/src/acl.mk
qpid/trunk/qpid/cpp/src/qpid/acl/Acl.cpp
qpid/trunk/qpid/cpp/src/qpid/acl/Acl.h
qpid/trunk/qpid/cpp/src/qpid/acl/AclPlugin.cpp
qpid/trunk/qpid/cpp/src/qpid/acl/management-schema.xml
qpid/trunk/qpid/cpp/src/qpid/broker/AclModule.h
qpid/trunk/qpid/cpp/src/qpid/broker/Broker.cpp
qpid/trunk/qpid/cpp/src/tests/acl.py
qpid/trunk/qpid/cpp/src/tests/run_acl_tests
Modified: qpid/trunk/qpid/cpp/src/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/CMakeLists.txt?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/CMakeLists.txt (original)
+++ qpid/trunk/qpid/cpp/src/CMakeLists.txt Fri Aug 24 15:24:07 2012
@@ -600,6 +600,8 @@ if (BUILD_ACL)
qpid/acl/AclPlugin.cpp
qpid/acl/AclReader.cpp
qpid/acl/AclReader.h
+ qpid/acl/AclResourceCounter.cpp
+ qpid/acl/AclResourceCounter.h
qpid/acl/AclValidator.cpp
qpid/acl/AclValidator.h
)
Propchange: qpid/trunk/qpid/cpp/src/CMakeLists.txt
------------------------------------------------------------------------------
Merged /qpid/branches/qpid-2393/qpid/cpp/src/CMakeLists.txt:r1375790-1376954
Modified: qpid/trunk/qpid/cpp/src/acl.mk
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/acl.mk?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/acl.mk (original)
+++ qpid/trunk/qpid/cpp/src/acl.mk Fri Aug 24 15:24:07 2012
@@ -31,6 +31,8 @@ acl_la_SOURCES = \
qpid/acl/AclPlugin.cpp \
qpid/acl/AclReader.cpp \
qpid/acl/AclReader.h \
+ qpid/acl/AclResourceCounter.cpp \
+ qpid/acl/AclResourceCounter.h \
qpid/acl/AclValidator.cpp \
qpid/acl/AclValidator.h
Modified: qpid/trunk/qpid/cpp/src/qpid/acl/Acl.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/acl/Acl.cpp?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/acl/Acl.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/acl/Acl.cpp Fri Aug 24 15:24:07 2012
@@ -18,6 +18,7 @@
#include "qpid/acl/Acl.h"
#include "qpid/acl/AclConnectionCounter.h"
+#include "qpid/acl/AclResourceCounter.h"
#include "qpid/acl/AclData.h"
#include "qpid/acl/AclValidator.h"
#include "qpid/sys/Mutex.h"
@@ -32,6 +33,7 @@
#include "qmf/org/apache/qpid/acl/Package.h"
#include "qmf/org/apache/qpid/acl/EventAllow.h"
#include "qmf/org/apache/qpid/acl/EventConnectionDeny.h"
+#include "qmf/org/apache/qpid/acl/EventQueueQuotaDeny.h"
#include "qmf/org/apache/qpid/acl/EventDeny.h"
#include "qmf/org/apache/qpid/acl/EventFileLoaded.h"
#include "qmf/org/apache/qpid/acl/EventFileLoadFailed.h"
@@ -51,8 +53,8 @@ using qpid::management::Args;
namespace _qmf = qmf::org::apache::qpid::acl;
Acl::Acl (AclValues& av, Broker& b): aclValues(av), broker(&b), transferAcl(false), mgmtObject(0),
- connectionCounter(new ConnectionCounter(*this, aclValues.aclMaxConnectPerUser, aclValues.aclMaxConnectPerIp, aclValues.aclMaxConnectTotal))
-{
+ connectionCounter(new ConnectionCounter(*this, aclValues.aclMaxConnectPerUser, aclValues.aclMaxConnectPerIp, aclValues.aclMaxConnectTotal)),
+ resourceCounter(new ResourceCounter(*this, aclValues.aclMaxQueuesPerUser)){
agent = broker->getManagementAgent();
@@ -63,6 +65,7 @@ Acl::Acl (AclValues& av, Broker& b): acl
mgmtObject->set_maxConnections(aclValues.aclMaxConnectTotal);
mgmtObject->set_maxConnectionsPerIp(aclValues.aclMaxConnectPerIp);
mgmtObject->set_maxConnectionsPerUser(aclValues.aclMaxConnectPerUser);
+ mgmtObject->set_maxQueuesPerUser(aclValues.aclMaxQueuesPerUser);
}
std::string errorString;
if (!readAclFile(errorString)){
@@ -84,6 +87,15 @@ void Acl::reportConnectLimit(const std::
}
+void Acl::reportQueueLimit(const std::string user, const std::string queueName)
+{
+ if (mgmtObject!=0)
+ mgmtObject->inc_queueQuotaDenyCount();
+
+ agent->raiseEvent(_qmf::EventQueueQuotaDeny(user, queueName));
+}
+
+
bool Acl::authorise(
const std::string& id,
const Action& action,
@@ -136,6 +148,18 @@ void Acl::setUserId(const qpid::broker::
}
+bool Acl::approveCreateQueue(const std::string& userId, const std::string& queueName)
+{
+ return resourceCounter->approveCreateQueue(userId, queueName);
+}
+
+
+void Acl::recordDestroyQueue(const std::string& queueName)
+{
+ resourceCounter->recordDestroyQueue(queueName);
+}
+
+
bool Acl::result(
const AclResult& aclreslt,
const std::string& id,
Modified: qpid/trunk/qpid/cpp/src/qpid/acl/Acl.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/acl/Acl.h?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/acl/Acl.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/acl/Acl.h Fri Aug 24 15:24:07 2012
@@ -43,12 +43,14 @@ class Connection;
namespace acl {
class ConnectionCounter;
+class ResourceCounter;
struct AclValues {
std::string aclFile;
uint16_t aclMaxConnectPerUser;
uint16_t aclMaxConnectPerIp;
uint16_t aclMaxConnectTotal;
+ uint16_t aclMaxQueuesPerUser;
};
@@ -64,6 +66,7 @@ private:
qpid::management::ManagementAgent* agent;
mutable qpid::sys::Mutex dataLock;
boost::shared_ptr<ConnectionCounter> connectionCounter;
+ boost::shared_ptr<ResourceCounter> resourceCounter;
public:
Acl (AclValues& av, broker::Broker& b);
@@ -72,6 +75,7 @@ public:
* issue management counts and alerts for denied connections
*/
void reportConnectLimit(const std::string user, const std::string addr);
+ void reportQueueLimit(const std::string user, const std::string queueName);
inline virtual bool doTransferAcl() {
return transferAcl;
@@ -92,9 +96,11 @@ public:
const std::string& ExchangeName,
const std::string& RoutingKey);
+ // Resource quota tracking
virtual bool approveConnection(const broker::Connection& connection);
-
virtual void setUserId(const broker::Connection& connection, const std::string& username);
+ virtual bool approveCreateQueue(const std::string& userId, const std::string& queueName);
+ virtual void recordDestroyQueue(const std::string& queueName);
virtual ~Acl();
private:
Modified: qpid/trunk/qpid/cpp/src/qpid/acl/AclPlugin.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/acl/AclPlugin.cpp?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/acl/AclPlugin.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/acl/AclPlugin.cpp Fri Aug 24 15:24:07 2012
@@ -45,6 +45,7 @@ struct AclOptions : public Options {
("max-connections" , optValue(values.aclMaxConnectTotal, "N"), "The maximum combined number of connections allowed. 0 implies no limit.")
("max-connections-per-user", optValue(values.aclMaxConnectPerUser, "N"), "The maximum number of connections allowed per user. 0 implies no limit.")
("max-connections-per-ip" , optValue(values.aclMaxConnectPerIp, "N"), "The maximum number of connections allowed per host IP address. 0 implies no limit.")
+ ("max-queues-per-user", optValue(values.aclMaxQueuesPerUser, "N"), "The maximum number of queues allowed per user. 0 implies no limit.")
;
}
};
Modified: qpid/trunk/qpid/cpp/src/qpid/acl/management-schema.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/acl/management-schema.xml?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/acl/management-schema.xml (original)
+++ qpid/trunk/qpid/cpp/src/qpid/acl/management-schema.xml Fri Aug 24 15:24:07 2012
@@ -25,8 +25,10 @@
<property name="maxConnections" type="uint16" access="RO" desc="Maximum allowed connections"/>
<property name="maxConnectionsPerIp" type="uint16" access="RO" desc="Maximum allowed connections"/>
<property name="maxConnectionsPerUser" type="uint16" access="RO" desc="Maximum allowed connections"/>
+ <property name="maxQueuesPerUser" type="uint16" access="RO" desc="Maximum allowed queues"/>
<statistic name="aclDenyCount" type="count64" unit="request" desc="Number of ACL requests denied"/>
<statistic name="connectionDenyCount" type="count64" unit="connection" desc="Number of connections denied"/>
+ <statistic name="queueQuotaDenyCount" type="count64" unit="connection" desc="Number of queue creations denied"/>
<method name="reloadACLFile" desc="Reload the ACL file"/>
@@ -70,11 +72,13 @@
<arg name="reason" type="lstr"/>
<arg name="userId" type="sstr"/>
<arg name="clientAddr" type="sstr"/>
+ <arg name="queueName" type="sstr"/>
</eventArguments>
<event name="allow" sev="inform" args="userId, action, objectType, objectName, arguments"/>
<event name="deny" sev="notice" args="userId, action, objectType, objectName, arguments"/>
<event name="connectionDeny" sev="notice" args="userId, clientAddr"/>
+ <event name="queueQuotaDeny" sev="notice" args="userId, queueName"/>
<event name="fileLoaded" sev="inform" args="userId"/>
<event name="fileLoadFailed" sev="error" args="userId, reason"/>
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/AclModule.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/AclModule.h?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/AclModule.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/AclModule.h Fri Aug 24 15:24:07 2012
@@ -151,6 +151,11 @@ namespace broker {
*/
virtual void setUserId(const Connection& connection, const std::string& username)=0;
+ /** Approve queue creation by counting per-user.
+ */
+ virtual bool approveCreateQueue(const std::string& userId, const std::string& queueName)=0;
+ virtual void recordDestroyQueue(const std::string& queueName)=0;
+
virtual ~AclModule() {};
};
} // namespace broker
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/Broker.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/Broker.cpp?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/Broker.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/Broker.cpp Fri Aug 24 15:24:07 2012
@@ -1072,6 +1072,9 @@ std::pair<boost::shared_ptr<Queue>, bool
if (!acl->authorise(userId,acl::ACT_CREATE,acl::OBJ_QUEUE,name,¶ms) )
throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue create request from " << userId));
+
+ if (!acl->approveCreateQueue(userId,name) )
+ throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue create request from " << userId));
}
Exchange::shared_ptr alternate;
@@ -1116,6 +1119,8 @@ void Broker::deleteQueue(const std::stri
Queue::shared_ptr queue = queues.find(name);
if (queue) {
if (check) check(queue);
+ if (acl)
+ acl->recordDestroyQueue(name);
queues.destroy(name);
queue->destroyed();
} else {
Modified: qpid/trunk/qpid/cpp/src/tests/acl.py
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/acl.py?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/acl.py (original)
+++ qpid/trunk/qpid/cpp/src/tests/acl.py Fri Aug 24 15:24:07 2012
@@ -53,6 +53,9 @@ class ACLTests(TestBase010):
def port_u(self):
return int(self.defines["port-u"])
+ def port_q(self):
+ return int(self.defines["port-q"])
+
def get_session_by_port(self, user, passwd, byPort):
socket = connect(self.broker.host, byPort)
connection = Connection (sock=socket, username=user, password=passwd,
@@ -2243,6 +2246,62 @@ class ACLTests(TestBase010):
self.LookupPublish("joe@QPID", "QPID-work", "QPID", "allow")
self.LookupPublish("joe@QPID", "QPID-work2", "QPID", "allow")
+ #=====================================
+ # Queue per-user quota
+ #=====================================
+
+ def test_queue_per_user_quota(self):
+ """
+ Test ACL queue counting limits.
+ port_q has a limit of 2
+ """
+ # bob should be able to create two queues
+ session = self.get_session_by_port('bob','bob', self.port_q())
+
+ try:
+ session.queue_declare(queue="queue1")
+ session.queue_declare(queue="queue2")
+ except qpid.session.SessionException, e:
+ self.fail("Error during queue create request");
+
+ # third queue should fail
+ try:
+ session.queue_declare(queue="queue3")
+ self.fail("Should not be able to create third queue")
+ except Exception, e:
+ result = None
+ session = self.get_session_by_port('bob','bob', self.port_q())
+
+ # alice should be able to create two queues
+ session2 = self.get_session_by_port('alice','alice', self.port_q())
+
+ try:
+ session2.queue_declare(queue="queuea1")
+ session2.queue_declare(queue="queuea2")
+ except qpid.session.SessionException, e:
+ self.fail("Error during queue create request");
+
+ # third queue should fail
+ try:
+ session2.queue_declare(queue="queuea3")
+ self.fail("Should not be able to create third queue")
+ except Exception, e:
+ result = None
+ session2 = self.get_session_by_port('alice','alice', self.port_q())
+
+ # bob should be able to delete a queue and create another
+ try:
+ session.queue_delete(queue="queue1")
+ session.queue_declare(queue="queue3")
+ except qpid.session.SessionException, e:
+ self.fail("Error during queue create request");
+
+ # alice should be able to delete a queue and create another
+ try:
+ session2.queue_delete(queue="queuea1")
+ session2.queue_declare(queue="queuea3")
+ except qpid.session.SessionException, e:
+ self.fail("Error during queue create request");
class BrokerAdmin:
def __init__(self, broker, username=None, password=None):
Modified: qpid/trunk/qpid/cpp/src/tests/run_acl_tests
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/run_acl_tests?rev=1376961&r1=1376960&r2=1376961&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/run_acl_tests (original)
+++ qpid/trunk/qpid/cpp/src/tests/run_acl_tests Fri Aug 24 15:24:07 2012
@@ -24,22 +24,26 @@ source ./test_env.sh
DATA_DIR=`pwd`/data_dir
DATA_DIRI=`pwd`/data_diri
DATA_DIRU=`pwd`/data_diru
+DATA_DIRQ=`pwd`/data_dirq
trap stop_brokers INT TERM QUIT
start_brokers() {
- ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIR --load-module $ACL_LIB --acl-file policy.acl --auth no --log-to-file local.log > qpidd.port
+ ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIR --load-module $ACL_LIB --acl-file policy.acl --auth no --log-to-file local.log > qpidd.port
LOCAL_PORT=`cat qpidd.port`
- ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRI --load-module $ACL_LIB --acl-file policy.acl --auth no --max-connections-per-ip 2 --log-to-file locali.log > qpiddi.port
+ ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRI --load-module $ACL_LIB --acl-file policy.acl --auth no --max-connections-per-ip 2 --log-to-file locali.log > qpiddi.port
LOCAL_PORTI=`cat qpiddi.port`
../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRU --load-module $ACL_LIB --acl-file policy.acl --auth no --max-connections-per-user 2 --log-to-file localu.log > qpiddu.port
LOCAL_PORTU=`cat qpiddu.port`
+ ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRQ --load-module $ACL_LIB --acl-file policy.acl --auth no --max-queues-per-user 2 --log-to-file localq.log > qpiddq.port
+ LOCAL_PORTQ=`cat qpiddq.port`
}
stop_brokers() {
$QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORT
$QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORTI
$QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORTU
+ $QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORTQ
}
test_loading_acl_from_absolute_path(){
@@ -59,20 +63,24 @@ if test -d ${PYTHON_DIR} ; then
rm -rf $DATA_DIR
rm -rf $DATA_DIRI
rm -rf $DATA_DIRU
+ rm -rf $DATA_DIRQ
mkdir -p $DATA_DIR
mkdir -p $DATA_DIRI
mkdir -p $DATA_DIRU
+ mkdir -p $DATA_DIRQ
cp $srcdir/policy.acl $DATA_DIR
cp $srcdir/policy.acl $DATA_DIRI
cp $srcdir/policy.acl $DATA_DIRU
+ cp $srcdir/policy.acl $DATA_DIRQ
start_brokers
- echo "Running acl tests using brokers on ports $LOCAL_PORT, $LOCAL_PORTI, and $LOCAL_PORTU"
- $QPID_PYTHON_TEST -b localhost:$LOCAL_PORT -m acl -Dport-i=$LOCAL_PORTI -Dport-u=$LOCAL_PORTU || EXITCODE=1
+ echo "Running acl tests using brokers on ports $LOCAL_PORT, $LOCAL_PORTI, $LOCAL_PORTU, and $LOCAL_PORTQ"
+ $QPID_PYTHON_TEST -b localhost:$LOCAL_PORT -m acl -Dport-i=$LOCAL_PORTI -Dport-u=$LOCAL_PORTU -Dport-q=$LOCAL_PORTQ || EXITCODE=1
stop_brokers || EXITCODE=1
test_loading_acl_from_absolute_path || EXITCODE=1
rm -rf $DATA_DIR
rm -rf $DATA_DIRI
rm -rf $DATA_DIRU
+ rm -rf $DATA_DIRQ
exit $EXITCODE
fi
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org