Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.

Bug 522506

Summary: ACL issue - binding allowed to a queue when it should be denied
Product: Red Hat Enterprise MRG Reporter: Issue Tracker <tao>
Component: qpid-cppAssignee: Rajith Attapattu <rattapat+nobody>
Status: CLOSED ERRATA QA Contact: Frantisek Reznicek <freznice>
Severity: medium Docs Contact:
Priority: high    
Version: 1.1CC: esammons, freznice, gsim, iboverma, lbrindle, mcressma, ppecka, tao
Target Milestone: 1.2   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2009-12-03 09:18:20 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 527551    
Attachments:
Description Flags
the issue reproducer
none
repro with default allow rule
none
repro with default deny rule (succeeds) none

Description Issue Tracker 2009-09-10 14:52:47 UTC
Escalated to Bugzilla from IssueTracker

Comment 1 Issue Tracker 2009-09-10 14:52:49 UTC
Event posted on 09-09-2009 09:10am EDT by rrajaram

Description of problem:

ACL allows binding to a queue to which access should be denied. e.g.

ACL:
acl deny tester@QPID all queue name=baz
acl allow tester@QPID bind exchange name=foo queuename=bar routingkey=foo.bar

The following command succeed and it shouldn't
qpid-config -a baclo/baclo@localhost bind foo baz foo.bar

