This is part of an occasional series of small blog posts where I (Morag) will write about some of the quirks in IBM MQ, in the hope of invoking the response, "Well, I didn't know that!" Read other posts in this series.
As mentioned in last months blog post, the authorization requirement in IBM MQ for z/OS, for put and for get are the same. The following RACF permission would allow user GEMUSER to both put and get to the queue called DEV.QUEUE on queue manager MQG1.
PERMIT MQG1.DEV.QUEUE CLASS(MQQUEUE) ID(GEMUSER) ACCESS(UPDATE)
So what can you do if you need to authorize a user to be able to put to a queue but not get from it?
A common example for such a thing might be the queue manager defined Dead-Letter queue. Common advice for that queue is to make sure that pretty much anyone can put to it (so that authorization failures can at least go on the DLQ and not stop the channel), but to lock down securely who can get from it so that it is only the user ID that runs the Dead-Letter handler.
Given the above, how can I possibly separate the two? That is exactly what this blog post is going to answer.
Before we look at security, let's first take a look at the behaviour of alias queues. Below I have two definitions. A local queue that is enabled for put and an alias queue pointing at it which is disabled for put.
DEFINE QLOCAL(DEV.QUEUE.1) PUT(ENABLED)
DEFINE QALIAS(DEV.QUEUE.1.NOPUT) PUT(DISABLED)
If my application does an MQOPEN of DEV.QUEUE.1, it will be able to put messages, but if it does an MQOPEN of DEV.QUEUE.1.NOPUT it will fail with MQRC_PUT_INHIBITED when it tries to put messages.
If we switch things around and have the local queue disabled for put and the alias queue enabled for put, like this:
DEFINE QLOCAL(DEV.QUEUE.2) PUT(DISABLED)
DEFINE QALIAS(DEV.QUEUE.2.PUT) PUT(ENABLED)
The alias queue does not over-ride the base local queue. Regardless of which queue my application does an MQOPEN of, it will fail with MQRC_PUT_INHIBITED when it tries to put messages.
So if I want to allow people to put and get using aliases targeting my local queue, the local queue must be enabled for both.
Security on Alias Queues
Another part of the puzzle is when you realise that the authority check in IBM MQ is done on the named queue. So if I have an application that does an MQOPEN for an alias queue name, at no point will the authorities set up for the local queue be checked. Only the authorities for the alias queue that my application specifically named will be checked - even though the queue will resolve to that local queue.
Separate put and get authorities on IBM MQ for z/OS
So it is possible to set up separate put and get authorities on IBM MQ for z/OS by setting up two alias queues which provide a portal into the local queue, thus:
DEFINE QLOCAL(DEV.QUEUE) PUT(ENABLED) GET(ENABLED)
DEFINE QALIAS(DEV.QUEUE.PUT) TARGET(DEV.QUEUE) PUT(ENABLED) GET(DISABLED)
DEFINE QALIAS(DEV.QUEUE.GET) TARGET(DEV.QUEUE) PUT(DISABLED) GET(ENABLED)
and then to set up your authorities, so that no-one needs access to the local queue directly. Profiles are put in place for each of the alias queues, and users granted access to the appropriate alias queue name depending on whether they need put access or get access.
PERMIT MQG1.DEV.QUEUE.PUT CLASS(MQQUEUE) ID(PUTUSER) ACCESS(UPDATE)
PERMIT MQG1.DEV.QUEUE.GET CLASS(MQQUEUE) ID(GETUSER) ACCESS(UPDATE)
Of course, if you do have users that need access to both, you can also set up profiles on the base local queue and use that too as shown at the start of the post.
So, now you know how to separate authorities in IBM MQ for z/OS when you need to have some applications able to put to a queue but not get from it. While the authorities model does not allow for it directly, the use of appropriately defined alias queues let you set up exactly what you need.
#mquirks #IBMMQ #ChampionsCorner