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.  zSecure CARLa Question -- Cross-Checking Data

    Posted 10/17/19 10:53 AM
    Greetings, I hope this is the new best place for zSecure CARLa questions!

    I'm looking to use CARLa to check the contents of a dataset vs. what's in an actual live RACF database, if possible.

    The basic display CARLa is below but I'm struggling to add the last piece to find $USER and $GROUP connections in the $CONNECT deftype which are not present in the RACF newlist type. Would this be some sort of 2-pass CARLa ? Any guidance would be helpful.


    ​Deftype type=$CONNECT
    Alloc type=$CONNECT dsn=MY.DATASET
    Define type=$CONNECT $USER(8)     as substr(record,1,8)
    Define type=$CONNECT $GROUP(8) as substr(record,10,8)
    Newlist type=$CONNECT retain pl=0
    Summary $USER('User') $GROUP('Group') Count(nondisplay)


    newlist type=RACF retain pl=0
    select class=user segment=base
    sortlist key(8,"User") connects(8,"Group")

    ------------------------------
    Adam Klinger
    ------------------------------


  • 2.  RE: zSecure CARLa Question -- Cross-Checking Data

    Posted 10/18/19 05:32 AM

    Hi Adam.  You might think that you could use "look up" to compare fields in RACF profiles with an external file.  Like using key:$connect.$user.$group in your second newlist.
    The point is, a lookup has a key field and only one record is retained for each value of said key.  That means, if your MY.DATASET contains several groups for 1 user id, the LOOKUP only remembers the first:
    ADAM     SYS1
    ADAM     DEV
    ADAM     ADAMSGRP
    a lookup from ADAM to $GROUP always and only returns SYS1.  This is reported in SYSPRINT with a message
    CKR1142 00 Duplicate and conflicting entry for key=ADAM in lookup $CONNECT.$USER.$GROUP
    Value "SYS1" retained, value "DEV" from record 2 ignored.

    Alternative methods, like writing the connect info to an external file, and processing this external file together with MY.DATASET, fail for the same reason.  And COMPAREOPT, the method to see where lines are different, is not supported for DEFTYPE newlists.

    I had a similar challenge when I built the alert configuration whitelists in C2PCUST members SENSREAD, SENSUPDT etc.  In each member, I wanted to support multiple resources for the same user id.  I ended up reading the member using a CARLa program and converting the whole member into a single EXCLUDE command.  The code to do this conversion is in SCKRSLIB(C2PSDFSE).    It is fairly complex.

    Also, if we want to single out individual connect entries, it is easier to use RACF_ACCESS as the newlist type, where you can use SELECT to identity one connect, as opposed to SUBSELECT in RACF newlists.  The group name is in the PROFILE field and the user id is in ID.  The following JCL would do the job, I think.
    //JCLLIB JCLLIB ORDER=(CKR231.CKRPARM,
    // CKR231.SCKRPROC)
    //*
    //STEP1 EXEC C2RC
    //CKR2PASS DD DISP=(NEW,PASS),DSN=&&CKR2PASS,SPACE=(CYL,(5,5))
    //SYSIN DD *
    Deftype type=$CONNECT
    Alloc   type=$CONNECT dsn=MY.DATASET
    Define  type=$CONNECT $USER(8)  as word(record,1)
    Define  type=$CONNECT $GROUP(8) as word(record,2)

    Newlist type=$CONNECT nopage dd=ckr2pass
    define once(nd) boolean where $user==$user
      sum once count(nd) "define found_connect('Match',5) boolean where",
                         "((complex<<>>complex,"
      sum ")) or (id=" | $user(0) | " profile=(,",
        * $group(0) | "," count(nd)
      sum once count(nd) "))"
    /*
    //STEP2 EXEC C2RC
    //CKR2PASS DD DISP=(OLD,PASS),DSN=&&CKR2PASS,SPACE=(CYL,(5,5))
    //SYSIN DD *
    alloc type=RACF active
    Deftype type=$CONNECT
    Alloc   type=$CONNECT dsn=MY.DATASET
    Define  type=$CONNECT $USER(8) as word(record,1)
    Define  type=$CONNECT $GROUP(8) as word(record,2)

    Newlist type=$CONNECT retain pl=0
      summary $USER('User') $GROUP('Group') Count(nondisplay)

    newlist type=RACF_ACCESS pl=0
      imbed dd=ckr2pass
      select class=group exists(id:$connect.$user.$user)
      sortlist id(8,"User") profile(8,"Group") found_connect
    //
    The first step generates a DEFINE command that is evaluated for each RACF_ACCESS entry:
    define found_connect('Match',5) boolean where ((complex<<>>complex,
    )) or (id=ADAM profile=(,
    ADAMGRP,
    DEV,
    SYS1,
    ))

    Don't think too much about the COMPLEX<<>>COMPLEX clause, it is needed to generate balancing parentheses.  An alternative method is described in the Wiki (while it lasts).



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



  • 3.  RE: zSecure CARLa Question -- Cross-Checking Data

    Posted 10/18/19 08:16 AM
    This is a great start, appreciate the quick response. As far as the data format for the external file you are correct in that it would be as such:

    ADAM     SYS1
    ADAM     DEV
    ADAM     ADAMSGRP

    For ideal behavior I'd be looking to report on *only* UserID / Group connections that are in the external file but *not* in the live RACFDB. Running via the zSecure CO dialog using "Two pass query" would also be preferred (if possible).

    I'll start with the great information you provided and see if I can tweak it as such but any pointers would be great

    ------------------------------
    Adam Klinger
    ------------------------------



  • 4.  RE: zSecure CARLa Question -- Cross-Checking Data

    Posted 10/18/19 12:27 PM
    That should be easy.  There is this defined boolean found_connect,  Specify it as condition on the SELECT command in the 2nd pass:

    newlist type=RACF_ACCESS pl=0
      imbed dd=ckr2pass
      select class=group exists(id:$connect.$user.$user)
    not(found_connect)
      sortlist id(8,"User") profile(8,"Group")

    Tenzij hierboven anders aangegeven: / Unless stated otherwise above:
    IBM Nederland B.V.
    Gevestigd te Amsterdam
    Inschrijving Handelsregister Amsterdam Nr. 33054214


    ------Original Message------

    This is a great start, appreciate the quick response. As far as the data format for the external file you are correct in that it would be as such:

    ADAM     SYS1
    ADAM     DEV
    ADAM     ADAMSGRP

    For ideal behavior I'd be looking to report on *only* UserID / Group connections that are in the external file but *not* in the live RACFDB. Running via the zSecure CO dialog using "Two pass query" would also be preferred (if possible).

    I'll start with the great information you provided and see if I can tweak it as such but any pointers would be great

    ------------------------------
    Adam Klinger
    ------------------------------


  • 5.  RE: zSecure CARLa Question -- Cross-Checking Data

    Posted 10/18/19 12:30 PM
    My bad, my suggestion shows the connect in RACF, but not in the control file.  You want it the other way around.  Let me work on that.

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



  • 6.  RE: zSecure CARLa Question -- Cross-Checking Data

    Posted 10/18/19 12:51 PM
    //JCLLIB JCLLIB ORDER=(CKR231.CKRPARM,
    // CKR231.SCKRPROC)
    //*
    //STEP1 EXEC C2RC
    //CKR2PASS DD DISP=(NEW,PASS),DSN=&&CKR2PASS,SPACE=(CYL,(5,5))
    //SYSIN DD *
    alloc type=RACF active

    Deftype type=$CONNECT
    Alloc   type=$CONNECT dsn=MY.DATASET
    Define  type=$CONNECT $USER(8)  as word(record,1)
    Define  type=$CONNECT $GROUP(8) as word(record,2)

    Newlist type=RACF_access nopage dd=ckr2pass
      define once(nd) boolean where id==id
      select class=group exists(id:$connect.$user.$user)
      sum once count(nd) "define found_connect('Match',5) boolean where",
                         "((complex<<>>complex,"
      sum ")) or ($user=" | id(0) | " $group=(,",
        * profile(0) | "," count(nd)
      sum once count(nd) "))"
    /*
    //STEP2 EXEC C2RC
    //CKR2PASS DD DISP=(OLD,PASS),DSN=&&CKR2PASS,SPACE=(CYL,(5,5))
    //SYSIN DD *
    alloc type=RACF active

    Deftype type=$CONNECT
    Alloc   type=$CONNECT dsn=CRMAROB.MY.DATASET
    Define  type=$CONNECT $USER(8)  as word(record,1)
    Define  type=$CONNECT $GROUP(8) as word(record,2)

    Newlist type=$CONNECT retain pl=0 title="Control file"
      summary $USER('User') $GROUP('Group') Count(nondisplay)

    newlist type=$CONNECT pl=0 title="Missing connects"
      imbed dd=ckr2pass
      select not(found_connect)
      sortlist $user(8,"User") $group(8,"Group")
    //

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