I believe this is because SessionAdapter::ExchangeHandlerImpl::bind is not checking either queueName or routingKey. I.e.
   AclModule* acl = getBroker().getAcl();
   if (acl) {
       if (!acl->authorise(getConnection().getUserId(),acl::ACT_BIND,acl::OBJ_EXCHANGE,exchangeName,routingKey) )

should read:
   AclModule* acl = getBroker().getAcl();
   if (acl) {
       std::map<acl::Property, std::string> params;
       params.insert(make_pair(acl::PROP_QUEUENAME, queueName));
       params.insert(make_pair(acl::PROP_ROUTINGKEY, routingKey));
       if (!acl->authorise(getConnection().getUserId(),acl::ACT_BIND,acl::OBJ_EXCHANGE,exchangeName,&params) )

NOTE:
This problem has already been reported at Apache under issue Id QPID-2063

How reproducible:
Always

Steps to Reproduce:

1. Create ACL for deny binding for a Q

Actual results:

ACL which has been set does not deny the binding

Expected results:

ACL which has been set should deny the binding

Additional info:

https://issues.apache.org/jira/browse/QPID-2063
This event sent from IssueTracker by mcressma  [SEG - MRG]
 issue 340290

Comment 3 Rajith Attapattu 2009-09-11 23:36:44 UTC
Applied patch from Tim at rev 813850 (trunk) and I also added test cases at the same rev.

Comment 5 Frantisek Reznicek 2009-10-19 13:42:03 UTC
Created attachment 365238 [details]
the issue reproducer

The bash issue reproducer on latest packages

Comment 6 Frantisek Reznicek 2009-10-19 13:54:13 UTC
The above comment is reproducer I used to prove it fails on latest packages:
  python-qpid-0.5.752581-3.el5
  qpid*-0.5.752581-28.el5
  qpid-java-client-0.5.751061-9.el5
  qpid-java-common-0.5.751061-9.el5
  rhm-0.5.3206-14.el5

The problem description is confusing in many ways, so let me try to rephrase it more clever way:

There is the ACL problem inside the MRG broker which allows binding creation between the exchange (foo) and queue (bar, baz) even in the case there is restricted access to the queue (baz).

ACL file:
acl deny tester@QPID all queue name=baz
acl allow tester@QPID bind exchange name=foo queuename=bar routingkey=foo.bar
acl allow all all

The second line is dead one, but having it there just for keeping the ACL as close as possible to the original one.

Restarting broker with above acl loaded passes fine.

The binding action is done via qpid-config

qpid-config -a tester/tp@localhost bind foo baz foo.bar
qpid-config -a tester/tp@localhost bind foo bar foo.bar

Both commands succeed with exit code 0 and binding is done:
Queue 'bar'
    bind [bar] => ''
    bind [foo.bar] => foo
Queue 'baz'
    bind [baz] => ''
    bind [foo.bar] => foo

This behavior is not correct in my eyes.

I believe the ACL above should block the command:
qpid-config -a tester/tp@localhost bind foo baz foo.bar
and let the other one succeed.

Let me know if my understanding is correct.

I'm moving this issue back to ASSIGNED with NEEDINFO from anyone.

P.S. Reproducer in above post accepts no argument, just make sure all qpidd instances are killed.

Comment 7 Rajith Attapattu 2009-10-20 17:12:14 UTC
Frantisek my bad for not explaining this clearly.

I have tested the packages in the candidate repo and it works as expected. Here is an easy way to test.

Use the following ACL file.

acl allow guest@QPID bind exchange name=foo queuename=bar routingkey=foo.bar
acl deny all all

Then modify the queue_declare.py (which comes with the example) as follows.
#session.queue_declare(queue="message_queue")  --> comment this line
session.exchange_bind(exchange="foo", queue="baz", binding_key="foo.bar")

This should fail with ACL exception

session.exchange_bind(exchange="foo", queue="bar", binding_key="foo.bar")
You will see the ACL pass but will fail due to queue is not around.

To test it the other way around.
acl deny guest@QPID bind exchange name=foo queuename=baz routingkey=foo.bar
acl allow all all

session.exchange_bind(exchange="foo", queue="baz", binding_key="foo.bar")
Should fail with ACL exception

session.exchange_bind(exchange="foo", queue="bar", binding_key="foo.bar")
Should fail with queue not found exception

Also if you turn the trace on for the broker you should be able to see how the broker is interpreting the rules.
Here is an example rule.

2009-oct-20 12:51:20 debug ACL: Lookup for id:guest@QPID action:bind objectType:exchange name:foo with params { routingkey=foo.bar queuename=bar }
2009-oct-20 12:51:20 debug ACL: checking the following rules for : guest@QPID
2009-oct-20 12:51:20 debug ACL: checking rule [log=0, logOnly=0 props{ name=foo routingkey=foo.bar queuename=bar }]
2009-oct-20 12:51:20 debug ACL: name 'foo' matched with name 'foo' given in the rule
2009-oct-20 12:51:20 debug ACL: the pair(routingkey,foo.bar) given in lookup matched the pair(routingkey,foo.bar) given in the rule
2009-oct-20 12:51:20 debug ACL: the pair(queuename,bar) given in lookup matched the pair(queuename,bar) given in the rule
2009-oct-20 12:51:20 debug Successful match, the decision is:deny
2009-oct-20 12:51:20 debug Exception constructed: ACL denied exchange bind request from guest@QPID (qpid/broker/SessionAdapter.cpp:175)
2009-oct-20 12:51:20 error Execution exception: not-allowed: ACL denied exchange bind request from guest@QPID (qpid/broker/SessionAdapter.cpp:175)
2009-oct-20 12:51:20 trace SENT [127.0.0.1:37695]: Frame[BEbe; channel=1; {ExecutionExceptionBody: error-code=530; command-id=0; class-code=7; command-code=4; field-index=0; description=not-allowed: ACL denied exchange bind request from guest@QPID (qpid/broker/SessionAdapter.cpp:175); error-info={};

Comment 8 Frantisek Reznicek 2009-10-21 14:45:34 UTC
Hello Rajith,
sorry to bother you again with broker ACL, but I need to claim that is is not working, because of following situation:

A] The BZ522506 points out that echange-queue binding should be denied if all queue operations are denied, even if binding echange-queue is explicitly allowed.

So my question is why qpidd acl plugin allows binding exchange foo and queue baz?, if ACL looks like this:
  acl deny tester@QPID all queue name=baz
  acl allow tester@QPID bind exchange name=foo queuename=baz routingkey=foo.bar
  acl allow all all

(Second rule is indeed dead one)


[root@ibm-firefly bz522506]# bash bz522506.sh
tester@QPID
starting the broker
tcp        0      0 0.0.0.0:5672                0.0.0.0:*                   LISTEN      23488/qpidd
create Qs and E
.creation passed
Listing queues
Queue Name                                     Attributes
======================================================================
bar
baz
reply-ibm-firefly.rhts.bos.redhat.com.23518.1  auto-del excl
topic-ibm-firefly.rhts.bos.redhat.com.23518.1  auto-del excl
Listing exchanges
Type      Exchange Name    Attributes
==================================================
direct
topic     qpid.management
direct    amq.direct       --durable
topic     amq.topic        --durable
fanout    amq.fanout       --durable
headers   amq.match        --durable
direct    foo
Performing bind foo baz foo.bar
.0
ERROR:Expecting failure
Performing bind foo bar foo.bar
.0
Q&E Summary:
Queue 'bar'
    bind [bar] => ''
    bind [foo.bar] => foo
Queue 'baz'
    bind [baz] => ''
    bind [foo.bar] => foo
Queue 'reply-ibm-firefly.rhts.bos.redhat.com.23542.1'
    bind [reply-ibm-firefly.rhts.bos.redhat.com.23542.1] => ''
    bind [reply-ibm-firefly.rhts.bos.redhat.com.23542.1] => amq.direct
Queue 'topic-ibm-firefly.rhts.bos.redhat.com.23542.1'
    bind [topic-ibm-firefly.rhts.bos.redhat.com.23542.1] => ''
    bind [schema.#] => qpid.management
    bind [console.obj.*.*.org.apache.qpid.broker.agent] => qpid.management
Stopping broker
.finished (dur:15sec[s], failures:1)
[root@ibm-firefly bz522506]# cat a.acl
acl deny tester@QPID all queue name=baz
acl allow tester@QPID bind exchange name=foo queuename=baz routingkey=foo.bar
acl allow all all


2009-oct-21 10:31:29 notice Read ACL file "/root/bz/bz522506/a.acl"
2009-oct-21 10:31:29 debug Group list: 0 groups found:
2009-oct-21 10:31:29 debug Name list: 2 names found:
2009-oct-21 10:31:29 debug  * tester@QPID
2009-oct-21 10:31:29 debug Rule list: 3 ACL rules found:
2009-oct-21 10:31:29 debug    0 deny [tester@QPID] * queue name=baz
2009-oct-21 10:31:29 debug    1 allow [tester@QPID] bind exchange name=foo routingkey=foo.bar queuename=baz
2009-oct-21 10:31:29 debug    2 allow [*] *
2009-oct-21 10:31:29 debug ACL Load Rules
2009-oct-21 10:31:29 debug ACL Processing  3 allow [*] *
2009-oct-21 10:31:29 debug ACL FoundMode allow
2009-oct-21 10:31:29 debug ACL Processing  2 allow [tester@QPID] bind exchange name=foo routingkey=foo.bar queuename=baz
2009-oct-21 10:31:29 debug ACL Skipping based on Mode:allow
2009-oct-21 10:31:29 debug ACL Processing  1 deny [tester@QPID] * queue name=baz
2009-oct-21 10:31:29 debug ACL: Adding actions {consume,publish,create,access,bind,unbind,delete,purge,update} to objects {queue} with props { name=baz } for users {tester@QPID}
2009-oct-21 10:31:29 info ACL Plugin loaded
...
2009-oct-21 10:31:40 debug ACL: Lookup for id:tester@QPID action:bind objectType:exchange name:foo with params { routingkey=foo.bar queuename=baz }
2009-oct-21 10:31:40 debug No successful match, defaulting to the decision mode allow





B] Now to the case you mentioned:
ACL:
acl allow tester@QPID bind exchange name=foo queuename=bar routingkey=foo.bar
acl deny all all

This is indeed other case which is similar. In my understanding all binding operations should be denied because of the fact that all accesses to the queues are denied. That's also what I can see which is in contrary what you stated there (you said there are two different exception thrown for binding foo-bar and foo-baz)

[root@ibm-firefly bz522506]# bash bz522506_mod1.sh
tester@QPID
starting the broker
tcp        0      0 0.0.0.0:5672                0.0.0.0:*                   LISTEN      23561/qpidd
create Qs and E
.creation passed
Listing queues
Queue Name                                     Attributes
======================================================================
reply-ibm-firefly.rhts.bos.redhat.com.23579.1  auto-del excl
topic-ibm-firefly.rhts.bos.redhat.com.23579.1  auto-del excl
Listing exchanges
Type      Exchange Name    Attributes
==================================================
direct
topic     qpid.management
direct    amq.direct       --durable
topic     amq.topic        --durable
fanout    amq.fanout       --durable
headers   amq.match        --durable
direct    foo
Performing bind foo baz foo.bar
Failed: SessionException - exception(error_code=530, command_id=serial(0), class_code=8, command_code=1, field_index=0, description=u'not-allowed: ACL denied queue create request from tester@QPID (qpid/broker/SessionAdapter.cpp:342)', error_info={})
.1
Performing bind foo bar foo.bar
Failed: SessionException - exception(error_code=530, command_id=serial(0), class_code=8, command_code=1, field_index=0, description=u'not-allowed: ACL denied queue create request from tester@QPID (qpid/broker/SessionAdapter.cpp:342)', error_info={})
.1
Q&E Summary:
Queue 'reply-ibm-firefly.rhts.bos.redhat.com.23599.1'
    bind [reply-ibm-firefly.rhts.bos.redhat.com.23599.1] => ''
    bind [reply-ibm-firefly.rhts.bos.redhat.com.23599.1] => amq.direct
Queue 'topic-ibm-firefly.rhts.bos.redhat.com.23599.1'
    bind [topic-ibm-firefly.rhts.bos.redhat.com.23599.1] => ''
    bind [schema.#] => qpid.management
    bind [console.obj.*.*.org.apache.qpid.broker.agent] => qpid.management
Stopping broker
.finished (dur:11sec[s], failures:0)
[root@ibm-firefly bz522506]# cat a.acl
acl allow tester@QPID bind exchange name=foo queuename=bar routingkey=foo.bar
acl allow guest@QPID all all
acl deny all all

Comment 9 Frantisek Reznicek 2009-10-21 14:46:33 UTC
Created attachment 365518 [details]
repro with default allow rule

Comment 10 Frantisek Reznicek 2009-10-21 14:47:12 UTC
Created attachment 365519 [details]
repro with default deny rule (succeeds)

Comment 11 Frantisek Reznicek 2009-10-21 16:12:32 UTC
The issue has been fixed, validated on RHEL 4.8 / 5.4 i386 / x86_64 on packages:

[root@mrg-qe-02 bz522506]# rpm -qa | grep qpid | sort -u
python-qpid-0.5.758389-2.el5
qpidc-0.5.752581-29.el5
qpidc-debuginfo-0.5.752581-29.el5
qpidc-devel-0.5.752581-29.el5
qpidc-perftest-0.5.752581-29.el5
qpidc-rdma-0.5.752581-29.el5
qpidc-ssl-0.5.752581-29.el5
qpidd-0.5.752581-29.el5
qpidd-acl-0.5.752581-29.el5
qpidd-cluster-0.5.752581-29.el5
qpidd-devel-0.5.752581-29.el5
qpid-dotnet-0.4.738274-2.el5
qpidd-rdma-0.5.752581-29.el5
qpidd-ssl-0.5.752581-29.el5
qpidd-xml-0.5.752581-29.el5
qpid-java-client-0.5.751061-9.el5
qpid-java-common-0.5.751061-9.el5


-> VERIFIED

Comment 13 Irina Boverman 2009-10-28 17:40:23 UTC
Release note added. If any revisions are required, please set the 
"requires_release_notes" flag to "?" and edit the "Release Notes" field accordingly.
All revisions will be proofread by the Engineering Content Services team.

New Contents:
Corrected problem allowing ACL binding to a queue to which access should be denied (522506)

Comment 14 Lana Brindley 2009-11-24 03:23:37 UTC
Release note updated. If any revisions are required, please set the 
"requires_release_notes"  flag to "?" and edit the "Release Notes" field accordingly.
All revisions will be proofread by the Engineering Content Services team.

Diffed Contents:
@@ -1 +1,8 @@
-Corrected problem allowing ACL binding to a queue to which access should be denied (522506)+Messaging bug fix.
+
+C: Creating an access control list (ACL) to be bound to queue that it does not have access to, should result in the access being denied.
+C: Access is not denied
+F:
+R:
+
+NEED FURTHER INFO FOR RELNOTE.

Comment 15 Rajith Attapattu 2009-11-24 17:04:41 UTC
The JIRA itself is very descriptive. Therefore I don't think we need any specific release notes for this issue. Hence I am deleting the release note text.

Comment 16 Rajith Attapattu 2009-11-24 17:04:41 UTC
Deleted Release Notes Contents.

Old Contents:
Messaging bug fix.

C: Creating an access control list (ACL) to be bound to queue that it does not have access to, should result in the access being denied.
C: Access is not denied
F:
R:

NEED FURTHER INFO FOR RELNOTE.

Comment 18 errata-xmlrpc 2009-12-03 09:18:20 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHEA-2009-1633.html