Wednesday, February 26, 2025

Faster way to check authority to IFS object with SQL

I could already check my authorization to an object in the IFS using the IFS_OBJECT_PRIVILEGES SQL Table function. If I wanted to check if I was authorized to, let's say, read the object the Table function still takes time to retrieve columns of data even if I don't include them in my result set. A better approach would be if I can just check if I am authorized to an IFS object, and have a return code that indicates if I am authorized or not.

A new SQL scalar function, IFS_ACCESS, was added as part of the last round of Technology Refreshes, IBM i TR5 and 7.5 TR11, that does this, which makes the time taken to check if I am authorized a whole lot faster.

All of examples are going to use a stream file, *STMF, in my folder in the IFS. I can check who and what authorizations they have to the object by using the IFS_OBJECT_PRIVILEGES View:

01  SELECT PATH_NAME,AUTHORIZATION_NAME,OBJECT_TYPE,DATA_AUTHORITY
02    FROM TABLE(QSYS2.IFS_OBJECT_PRIVILEGES('/home/MyDirectory/test.txt'))

Line 1: I am only interested in these columns:

  • PATH_NAME:  Path or file name
  • AUTHORIZATION_NAME:  User
  • OBJECT_TYPE:  In this case it will always be "*STMF", which is for a stream file
  • DATA_AUTHORITY

Line 2: In all of these examples I will be using the file test.txt, which is in my folder MyFolder.

The results for this statement are:

                         AUTHORIZATION  OBJECT  DATA_
PATH_NAME                _NAME          _TYPE   AUTHORITY
-----------------------  -------------  ------  ---------
/home/MyFolder/test.txt  *PUBLIC        *STMF   *RWX
/home/MyFolder/test.txt  SIMON          *STMF   *RWX

The results show that both I, with the user profile SIMON, and the public have read, write, and execute authority to the file.

The IFS_ACCESS is found in the SYSTOOLS library, and it has three parameters:

  1. READ:  Do I have read authority to the object?
  2. WRITE:  Do I have write authority to the object?
  3. EXECUTE:  Can I execute the object?

The valid values for the parameters are "YES" and "NO", with the default being No.

In the statement below I am going to test if I am authorized for all of those authorizations to my file, test.txt. As this is a Scalar function I can use the Values SQL statement to execute it:

01  VALUES SYSTOOLS.IFS_ACCESS(
02               PATH_NAME => '/home/MyFolder/test.txt', 
03               READ => 'YES',
04               WRITE => 'YES',
05               EXECUTE => 'YES')

This returns an ERRNO code:

00001
------
     0

I happen to know that "0" is the equivalent of executed successfully. But I am not so sure about other ERRNO codes, therefore, I can wrap the above inside the ERRNO_INFO scalar function:

01  VALUES SYSTOOLS.ERRNO_INFO(
02    SYSTOOLS.IFS_ACCESS(
03          PATH_NAME => '/home/MyFolder/test.txt', 
04          READ => 'YES',
05          WRITE => 'YES',
06          EXECUTE => 'YES'))

This returns the ERRNO description:

00001
------------------
There is no error.

If I just wanted to check if I am authorized to read the file my statement would become:

01  VALUES SYSTOOLS.ERRNO_INFO(
02    SYSTOOLS.IFS_ACCESS(PATH_NAME => '/home/MyFolder/test.txt', 
03                      READ => 'YES'))

The results tell me I am authorized to read the file:

00001
------------------
There is no error.

The user profile SIMON is not authorized to change the authority on the IFS object, there I use my other profile SIMON2, which does. I use the Change Authority command, CHGAUT, to well... change the authority of the file:

CHGAUT OBJ('/home/MyFolder/test.txt') USER(SIMON) DTAAUT(*WX)

I have change SIMON's authorization to write and execute only. I can confirm that using the IFS_OBJECT_PRIVILEGES Scalar function again. The results are now:

                        AUTHORIZATION  OBJECT  DATA_
PATH_NAME               _NAME          _TYPE   AUTHORITY
----------------------  -------------  ------  ---------
/home/MyFolder/test.txt  *PUBLIC       *STMF   *RWX
/home/MyFolder/test.txt  SIMON2        *STMF   *RWX
/home/MyFolder/test.txt  SIMON         *STMF   *WX

Now when I check if I am authorized to read, write, and execute the file:

01  VALUES SYSTOOLS.ERRNO_INFO(
02    SYSTOOLS.IFS_ACCESS(
03          PATH_NAME => '/home/MyFolder/test.txt', 
04          READ => 'YES',
05          WRITE => 'YES',
06          EXECUTE => 'YES'))

