Swapping AS/400 User Profiles
by Shannon O'Donnell
[The code for this article is available for download.]
I recently had to give an AS/400 interactive job the ability to run under two different OS/400 user profiles. Under certain conditions, user "Abel" had to be allowed to Telnet to a second AS/400, but on the second AS/400 he had to be automatically signed on as user "Baker." It seemed like an impossible requirement until I discovered the "Get Profile Handle" and "Set Profile" APIs.
The job requirement for this particular application stated that, from within an OS/400 application, the user should be allowed to Telnet to a remote system (AS/400), but when he got there, he should be automatically logged on as a different user. That's because they did not want to duplicate and maintain all the user profiles on the home system. They wanted one "Public" user profile to be used on the target system so they could restrict just this one profile to whatever functionality and authorizations were needed, rather than having to manage and maintain a duplicate set of user profiles from the home system. Hence the need for any user profile on the home system to Telnet to the remote system and automatically log on as the Public user profile. To accomplish this, I made use of two security-related APIs.
The Get Profile Handle API
The Get Profile Handle (QSYGETPH) and Set Profile (QWTSETP) APIs are both members of the security APIs provided by IBM that allow AS/400 programmers to use low-level OS/400 security functions.
The QSYGETPH API accepts a valid OS/400 user ID and password, then returns a "handle," an internal numeric value that allows you to programmatically refer to that user profile. Once you have this handle, you can manipulate it--in this case, by setting the current job's user profile to run under the user profile whose handle was retrieved by calling the QSYGETPH API. This API also validates an OS/400 user profile and password, so if you should happen to have a requirement to validate only a profile and password, QSYGETPH is a great one to use.
The Set Profile API
The QWTSETP API uses the handle returned by QSYGETPH to change the current job to run under a new user profile.
Once the job has been changed to run under the new user profile, every activity thereafter will happen under that new profile. So if, for example, you were to display spool files, you would see the spool files for the new user profile, even though you signed on under a different profile. If you submitted a new job, it would be submitted under the new profile. Using the QSYGETPH and QWTSETP APIs is a good way to temporarily gain control of another user profile.
A Word About Telnet
Before I cover the RPG IV code required to make all this work, I'll tell you how to automatically Telnet to a remote system and automatically log on under the new user profile. With V5R1 and later versions of OS/400, you can use the RMTUSER parameter of the TELNET command to specify which OS/400 user profile you want to pass to the Telnet server on the remote system. If the "remote sign-on control" system value (QRMTSIGN) is set to *SAMEPRF (same profile), the Telnet server will automatically log on the user, using the value specified on the RMTUSER parameter of the TELNET command. This sounds more complex than it really is, so just try it before giving up.
If you have access to a second AS/400 on a TCP/IP network (for example, local or Internet), set the remote AS/400's QRMTSIGN to *SAMEPRF. Make sure that the user profile under which you are logged on for the home AS/400 also exists on the target AS/400. If it does, enter the following command from the home AS/400:
TELNET RMTSYS(REMOTESYSTEM) RMTUSER(YOURCURRENTPROFILE)
You then should be able to automatically log on to the remote system.
I mention all of this here because I did not provide the Telnet example in the sample code included with this article. Instead, I provide a more useful example that shows how to use the QSYGETPH and QWTSETP APIs without needing to have access to a second AS/400.
The Sample Code
The RPG IV code swapusrprf is all you need to swap OS/400 user profiles. This program prototypes the QSYGETPH and QWTSETP APIs, as well as a couple of internal subprocedures used to call those APIs. You could just as easily remove the internal subprocedures and put all of the logic in a mainline routine, if you so desired.
The RPG IV program accepts the new user profile and password for the job that is currently running. The first step is to retrieve the handle to the new user profile, by calling the QSYGETPH API. Once the handle has been retrieved, a call is made to the QWTSETP API to change the user profile for job that is currently running. It couldn't be any easier!
The CL program, testswapu, shows how you can test the swapping process. This CL program accepts, as a parameter, the user profile and password you want to swap to. This brings up an important point: In order to swap from one user profile to another, you must know the new user profile's password.
This is obviously a security check designed to prevent users from swapping user profiles willy-nilly. But there is a way to circumvent the requirement for a password. In fact, we need to exploit this hole in the security process so that when the job needs to be set back to the original user profile, we don't have to know what that user profile's password is.
Say you have user Abel, who wants to Telnet to the remote system using a Public user profile. User Abel calls the security APIs detailed in this article to change the current job from user Abel to user Baker. User Baker becomes the profile that Telnets to the remote system. Now, when user Baker returns to the home system (Baker ends Telnet), user Baker must disappear and we must allow user Abel to regain control of the job. Because user Baker is a Public user profile, we might safely assume that it is okay for user Abel to know user Baker's password. But when the Telnet job ends, we do not want user Baker to know user Abel's password. Because if user Baker knew this, anyone who knew user Baker's password would also have access to user Abel's password, and that could lead to all kinds of bad things.
That said, we can exploit a feature of the QSYGETPH API that says that if you do not want to validate the user profile's password, you don't have to. Instead, you can pass a value of *NOPWDCHK to the QSYGETPH API, and as long as the original user profile has at least *USE authority for the new user profile, it is allowed to execute the API. It's a bit of a security hole, but since you first have to grant *USE authority to the original profile for the new profile, it's a hole we can live with.
In the CL program, the user profile is swapped for the new user profile (passed in as a parameter), then the spool files for the new user profile are displayed. This is done to show that the user profile was actually changed. Next, we swap the user profile back to the original user profile and again display the spool files for the original user profile. Again, this is done to demonstrate that the profile was actually swapped back. You can run this program yourself if you know the passwords for at least two OS/400 user profiles on your system (your own and the one to swap to).
There are a few caveats when using all of this swapping stuff. The first, which I mentioned above, is that you must already know the password of the user profile you want to swap to. The second caveat, also mentioned above, is that, if you do not know the password of the user profile you want to swap to, the current user profile must have at least *USE authority to the second user profile. You can set this authority by using the command WRKOBJ USERPROFILENAME *USRPRF (see Figure 1).
A third caveat, not yet mentioned, is that the current job's information (such as job number or job user name) is not updated to reflect the new user profile information. This is not necessary anyway, and I only mention it here so that when you look at the job after doing the swap, you are not confused by seeing the original job information that is displayed. That's also why I used the WRKSPLF command in the test program, so you could see a command execute under the new user profile.
What Good Is All of This?
All of this might sound good to you, and you may be thinking, "Yeah. That's cool, but so what? I don't need to Telnet to a remote system. When would I ever use this technique?" I would answer that by saying, "Use your imagination!" The first thing that came to mind when trying to think of another use for this technique was as a help-desk application. You might set up a job such that a help-desk operator could ask the person needing help for his user profile and password, then call a procedure that would swap the help-desk operator's user profile for that of the person needing help, and that way the help-desk person could attempt to run the job using the same criteria as the person with the problem. That's just one possible use for this technique. Put your mind to it, and I'm sure you can think of others. If you do, send me an e-mail and let me know what you came up with!
Contact the Editors
|Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.|