If you thought it was easy, I would disagree with you.
While investigating a security problem (why my code worked, when it should have got a not authorised return code) I struggled to answer questions like
- Is this user authorised to use this queue?
- I’ve remove the permission, but it still has it! Why?
- Which profile gave what access to the queue?
- Who is authorised to this queue?
- What security profiles are involved with this user and that queue.?
- Can I audit the list of people and their access to the queues beginning with CP?
There are links to my solutions for some of the problems.
Morag contacted me and said:
I wrote a little blog post about using DISPLAY ENTAUTH – hope it helps. See here:
Morag
What commands are there?
There are four MQ commands providing similar functions
- dspmqaut – displays the authorizations of a specific IBM® MQ object.
- dmpmqaut – dump a list of current authorizations for a range of IBM® MQ object types and profiles.
- dmpmqcfg – dump queue manager configuration.
- runmqsc dis authrec – display the authority records associated with a profile name. This can produce the output on one line, so making it much easier to have scripts to post process it. Ive written a small python script (see the end of the blog post) to make this data more usable.
- runmqsc dis entauth – display the authorizations an entity has to a specified object
Definition of terms
Profile name
This can be the name of a queue, or a string which is used for comparisons and can include single * or double **. For example
- PAYROLL for a particular queue,
- PAYROLL.*.INPUT, which would apply to objects PAYROLL.A.INPUT, PAYROLL.B.INPUT, but not PAYROLL.A.B.INPUT, nor PAYROLL.INPUT.
- PAYROLL.**.INPUT which would apply to PAYROLL.A.INPUT, PAYROLL.B.INPUT, PAYROLL.A.B.INPUT, but not PAYROLL.INPUT.
- ** used as a fall back if there are no other definitions.
Example profiles
- setmqaut -m QMA -n PAYROLL -t queue -g testuser +put
- setmqaut -m QMA -n ‘PAYROLL.*.INPUT’ -t queue -g testuser +put
- setmqaut -m QMA -n ‘PAYROLL.**.INPUT’ -t queue -g testuser +put
- setmqaut -m QMA -n ‘**’ -t queue -g MQAdmin +chg +dlt
On Unix you need the single quotes around any profile which includes *, to prevent the shell replacing it with a list of file names.
You need to be careful about quoting strings with mixed case data. dspmqaut and setmqaut do not need quoting. For runmqsc display|set authrec the mixed case fields need quoting.
A profile is created
- by the setmqaut command,
- the runmqsc set authrec command,
- when the object is created. In which case, the queue manager creates an entry for the mqm group, and for the principal group of the user that created the object. Userid ibmsys1 created a queue, and there were entries for group mqm, and group zpdt. These definitions have full access. (The userid that created a queue can put and get messages from the queue – and you cannot separate administration of the queue, and usage of the queue.)
Userid and group
Unix has the concept of User Private Groups (UPG). A userid can have a group with the same name as the userid, which makes the security just a touch more confusing.
You can use the id command to list which groups a userid is in
id ibmsys1
uid=1001(ibmsys1) gid=1006(zpdt) groups=1006(zpdt),27(sudo),1007(MQAdmin)
Userid ibmsys1 with numeric id 1001 is a member of 3 groups: zpdt, sudo and MQAdmin.
You can specify the authority to be given to a userid – but it looks like the userid is not used, but the default group is used! See Explicit giving a userid access – does not give the userid access. This could just be a Linux feature.
Displaying information.
dspmqaut -m QMA -n ‘PAYROLL.**.INPUT’ -t queue -g testuser
This lists the information for the group testuser and the profile PAYROLL.**.INPUT’. It reports “put” access.
What access does the group ibmsys1 have?
dspmqaut -m QMA -n ‘PAYROLL’ -t queue -g ibmsys1
Entity ibmsys1 has the following authorizations for object PAYROLL:
Shows the group has no access defined.
What access does the userid (principal) ibmsys1 have?
dspmqaut -m QMA -n ‘PAYROLL’ -t queue -p ibmsys1
Entity ibmsys1 has the following authorizations for object PAYROLL:
dlt
chg
This is because userid ibmsys1 has MQAdmin as one of its group.
Adding -e option to the dmpmqaut command (Display all profiles used to calculate the cumulative authority that the entity has to the object specified in -n Profile
) shows which profiles will be used.
dmpmqaut -m QMA -n ‘PAYROLL’ -t queue -p ibmsys1 -e
profile: **
object type: queue
entity: MQAdmin
entity type: group
authority: dlt chg
We can see that the profile used to determine the access permissions came from the “**” profile statement for group(entity) MQAdmin.
Explicit giving a userid access – does not give the userid access.
On my Linux Ubuntu machine, using the following command to explicitly give a userid access; gives it to the userid’s principal group.
setmqaut -m QMA -n PAYROLL -t queue -p ibmsys1 +put
dmpmqaut -m QMA -n PAYROLL -t queue -p ibmsys1 -e
profile: PAYROLL
object type: queue
entity: zpdt
entity type: group
authority: putprofile: **
object type: queue
entity: MQAdmin
entity type: group
authority: dlt chg
This shows the group zpdt got the access – not the userid.
For this userid we can see that there was a specific profile “PAYROLL” for the zpdt group giving put permission, and the generic profile for the MQAdmin group giving inquire and display permissions.
The display authrec command
If you use dis authrec profile(PAYROLL) it will display all possible profiles including the profiles for queues, process etc. Ensure all mixed case values are surrounded by single quotes.
dis authrec profile(PAYROLL) objtype(queue)
gave
AMQ8864I: Display authority record details. PROFILE(PAYROLL) ENTITY(colinpaice) ENTTYPE(GROUP) OBJTYPE(QUEUE) AUTHLIST(BROWSE,CHG,CLR,DLT,DSP,GET,INQ,PUT,PASSALL,PASSID,SET,SETALL,SETID) AMQ8864I: Display authority record details. PROFILE(PAYROLL) ENTITY(mqm) ENTTYPE(GROUP) OBJTYPE(QUEUE) AUTHLIST(BROWSE,CHG,CLR,DLT,DSP,GET,INQ,PUT,PASSALL,PASSID,SET,SETALL,SETID) AMQ8864I: Display authority record details. PROFILE(PAYROLL) ENTITY(testuser) ENTTYPE(GROUP) OBJTYPE(QUEUE) AUTHLIST(PUT) AMQ8864I: Display authority record details. PROFILE(**) ENTITY(test) ENTTYPE(GROUP) OBJTYPE(QUEUE) AUTHLIST(DSP,INQ) AMQ8864I: Display authority record details. PROFILE(**) ENTITY(MQAdmin) ENTTYPE(GROUP) OBJTYPE(QUEUE) AUTHLIST(CHG,DLT)
but
dis authrec profile(PAYROLL) objtype(queue) group(MQAdmin)
gives not found however, using single quotes,
dis authrec profile(PAYROLL) objtype(queue) group(‘MQAdmin’)
gives
AMQ8864I: Display authority record details. PROFILE(**) ENTITY(MQAdmin) ENTTYPE(GROUP) OBJTYPE(QUEUE) AUTHLIST(CHG,DLT)
List all objects
You can use
runmqsc dis authrec type(queue)
to display all queue records with (up to three lines per entry) see above for an example.
You can use the dmpmqaut -l option Dump only the profile name and type. Use this option to generate a terse list of all defined profile names and types.
dmpmqaut -m QMA -l -t queue
Which gives output like
profile: PAYROLL, object type: queue
profile: PAYROLL.*.INPUT, object type: queue
profile: PAYROLL.**.INPUT, object type: queue
Unfortunately this is output to stderr, so you cannot immediately pipe this into grep or other commands.
You can use
dmpmqaut -m QMA -l -t queue 3>&1- 1>&2 2>&3|grep PAYROLL
The dmpmqaut command says you can use generics and wild cards in the name described Using OAM generic profiles on AIX®, Linux®, and Windows systems. I could not get this to work, for example using PAYROLL.**
The runmqsc DIS AUTHREC command says profile can have The name of the object or generic profile for which to display the authority records.
I think the documentation means “the string used in the profile definition, not a generic search argument.”
For example I wanted to use a qualifier ‘*’, but the command
dmpmqaut -m QMA -n ‘CP.*’
gives
No matching authority records.
runmqsc dis entauth – display the authorizations an entity has to a specified object
This very useful command was pointed out to me by Morag. It has been in MQ since MQ 7.5.
It allows you to ask what permissions a userid or group has to a specific resource. For example
A typical display
dis entauth principal(‘testuser’) objtype(queue) objname(CP0000)
AMQ8866I: Display entity authority details.
OBJNAME(CP0000) ENTITY(testuser)
ENTTYPE(PRINCIPAL) OBJTYPE(QUEUE)
AUTHLIST(BROWSE,CRT,GET,INQ,PUT,PASSALL,PASSID,SET,SETALL,SETID)
Queue does not exist
dis entauth principal(‘testuser’) objtype(queue) objname(CP000ZZZZZZ)
AMQ8147E: IBM MQ object CP000ZZZZZZ not found.
Silly me – I missed the quotes off from around the userid
dis entauth principal(testuser) objtype(queue) objname(CP0000)
3 : dis entauth principal(testuser) objtype(queue) objname(CP0000)
AMQ8871E: Entity, principal or group not known.
Dump mq configuration
You can use the dmpmqcfg command to dump out the authrec records.
dmpmqcfg -m QMA -x authrec -o 1line
gives output like (where there is one line for each SET… statement).
SET AUTHREC PROFILE(‘CP.*.00’) GROUP(‘colinpaice’) OBJTYPE(QUEUE) AUTHADD(GET,PUT)
SET AUTHREC PROFILE(‘PAYROLL.**.INPUT’) GROUP(‘testuser’) OBJTYPE(QUEUE) AUTHADD(PUT)
SET AUTHREC PROFILE(‘@class’) GROUP(‘colinpaice’) OBJTYPE(QUEUE) AUTHADD(CRT)
The -o 1line option creates one line of output for each record. You can use platform tools to process the data, for example use grep to filter lines, and parse the parts between ‘ ‘. See an example python script at the bottom.
The documentation says -n [*|ObjectName] Filter the definitions produced by object or profile name, the object/profile name can contain a single asterisk. But it didnt work for me.
My basic queries
Is this user authorised to use this queue?
You can use
dspmqaut -m QMA -n PAYROLL.A -t queue -p ibmsys1
If the queue does not exist you will get AMQ7085E: Object PAYROLL.A, type queue not found.
Or you can use the runmqsc command
dis entauth principal(‘testuser’) objtype(queue) objname(CP0000)
What security profiles are involved with this user and that queue.
Or which profiles gave a user access to the queue?
Display the userids id and groups. If userid is in group mqm, it will get all access regardless of the setmqaut settings.
Display all the profiles involved with a userid -e … or group -g …
dmpmqaut -m QMA -n PAYROLL.A -t queue -e
Display all the permission a user has with a userid -p … or group -g …
dspmqaut -m QMA -n ‘CP.ZZ.00’ -t queue -p testuser
Entity testuser has the following authorizations for object CP.ZZ.00:
inq
crt
dsp
Display the profiles which determine the permissions for a user
dmpmqaut -m QMA -n ‘CP.ZZ.00’ -t queue -e -p testuser
profile: **
object type: queue
entity: test
entity type: group
authority: inq dspprofile: @class
object type: queue
entity: test
entity type: group
authority: crt
The inq and dsp permissions came from the “**” profile for the test group.
Who is authorised to this queue?
This is a tricky one. I could find two hard ways of
dmpmqaut -m QMA -n ‘CP.ZZ.00’ -t queue 2> file
dmpmqcfg -m QMA -x authrec -o 1line > file
Then post-processing the output to extract group name and permissions, then merging the records.
For example to see the members of a group.
getent group |grep mqm
gives
mqm:x:1003:colinpaice,ibmsys1
I want to audit the access to the queues beginning with CP.
Another tricky one.
- dmpmqcfg -m QMA -n ‘CP*’ -t queue -o 1line -x object > queuelist
- This gives a list of all queues starting with CP. Process this list to select each queue in turn
- dmpmqaut -m QMA -n $queuename -t queue -e > accesslist
- This accesslist file has the profile name, the group and the permissions.
- Take each group name, and extract the members of the group.
- For each member of the list use
- dspmqaut -m QMA -n $queue -t queue -p $userid
- Take this list extract the permissions, and produce a pretty report.
If there is a better way I would love to hear it.
A partial solution is to take the output of
dmpmqaut -m QMA -l -t queue 2>list
dmpmqcfg -m QMA -x authrec -o 1line > file
Then use tools like grep to extract the records of interest, then use other tools to issue dmpmqaut -m QMA -n ‘….’ -t queue, capture the output and process it.
But this means you have to interpret generic profiles like ‘CP.**.INPUT’ yourself.
Sample code for post processing dmpmqcfg output
Below is a small Python program that takes the output from dmpmqcfg and processes it to replace groups with users in the groups, and gives one line per userid,permission,profile, source_group
#
# Copyright (c) 2020 Stromness Software Solutions.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# * Contributors:
# * Colin Paice - Initial Contribution
#
from sys import stdin
import grp
for line in stdin:
sline= line.strip()
s = sline.split(' ')
if s[0] != "SET":
continue
p = s[2][9:-2] # get the profile
g = s[3][7:-2] # get the group
try:
ginfo = grp.getgrnam(g)
ids = ginfo.gr_mem
if len(ids) == 0: # group can be empty
ids = [g]
except KeyError:
ids = [g] # group not found - must be userid
t = s[4][8:-1] #type
a = s[5][8:-1] # get the authorities
aa = a.split(",")
# Output userid authority profile type group_it_came_from
for aaa in aa:
for i in ids:
print(i,aaa,p,t.g)
Invoke it as
cat data | python3 ~/python/sec.py |sort -k1,3|uniq |grep -v mqm
grep -v mqm removes all accesses due to group mqm membership
Example output
colinpaice SET SYSTEM.SELECTION.VALIDATION.QUEUE QUEUE colinpaice SET TEMP QUEUE colinpaice colinpaice SET XQMB QUEUE colinpaice colinpaice SUB SYSTEM.ADMIN.TOPIC TOPIC colinpaice testuser PUT COLIN_* QUEUE test testuser PUT CP0000 QUEUE testuser
You missed the MQSC command DISPLAY ENTAUTH in your list
LikeLike
Thank you – that looks a good command – I’ll play with it, and incorporate it.
LikeLike
PAYROLL.**.INPUT does apply to PAYROLL.INPUT.
You can add SecurityPolicy=user to the Service stanza of the qm.ini on Unix since v8.0 to allow principal based permissions, this is also how windows works by default even prior to v8.0.
LikeLike
Thank you .. I’ll check.. ( I did so much testing – I may have slipped up)
I feel a blog post coming on about this and the implications of it. it feels like a well kept ( or badly documented) option.
LikeLike
I wrote a little blog post about using DISPLAY ENTAUTH – hope it helps. See here: https://community.ibm.com/community/user/integration/blogs/morag-hughson/2021/05/27/ibm-mq-little-gem-52-display-entauth
LikeLike