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.  Date Format on Summary Command

    Posted Mon May 08, 2023 03:36 PM

    I opened a case TS012958771 and they could not find a resolution.   Suggest I ask the question here.

    Using NEWLIST TYPE RACF_ACCESS trying to the SUMMARY Command to print a date in the following format DDMMMYYYY. This works when the days are 2 digits, but not on days that are a single digit. I saw in the manuals a figure for the LIST command that showed the options for DATE output. It indicated a date with the length of 9 or 10 should produce the correct output. I tried this on the SUMMARY command and it does not see to work, and I do not see a similar chart for SUMMARY as I did for LIST.

    In the example carla below (Created from AM.3) I am trying to get the field LASTUSE to print as a 2 digit day, Month, and year (ddmmmyyyy). But so far I can only get a one digit day on calendar days the 1st - 9th.

    Suggestions?

    n type=RACF_ACCESS name=CTBYPRFL nodetailinherit required
    st="Permit and UACC usage, Access monitor records for any
    /* Generated by CKRP3AM4 */
    define count_suc(7,"Allowed",udec$abbr,bw,noprop)
    sum(access_count_suc)
    define count_vio(5,"Deny",udec$abbr,bw,noprop)
    sum(access_count_vio)
    define count_unk(5,"Unexp",udec$abbr,bw,noprop)
    sum(access_count_unk)
    define lastuse(10,"LastUse",noprop) max(access_lastuse)
    define firstuse(9,"Firstuse",noprop) min(access_lastuse)
    define prof#(5,"Prof",dec,bw,noprop) sumcount
    define auth#(5,"Auth",dec,bw,noprop) count
    define Miss#(7,"Missing",dec,noprop) count where
    (proftype="missing"C)
    define Pres#(8,"Permits",dec,noprop) count where
    (proftype<>"missing"C)
    define Perm#(8,"Permits and UACC",dec,noprop) count
    select raclist_merge=no class<>group proftype<>GLOBAL

    summary,
    id,
    class(nd),
    profile(nd),
    lastuse(key,"Last-Used",10),
    access_intent_max_suc("Access-Used",12,max),
    access("Access-Allowed",14),
    count_suc(key,14),
    class(pas,key),
    profile(key,60),




    ------------------------------
    Linnea Sullivan
    ------------------------------


  • 2.  RE: Date Format on Summary Command

    Posted Tue May 09, 2023 02:42 AM
    Edited by Jeroen Tiggelman Tue May 09, 2023 08:30 AM

    Hi Linnea,

    SUMMARY is a "LIST family command", so you should expect the output to be similar to LIST.

    However, you base the LASTUSE defined variable on the ACCESS_LASTUSE field in TYPE=RACF_ACCESS.
    The ACCESS_LASTUSE field in is a TOD field, and its output differs from the sample output shown for the DATE format.

    You can see this with

    n type=field                                      
    s newlist_type=racf_access field=access_lastuse   
    sortlist format                                   
    
    B U I L T I N   F I E L D S    8 May 2023 23:25     
                                                        
    Format                                              
    TOD                                                 


    [Or with the FIELD primary command under ISPF you could navigate to the newlist type and field and see all the characteristics.]

    I did not look for RACF_ACCESS input for my test this morning, so I built a sample of how to convert the date format with a different TOD field:

    n type=racf                                   
    s exists(certend)                             
    def ce_date as convert(certend,tod,date)      
    summary ce_date(9)                            


    So, you can convert the TOD field to a DATE field using the CONVERT function of the DEFINE command. After that, you would expect it to work like a DATE field.

    Unfortunately, there are limitations to defining fields in terms of other defined fields. I believe it is currently not possible to take the MAX of a CONVERT result in a single pass.

    I guess you could write out the results as you do now overriding the output format on the field to ASIS, and read the output back in as input using DEFTYPE, and CONVERTing TOD to DATE on this part of the data (while just echoing the other parts of the line).

    If you don't like that approach, it might be time to request an enhancement.


    Edit: Changed HEX to ASIS

    ------------------------------
    Jeroen Tiggelman
    IBM - Software Development and Level 3 Support Manager IBM Security zSecure Suite
    Delft
    ------------------------------



  • 3.  RE: Date Format on Summary Command

    Posted Tue May 09, 2023 02:52 AM
    Edited by Jeroen Tiggelman Tue May 09, 2023 02:58 AM

    Actually, your summary also would not necessarily produce the same output if you converted TOD to DATE before summarizing.
    So perhaps the reformatting-afterwards approach might be best anyway..


    ------------------------------
    Jeroen Tiggelman
    IBM - Software Development and Level 3 Support Manager IBM Security zSecure Suite
    Delft
    ------------------------------



  • 4.  RE: Date Format on Summary Command

    Posted Tue May 09, 2023 08:49 AM
    Edited by Jeroen Tiggelman Tue May 09, 2023 09:01 AM

    Hi again,

    Although you cannot generally DEFINE in terms of another DEFINE, we also have a separate MAX modifier that you can use on the SUMMARY instead of using a variable defined via DEFINE MAX. As it turns out, this can also be used on a variable with a CONVERT.

    So I think this query should do what you want:

    n type=racf_access                                                      
    select raclist_merge=no class<>group proftype<>GLOBAL                   
    define count_suc(7,"Allowed",udec$abbr,bw,noprop)                       
    sum(access_count_suc)                                                   
    define lastuse(10,"LastUse",noprop) as CONVERT(access_lastuse,TOD,DATE) 
    summary id class(nd) profile(nd) lastuse(key,"Last-Used" 10 MAX),       
    access_intent_max_suc("Access-Used",12,max) access("Access-Allowed",14),
    count_suc(key,14) class(pas,key) profile(key,60),                       


    I also tried to make this work with a two-pass approach as I described. It turned out you need to write the original field as ASIS and not as HEX.

    You then get something clunky like this:

    Pass 1

    alloc type=output dd=interim dsn=CRMBINT.C2R2295.REPORT                 
    n type=racf_access   dd=interim                                         
    select raclist_merge=no class<>group proftype<>GLOBAL                   
    define count_suc(7,"Allowed",udec$abbr,bw,noprop)                       
    sum(access_count_suc)                                                   
    define lastuse(10,"LastUse",noprop) as access_lastuse                   
    summary id class(nd) profile(nd) lastuse(key,"Last-Used" 10 ASIS),      
    access_intent_max_suc("Access-Used",12,max) access("Access-Allowed",14),
    count_suc(key,14) class(pas,key) profile(key,60),                                       


    Pass 2

    deftype type=$                                                    
    alloc type=$ dsn=CRMBINT.C2R2295.REPORT                           
    n type=$ name=TITLE nopage                                        
    def test(8) as substring(record,74,8)                             
    def before(10) as substring(record,1,10)                           
    def at(10) as substring(record,11,10)                              
    def at_date(10) as convert(substring(record,11,8),tod,date),      
      where substring(record,11,1)<>' '                               
    def after(0) as substring(record,21)                              
    s test=' '                                                        
    list record(0)                                                    
    n type=$ name=HEADER nopage                                       
    s test='Profile 'c                                                
    list before | at | after                                          
    n type=$ name=DATA nopage                                         
    x likelist=TITLE                                                  
    x likelist=HEADER                                                 
    list before | at_date | after                                     


    Where my REPORT file is VBA. If you use VB, you need most substring offsets one lower.
    For the data lines, I am just copying the parts before and after the value we want to convert.
    The conversion itself is probably clear. The WHERE clause is there to not generate dates from converted missing values.
    The extra two newlists are there to not modify the title and column header lines but always just copy those..
    I use LIST as opposed to SORTLIST so that the lines remain in the order in which they are read.
    (LIST writes immediately when reading a line, whereas SORTLIST reads into memory, sorts, and then produces output--in the order of the newlist statements.)

    I am sure the direct method makes a lot more sense, but thought I would include the "how to" on the circumvention idea anyway. ;-)

    Edits: corrected some of the substring lengths.

    Regards,



    ------------------------------
    Jeroen Tiggelman
    IBM - Software Development and Level 3 Support Manager IBM Security zSecure Suite
    Delft
    ------------------------------



  • 5.  RE: Date Format on Summary Command

    Posted Wed May 10, 2023 01:48 AM

    I realized that using ASIS as an intermediate format without further precautions is not safe.
    The data might contain control characters, which might get stripped out when the data is being written out to the intermediate file.

    Then I realized that by contrast a human-readable date would be safe, and that the CARLa date input parser is fairly lenient.
    So a better circumvention would be to write out the original query, which generates dates, albeit with leading blanks instead of leading zeroes.
    And then read those back in, converting them into date values again, and writing them out again using DATE.

    In other words, use the following DEFINE CONVERT:

    def at_date(10) as convert(substring(record,11,10),datetime,date),
      where substring(record,11,2)<>' '                               

    Note that this uses the whole 10 characters as input, not just the first 8 positions, and that the test for missing is now on the second position, as the first one might be blank in a valid date.



    ------------------------------
    Jeroen Tiggelman
    IBM - Software Development and Level 3 Support Manager IBM Security zSecure Suite
    Delft
    ------------------------------