9.13. ACL Lookup Query Methods
QMF methods are available to query the ACL Authorization interface.
The Broker must be started with the ACL file that you wish to query, and that ACL file must include sufficient permissions to allow the lookup operations:
# Catch 22: allow anonymous to access the lookup debug functions acl allow-log anonymous create queue acl allow-log anonymous all exchange name=qmf.* acl allow-log anonymous all exchange name=amq.direct acl allow-log anonymous all exchange name=qpid.management acl allow-log anonymous access method name=Lookup*
The QMF methods to query the ACL Authorization interface are
Lookup
and LookupPublish
.
The
Lookup
method is a general query for any action, object, and set of properties. The LookupPublish
method is the optimized, per-message fastpath query.
In both methods the result is one of:
allow
, deny
, allow-log
, or deny-log
.
Method: Lookup
Argument | Type | Direction |
---|---|---|
userId
|
long-string
|
I
|
action
|
long-string
|
I
|
object
|
long-string
|
I
|
objectName
|
long-string
|
I
|
propertyMap
|
field-table
|
I
|
result
|
long-string
|
O
|
Method: LookupPublish
Argument | Type | Direction |
---|---|---|
userId
|
long-string
|
I
|
exchangeName
|
long-string
|
I
|
routingKey
|
long-string
|
I
|
result
|
long-string
|
O
|
Management Properties and Statistics
The following properties and statistics have been added to reflect command line settings in effect and Acl quota denial activity.
Element | Type | Access | Description |
---|---|---|---|
maxConnections
|
uint16
|
ReadOnly
|
Maximum allowed connections
|
Element | Type | Access | Description |
---|---|---|---|
maxConnectionsPerIp
|
uint16
|
ReadOnly
|
Maximum allowed connections
|
maxConnectionsPerUser
|
uint16
|
ReadOnly
|
Maximum allowed connections
|
maxQueuesPerUser
|
uint16
|
ReadOnly
|
Maximum allowed queues
|
connectionDenyCount
|
uint64
| |
Number of connections denied
|
queueQuotaDenyCount
|
uint64
| |
Number of queue creations denied
|
Example
Procedure 9.1. ACL Lookup Example
To see a practical example, follow these steps.
- Start the broker using the example ACL file
acl-test-01-rules.acl
reproduced below, and withQPID_LOG_ENABLE=debug+:acl
. - Run the Python script
acl-test-01.py
. - Examine the Python program output and the broker log.
ACL File acl-test-01-rules.acl
# acl-test-rules-00.acl # 27-march-2012 group admins moe@COMPANY.COM \ larry@COMPANY.COM \ curly@COMPANY.COM \ shemp@COMPANY.COM group auditors aaudit@COMPANY.COM baudit@COMPANY.COM caudit@COMPANY.COM \ daudit@COMPANY.COM eaduit@COMPANY.COM eaudit@COMPANY.COM group tatunghosts tatung01@COMPANY.COM \ tatung02/x86.build.company.com@COMPANY.COM \ tatung03/x86.build.company.com@COMPANY.COM \ tatung04/x86.build.company.com@COMPANY.COM \ HTTP/tatung-test1.eng.company.com@COMPANY.COM group publishusers publish@COMPANY.COM x-pubs@COMPANY.COM # Admins: This should be the *only* group which ever gets "all" access # to anything. Everything/everyone else must not be as permissive acl allow-log admins all all # Catch 22: allow anonymous to access the lookup debug functions acl allow-log anonymous create queue acl allow-log anonymous all exchange name=qmf.* acl allow-log anonymous all exchange name=amq.direct acl allow-log anonymous all exchange name=qpid.management acl allow-log anonymous access method name=Lookup* acl allow all publish exchange name='' # Auditors acl allow-log auditors all exchange name=company.topic routingkey=private.audit.* # Tatung acl allow-log tatunghosts publish exchange name=company.topic routingkey=tatung.* acl allow-log tatunghosts publish exchange name=company.direct routingkey=tatung-service-queue # Publish acl allow-log publishusers create queue acl allow-log publishusers publish exchange name=qpid.management routingkey=broker acl allow-log publishusers publish exchange name=qmf.default.topic routingkey=* acl allow-log publishusers publish exchange name=qmf.default.direct routingkey=* # Consumers - everyone acl allow-log all bind exchange name=company.topic routingkey=tatung.* acl allow-log all bind exchange name=company.direct routingkey=tatung-service-queue acl allow-log all consume queue acl allow-log all access exchange acl allow-log all access queue acl allow-log all create queue name=tmp.* durable=false autodelete=true exclusive=true policytype=ring # All else is denied acl deny-log all all
Python Script acl-test-01.py
# acl-test-00.py # test driver for QPID-3918 lookup hooks. # # The broker is to use acl-test-00-rules.acl. # import sys import qpid import qmf totalLookups = 0 failLookups = 0 exitOnError = True # # Run a type 1 lookup # This is the general lookup # def Lookup(acl, userName, action, aclObj, aclObjName, propMap, expectedResult = ''): global totalLookups global failLookups totalLookups += 1 result = acl.Lookup(userName, action, aclObj, aclObjName, propMap) suffix = '' if (expectedResult != ''): if (result.result != expectedResult): failLookups += 1 suffix = ', [ERROR: Expected ' + expectedResult + "]" if (result.result is None): suffix = suffix + ', [' + result.text + ']' print 'Lookup : [name:', userName, ", action: ", action, ", object: ", aclObj, \ ", objName: '", aclObjName, "', properties: ", propMap, \ "], [Result: ", result.result, "]", suffix if (exitOnError and failLookups > 0): sys.exit() # # Run a type 2 lookup # This is a specific PUBLISH EXCHANGE ['user', 'exchangeName', 'routingKey'] lookup # def LookupPublish(acl, userName, exchName, keyName, expectedResult = ''): global totalLookups global failLookups totalLookups += 1 result = acl.LookupPublish(userName, exchName, keyName) suffix = '' if (expectedResult != ''): if (result.result != expectedResult): failLookups += 1 suffix = ', [ERROR: Expected ' + expectedResult + "]" if (result.result is None): suffix = suffix + ', [' + result.text + ']' print 'LookupPublish : [name:', userName, \ ", exchName: '", exchName, "', key: ", keyName, \ "], [Result: ", result.result, "]", suffix if (exitOnError and failLookups > 0): sys.exit() # # AllBut # # Given All names and some names we don't want, # return the All list with the targets removed # def AllBut(allList, removeList): tmpList = allList[:] for item in removeList: try: tmpList.remove(item) except Exception, e: print "ERROR in AllBut() \nallList = %s \nremoveList = %s \nerror = %s " \ % (allList, removeList, e) return tmpList # # Main # # Fire up a session and get the acl methods # from qmf.console import Session sess = Session() broker = sess.addBroker() acls = sess.getObjects(_class="acl", _package="org.apache.qpid.acl") acl = acls[0] # print acl.getMethods() # just to see the method names available # # define some group lists # g_admins = ['moe@COMPANY.COM', \ 'larry@COMPANY.COM', \ 'curly@COMPANY.COM', \ 'shemp@COMPANY.COM'] g_auditors = [ 'aaudit@COMPANY.COM','baudit@COMPANY.COM','caudit@COMPANY.COM', \ 'daudit@COMPANY.COM','eaduit@COMPANY.COM','eaudit@COMPANY.COM'] g_tatunghosts = ['tatung01@COMPANY.COM', \ 'tatung02/x86.build.company.com@COMPANY.COM', \ 'tatung03/x86.build.company.com@COMPANY.COM', \ 'tatung04/x86.build.company.com@COMPANY.COM', \ 'HTTP/tatung-test1.eng.company.com@COMPANY.COM'] g_publishusers = ['publish@COMPANY.COM', 'x-pubs@COMPANY.COM'] g_public = ['jpublic@COMPANY.COM', 'me@yahoo.com'] g_all = g_admins + g_auditors + g_tatunghosts + g_publishusers + g_public action_all = ['consume','publish','create','access','bind','unbind','delete','purge','update'] # # Run some tests # print '#' print '# admin' print '#' for u in g_admins: Lookup(acl, u, "create", "queue", "anything", {"durable":"true"}, "allow-log") print '#' print '# auditors' print '#' uInTest = g_auditors + g_admins uOutTest = AllBut(g_all, uInTest) for u in uInTest: LookupPublish(acl, u, "company.topic", "private.audit.This", "allow-log") for u in uInTest: for a in action_all: Lookup(acl, u, a, "exchange", "company.topic", {"routingkey":"private.audit.This"}, "allow-log") for u in uOutTest: LookupPublish(acl, u, "company.topic", "private.audit.This", "deny-log") Lookup(acl, u, "bind", "exchange", "company.topic", {"routingkey":"private.audit.This"}, "deny-log") print '#' print '# tatungs' print '#' uInTest = g_admins + g_tatunghosts uOutTest = AllBut(g_all, uInTest) for u in uInTest: LookupPublish(acl, u, "company.topic", "tatung.this2", "allow-log") LookupPublish(acl, u, "company.direct", "tatung-service-queue", "allow-log") for u in uOutTest: LookupPublish(acl, u, "company.topic", "tatung.this2", "deny-log") LookupPublish(acl, u, "company.direct", "tatung-service-queue", "deny-log") for u in uOutTest: for a in ["bind", "access"]: Lookup(acl, u, a, "exchange", "company.topic", {"routingkey":"tatung.this2"}, "allow-log") Lookup(acl, u, a, "exchange", "company.direct", {"routingkey":"tatung-service-queue"}, "allow-log") print '#' print '# publishusers' print '#' uInTest = g_admins + g_publishusers uOutTest = AllBut(g_all, uInTest) for u in uInTest: LookupPublish(acl, u, "qpid.management", "broker", "allow-log") LookupPublish(acl, u, "qmf.default.topic", "this3", "allow-log") LookupPublish(acl, u, "qmf.default.direct", "this4", "allow-log") for u in uOutTest: LookupPublish(acl, u, "qpid.management", "broker", "deny-log") LookupPublish(acl, u, "qmf.default.topic", "this3", "deny-log") LookupPublish(acl, u, "qmf.default.direct", "this4", "deny-log") for u in uOutTest: for a in ["bind"]: Lookup(acl, u, a, "exchange", "qpid.management", {"routingkey":"broker"}, "deny-log") Lookup(acl, u, a, "exchange", "qmf.default.topic", {"routingkey":"this3"}, "deny-log") Lookup(acl, u, a, "exchange", "qmf.default.direct", {"routingkey":"this4"}, "deny-log") for a in ["access"]: Lookup(acl, u, a, "exchange", "qpid.management", {"routingkey":"broker"}, "allow-log") Lookup(acl, u, a, "exchange", "qmf.default.topic", {"routingkey":"this3"}, "allow-log") Lookup(acl, u, a, "exchange", "qmf.default.direct", {"routingkey":"this4"}, "allow-log") # # Report statistics # print 'Total Lookups: ', totalLookups print 'Failed Lookups: ', failLookups # # Close the session # sess.close()