Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Mass update to FILENAME field in S_DATASET authorization object

Former Member
0 Kudos

We are migrating to a new fileserver with a new hostname, and so I've been asked to update about 1900 instances of the S_DATASET authorization object for the new FILENAME value. I'd like to do this programmatically if possible.

What I've learned so far is that I need to update the value in table USR12, but the value is encoded. When I look at the table in SE16, I do not see the encoded value field. The value does show in UST12, but I'm told this is an unreliable table.

So I'd like to know..

1. How can I look at the value if not in SE16?

2. Is there an API I can use to encode/decode the value? If not, where is the specification on how to build it?

If this is better addressed in a different forum, which one should I try next?

Thanks,

Dan

14 REPLIES 14

Former Member
0 Kudos

This is the correct forum, but what you have heard so far sounds disastrous.....

The file name in S_DATASET is the logical file name. As long as you are not changing all your programs with regards to the file names and only changing the IP address for the new hardware behind the file system... you should not need to change anything in S_DATASET.

A better option in my opinion is anyway to not use generic includes for file system operations, and then use the program name (a program can normally only do that which it is designed to do) for primary control, together with the activity.

You can then enter the first nnnn characters of the file name and wildcard it for most roles.

My 2 cents,

Julius

0 Kudos

>

> This is the correct forum, but what you have heard so far sounds disastrous.....

>

> The file name in S_DATASET is the logical file name. As long as you are not changing all your programs with regards to the file names and only changing the IP address for the new hardware behind the file system... you should not need to change anything in S_DATASET.

>

> A better option in my opinion is anyway to not use generic includes for file system operations, and then use the program name (a program can normally only do that which it is designed to do) for primary control, together with the activity.

>

> You can then enter the first nnnn characters of the file name and wildcard it for most roles.

I'll admit, what we have here is not very pretty. There are full file paths hard coded into our authorizations, so there's no question we need to update the values.. but I'd like to straighten this out in the process. Your recommendations on the "right way" are therefore welcomed with open arms.

I agree with your assessment of shifting some responsibility over file access control to the program. We have several programs that allow the user to enter an arbitrary path for output though, so I understand why my predecessors did it the way they did.

Are you aware of any documentation that discusses best practice with regard to use of S_DATASET / file access outside of SAP that I can study up on?

Thanks,

Dan

0 Kudos

First of all, please take note that just because you are entering a work of art into an auth field, does not make the actual data checked any more granular. Particularly the length of the field, and in the coding itself a delevoper could use a variable of a type to be checked which is less than that which you are maintaining. So you should keep an eye on the constraints, and not just enter data at will.

Second: You need to be checking the authority of the user after they have input their parameters but before the actual DATASET operation is executed (at which time, the check is performed again anyway).

If you get that part right, then you can pretty much ignore the file_name field of S_DATASET or give it a generic name with a wildcard.

Instead, rather maintain the activity and program_name fields in SU24 at the time of developing or configuring the program so that they can be consistently reused, validate the path to prevent directory traversals and hook the critical directory paths you do have by protecting them with the S_PATH object.

If your network servers all have meaningfull alias names, then this is not maintenance intensive but requires some thought in the beginning.

