02-04-2009 9:53 PM
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
02-04-2009 10:53 PM
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
02-05-2009 3:03 PM
>
> 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
02-05-2009 6:25 PM
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
02-26-2009 8:39 PM
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
02-26-2009 9:16 PM
> 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
02-27-2009 4:56 PM
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
02-27-2009 6:55 PM
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
02-27-2009 11:19 PM
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
03-04-2009 9:04 PM
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
03-04-2009 9:30 PM
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
03-05-2009 4:57 PM
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
02-05-2009 12:30 AM
>
> 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.
02-05-2009 3:25 PM
>
> 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
02-05-2009 4:09 PM
>
>
> 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 !!