APIs By Example: Profile Authorization Management

Article ID: 20539
In the previous installment of APIs by Example, I presented the 
Override Group Profile (OVRGRPPRF) command, which enables a temporary 
change of a job's current group profile. To control when and for how 
long to make the OVRGRPPRF command available, the command includes an 
authorization code parameter that is to be requested from a security 
administrator.

To allow a security administrator to issue an authorization code, the 
Add Profile Authorization Code (ADDPRFAUT) command is provided, and 
with this week's version of the OVRGRPPRF command, no user will be 
able to run that command without an authorization code.

The new version of the OVRGRPPRF command further addresses two issues 
that emerged after publication:

a) At security level 40 and above, the command's "hidden" profile 
token parameter would be passed by value the first time the OVRGRPPRF 
command was run in a job, causing the command to fail. (However, any 
further attempts would succeed.) The passing of the profile token 
parameter has been changed and is now performed by means of a 
temporary user space.

b) In the event that the OVRGRPPRF command was run by a user profile 
that had OWNER(*GRPPRF) specified, the system would not allow a change 
of the effective group profile, so the command would fail.

By temporarily adding the original group profile to the current job's 
array of supplemental groups, it was possible to address this problem 
on systems running V5R2 or later. (Thank you Jean-Marie Sauvageot for 
reporting these issues.)

Now back to the ADDPRFAUT command. The command's prompt panel follows:
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

             Add profile authorization code (ADDPRFAUT)

 Type choices, press Enter.

 User profile . . . . . . .                 Name
 Group profile  . . . . . .                 Name
 Authorization code . . . .                 Character value
 Reason . . . . . . . . . . 
 Valid time . . . . . . . .   60            Minutes
 Replace authorization code   *NO           *NO, *YES

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
A short explanation of the command's parameters follows. Please refer to the command's help text for further details: User profile: The user profile being authorized to perform a temporary group profile override. Group profile: The group profile that the specified user profile is authorized to override its current group profile to. Authorization code: The authorization code that should be entered in the OVRGRPPRF command to allow the group profile override to take place. By default the authorization code is capitalized. Reason: A brief explanation of the reason for the group profile override. This information will also be recorded in an audit journal entry. Valid time: Specifies the number of minutes that the authorization code will be valid, counting from the time it is created. Replace authorization code: If an authorization code already exists for the specified user profile and group profile, the ADDPRFAUT command will fail unless this parameter is set to *YES. In the event that an authorization code has expired, this setting also allows you to renew that authorization code. The ADDPRFAUT command writes audit journal entries to the system audit journal, QAUDJRN. It documents both initiation and termination of the command. The audit entries will have journal code 'U'. The entry type for initial profile authorization is 'A0' and the entry type for exit profile authorization is 'A1'. The data structures JrnEntA0 and JrnEntA1 in the sources CBX1291V and CBX1291, respectively, document the layout of the two journal entry formats. As I mentioned last time, the core of this utility is a validation list object that is used to store the authorization codes and the authorization codes' expiration timestamps. Validation lists are managed by a set of APIs, which come in two flavors: One for ILE programs, and one for OPM programs. To call these APIs, some complex data structures have to be employed. V5R1 of ILE RPG brought the new keywords LikeDs and Inz(*LikeDs), which made it possible to define a data structure with the same format as another data structure and, at the same time, initialize the new data structure with the same values specified in the "template" data structure. V5R2 enhanced this ability further by allowing you to specify these keywords on a subfield of a data structure. This way, you could have one data structure be part of another. In other words, the "Chinese box" data structure became possible. Prior to these enhancements, it was not possible to code an exact match of the data structures as they are specified in the documentation. It was possible to perform a successful call to the API, but the flexibility provided by the data structures was lost. For example, take a look at the Add Validation List Entry API parameter data structure that specifies the entry's attribute data, Qsy_Attr_Info_T. It's defined by three subfields:
     **-- Validation list attribute data:
A->  D Qsy_Attr_Info_T...
     D                 Ds                Qualified
     D  Number_Attrs               10i 0 Inz( 1 )
     D  Res_align                  12a
B->  D  Attr_Descr                       LikeDs(Qsy_Attr_Descr_T)
C->  D                                   Inz( *LikeDs )
The third parameter, Attr_Descr, is defined by the LikeDs to have the same format as the template data structure called Qsy_Attr_Descr_T (B). The many subfield initializations in the template data structure are propagated to the Attr_Descr parameter with the Inz( *LikeDs ) keyword (C). The following code snippet shows these initializations:
     D Qsy_Attr_Descr_T...
     D                 Ds                Qualified
     D  Attr_Location            10i 0 Inz( QSY_IN_VLDL )
     D  Attr_Type                10i 0 Inz( QSY_SYSTEM_ATTR )
     D  Attr_Res                  8a   Inz( *Allx'00' )
