How easy is it to display security information on midrange.

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

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

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: put

profile: **
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 dsp

profile: @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

6 thoughts on “How easy is it to display security information on midrange.

  1. 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.

    Like

  2. 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.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s