This blog post follows on from Using LDAP with multi platform.
Nested groups can be used to simplify administration
It is good practice to grant authority to access resources using groups, rather than giving access to individual userids. For example if an application uses 10 queues, and a new person joins the team you can either connect the new id to one group, or give the id access to the 10 queues.
Using nested groups takes this further. Imagine the payroll queues are managed by the GRPAYROLL access group, the HR queues managed by the GRHR access group, and the Finance queue managed by the GRFINANCE access group. The MQ system programmers can manage any queue. You could give GRMQADMIN access to the Payroll queues, HR queues, and Finance queues. Or you say the GRMQADMIN is the super set and includes a reference to GRPAYROLL, GRHR, and GRFINANCE. If you define a HR queue, you just give GRHR access to it, and the MQ Administration team get access to it “for free”.
You can take this further, and have a group GRHR_GR1, and GRHR_GR2 which give access to a subset of HR queues. The GRHR group could include both of these.
The model of this is a tree where a group high up in the tree incorporates the groups lower down the tree.
There are two ways of defining groups in LDAP.
1. Define a group record, and list the members of the group. This is called a static group
To retrieve the groups for a user, you issue a query for all groups which have the given member data.
2. Specify the group name as part of the user’s record, this is known as a dynamic group.
For this you retrieve the “group” attributes from the record. Note: The group attribute does not exist in LDAP, you have to use a different one ( I used the st attribute).
Nested group support.
There is an MQ AUTHINFO parameter NESTGRP. The documentation says
- NESTGRP Group nesting.
- YES The group list is searched recursively to enumerate all the groups to which a user belongs.
Static groups and nested group support.
My MQ ADUTHINFO had
BASEDNG(‘ou=groups,o=your Company’) +
On my system the userid ibmuser is a “member” of two groups mqstatic and mqstatic2
dn: cn=mqstatic,ou=groups,o=your Company
member: cn=ibmuser,o=your Company
member: cn=adcdb,o=your Company
dn: cn=mqstatic2,ou=groups,o=your Company
member: cn=ibmuser,o=your Company
There is another group, which refers to the mqstatic group.
dn: cn=mega,ou=groups,o=your Company
member: cn=mqstatic,ou=groups,o=your Company
member: cn=gg,ou=groups,o=your Company
As part of the userid to group mapping, MQ issues the query What groups have member: cn=ibmuser,o=your Company. The response is
- dn: cn=mqstatic2,ou=groups,o=your Company
- dn: cn=mqstatic,ou=groups,o=your Company
When NESTGRP(YES) is specified MQ then queries all groups that have cn=mqstatic2,ou=groups,o=your Company, and does another query for dn: cn=mqstatic,ou=groups,o=your Company
and gets the response dn: cn=mega,ou=groups,o=your Company.
The cn=ibmuser is associated with the three groups, and those three groups are used for access checking.
For a data model I see it as
The “isusedby” attribute name, is in reality “member”, which I feel is very confusing, as member implies membership, and there is no membership involved. This is an LDAP naming problem – not MQ’s.
This model feels upside down (or inside out) (or both). It takes several cups of tea with biscuits to draw up the groups and the connections definitions you need. Put the kettle on, and try defining the groups for the MQADMIN, GRFINANCE, and GRFINANCEGR1, GRFINANCEGR2 groups; three people in MQADMIN, and two people in finance; then add a definition for GRFINANCEGRN.
Using dynamic groups and nested group support
This feels more the right way up – but it is upside down compared to static groups.
My authinfo had
BASEDNU(‘o=Your Company’) +
With my userid I had
dn: cn=user1, o=Your Company
st: cn=group,ou=groups,o=your Company
st: cn=mqadmin,ou=groups,o=your Company
Where st: defined the groups.
For the entry for cn=group, I defined a nested group called cn=deepergroup.
dn: cn=group,ou=groups,o=your Company
st : cn=deepergroup,o=your Company
sn : groupgroup
You need an entry for cn=deepergroup… in LDAP
dn: cn=deepergroupou=groups,o=your Company
# no st attribute, so there is no more nesting
I define the cn=mqadmin group to LDAP with no “sn” entry, because it has no nesting.
MQ issues a query to LDAP asking for the group definitions ( st in my case) for the given user. For each group that gets returned, query that group for any more group (st in my case) definitions, etc.
Together these give three groups for the cn=ibmuser:
- cn=mqadmin,ou=groups,o=your Company
- cn=deepergroup,ou=groups,o=your Company
- cn=group,ou=groups,o=your Company
Dynamic group data model
The data model for dynamic group feels more natural, where the “is in” and “includes” are the attribute you chose, “st” in my case.
- is in: cn=group1…
- includes: cn=groupdeep
Enabling nestgrp(yes) with dynamic groups may throw errors
If you start with
With nestgrp(no) this defines the userid is in two groups.
If you enable nestgrp(yes) then when the user id is used, MQ checks there are entries in LDAP for group=cn=group1,.. and group=cn=group2,… If the definitions do not exist, you get the MQ message:
AMQ5532E: Error authorizing entity in LDAP
The LDAP authorization service has failed in the ldap_first_entry call while trying to find user or group ‘NULL’. Returned count is 0. Additional context is ‘cn=group1,… ‘.
To solve the problem I defined the two groups to LDAP.
For group1 I defined
and I defined the deepergroup group (to keep mq happy) with no group entries (to indicate end of the nesting).