F->  D  Attr_ID_p                  *
     D  Attr_Other_Descr...
     D                           32a   Inz( *Allx'00' )
     D  Attr_Data_Info...
     D                           96a
D->  D   Attr_VLDL                     LikeDs(Qsy_In_VLDL_T )
     D                                 Overlay(Attr_Data_Info: 1)
E->  D                                 Inz( *LikeDs )
     D   Attr_In_Other...
     D                           96a   Overlay(Attr_Data_Info:1)
     D                           64a   Overlay(Attr_In_Other:33)
     D                                 Inz( *Allx'00' )
     D  Attr_Other_Data...
     D                           32a   Inz( *Allx'00' )
The Qsy_Attr_Descr_T data structure again contains an embedded data structure, Attr_VLDL. This data structure is, in turn, defined by the template data structure Qsy_In_VLDL_T (D). The Attr_VLDL data structure is initialized with the values from the template data structure using the Inz( *LikeDs ) keyword (E). The following code is where those initializations take place:
     D Qsy_In_VLDL_T   Ds                  Qualified
     D  Attr_CCSID               10i 0 Inz( -1 )
G->  D  Attr_Len                 10i 0 Inz( 1 )
     D  Attr_Res_1                8a   Inz( *Allx'00' )
H->  D  Attr_Value_p               *

     **-- Qsy_Attr_Descr_T structure constants:
     D QSY_IN_VLDL     c                   0
     D QSY_SYSTEM_ATTR...
     D                 c                   0
     **-- Qsy_In_VLDL_T structure parameter:
     D Qsy_Vfy_Only    s              1a   Inz( '0' )

        Reset  Qsy_Entry_ID_Info_T;
In the code, the complex data structures' subfields are referred to by specifying their qualified name:
A->  Qsy_Attr_Info_T
B->  |               Attr_Descr
F->  |               |          Attr_ID_p
     |               |          |
     Qsy_Attr_Info_T.Attr_Descr.Attr_ID_p = %Alloc( 15 );

A->        Qsy_Attr_Info_T
B->        |               Attr_Descr
F->        |               |          Attr_ID_p
           |               |          |
     %Str( Qsy_Attr_Info_T.Attr_Descr.Attr_ID_p: 15 ) 
           = 'QsyEncryptData';

A->  Qsy_Attr_Info_T
B->  |               Attr_Descr
D->  |               |          Attr_VLDL
G->  |               |          |         Attr_Len
     |               |          |         |
     Qsy_Attr_Info_T.Attr_Descr.Attr_VLDL.Attr_Len 
           = %Size( Qsy_Vfy_Only );

A->  Qsy_Attr_Info_T
B->  |               Attr_Descr
D->  |               |          Attr_VLDL
H->  |               |          |         Attr_Value_p
     |               |          |         |
     Qsy_Attr_Info_T.Attr_Descr.Attr_VLDL.Attr_Value_p 
            = %Addr( Qsy_Vfy_Only );
The use of functionality requires V5R2 or later, which of course means that the profile authorization utility also requires V5R2 or later. In the event that you need to compile this utility to V5R1, you can find an example of how to code the validation list data structures for earlier releases at the following link: http://www.iseriesnetwork.com/resources/artarchive/index.cfm?fuseaction=... Or you can contact me at the e-mail address specified below, and I'll try to help you out. Finally, to let you easily verify and remove authorization codes, the Manage Profile Authorization (MNGPRFAUT) command is also provided:
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

              Manage profile authorization (MNGPRFAUT)

 Type choices, press Enter.

 User profile . . . . . . .                 Name
 Group profile  . . . . . .                 Name
 Authorization option . . .   *VERIFY       *VERIFY, *REMOVE

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
If you run the MNGPRFAUT command, specifying OPTION(*VERIFY), a message is returned specifying the following information:
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

                  Additional Message Information

Message ID . . . : CBX0001      Severity . . . . . . : 00
Message type . . : Information
Date sent  . . . : 09-01-05     Time sent  . . . . . : 15:06:12

Message . . . . :   User profile JMS authorization code to group 
profile QSECOFR verified.

The following authorization code attributes were returned:
  Creation date  . . . . . . :  08-01-05 17:48:58
  Last verification date . . :  08-01-05 17:49:00
  Invalid password count . . :  0

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Specifying OPTION(*REMOVE) physically removes the authorization code from the utility validation list. As always, please refer to the command's help text for further details. To offer a single entry point for all three profile authorization commands, I have further included a UIM menu. Running the command GO PRFAUT will take you to the following panel:
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

PRFAUT              Profile Authorization Menu
                                                 System: SYSTEM
