Learn a basic authority-related technique along with a practical Print Private Authorities utility.
In IBM i, there are authority special values defined at the OS level, which are used by authority-related CL commands and APIs, and there are other authority special values defined at the Machine Interface (MI) level, which are used by Authorization Management MI instructions. The meanings of these two sets of authority values are almost identical; however, their representations are far different from each other.
An OS-level authority special value is a 10-byte character string, e.g., *ADD. An MI authority value is 2-byte authority field, e.g., bit 5 of a 2-byte authority field represents Insert authority to an MI object. As you might notice, when these two sets of authority values are used in a same application, methods for conversion between them would be needed. This article will use practical examples to show you one of the possible solutions to convert authority values from the OS level to the MI level and back.
Convert Authority Special Values to MI Authority Values
The Convert Authority Values to MI Value (QSYCVTA) API converts one or more authority special values to the corresponding MI representation of that value. The output 2-byte MI authority value is returned in the first parameter of the QSYCVTA API. The second parameter (authority special values) of the QSYCVTA API can contain up to eleven 10-character fields. Each of the 10-character fields can contain one of the following OS-level authority special values.
Special Value |
Description |
*ADD |
Add authority. |
*AUTL |
Authorization list authority. If this value is specified, no other values can be specified. This authority value is valid only for *PUBLIC authority on an object secured by an authorization list. |
*AUTLMGT |
Authorization list management authority. |
*DLT |
Delete authority. |
*EXECUTE |
Execute authority. |
*EXCLUDE |
Exclude authority. If this value is specified, no other values can be specified. |
*OBJALTER |
Object alter authority. |
*OBJEXIST |
Object existence authority. |
*OBJMGT |
Object management authority. |
*OBJOPR |
Object operational authority. |
*OBJREF |
Object reference authority. |
*READ |
Read authority. |
*UPD |
Update authority. |
*USE |
Use authority. |
*CHANGE |
Change authority. |
*ALL |
All authority. |
Note that within all the authority values accepted by QSYCVTA, *ADD, *DLT, *READ, *UPD, and *EXECUTE are data authorities, and *OBJALTER, *OBJEXIST, *OBJMGT, *OBJOPR, and *OBJREF are object authorities. *EXCLUDE is both a data authority and an object authority, which means the user is not permitted to access the object. *USE, *CHANGE, and *ALL are system-predefined authority values that are combinations of more than one individual authority values. The following is an example EDTOBJAUT display that shows the composition of these system-predefined authority values.
Edit Object Authority
Object . . . . . . . : SPCX Owner . . . . . . . : LJL
Library . . . . . : QGPL Primary group . . . : *NONE
Object type . . . . : *USRSPC ASP device . . . . . : *SYSBAS
Type changes to current authorities, press Enter.
Object secured by authorization list . . . . . . . . . . . . *NONE
Object ----------Object----------- ---------------Data---------------
User Group Authority Opr Mgt Exist Alter Ref Read Add Update Delete Execute
*PUBLIC *USE X X X
X1 *CHANGE X X X X X X
X *EXCLUDE
X2 *ALL X X X X X X X X X X
Also note that *EXCLUDE is different from no authority. For example, if a user does not have private authority to an object, the *PUBLIC authority can be used for the user to access the object; however, if the user has *EXCLUDE private authority to the object, object access will be prohibited.
The following RPG example program (autbits01.rpgle) uses the QSYCVTA API to convert each individual authority special value to the corresponding MI authority values.
h dftactgrp(*no) bnddir('QC2LE')
d qsycvta pr extpgm('QSYCVTA') d miaut d spcval d numval 10u 0 d ec d cvthc pr extproc('cvthc') d d d 10u 0 value
d miaut s d ARRELMT c 16 d ds d spcvali d '*OBJEXIST + d *OBJMGT + d *OBJOPR + d *READ + d *ADD + d *DLT + d *UPD + d *EXCLUDE + d *AUTLMGT + d *EXECUTE + d *OBJALTER + d *OBJREF + d *AUTL + d *USE + d *CHANGE + d *ALL ') d spcval d overlay(spcvali) d msg ds qualified d spcval d d miaut d num s 10u 0 inz(1) d ec s d i s 5u 0
/free for i = 1 to ARRELMT; qsycvta(miaut : spcval(i) : num : ec); msg.spcval = spcval(i); cvthc(msg.miaut : miaut : 4); dsply msg ''; endfor;
*inlr = *on; /end-free |
Output of autbits01.rpgle is the following:
DSPLY *OBJEXIST 8000 DSPLY *OBJMGT 4000 DSPLY *OBJOPR 3000 DSPLY *READ 0800 DSPLY *ADD 0400 DSPLY *DLT 0200 DSPLY *UPD 0100 DSPLY *EXCLUDE 0040 DSPLY *AUTLMGT 0020 DSPLY *EXECUTE 0010 DSPLY *OBJALTER 0008 DSPLY *OBJREF 0004 DSPLY *AUTL 0000 DSPLY *USE 3810 DSPLY *CHANGE DSPLY *ALL FF |
Utilize the MI Authority Value Returned by the QSYCVTA API
The 2-byte MI authority value returned by the QSYCVTA API is useful when you're working with the test authority MI instructions, such as Test Authority (TESTAU) and Test User List Authority (TESTULA). It also can be used as one of the search criteria (the minimum required authority) when resolving a system pointer to an MI object via the Resolve System Pointer (RSLVSP) MI instruction. For example, the following RPG program (autbits02.rpgle) resolves a system pointer to a user space object (with MI object type code hex 1934) called SPCX in the library list that the current invocation has at least *CHANGE authority to!
h dftactgrp(*no)
/copy mih-ptr
d qsycvta pr extpgm('QSYCVTA') d miaut d spcval d numval 10u 0 d ec
d spcx s * d aut_change s d num s 10u 0 inz(1) d ec s
/free rslvsp_tmpl.obj_type = x'1934'; rslvsp_tmpl.obj_name = 'SPCX'; qsycvta( rslvsp_tmpl.auth : aut_change : num : ec ); // Convert *CHANGE to MI auth-value rslvsp2( spcx : rslvsp_tmpl ); // Check SYSPTR spcx
*inlr = *on; /end-free |
The first user space object called SPCX in the library list of the current job that the current invocation has at least *CHANGE authority to will be resolved. If no such user space object is found, program AUTBITS02 will fail with an Object Not Found exception (hex 2201), aka MCH3401.
Convert MI Authority Values to Authority Special Values
Why do we need to convert MI authority values to authority special values defined at the OS level? Authority values returned by authorization management MI instructions are in the form of MI authority bits. Various authority fields we read in the encapsulated part of an MI object via the System Service Tools (SST) are also in the form of MI authority bits. When evaluating the value of a system pointer in a debug session, the authority bits in the system pointer are also in the form of MI authority bits.
Map MI Authority Bits to OS Level Authority Special Values
By using the above-shown output of program autbis01.rpgle in combination with the document on Authorization Management MI instructions in the Information Center, you can easily figure out the following mapping relationship from MI authority bits to OS-level authority special values.
Mapping Relationship from MI Authority Bits to OS-Level Authority Special Values |
|||
MI Authority Value |
Authority Special Values |
Authority Bits |
Description |
8000 |
*OBJEXIST |
Bit 0 = 1 |
Object existence authority |
4000 |
*OBJMGT |
Bit 1 = 1 |
Object management authority |
3000 |
*OBJOPR |
Bit 2 = 1, and bit 3 = 1 |
Object operational authority (Authorized pointer plus space authority) |
0800 |
*READ |
Bit 4 = 1 |
Read authority |
0400 |
*ADD |
Bit 5 = 1 |
Add authority |
0200 |
*DLT |
Bit 6 = 1 |
Delete authority |
0100 |
*UPD |
Bit 7 = 1 |
Update authority |
0040 |
*EXCLUDE |
Bit 9 = 1 |
Excluded. If this value is specified, no other values can be specified. |
0020 |
*AUTLMGT |
Bit 10 = 1 |
Authority list management |
0010 |
*EXECUTE |
Bit 11 = 1 |
Execute authority |
0008 |
*OBJALTER |
Bit 12 = 1 |
Object alter authority |
0004 |
*OBJREF |
Bit 13 = 1 |
Object reference authority |
0000 |
*AUTL |
|
Authorization list authority. If this value is specified, no other values can be specified. This authority value is only valid for *PUBLIC authority on an object secured by an authorization list. |
System-Predefined Authority Special Values (*USE, *CHANGE, *ALL) |
|||
3810 |
*USE |
|
|
|
*CHANGE |
|
|
FF |
*ALL |
|
|
The algorithm of mapping an input 2-byte MI authority value to an OS-level authority special value is quite simple and straightforward. For example:
- 1.Check for *EXCLUDE and *AUTL authorities. If the input MI authority value is one of them, no further test is needed.
- 2.Check for one of the system-predefined authority special values: *USE, *CHANGE, and *ALL. If matches, no further test is needed.
- 3.Check whether bit 2 and bit 3 are both set. If so, the *OBJMGT authority is specified.
- 4.Check each of the other 10 authority bits. If an individual authority bit is set, record the corresponding special value.
The following example RPG procedure (cvt_auth_val), which is extracted from autbits03.rpgle, implements the above-shown algorithm. Procedure cvt_auth_val accepts an input 2-byte MI authority value and returns a list of converted OS-level authority special values via its second parameter, a data structure of type auth_val_lst_t.
* Authority value list DS d auth_val_lst_t ds qualified d num_auth 5u 0 d auth_val * ... ... p cvt_auth_val b d auth_bit_t ds qualified d mi_aut_bit d auth_val
* *EXCLUDE, *AUTL, *USE, *CHANGE, *ALL d a1 ds qualified d c d x'00405CC5E d 00005CC1E4E3D34040404040+ d 38105CE4E d d FF d ) d arr likeds(auth_bit_t) d dim(5) d overlay(c) * Auth constants array 2 (10 elements) * *OBJEXIST, *OBJMGT, *OBJOPR, *READ, *ADD, *DLT, *UPD, * *AUTLMGT, *EXECUTE, *OBJALTER, *OBJREF d a2 ds qualified d c d x'80005CD d 40005CD d 08005CD d 04005CC d 02005CC4D3E3404040404040+ d 01005CE4D d 00205CC1E4E3D3D d 00105CC5E d 00085CD d 00045CD d arr likeds(auth_bit_t) d dim(10) d overlay(c)
d i s 5u 0
d cvt_auth_val pi d mi_aut_val d auth_val_lst likeds(auth_val_lst_t)
/free // *EXCLUDE, *AUTL and system-predefined authorities: // *USE, *CHANGE, *ALL for i = 1 to 5; if mi_aut_val = a1.arr(i).mi_aut_bit; auth_val_lst.num_auth = 1; auth_val_lst.auth_val(1) = a1.arr(i).auth_val; return; endif; endfor;
// Test for *OBJOPR (hex 3000) auth_val_lst.num_auth = 0; if %bitand( mi_aut_val : x'3000' ) > x'0000'; auth_val_lst.num_auth += 1; auth_val_lst.auth_val(1) = '*OBJOPR'; endif;
// Test for 10 indivisual authorities for i = 1 to 10; if %bitand ( mi_aut_val : a2.arr(i).mi_aut_bit ) > x'0000'; auth_val_lst.num_auth += 1; auth_val_lst.auth_val(auth_val_lst.num_auth) = a2.arr(i).auth_val; endif; endfor;
return; /end-free p e |
A Real Example: Print the User Profiles Privately Authorized to an Object and Corresponding Private Authority Values
The Materialize Authorized Users (MATAUU) MI instruction materializes the authorization states in an MI object and the identification of the user profiles. The materialized authority states are in the form of MI authority bits. The following example RPG program (prtpraut.rpgle) materializes private authorized user profiles and corresponding private authority states with option hex 32, and converts the authority states to OS-level authority special values using the above-mentioned cvt_auth_val procedure.
h dftactgrp(*no) fQSYSPRT o f 132 disk /copy mih-ptr /copy mih-prcthd /copy mih-auth /copy mih-pgmexec * Authority value list DS d auth_val_lst_t ds qualified d num_auth 5u 0 d auth_val * My prototype d i_main pr extpgm('PRTPRAUT') d obj_name d obj_type * Convert MI authority bits to authority special values d cvt_auth_val pr extproc('cvt_auth_val') d mi_aut_val d auth_val_lst likeds(auth_val_lst_t) * A speical prototype for system built-in _CALLPGMV d x pr extproc('_CALLPGMV') d callee * d argv d argc 10u 0 value * Parameter list of QLICNV * d qlicnv_argv ds d ex_type d d mi_type d d arrow d * * QLICNV's entry number in SEPT d QLICNV_ENTRY c x'
d @pco s * d @sept s * based(@pco) d sept s * based(@sept) d dim(7000)
d obj s * * MATAUU option d mat_opt s * MATAUU materialization template d tmpl ds likeds(matauu_tmpl_t) d based(@tmpl) d authd ds likeds(auth_desc_long_t) d based(@authd) d len s 10u 0 d inx s 10u 0 d ws s d user s d prau s d autlst ds likeds(auth_val_lst_t)
d i_main pi d obj_name d obj_type
/free // [1] // Call QLICNV to convert external object type to MI object type ex_type = %subst(obj_type : 2 : 7); @pco = pcoptr2(); // [1.1] Locate SEPT x ( sept(QLICNV_ENTRY) : qlicnv_argv : 3 ); // [1.2] Call QLICNV via SEPT
// [2] Resolve target object rslvsp_tmpl.obj_name = obj_name; rslvsp_tmpl.obj_type = mi_type; rslvsp2 (obj : rslvsp_tmpl);
// [3] Materialize private authorities in @var obj // [3.1] Allocate storage for the materialization tmplate mat_opt = x'32'; @tmpl = modasa(8); tmpl.bytes_in = 8; matauu(@tmpl : obj : mat_opt); len = tmpl.bytes_out; @tmpl = modasa(len);
// [3.2] // Materialize private authorized USRPRFs and // corresponding private authority states tmpl.bytes_in = len; matauu(@tmpl : obj : mat_opt);
except OBJREC; // [3.3] Check each entry returned by MATAUU @authd = @tmpl + %size(matauu_tmpl_t); // size=16 for inx = 1 to tmpl.num_private_users; // Set USER field in PRAUREC user = authd.usrprf_name;
// [3.4] Convert MI auth-bits to special values autlst.num_auth = 0; cvt_auth_val( authd.private_auth : autlst);
@prau = %addr(autlst) + 2; // PRAU field in PRAUREC except PRAUREC;
// Next entry @authd += %size(auth_desc_long_t); endfor;
*inlr = *on; /end-free
* Output record formats oQSYSPRT e OBJREC o obj_name o ws o obj_type * Private authority for a USRPRF oQSYSPRT e PRAUREC o user o ws o prau
p cvt_auth_val b * Contents of procedure cvt_auth_val is omitted. p e |
Notes
- [1] Call the QLICNV API to convert an input external object type to MI object type. Note that the public authority of QLICNV is *EXCLUDE. Therefore, you should access it via its resolved system pointer in SEPT instead of resolving it via its symbolic identifier. This API was discussed in my article "Want to Know All the MI Object Types Supported by Your IBM i?"
- [1.2] Note the definition of data structure qlicnv_argv. The QLICNV API accepts parameters passed by value. However, Call Program verbs in IBM i high-level languages do not support this kind of external program call. Here, a tiny trick is used to let the CALLPGMV system built-in to help us pass parameters to the QLICNV API by values.
- [2] Resolve a system pointer to the target object.
- [3] Materialize private authorities in the target object.
- [3.4] Convert MI authority bits to OS-level authority special values via the cvt_auth_val procedure.
To test the PRTPRAUT program, you can create a User Space object and set one or more private authorities in it. For example:
/* Call QUSCRTUS to create a User Space object called SPCABC */ CALL PGM(QUSCRTUS) PARM('SPCABC *CURLIB' 'ABC' X'00001000' X'00' *EXCLUDE 'Test of PRTPRAUT') /* Grant *USE and *ADD authority for user profile X1 on SPCABC */ GRTOBJAUT OBJ(SPCABC) OBJTYPE(*USRSPC) USER(X1) AUT(*USE) GRTOBJAUT OBJ(SPCABC) OBJTYPE(*USRSPC) USER(X1) AUT(*ADD) /* Grant *USE, *UPD, and *DLT authority for user profile X2 on SPCABC */ GRTOBJAUT OBJ(SPCABC) OBJTYPE(*USRSPC) USER(X2) AUT(*USE) GRTOBJAUT OBJ(SPCABC) OBJTYPE(*USRSPC) USER(X2) AUT(*UPD) GRTOBJAUT OBJ(SPCABC) OBJTYPE(*USRSPC) USER(X2) AUT(*DLT) |
Call PRTPRAUT to retrieve the private authority information of User Space SPCABC like this:
CALL PRTPRAU (SPCABC *USRSPC)
The resulting spooled file might look like the following:
SPCABC *USRSPC X1 *OBJOPR *READ *ADD *EXECUTE X2 *OBJOPR *READ *DLT *UPD *EXECUTE |
LATEST COMMENTS
MC Press Online