Thanks Jeroen and Rob.
I was a bit slow on the up take but I think I finally understand what you meant. I need to pick SUBSELECT or RACF_ACCESS not try to do them both.
I was able to get both my queries working, the only sacrifice I had to make was not resolving to the user in the Personal User with > Update access report which wasn't really necessary anyway.
Original Message:
Sent: Fri September 12, 2025 03:37 AM
From: Jeroen Tiggelman
Subject: CARLA to create list of > READ dataset permissions for select users
Hi Nathan,
Yes, the point of the ACL() construction is that the whole clause is evaluated against each entry in the repeat group, while if you select on the individual repeated fields each field is scanned separately for the occurrence of one of the specified values, and the "found" or "not found" results are then ANDed (as just putting clauses behind each other is an implicit AND).
@Rob: "limitedACLsubselectclause" is how we have always documented this since I built the function back in 2001: https://www.ibm.com/docs/en/szs/3.1.0?topic=SS2RWS_3.1.0/carla_lang/carla_cmnd_lang_select_srch_prof_name.htm#carla_cmnd_lang_select_srch_prof_name__selacl
Regards,
------------------------------
Jeroen Tiggelman
IBM - Software Development Manager IBM zSecure
Delft
Original Message:
Sent: Thu September 11, 2025 07:19 PM
From: Nathan Shrive
Subject: CARLA to create list of > READ dataset permissions for select users
Thanks. It ran, but unfortunately I'm still getting some undesired results where dataset profiles are appearing in the report that have no matching ID entries. I think the issue is those dataset profiles have an ACL entry that matches the criteria useracs=(alter,update,control), and a different ACL entry that matches userid:$ids.id.record<>' ' so the profile meets the selection criteria.
In the training material we got from Tom a year or so ago it has this line:
'Alternatively, for SELECT ACL, you can use ACL(ID=<id> ACCESS=<access>) to enforce that the ID and ACCESS tested belong to the same ACL entry'</access></id>
So I assume that means if you don't use the subselect syntax it looks across multiple ACL entries? I think thats also the same problem I am having with the other revoke group connections query.
------------------------------
Nathan Shrive
Original Message:
Sent: Thu September 11, 2025 05:55 AM
From: Jeroen Tiggelman
Subject: CARLA to create list of > READ dataset permissions for select users
The syntax of the limitedACLsubselectclause was taken from the normal syntax from DEFINE ... SUBSELECT ACL(), with the restriction that USER and GROUP cannot be used, because this information is not known at the type the selection is processed. That syntax was based on the sub-fields of this combined field on output.
The ACL (CARLa) field combines information from both the unconditional and conditional access control lists.
For the DATASET class, the unconditional access control list consists of the repeated (RACF database template) fields USERID, USERACS, and ACSCNT.
The conditional access control list consists of the repeated fields PROGRAM, USER2ACS, PROGACS, PACSCNT, and ACL2VAR.
Regards,
Jeroen
------------------------------
Jeroen Tiggelman
IBM - Software Development Manager IBM zSecure
Delft
Original Message:
Sent: Thu September 11, 2025 03:38 AM
From: Rob van Hoboken
Subject: CARLA to create list of > READ dataset permissions for select users
Yes, I'm logged on to TSO now and can check the syntax. The standard field for ACCESS levels in DATASET profiles is USERACS, together in a repeated list with USERID, so the select should have been
SELECT class=dataset useracs=(alter,update,control),
userid:$ids.id.record<>' '
The ACL( ) compound field was designed to make the syntax easier, so SELECT ACL(ID=xxx) instead of USERID (which also selects groups), and SELECT ACL(ACCESS>READ) instead of USERACS>READ.
------------------------------
Rob van Hoboken
Original Message:
Sent: Thu September 11, 2025 03:08 AM
From: Nathan Shrive
Subject: CARLA to create list of > READ dataset permissions for select users
Thanks Rob,
Unfortunately when I updated the select statement to this:
SELECT class=dataset access=(alter,update,control),
userid:$ids.id.record<>' '
I got this message:
CKR1036 12 Field "ACCESS" is only supported for SUBSELECT clauses at SYSIN line 9
------------------------------
Nathan Shrive
Original Message:
Sent: Thu September 11, 2025 02:55 AM
From: Rob van Hoboken
Subject: CARLA to create list of > READ dataset permissions for select users
Awkward. There is no real reason why a DEFTYPE lookup should be denied, except complexity in the (assembler) code and lack of time. Anyway. You can change the SELECT command to
SELECT class=dataset access=(alter,update,control) userid:$ids.id.record>' '
though this does not check on the combination of suspect user IDs and excessive access within each ACL entry. As a result, profiles will be selected where a suspect user ID only has READ, though those lines will be suppressed in output by the output SUBSELECT.
------------------------------
Rob van Hoboken
Original Message:
Sent: Wed September 10, 2025 07:30 PM
From: Nathan Shrive
Subject: CARLA to create list of > READ dataset permissions for select users
Hi Rob, thanks very much for your detailed response! Unfortunately, when I ran the code I got this:
PARM: I DD=CKRSPROF
Include CKRSPROF subsys EA1917.EA1917GP.JOB01024.D0000103.?
1 |PRINT DD=CKREPORT
2 |IMBED MEMBER=CKRXDEF1 NOLIST
End of CKRSPROF (include level 1)
Input: SYSIN subsys EA1917.EA1917GP.JOB01024.D0000104.?
1 |
2 |alloc type=racf active
3 |deftype type=$ids
4 |alloc type=$ids dd=IDLIST
5 |define type=$ids id(8) as substr(record,1,8)
6 |NEWLIST type=racf retain
7 |DEFINE #stripacl(explode) subselect acl(access=(alter,update,control),
8 |user:$ids.id.record<>' ')
9 |SELECT class=dataset acl(access=(alter,update,control),
10 | id:$ids.id.record<>' ')
CKR1159 12 Lookup not allowed in subselect clause in SELECT statement - before word "$ids.id.record<>" at SYSIN line 10
11 |sortlist profile #stripacl
12 |
------------------------------
Nathan Shrive
Original Message:
Sent: Wed September 10, 2025 01:52 PM
From: Rob van Hoboken
Subject: CARLA to create list of > READ dataset permissions for select users
Hey Nathan.
The thing about NEWLIST TYPE=RACF, it selects profiles (only) on the fields that are available in the profile. That is due to the place where the SELECT command is processed, (almost) directly in the profile reading engine. It sees profiles in the physical order of profiles in the database. So when SELECT sees a DATASET profile, it does not know if the USERID field in the profile refers to a user ID or to a group name. And worse, if the USERID field contains a group name, it has no clue about the user IDs connected to the group.
Consequently, the values you can use in the SELECT USERID=xxx command must be exactly the values that are specified in the profile. The ACL( ) compound field is, essentially, syntax sugar to make it easier to specify a combination of the value you expect in the USERID field and in the ACCESS field for a single ACL entry. It does not support functions like EXPLODE and RESOLVE. This is reflected by the field name ID in SELECT ACL(ID=(D%1*,D%2*,D%3*)) that you used. This variant of ACL() does not know USER= or GROUP=.
For many reports I reach out to NEWLIST TYPE=RACF_ACCESS, it makes the ID and ACCESS field easier to specify, and it is processed after all the profiles have been read, so lookup from the ID field is possible in the SELECT command, which it is not (really) in NEWLIST TYPE=RACF. However, NEWLIST TYPE=RACF_ACCESS does not support EXPLODE and RESOLVE either. If only there was an Idea that you could vote for...
Nope, you are stuck with the old fashioned two-pass CARLa. Pass 1 should collect all groups that have one of your suspect users connected, and write these groups into a flat file. Pass 2 should check the values in USERID, and compare these either to the list of patterns, or to the names in the flat file.
Or your pass 1 could write one file with BOTH the group names containing the suspect users AND the suspect user ids too. This is what the batch job would look like.
// EXEC C2RC
//CKR2PASS DD DISP=(,PASS),DSN=&&IDS
//SYSIN DD *
newlist type=racf nopage dd=ckr2pass
select class=group userid=(,
D%1*,,
D%2*,,
D%3*,,
D%4*,,
D%5*,,
D%6*,,
D%7*,,
D%8*,,
D%9*,,
D%0*,,
L%1*,,
L%2*,,
L%3*,,
L%4*,,
L%5*,,
L%6*,,
L%7*,,
L%8*,,
L%9*,,
L%0*,
)
sortlist profile(8)
newlist type=racf nopage dd=ckr2pass
define masklist as profile
select class=user seg=base masklist=(,
D%1*,,
D%2*,,
D%3*,,
D%4*,,
D%5*,,
D%6*,,
D%7*,,
D%8*,,
D%9*,,
D%0*,,
L%1*,,
L%2*,,
L%3*,,
L%4*,,
L%5*,,
L%6*,,
L%7*,,
L%8*,,
L%9*,,
L%0*,
)
sortlist profile(8)
// EXEC C2RC
//IDLIST DD DISP=OLD,DSN=&&IDS
//SYSIN DD *
alloc type=racf active
deftype type=$ids
alloc type=$ids dd=IDLIST
define type=$ids id(8) as substr(record,1,8)
NEWLIST type=racf retain
DEFINE #stripacl(explode) subselect acl(access=(alter,update,control) user:$ids.id.record<>' ')
SELECT class=dataset acl(access=(alter,update,control) id:$ids.id.record<>' ')
sortlist profile #stripacl
//
Typed from memory, while logged off, not tested.
------------------------------
Rob van Hoboken
Original Message:
Sent: Wed September 10, 2025 01:55 AM
From: Nathan Shrive
Subject: CARLA to create list of > READ dataset permissions for select users
Hi team,
I'm trying to create a list of dataset profile permits where users matching a specific logon ID format have greater than READ access either directly or via a group. This is my current code, it nearly works but only returns profiles where matching IDs have direct permits. I can't seem to figure out a way to get it to show permits to the selected users that occur via groups as well. Can you offer any suggestions?
NEWLIST type=racf retain
DEFINE #stripacl(explode) subselect acl(access=(alter,update,control),
user=(,
D%1*,,
D%2*,,
D%3*,,
D%4*,,
D%5*,,
D%6*,,
D%7*,,
D%8*,,
D%9*,,
D%0*,,
L%1*,,
L%2*,,
L%3*,,
L%4*,,
L%5*,,
L%6*,,
L%7*,,
L%8*,,
L%9*,,
L%0*,
))
SELECT c=dataset segment=base,
acl(access=(alter,update,control),
id=(,
D%1*,,
D%2*,,
D%3*,,
D%4*,,
D%5*,,
D%6*,,
D%7*,,
D%8*,,
D%9*,,
D%0*,,
L%1*,,
L%2*,,
L%3*,,
L%4*,,
L%5*,,
L%6*,,
L%7*,,
L%8*,,
L%9*,,
L%0*,
))
SORTLIST class key #stripacl
------------------------------
Nathan Shrive
------------------------------