Many of you running at security level 30 or higher still have concerns about your system's security. One concern you may have is the level of exposure resulting from one person having the Security Officer password. For that matter, any profile that has significant authority (e.g., *ALLOBJ authority) may present a problem. Those passwords place a lot of power in one person's hands, and that may not be acceptable in your situation.
Some sites require that two people share the Security Officer password, each having half. While that method is more secure, it makes changing the password difficult because both people must be present to change the password, and it usually limits the number of people with any authority to two. I have a solution that's more flexible.
I have implemented a function I call "two-level sign-on" that allows a user to know the total password but requires another user's approval to complete the sign-on process. This article contains the code and considerations for secondary authentication for a "super user" profile like QSECOFR.
The two-level sign-on strategy requires executing an initial program for the QSECOFR user profile. 1 illustrates the screen interactions when two-level sign-on is implemented.
The two-level sign-on strategy requires executing an initial program for the QSECOFR user profile. Figure 1 illustrates the screen interactions when two-level sign-on is implemented.
The super user signs on to the AS/400 by entering his user profile and password on the sign-on screen that has been customized to prevent override of the initial program. This activates a call to the initial program, which displays a secondary authentication screen that prompts for the second user's profile and password. The list of approvers (second users) can include more than one individual.
First, the program checks to see if the user has the authority to approve the sign-on of a super user. If the user is authorized, OS/400 application program interfaces (APIs) check the second user's password. If the password is correct, the super user is allowed to proceed and the sign-on continues. Otherwise, the second user is prompted to reenter his password.
You need to make sure that the initial program for the super user always runs. Normally, you could accomplish this by specifying LMTCPB(*PARTIAL) in the user profile. However, the QSECOFR user profile LMTCPB field cannot be changed. Therefore, you must modify the sign-on screen to prevent entry of the initial program field of the sign-on screen (see the accompanying sidebar, "Modifying the AS/400 Sign-on Display"). Figures 2 and 3 show the code for the two-level sign-on display file and CL program. Make the CL program the initial program for the QSECOFR profile with the following command:
CHGUSRPRF USRPRF(QSECOFR) + INLPGM(TLS001CL)
In addition to implementing the two-level sign-on program for the super users, you should put controls in place that detect modification of either the two-level sign-on program or the super user profiles. I recommend the following audit controls:
1. Turn on *CMD auditing for all super users.
CHGUSRAUD USRPRF(super-user) + AUDLVL(*CMD)
2. Turn on *SECURITY, *DELETE, and *SYSMGT in the security auditing level system value for all users or in the user profile for individual users.
? System value for all users
CHGSYSVAL SYSVAL(QAUDLVL) + VALUE('*SECURITY *DELETE *SYSMGT')
? User profile for individual users
CHGUSRAUD USRPRF(super-user) + AUDLVL(*CMD *SECURITY *DELETE *SYSMGT)
These controls will allow you to review the audit journal for modifications to the two-level sign-on program or to super user profiles (e.g., a change in the initial program).
Managing the Risk
With this technique, you should keep in mind that if the TLS001CL program encounters an error writing to the display file, then the user is signed on without a secondary password. This seems to be the better of two alternatives: sign the user off and run the risk that nobody will have sufficient authority to solve a system problem or allow the sign-on as is done here. This exposure should be rare, but, for example, it could occur if the display file is deleted or renamed. In this case, a message is sent to QSYSOPR to document the error, and the program intentionally signs the user on. To reduce the risk of anyone tampering with the TLS001DF display file, you should limit the amount of authority you give it and periodically review your audit journals.
Super user profiles such as QSECOFR are a necessary security risk; we need profiles that can administer the system, but we need to exercise caution about how those profiles are used. The method and code shown in this article help reduce exposure. The use of a second individual to monitor the activities of the QSECOFR or other super user is a deterrent to improper use of these powerful profiles.
Wayne O. Evans is an AS/400 security consultant and a frequent speaker on security topics. He developed this support at the request of a bank that wanted better control over the actions of super users. During his 27 years with IBM Corporation, he was involved with AS/400 security design issues. Prior to working on security, Wayne was the team leader and designer for the command definition and CL language on the S/38.
Modifying the AS/400 Sign-on Display
The two-level sign-on technique presented in this article requires you to modify your AS/400 sign-on screen to remove the Program/procedure prompt. This modification prevents users from entering a program name in order to bypass the initial program in their user profiles. Even if you don't plan to implement the two-level sign-on technique, you may want to customize your sign-on screen anyway to add things like your company name or logo. This technique was first presented in "Customizing the Sign-on Display" (MC, May 1991). Because it's been awhile since we've discussed this topic, let's take another look at the steps necessary to accomplish this task.
The first step is to locate the DDS source code for the sign-on screen from member QDSIGNON in file QDDSSRC in library QGPL. Once you've found the source code, copy it to another source member and give it a new name, such as SGN001DF. Next, modify the new source member you just created. Be sure you don't modify the original source member in case you need to revert back to using the original sign-on display file. When modifying the source code, you should keep a few restrictions in mind:
? Don't add, delete, or change the size of any of the fields.
? You can move fields to new locations on the screen as long as you don't change the order of the fields. (This also means you should not use the Sort by row/column option in SDA.)
? Don't remove the conditioning indicators on any of the fields.
Although there are a lot of restrictions concerning the fields, there are no restrictions on the constants. Feel free to add or remove constants anywhere on the screen to make it look the way you want.
One of the restrictions on the fields is that you can't delete any of them. So how do you remove the Program/procedure prompt to implement the two-level sign-on technique? The trick is to change the display attribute of the field to non-displayed and protected with the DSPATR(ND PR) keyword. This prevents users from seeing or keying into the field, which serves the purpose of not allowing them to override the initial program.
After you modify the source code, compile it. Now you're ready to put your new sign-on screen to use by assigning it to your interactive subsystem (usually QINTER). To do this, you'll need to end the subsystem, change its description, and then start it back up again.
ENDSBS SBS(QINTER) CHGSBSD SBSD(QINTER) + SGNDSPF(XXX/SGN001DF) STRSBS SBSD(QINTER)
If for any reason you need to revert back to your original sign-on screen, just change the subsystem description back to using the QDSIGNON display file.
? Robin Klima
Figure 1: Flow of Two-level Sign-on
Figure 2: Display File TLS001DF
*========================================================================= * To compile: * * CRTDSPF FILE(XXX/TLS001DF) SRCFILE(XXX/QDDSSRC) * *========================================================================= *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 A R SIGNON BLINK A OVERLAY A CA03(03) A 1 30'Second Level Sign On' A DSPATR(HI) A 6 17'User . . . . . . . . . . . . . .' A USERID 10 B 6 53 A 7 17'Password . . . . . . . . . . . .' A PASSWRD 10 I 7 53DSPATR(ND) A 23 2'F3=Sign off' A COLOR(BLU) A R MSGSFL SFL A SFLMSGRCD(24) A MSGKEY SFLMSGKEY A PGMQ SFLPGMQ A R MSGCTL SFLCTL(MSGSFL) A SFLDSP A SFLDSPCTL A N03 SFLEND A SFLINZ A SFLSIZ(2) A SFLPAG(1) A PGMQ SFLPGMQ *. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
Figure 3: CL Program TLS001CL/*==================================================================*/ /* To compile: */ /* */ /* CRTCLPGM PGM(XXX/TLS001CL) SRCFILE(XXX/QCLSRC) */ /* */ /*==================================================================*/ PGM DCL VAR(&HANDLE) TYPE(*CHAR) LEN(12) DCL VAR(&FSTUSR) TYPE(*CHAR) LEN(10) DCLF FILE(TLS001DF) MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR)) CHGVAR VAR(&PGMQ) VALUE('TLS001CL') RTVJOBA USER(&FSTUSR) AGAIN: SNDF RCDFMT(MSGCTL) SNDRCVF RCDFMT(SIGNON) IF COND(&IN03) THEN(SIGNOFF) RMVMSG CLEAR(*ALL) /* Validate user profile */ IF COND((&USERID *NE 'APPROVER1') + *AND (&USERID *NE 'APPROVER2') + *AND (&USERID *NE 'APPROVER3')) + THEN(DO) SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('User + profile' *BCAT &USERID *BCAT 'not valid + for second level sign on') TOPGMQ(*SAME) GOTO CMDLBL(AGAIN) ENDDO /* Validate password */ CALL PGM(QSYGETPH) PARM(&USERID &PASSWRD &HANDLE) MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(AGAIN)) GOTO CMDLBL(ENDPGM) ERROR: SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Error + found in initial program for user' *BCAT + &FSTUSR) TOMSGQ(QSYSOPR) MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ENDPGM)) ENDPGM: ENDPGM