For further details, see [this blog|https://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/11687] [original link is broken] [original link is broken] [original link is broken]; which I wrote a while back to explain the SU24 connection. The example chosen for the blog is exactly this one which you are asking about.

Cheers,

Julius

0 Kudos

Thank you for all of the comments and pointers. I've done quite a bit of reading on S_PATH since my last post, and I'm feeling more comfortable with the concept.

What I'd like to do is deny all file paths by default and permit only those that I specify. I understand that SAP will evaluate the most specific path in the SPTH table, but I'm unclear when I need to bring the FS_NOREAD and FS_NOWRITE fields into play.

If all I do is define a path "*" in SPTH with an authorization group "ZALL" that no one is granted, will all users be denied access to all paths?

-Dan

0 Kudos

> If all I do is define a path "*" in SPTH with an authorization group "ZALL" that no one is granted, will all users be denied access to all paths?

No. Being an authorization check table, the user can be authorized for a multiple of values.

Protecting '*' unless otherwise (specifically) authorized would work for application coding where the DATASET authority is checked before the ABAP operation DATASET is executed.

As this check is in the kernel (invoked by the ABAP language and not by the ABAP coding...) I do not know whether the path will infact be checked (my guess is that system "internal only" calling programs are protected by default), but it might work for all application coding scenarios which the user can reach and influence themselves.

When I have an opportunity, I will test it (please try the same). In the next release (I am waiting for a trial system...) it will also be possible to debug certain "released for debugging" kernel routines in display mode, and if it is possible to take a closer look into file system operations then that would be a help as well.

Please update if you make progress and I will do the same if I can get hold of a system with an appropriate release to test with.

Cheers,

Julius

0 Kudos

I fired up my sandbox and did some testing.

While configuring the SPTH table, I stumbled upon some very useful documentation. Here's what it said:


Path                   Saveflag  Fs_noread Fs_nowrite Fs_Brgru
=============================================================
*                                 X         X
/usr/temp
/usr/temp/FI           X                                 FIFI

Meaning: In principle, nothing in the file system can be changed from 
ABAP/4, BUT everything under '/usr/temp' is opened without backup or 
authorization check EXCEPT '/usr/temp/FI' and sub-directories that are 
backed up and whose files can only be modified by users who have the 
appropriate authorization for authorization class FIFI.

But when I set up my test, it doesn't behave that way. I have to assign an auth group name in FS_BRGRU for the "*" entry, or else auth check on S_PATH isn't peformed (according to system trace). It seems that omitting auth group tells SAP to skip the S_PATH auth check. So to me, the table above should look like this instead:


Path                   Saveflag  Fs_noread Fs_nowrite Fs_Brgru
=============================================================
*                                 X         X            DUMY
/usr/temp
/usr/temp/FI           X                                 FIFI

I'm interested to hear your results, Julius!

Thanks,

Dan

0 Kudos

Another anomaly I've observed is that the suggestion in SAP note 177702 about adding entries to preclude directory traversal doesn't work (at least not how they describe!).

I set up the following SPTH configuration, and was still able to open /temp/FI/../../testfile.txt


Path                   Saveflag  Fs_noread Fs_nowrite Fs_Brgru
=============================================================
*                                 X         X            DUMY
/temp/FI               X                                 FIFI
/temp/FI/..                       X         X            FIFI

However, the following configuration produces the intended result.


Path                   Saveflag  Fs_noread Fs_nowrite Fs_Brgru
=============================================================
*                                 X         X            DUMY
/temp/FI/..                       X         X            DUMY
/temp/FI               X                                 FIFI

In fact, since I do not assign DUMY to any user, the latter configuration works whether I have the FS_NOREAD and FS_NOWRITE flags set. So once again, I fail to understand how FS_NOREAD and FS_NOWRITE flags come into play.

-Dan

0 Kudos

Hi Dan,

I will need to get hold of a sandbox to test in detail, but from past tests I have done you might want to consider the following:

To use the DATASET command (ABAP statement) itself, you will need to know the values of the fields of the S_DATASET authorization object already... so you can (and should) check the authority of the caller before the actual statement itself is executed. This is done by calling function module AUTHORITY_CHECK_DATASET to be able to react to the missing authority, because it is going to dump anyway...

The S_PATH check is also performed at this time by the application layer which prior determines which OS it is running on and which characters are permitted and in which format they are sent from the application layer to the SAP kernel for the check. But this check is returned to the application layer before the DATASET command itself is allowed.

So I suspect that if you do not check it in your application coding, then the ABAP coding statements themselves will not check it either...

Can you describe your tests in more detail? (if custom coding, please post the relevent coding parts. If standard, please mention the transaction).

Cheers,

Julius

0 Kudos

To use the DATASET command (ABAP statement) itself, you will need to know the values of the fields of the S_DATASET authorization object already... so you can (and should) check the authority of the caller before the actual statement itself is executed. This is done by calling function module AUTHORITY_CHECK_DATASET to be able to react to the missing authority, because it is going to dump anyway...

The mandatory authorization check in the kernel should enforce our security model whether or not the developers handle an error. Therefore in my tests, I have not called AUTHORITY_CHECK_DATASET as the unhandled exception show that the kernel check is doing its job.

The S_PATH check is also performed at this time by the application layer which prior determines which OS it is running on and which characters are permitted and in which format they are sent from the application layer to the SAP kernel for the check. But this check is returned to the application layer before the DATASET command itself is allowed.

The documentation I've read indicates that S_PATH is inspected only if the S_DATASET check succeeds. This seems to bear out in the system trace. The DATASET function bombs if either of the two authority checks fail.

Can you describe your tests in more detail? (if custom coding, please post the relevent coding parts. If standard, please mention the transaction).

You can laugh.. I do not make a living writing ABAP code. This is a simple test program that I scavenged from the Internet.


REPORT  ZFILETEST.

DATA FNAME(60) VALUE 'C:\TEMP\ZFILETEST.TXT'.

OPEN DATASET FNAME FOR INPUT IN TEXT MODE ENCODING DEFAULT.

IF SY-SUBRC = 0.
  WRITE / 'File opened'.
ELSE.
  WRITE / 'File not found'.
ENDIF.

I altered the DATA variable between trials to try several paths like C:\ZFILETEST.TXT and C:\TEMP\..\ZFILETEST.TXT. In my previous post, I represented the SPTH filenames to look like unix paths (i.e. /data/FI) because I was copying and pasting from an example I found.. but in reality, my sandbox SPTH table used C:\ as the root.

-Dan

0 Kudos

Hi Dan,

Yes, you can find some good stuff in the internet, but also some rubbish...

> The documentation I've read indicates that S_PATH is inspected only if the S_DATASET check succeeds. This seems to bear out in the system trace. The DATASET function bombs if either of the two authority checks fail.

From memory, this is exactly what the function module does, after having determined which OS it is running on. The kernel itself will first check the S_DATASET object which includes the program name as a field for the check! In that program (which the user must be authorized for...), the developer first needs to check the authority for the DATASET statement using the FM before the kernel does, and react to it.

Your code "on the inside" did not do that...

That is why I also stated in the above mentioned blog, that restricting the program name field of S_DATASET is the quickest security win - also for S_PATH (if used)...

I think at this stage it is also fair to point out that there are newer technologies for integration than file system operations. You might want to take a look into qRFC using the DESTINATION IN GROUP option.

FTPing files around (and hunting down IDOCS) is no longer state-of-the-art technology. But it does work.

Cheers,

Julius

0 Kudos

Hi there,

Okay I started a few tests and made a bit of progress, but am running into the problem that if I don't check the authority first using the FM and want to test what happens when the user is not authorized, then the bugger dumps (as expected and mentioned in the note)...

But the behaviour as you have described:

>


> Path                   Saveflag  Fs_noread Fs_nowrite Fs_Brgru
> =============================================================
> *                                 X         X            DUMY
> /temp/FI/..                       X         X            DUMY
> /temp/FI               X                                 FIFI
> 

... is correct, and I found something interesting in the F1 on the spth-path field which explains this.

> Caution:

> - If you enter paths generically in the table SPTH, the most precise specification counts.

> - If you select the no-read or no-write fields in the table SPTH, this overrides the authorization group.

So, the DUMY is not needed as the check does not use it in those cases, and "/temp/FI/.." is anyway more specific than "*" so the system would have used it for DUMY anyway. But that is irrelevant... because if the begru field is empty in the FM, then the check is not performed.

So, the only check which is effective to protect the path, is:


Path                   Saveflag  Fs_noread Fs_nowrite Fs_Brgru
=============================================================
/temp/FI               X                                           FIFI

... and the "fs_noread" and "fs_nowrite" flags should be understood as "no protectable authority to read" and "no protectable authority to write" and not the activity field which the authority is being checked against. This is coming from the S_DATASET check (which is already known at that time to the function module).

Using these flags, you can leave the entries in the table without having to delete them if you want to turn them off and on temporarily. Perhaps an "active / inactive" switch would have been clearer...

form CHECK_PERMISSION using ISPTH_HEAD type SPTH
                            MODE       type CLIKE
                            SUBRC      type SY-SUBRC.

data: ACTIVITY like AUTHB-ACTVT.

   SUBRC = 0.

   case MODE.
     when 'R'.
          ACTIVITY = '03'.
     when 'W'.
          ACTIVITY = '02'.
     when 'D'.
          ACTIVITY = '02'.
   endcase.

   if ISPTH_HEAD-FS_BRGRU <> SPACE.  "Here it is... for BEGRU checks there must be a value...
      authority-check object 'S_PATH'
          id  'FS_BRGRU' field ISPTH_HEAD-FS_BRGRU
          id  'ACTVT'    field ACTIVITY.
       if SY-SUBRC <> 0.
          SUBRC = 3.
       endif.
   endif.

endform.

Cheers,

Julius

Former Member
0 Kudos

>

> We are migrating to a new fileserver with a new hostname, and so I've been asked to update about 1900 instances of the S_DATASET authorization object for the new FILENAME value. I'd like to do this programmatically if possible.

>

> What I've learned so far is that I need to update the value in table USR12, but the value is encoded. When I look at the table in SE16, I do not see the encoded value field. The value does show in UST12, but I'm told this is an unreliable table.

>

>

Hi Dan,

Is your filename path hardcoded in the S_dataset Auth object. How are the roles working when you transport them from Dev -> Quality -> Production.

As Julius already suggested filename path should always be something with a wildcard so that it is applies for all the systems.

Anyway did you try SE16 -> AGR_1251 table. In the Object field give S_DATASET and find out all your customised roles with their authorization for S_DATASET object and in edit mode you can update it.

0 Kudos

>

> Is your filename path hardcoded in the S_dataset Auth object. How are the roles working when you transport them from Dev -> Quality -> Production.

>

> As Julius already suggested filename path should always be something with a wildcard so that it is applies for all the systems.

>

> Anyway did you try SE16 -> AGR_1251 table. In the Object field give S_DATASET and find out all your customised roles with their authorization for S_DATASET object and in edit mode you can update it.

You're getting to the root of the problem, which is simply that our configuration is not optimal.

One question I'm gnawing on is how to prevent cross-system contamination of data. If all systems have the same authorization with a wildcard for the path, how would we preclude a program in development from reading and writing a production data file?

Speaking of AGR_1251.. do I understand correctly that if I update the values in this table, USR12 will be updated when I regenerate the roles and perform a user master compare?

Thanks,

Dan

0 Kudos

>

>

> You're getting to the root of the problem, which is simply that our configuration is not optimal.

>

> One question I'm gnawing on is how to prevent cross-system contamination of data. If all systems have the same authorization with a wildcard for the path, how would we preclude a program in development from reading and writing a production data file?

>

> Speaking of AGR_1251.. do I understand correctly that if I update the values in this table, USR12 will be updated when I regenerate the roles and perform a user master compare?

>

> Thanks,

>

> Dan

All the roles are client dependent. So the authorization that you have in one client does not give you access in another client or another system. So I do not think a program in devlopment can read or write to a file in Production. But a Program in Production can do read and write a file in Production.

Coming to your second question whatever you said is correct. if you update the table and then go back to the to role, you will see the feild for this object S_dataset has got a entry now and the object has turned yellow now instead of green. You need to generate it again and do a user master compare.

You can try it yourself in your sandbox by creating a temp role with this object S_dataset with some values and then edit it through AGR_1251 and then again go back and see the temp role

Hope it helps !!