I admit that I’m a little overdue to post this follow-up to my post about accessing RACF info from a COBOL program in CICS. But when I posted it, I had no idea that was going to be the single most viewed entry on my blog site. So I’ve finally had enough people asking about the teaser with which I ended that post, promising to show how to access the list of groups to which the user is connected, that I’ve been shamed into following thr0ugh. The latest episode of “One Way Out” has ended, so it’s time to quit goofing off and meet that obligation …
Some of this will be a repeat of my original post, but I’ll quickly cover those things so new blogees won’t necessarily have to chase it down. First, to access the ACEE (the RACF control block that has so much RACF info on the user), we’ll need a pointer defined in working storage to point to the control block – something like this:
77 WS-ACEE-ADDR-POINTER USAGE IS POINTER.
And, while we are defining things in working storage, let’s set up a table to contain the groups to which our CICS user is connected:
05 WS-GROUPS PIC X(8 ) OCCURS 10 TIMES.
The occurs number is arbitrary. I picked 10 because that would seem to be large enough to cover the list of groups for most users, but if your shop uses groups more extensively, perhaps not. Code a bigger value, or devise a much more clever scheme … I’m not going to spend time on it because that’s not important for what I’m showing here.
We’ll also need somewhere to count the groups as we find them:
77 WS-GROUP-CNT PIC S9(4) COMP VALUE 1.
The IBM-provided record layout for the ACEE is in SYS1.MACLIB(IHQAACEE). But we are not interested in every field listed, so let’s dumb-down the record layout into a data structure in the linkage section, replacing what we are not interested in with FILLER, like this:
05 FILLER PIC X(021).
05 ACEEUSRI PIC X(008).
05 FILLER PIC X(001).
05 ACEEGRPN PIC X(008).
05 FILLER PIC X(062).
05 ACEEUNAM-POINTER USAGE IS POINTER.
05 FILLER PIC X(012).
05 ACEECGRP-POINTER USAGE IS POINTER.
There are a couple of pointers in that data structure … We saw in my original post that the first one points to an area of storage containing the user name (as defined in RACF). We’ll ignore it, as we are only interested in the second one at this time – it points to our list of groups, which we will define with the following data structure in the linkage section:
05 FILLER PIC X(008).
05 CGRPNUM PIC S9(4) COMP.
05 FILLER PIC X(022).
05 CGRPENT OCCURS 10 TIMES DEPENDING ON CGRPNUM.
10 CGRPNAME PIC X(008).
10 FILLER PIC X(016).
CGRPNUM is going to contain the number of entries in this list. I chose to have it occur up to 10 times because that was the arbitrary value I chose in my table to contain the groups in working storage.
So much for the data definitions – let’s now go get the data! In the procedure division, we’ll need to use the CICS API that allows us to address the ACEE:
EXEC CICS ADDRESS ACEE (WS-ACEE-ADDR-POINTER)
Now that we have the address of the ACEE, we can now access that control block, and once we have it, we can access the list of groups, just by setting pointers:
SET ADDRESS OF ACEE TO WS-ACEE-ADDR-POINTER.
SET ADDRESS OF ACEE-GROUP-TABLE TO ACEECGRP-POINTER.
All that’s left to do is run the list, getting our groups:
PERFORM 200-GET-GROUP THROUGH 200-EXIT
UNTIL WS-GROUP-CNT IS GREATER THAN CGRPNUM
OR WS-GROUP-CNT IS GREATER THAN 10.
That defines our loop (again, with my arbitrary limit of 10), so now let’s set up what gets done in the loop – move the value from the control block to our working storage table and increment to point to the next group:
MOVE CGRPNAME (WS-GROUP-CNT) TO WS-GROUPS (WS-GROUP-CNT).
ADD 1 TO WS-GROUP-CNT.
That is it! Like on our first example, the COBOL coding is not the hard part … The only hard part is knowing where the information is – and I hope I have helped exposed that with these examples. Browse through the assembler definition of the ACEE – you may see some other information that can help you get a job done!