Select one of the following:

  Override commands
     1. Override group profile                       OVRGRPPRF

  Management commands
    11. Add profile authorization                    ADDPRFAUT
    12. Manage profile authorization                 MNGPRFAUT

  Service options
    90. Sign off                                     SIGNOFF
                                                        Bottom
Selection or command
===>
F3=Exit   F4=Prompt   F9=Retrieve   F12=Cancel

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
You will only see the menu options that your user profile is actually authorized to, as defined by the object authorization of each command associated with the individual menu options. Help text is also available for the menu at global, option, and F-key levels. In the following section, you will find a specification of the sources involved in the profile authorization utility, as well as instructions on how to create and configure all the utility objects: The OVRGRPPRF command includes the following sources: CBX128 -- Command processing program that performs the group profile override. CBX128V -- Validity checking program that performs integrity and access control. CBX128H -- Command help text panel group. CBX128X -- Command definition source member. CBX128M -- Creates and configures all command objects. The ADDPRFAUT command includes the following sources: CBX1291 -- Command processing program stores the profile authorization code in a validation list. CBX1291V -- Validity checking program that performs integrity and access control. CBX1291H -- Command help text panel group. CBX1291X -- Command definition source member. CBX1291M -- Creates and configures all command objects. The MNGPRFAUT command includes the following sources: CBX1292 -- Command processing program that performs the group profile override. CBX1292V -- Validity checking program that performs integrity and access control. CBX1292H -- Command help text panel group. CBX1292X -- Command definition source member. CBX1292M -- Creates and configures all command objects. The PRFAUT menu includes the following source: CBX129 -- The UIM menu source member. Once all the above-specified source members have been copied to their default source files and the program CBX128M has been compiled, calling CBX128M will create all necessary command objects. Specify the source file library as the only parameter. All the command objects will be created in that library as well.
  Call   Pgm( CBX128M )   Parm( '' )
The commands' objects will be created in the library where the source files are located. Please note that to successfully run the above program, the user profile performing the call must have *ALLOBJ special authority. Please also note that the primary objective of the above commands is to demonstrate practical use of the IFS security APIs. Before creating and installing the objects on a production system, you should carefully and thoroughly test the utility, to ensure that it meets your security requirements and guidelines. This article demonstrates the following APIs: Get Effective Group ID (getegid) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/getegid.... Get Group Information using Group Name (getgrnam) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/getgrnam... Set Effective Group ID (qsysetegid) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qsyseteg... Get Supplemental Group IDs (qsygetgroups) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qsygetgr... Set Supplemental Group IDs (qsysetgroups) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qsysetgr... Retrieve Job Information (QUSRJOBI) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qusrjobi... Retrieve Object Information (QUSROBJD) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qusrobjd... Retrieve User Information (QSYRUSRI) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qsyrusri... Create User Space (QUSCRTUS) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/quscrtus... Delete User Space (QUSDLTUS) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qusdltus... Retrieve Pointer to User Space (QUSPTRUS) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qusptrus... Send Program Message (QMHSNDPM) API: http://publib.boulder.ibm.com/iseries/v5r2/ic2924/info/apis/QMHSNDPM.htm Check User Special Authorities (QSYCUSRS) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/QSYCUSRS... Send Journal Entry (QJOSJRNE) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/QJOSJRNE... The Find Validation List Entry (QsyFindValidationLstEntry) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/QSYFIVLE... The Find Validation List Entry Attributes (QsyFindValidationLstEntryAttrs) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/QSYFIVLA... The Verify Validation List Entry (QsyVerifyValidationLstEntry) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/QSYVFVLE... The Add Validation List Entry (QsyAddValidationLstEntry) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qsyavle.... The Remove Validation List Entry (QsyRemoveValidationLstEntry) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/QSYRVLE.... The Generate Profile Token (QsyGenPrfTkn) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qsygenpt... The Check Profile Token User (QsyChkPrfTknUser) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qsychktu... The Get Profile Token Time Out (QsyGetPrfTknTimeOut) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qsygetpt... The Remove Profile Token (QsyRemovePrfTkn) API: http://as400bks.rochester.ibm.com/iseries/v5r2/ic2924/info/apis/qsyrptkn... The following MI built-in function is demonstrated in this article: _MODINVAU -- Modify Invocation Authority Attributes http://publib.boulder.ibm.com/iseries/v5r1/ic2924/tstudio/tech_ref/mi/MO... The following function from the ILE C runtime library is demonstrated in this article: strerror -- Set Pointer to Run-Time Error Message http://publib.boulder.ibm.com/iseries/v5r2/ic2924/books/c415607107.htm#H... You can retrieve the source code for this utility from http://www.iseriesnetwork.com/noderesources/code/clubtechcode/PrfAutMgt.... . The above article was written by Carsten Flensburg. If you have any questions, you can contact Carsten at mailto:flensburg@novasol.dk .

ProVIP Sponsors

ProVIP Sponsors