5

I am writing Java code on z/OS and I need to find out which security manager (RACF, ACF2 or TopSecret) is active on the system. How can I do this?

John Czukkermann
  • 539
  • 1
  • 4
  • 13

1 Answers1

6

Edit: Fixed the incorrect offset of cvtracOffsetRCVTID to the correct value of 0x0.

You can use the IBM JZOS package to peek at memory as follows. For production code, I would create an enumeration for the security managers and rather than pass strings around and have to deal with string comparisons.

import com.ibm.jzos.ZUtil;

/**
 * This is a sample program that uses IBM JZOS to determine
 * the Enterprise Security Manager that is active on a z/OS
 * system.
 * <p>
 * @see com.ibm.jzos.ZUtil#peekOSMemory(long, int)
 * @see com.ibm.jzos.ZUtil#peekOSMemory(long, byte[])
 */
public class peek {
    
    public static void main(String[] args) throws Exception {

        byte[] rcvtIdBytes = new byte[4];
        long pPSA  = 0L;
        int psaOffsetCVT = 16;
        long pCVT  = ZUtil.peekOSMemory(pPSA + psaOffsetCVT, 4); // Get address of CVT from PSA+16
        
        int cvtOffsetCVTRAC = 0x3e0; // Offset of CVTRAC (@RCVT) in the CVT
        long pCVTRAC =
                ZUtil.peekOSMemory(pCVT + cvtOffsetCVTRAC, 4); // Get the address of CVTRAC (Mapped by ICHPRCVT)
        
        // Now we can retrieve the 4 byte ID (in IBM-1047) of the active ESM.
        int cvtracOffsetRCVTID = 0x0;                                        
        // Offset of RCVTID in the RCVT.

        // The RCVTID value is:
        //    "RCVT" for RACF
        //    "ACF2" for ACF2
        //    "RTSS" for TopSecret
        ZUtil.peekOSMemory(pCVTRAC + cvtracOffsetRCVTID, rcvtIdBytes);   // Get the RCVTID
        
        String rcvtId = new String(rcvtIdBytes, "IBM-1047");

        System.out.println("The Security Manager is: "+rcvtId);
    }
}
John Czukkermann
  • 539
  • 1
  • 4
  • 13
  • Cut and pasted the example and it worked flawlessly, thanks John. `IBMUSER:/u/ibmuser>java -classpath . peek` *The Security Manager is: RACF* – Hogstrom Sep 20 '18 at 19:10
  • This should print out 'RCVT' for RACF I believe, not 'RACF'. I also _think_ the code might be wrong and the offset into the RCVTID should be 0 (not 0x45). – mike Jul 05 '23 at 23:19
  • 1
    @mike You are correct. The offset for RCVTID is wrong. I corrected the post and added comments regarding what the expected values are for RCVTID. – John Czukkermann Jul 06 '23 at 12:56
  • Thanks @JohnCzukkermann! I was confused! @hogstrom I think you got 'lucky' seeing RACF show up - it was in the middle of a dataset string somewhere I think? – mike Jul 06 '23 at 16:54
  • @JohnCzukkermann its possible. I just fired up your original code and got the result I was expecting. Now, if only lottery numbers worked that way. – Hogstrom Jul 08 '23 at 21:48
  • @Hogstrom You only got RACF back because the index happens to land in the right spot for the name of the RACF data set. SYS1.RACF in our tests. – John Czukkermann Aug 21 '23 at 18:55