I get the following result as I am no longer authorized to read the file.

00001
------------------
Permission denied.

If I just wanted to check if I can write to and execute the file:

01  VALUES SYSTOOLS.ERRNO_INFO(
02    SYSTOOLS.IFS_ACCESS(
03          PATH_NAME => '/home/MyFolder/test.txt', 
04          WRITE => 'YES',
05          EXECUTE => 'YES'))

I am still authorized:

00001
------------------
There is no error.

It is more likely that I would give read only authority to the file. SIMON2 does that with:

CHGAUT OBJ('/home/MyFolder/test.txt') USER(SIMON) DTAAUT(*R)

The results from IFS_OBJECT_PRIVILEGES show that I just have read access:

                        AUTHORIZATION  OBJECT  DATA_
PATH_NAME               _NAME          _TYPE   AUTHORITY
-----------------------  -------------  ------  ---------
/home/MyFolder/test.txt  *PUBLIC        *STMF   *RWX
/home/MyFolder/test.txt  SIMON2         *STMF   *RWX
/home/MyFolder/test.txt  SIMON          *STMF   *R

Now if I want to check if I have read authorization I would just:

01  VALUES SYSTOOLS.ERRNO_INFO(
02    SYSTOOLS.IFS_ACCESS(
03          PATH_NAME => '/home/MyFolder/test.txt', 
04          READ => 'YES'))

And the results confirms that I am:

00001
------------------
There is no error.

To demonstrate that SIMON and SIMON2 have different authority to the file if I execute the following in a ACS "Run SQL Scripts" session when signed on as SIMON2:

01  VALUES SYSTOOLS.ERRNO_INFO(
02    SYSTOOLS.IFS_ACCESS(
03          PATH_NAME => '/home/MyFolder/test.txt', 
04          READ => 'YES',
05          WRITE => 'YES',
06          EXECUTE => 'YES'))

The results are:

00001
------------------
There is no error.

How could I use this? Here is an example of the SQL embedded in a RPG program:

01  **free                                                        
02  dcl-s ErrNo uns(5) ;

03  exec sql SET :ErrNo = SYSTOOLS.IFS_ACCESS(
                            PATH_NAME => '/home/MyFolder/test.txt',
                            READ => 'YES') ;

04  if (ErrNo = 0) ;
05    dsply 'You can read the file' ;
06  else ;
07    dsply ('You cannot read the file (' + %char(ErrNo) + ')') ;
08  endif ;

09  *inlr = *on ;

Line 2: This variable will contain the ERRNO returned from the IFS_ACCESS.

Line 3: I can use the Set statement to return the result of IFS_ACCESS into the RPG variable ErrNo.

Lines 4 8: If the returned ERRNO is zero then "You can read the file" is shown to the user. If I am not authorized to read the file then "You cannot read the file" and the ERRNO is displayed.

As I am authorized to read the file the following is shown:

DSPLY  You can read the file

If I was not then the following is displayed:

DSPLY  You cannot read the file (3401)

As IFS_ACCESS is a Scalar function I can use it in a Select statement. For example, I can list the stream files in my folder and check if I have execute authorization to them:

01  SELECT PATH_NAME,OBJECT_TYPE,
02         SYSTOOLS.ERRNO_INFO(
03           SYSTOOLS.IFS_ACCESS(PATH_NAME,
04                               EXECUTE => 'YES'))
05    FROM TABLE(QSYS2.IFS_OBJECT_STATISTICS('/home/MyFolder/',
06                                           'NO','*STMF'))

I am using the SQL table function IFS_OBJECT_STATISTICS to list the contents of my folder.

Line 1: I want the path (file) name and object type from IFS_OBJECT_STATISTICS.

Lines 2 and 3: This is the same statement I have shown above, ERRNO_INFO containing IFS_ACCESS, and I want to check if I have execute authorization.

Line 5 and 6: The IFS_OBJECT_STATISTICS is passed my folder name. 'NO' means that I do not want to look in any subfolders in my folder. '*STMF' is to only return Stream files.

The results are:

                                OBJECT
PATH_NAME                       _TYPE   00003
------------------------------  ------  ------------------
/home/UQ142SH/another_file.txt  *STMF   There is no error.
/home/UQ142SH/test.txt          <NULL>  Permission denied.
/home/UQ142SH/some_file.txt     *STMF   There is no error.

This shows that the only file in my folder I do not have execute authority to is test.txt.

 

You can learn more about the IFS_ACCESS SQL Scalar function from the IBM website here.

 

This article was written for IBM i 7.5 TR5 and 7.4 TR11.

No comments:

Post a Comment

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.