The goal of this article is to expose some of the misconceptions and commonly made mistakes in IBM i security. As a consultant, I've answered these questions and stopped misconceptions on an individual basis, but making this knowledge known to a broader audience seems worthwhile.
The first topic to discuss is the user class attribute of the user profile. The user class is never used for authority checking. I wish I had a dollar for every time someone asked me a question and, when describing the situation, said, "The user is in the *SECOFR user class." When determining why a user can't access or can access but shouldn't be able to access an object, you should ignore the user class attribute. It simply doesn't matter what the user class is; the authority-checking algorithm never looks at that attribute. The user could be in the *USER user class and have all special authorities. Or the user could be assigned to the *SECOFR user class and have no special authorities. So looking at the user class could cause you to make assumptions that may not be true. The user class is used only when the profile is created to default the user's special authority assignment, to determine which IBM i menu options the user sees, and to determine whether special authorities should be adjusted when IPLing the system between security level 20 and a higher security level.
Most people know that adopted authority is enabled by setting an attribute of a program. The problem is that many people look at the wrong attribute. Two program attributes control adopted authority: Use Adopted Authority (USEADPAUT) and User Profile (USRPRF). Given the terminology, it's easy to see why most people think the USEADPAUT parameter controls whether a program adopts—but it doesn't. It's the USRPRF attribute that controls. When USRPRF is set to *USER—which is the default—the program doesn't adopt. When USRPRF is set to *OWNER, the program uses the authority of the program owner if the person calling the program has insufficient authority.
So what does the USEADPAUT attribute control? First let me explain that once a program adopts (i.e., USRPRF is set to *OWNER), the adopted authority flows to all subsequent programs called thereafter. The USEADPAUT parameter controls whether a program will consume or use the adopted authority being passed to it from a program higher in the program call stack. It's the only way to not have the adopted authority be used—you can't control the flow of adopted authority in the program that adopts.
Speaking of adopted authority, once you set the program attribute of User Profile to be *OWNER, then everything that happens within the program adopts authority, right? Not exactly. If there's dynamic SQL in the program, the dynamic SQL statement doesn't have access to the adopted authority from the program. To have the dynamic SQL statement adopt authority, you have to set the Dynamic User Profile attribute to *OWNER when you compile the program. Note that I said when you compile the program. You can set a program's adopted authority attributes either when you compile the program or by running the Change Program (CHGPGM) command. Unfortunately, there's no interface that lets you change the Dynamic User Profile attribute after the program has been compiled. To change the value, you have to recompile the program.
This next myth deals with *ALLOBJ special authority. I've seen organizations assign *ALLOBJ at a user's group profile and then grant private authority of *EXCLUDE to various files or commands, thinking that this setup allows them control over the user's actions. (If you assign *ALLOBJ directly to the user, the IBM i authority-checking algorithm will always recognize the user's *ALLOBJ and never go on to check whether the user has been excluded from a file or other object.) Unfortunately, assigning *ALLOBJ to the user's group provides a false sense of security. Yes, the user will receive the "Not authorized to object xxx" message if he or she tries to directly access an object from which he or she has been excluded. The problem is that all the user has to do to get around this roadblock is to submit a job to run as a profile that hasn't been excluded from the object. And that's just one way around this roadblock. There are simply too many objects you'd have to omit the user from to cover all the alternative access methods. You could never be sure you covered them all. Plus, you'd have to scour the system after every upgrade to find any new methods that may have been introduced with the new release. You need to accept the fact that, when you assign a user *ALLOBJ special authority—whether at the user or the group level—that user will be able to access any object on the system.
Many people incorrectly assume that there is no authority checking at security level 20. Although it certainly has that appearance, the fact is that the same authority-checking algorithm is run at security level 20 that runs at security level 50. It looks like there's no security checking because, by default, all profiles are created with *ALLOBJ special authority. Therefore, by default, all users can access all objects on the system. Because the same algorithm is used at all levels, once a profile has been created, you can remove its *ALLOBJ special authority and test your security configuration before moving to a higher security level.
One of the reports that we run when we perform a security assessment lists profiles whose password expiration interval is set to *NOMAX. When we investigate these profiles, we discover that some of these have no password. Some administrators set profiles that have no password (i.e., the PASSWORD attribute is set to *NONE) to a password expiration interval of *NOMAX because they mistakenly assume that the system checks or would somehow require the profile to change its password. But that's not what happens. If the profile has no password, the password expiration interval attribute is never considered. Therefore, it's safe to leave the password expiration interval set to the default of *SYSVAL, thus avoiding auditors' (and our) reports that are looking for profiles with passwords that never change.
I've found that, in most organizations, saving audit journal receivers is poorly thought out. In fact, some organizations remove them from the system without saving them at all. From a compliance perspective, not saving audit journal receivers may put you out of compliance. For example, the Payment Card Industry (PCI) requires that audit information be kept online or easily accessible for 90 days and that all audit information be retained for at least one year. Make sure your method for saving audit journal receivers 1) provides a method for you to easily know which receivers need to be restored should you need to investigate an event and 2) considers your organization’s compliance requirements.
And since we're on the topic of auditing, another concern is with the QAUDCTL system value (this system value turns auditing on or off). If you don't have the value *OBJAUD specified in the QAUDCTL system value, no auditing will occur on individual objects. Let me explain further. Two types of auditing are available on the system: action auditing, which logs events such as the creation or deletion of objects, access attempts when the user doesn't have sufficient authority (authority failures), and so forth, and object auditing, which reads or updates individual objects. I've been asked on several occasions to help people figure out why they aren't getting any audit entries when an object is updated. They had configured auditing on the object (using the Change Object Auditing—CHGOBJAUD) command, but they had neglected to add *OBJAUD to the QAUDCTL system value.
Note: Another reason you may not be seeing any object auditing entries is because the action you're taking on the object isn't designed to generate an audit entry. To determine which actions generate object auditing entries for a particular object type, check the Security Reference manual, Appendix E.
Another myth that surrounds auditing is this: Once you turn on auditing, you have to review every audit journal entry that's generated. I'm not sure where that perception started, but it's untrue. In fact, even people who run regular reports out of the audit journal don't look at every audit journal entry. I've seen only one instance in which every entry was reviewed, and that organization employed a full-time person to do it. I can't imagine how boring that must have been! I recommend that everyone turn on auditing, and yes, I do recommend that some reports be run regularly. But even if you choose not to run any reports, I recommend that you turn on auditing so that if something happens, you have the forensic information you need to determine what occurred. Make sure you're saving your audit journal receivers so that if the event happened nine months ago, you know which media to bring back from storage.
The final myth I want to address is that of the discovery of inactive profiles. Many people seem to be hesitant to remove or even set inactive profiles to a status of *DISABLED. I've heard stories in which profiles have been deleted when they were active. The problem has always been that the wrong date is being examined. I've found that when active profiles are mistakenly deleted, it's because the last sign-on date was examined. Instead of the last sign-on date, you need to be looking at the last-used date. This date is updated regardless of how the profile is used—via FTP, ODBC, submitting a job, or signing on to the system. So stop looking at the last sign-on date and look at the last-used date—and go ahead and get your system cleaned up!
I hope this article has been helpful in clearing up one or more of the mysteries you've experienced with IBM i security. Now, go forth and spread the knowledge far and wide, so that we can all be more secure.
Carol Woodbury is president and co-founder of SkyView Partners Inc., a company specializing in security policy and compliance software and services. Carol is a system security expert, a noted author, and an award-winning presenter.