IBM Security Z Security

Security for Z

Join this online user group to communicate across Z Security product users and IBM experts by sharing advice and best practices with peers and staying up to date regarding product enhancements.

 View Only
  • 1.  Group reference matrix

    Posted 3 hours ago

    Some weeks ago, UJ97365 was made available for zSecure 3.1. This is the fix for APAR OA68008 and changes the way DEFINE .. WHERE .. works in combination with lookup.  Before this fix, the WHERE condition would be ignored in a lookup, that is, if you wanted to use WHERE to skip certain lines in a DEFTYPE file, they would still be used and you might get 

    CKR1142 08 Duplicate and conflicting entry for key=<key> in lookup...

    For example, with input file

    * This table lists the groups to print
    * enter group names from column 1, do not use generic patterns or specify commas at the end of the line
    SYS1
    SYS2

    and CARLa code like this, reading the table from DD name SELECT:

    deftype type=$select
    alloc type=$select dd=select
    define type=$select group as word(record,1) where substr(record,1,2)<>'* '

    newlist type=racf
    select class=group segment=base profile:$select.group.record<>' '
    sortlist profile(8) owner aclcnt

    you might get CKR1142 complaining about seeing a duplicate key "*".  With UJ97365 installed, the message disappears.  With this selective define, we were able to read a file with different record types in the 1st word of each record, and assign a different variable with the value in the 3rd word.  The report produced a matrix of all group names, and columns that showed the number of permits, the number of profiles owned, the number of users connect and data set profiles with matching HLQ, for each group, using a two step CARLa.

    Step 1: generate 3 different record types, each with a type, a group name and a count of the profiles containing that name in a unique field.  Store this in member GRPMTX1

    /* GRPMTX1
      group analysis report step 1
      export occurrences of groups (and users) into CKR2PASS
       count the number of times an ID occurs, precede with record type
    */
    newlist nopage dd=ckr2pass
      s (class=dataset or class=general) aclcnt>0
      sum 'STDACL'(8) userid count(9)

    newlist nopage dd=ckr2pass
      s class=dataset acl2cnt>0
     sum 'DSCDACL'(8) user2acs count(9)

    newlist nopage dd=ckr2pass
      s class=general acl2cnt>0
      sum 'GRCACL'(8) acl2uid count(9)

    newlist nopage dd=ckr2pass
      s class=user s=base
      sum 'USOWNER'(8) owner count(9)

    newlist nopage dd=ckr2pass
      s class=group s=base
      sum 'GPOWNER'(8) owner count(9)

    newlist nopage dd=ckr2pass
      s class=dataset s=base
      sum 'DSOWNER'(8) owner count(9)

    newlist nopage dd=ckr2pass
      s class=general s=base
      sum 'GROWNER'(8) owner count(9)

    newlist nopage dd=ckr2pass
      s class=user s=base
      sum 'CONNECT'(8) congrpnm count(9)

    newlist nopage dd=ckr2pass
      s class=dataset s=base
     sum 'DSPROF'(8) qual count(9)

    The reporting step reads this temporary file, assigning a value depending on the record type, store this in member GRPMTX2:

    /* GRPMTX2
       group analysis report step 2
       read occurrence and print as lookup from groups
    */
    deftype type=$usage
    alloc   type=$usage dd=usage
    newlist type=$usage outlim=0
      define STDACL_ID(8) as word(record,2),
            where word(record,1)=STDACL
      define STDACL(7) as convert(word(record,3),decimal),
            where word(record,1)=STDACL
      define DSCACL_ID(8) as word(record,2),
            where word(record,1)=DSCACL
      define DSCACL(7) as convert(word(record,3),decimal),
            where word(record,1)=DSCACL
      define GRCACL_ID(8) as word(record,2),
            where word(record,1)=GRCACL
      define GRCACL(7) as convert(word(record,3),decimal),
            where word(record,1)=GRCACL

      define USOWNER_ID(8) as word(record,2),
            where word(record,1)=USOWNER
      define USOWNER(7) as convert(word(record,3),decimal),
            where word(record,1)=USOWNER
      define GPOWNER_ID(8) as word(record,2),
            where word(record,1)=GPOWNER
      define GPOWNER(7) as convert(word(record,3),decimal),
            where word(record,1)=GPOWNER
      define DSOWNER_ID(8) as word(record,2),
            where word(record,1)=DSOWNER
      define DSOWNER(7) as convert(word(record,3),decimal),
            where word(record,1)=DSOWNER
      define GROWNER_ID(8) as word(record,2),
            where word(record,1)=GROWNER
    define GROWNER(7) as convert(word(record,3),decimal),
            where word(record,1)=GROWNER

      define CONNECT_ID(8) as word(record,2),
            where word(record,1)=CONNECT
      define CONNECT(7) as convert(word(record,3),decimal),
            where word(record,1)=CONNECT

      define DSPROF_ID(8) as word(record,2),
            where word(record,1)=DSPROF
      define DSPROF(7) as convert(word(record,3),decimal),
            where word(record,1)=DSPROF

    newlist type=racf toptitle='G R O U P   A N A L Y S I S   R E P O R T',

      st='         ------- Permits ------- ------- Profiles owned --------'

      s class=group s=base
      sortlist profile(8,'Group'),
               profile:$usage.STDACL_ID.STDACL(' Normal ',7),
               profile:$usage.DSCACL_ID.DSCACL('Cond DS',7),
               profile:$usage.GRCACL_ID.GRCACL('Cond Re',7),
               profile:$usage.USOWNER_ID.USOWNER('  Users',7),
               profile:$usage.GPOWNER_ID.GPOWNER(' Groups',7),
               profile:$usage.DSOWNER_ID.DSOWNER('Dataset',7),
               profile:$usage.GROWNER_ID.GROWNER('Resourc',7),
               universal,
               profile:$usage.CONNECT_ID.CONNECT('Connect',7),
               profile:$usage.DSPROF_ID.DSPROF('Ds prof',7)                

    Write JCL   like so:

    // JCLLIB ORDER=(SYS3.CKRPARM,SYS1.SCKRPROC)
    //COLLECT EXEC C2RC,PARM.C2RC='PRINT DD=CKREPORT;I M=C2RXDEF1 NOLIST'
    //SYSIN    DD *
    alloc type=racf backup
    //         DD DISP=SHR,DSN=USER.JOB.CARLA(GRPMTX1)
    //CKR2PASS DD DSN=&&USAGE,DISP=(,PASS)
    //REPORT EXEC C2RC,PARM.C2RC='PRINT DD=CKREPORT;I M=C2RXDEF1 NOLIST'
    //SYSIN    DD *
    alloc type=racf backup
    //         DD DISP=SHR,DSN=USER.JOB.CARLA(GRPMTX2)
    //USAGE    DD DSN=&&USAGE,DISP=OLD
    //C2RC.CKREPORT DD LRECL=255
    //CKR2PASS DD SYSOUT=*

    and you could get a report that contains

    G R O U P   A N A L Y S I S   R E P O R T  25 Aug 2025 09:24                            
             ------- Permits ------- ------- Profiles owned --------                        
                                                                                             
    Group     Normal Cond DS Cond Re   Users  Groups Dataset Resourc Uni Connect Ds prof    
    SYS1           1                       5      27       6      25          10     662   
    SYS2           5                                      64                         420   
    SYS3           8                                      50                         285



    ------------------------------
    Rob van Hoboken
    ------------------------------