Carol discusses the pros and cons of using adopted authority.
The answer to the question posed in the title of this article is "Yes." Let me explain. Adopted authority is very powerful and can be used as a method of elevating users' authority without actually giving them the authority directly. Adopted authority provides great flexibility, and I use it often when working with our clients. However, used without thought or with malice, adopted authority can pose a significant risk to your system. Perhaps for this reason, in some circles adopted authority has gotten a bad rap; the thought is that it's too dangerous and should be avoided at all costs. That's not my viewpoint, however. I'm a big fan of the power and flexibility of adopted authority, so let's look how it can be used safely.
Adopted authority is a way to temporarily elevate users' capabilities or access—in other words, give a user authority to objects or capabilities (that is, special authorities) without having to assign those special authorities directly to the user's profile. Adopted authority is configured through a program's User profile (USRPRF) attribute. When the program is called, the adopted authority is in effect for as long as it's in the call stack. The authority the user gains while the program is in the stack is the program owner's authority, including any special authorities the program owner has. Therefore, for as long as the program is in the stack, IBM i will check the caller of the program as well as the owner of the program for sufficient authority to access objects or perform tasks.
Let's look at some examples where adopted authority works well. I use adopted authority when an application's *PUBLIC authority is wide open (that is, database files are set to *PUBLIC, *ALL, or *CHANGE), or when application users are required to be a member of the group that owns the application, or when the application user is required to have *ALLOBJ. All cases give users authority to application data "outside" of the application—for example, through a command line, ODBC, DDM, or FTP. Application files can be set to *PUBIC authority of *EXCLUDE, and programs can be configured to adopt authority, allowing a user to take a menu option and have enough authority to access, change, or update an application object (such as a file) but not be allowed to perform the same operation outside of application interfaces.
Another use of adopted authority is to enable users such as operators and help desk personnel to perform tasks without adding the specific special authority required for that task to their profile. Operators and help desk personnel are often given menus through which they perform their tasks. Rather than assign a user a special authority, you can write a short Command Language (CL) program that adopts authority and performs tasks that would normally require the user to have a special authority. Resetting passwords is the perfect example. To re-set a user's password and/or re-enable the user's profile, you need authority to the user profile and *SECADM special authority. Rather than give the help desk and operations *SECADM, you can create a menu option that calls a program that prompts the Change User Profile (CHGUSRPRF) command. The program is configured to adopt and is owned by a profile that has *SECADM special authority, as well as *USE and *OBJMGT authority to all profiles on the system. (Or at least authority to the profiles you want them to be able to change.)
Earlier, I said that adopted authority is controlled through the User profile program attribute. This sometimes confuses people because they have been under the misconception that the Use adopted authority (USEADPAUT) parameter controls whether a program adopts. (Admittedly, the terminology is confusing.) The default value for the User profile parameter is *USER, which means that the program will not adopt authority. Changing it to *OWNER sets the attribute so the program will adopt authority.
The Use adopted authority parameter determines whether the program will use adopted authority being passed to it from a program higher in the call stack. When programs adopt authority, they automatically pass the adopted authority to subsequent programs. You cannot configure a program to not propagate authority…sort of (I'll clarify this statement in one moment). The Use adopted authority parameter determines whether you want IBM i to check the propagated adopted authority when it checks to see if the process has enough authority to access an object. When set to *NO, IBM i will never crawl back through the call stack to see if any previously called programs adopt. When set to *YES (the default), the program will use the adopted authority established by previously called programs. The one exception to this is when you invoke a program using the MODINVAU MI instruction. It allows you to call the program and indicate that you don't want the adopted authority established in the current program to be passed on to the program being called.
What's wrong with passing along adopted authority you ask? Nothing, except when there's a chance of some program down the line putting up a command line and letting the adopted authority flow through to all commands being run. (Yikes!) Or you're wanting users to run a command with only their authority, not the application owner's authority that's being adopted. Or someone with devious intent wants to insert a program into a library higher in the library list, knowing the Trojan horse program will be called before the intended application program and will exploit the adopted authority.
When an application provides a command line, you need to make sure that the program that calls the command line API does not use adopted authority—in other words, the USEADPAUT parameter is set to *NO. Or this the perfect time to use the MODINVAU instruction. Invoke the API using MODINVAU, specifying to suppress the adopted authority of the current program. The same considerations apply to menu options that run commands that you want run with only the user's authority. For example, a user takes a menu option that runs a query or some other command that allows them to see application data. The easy way around this is to write a short CL program that prompts the command being run. Then set the program's USRPRF attribute to *USER and the USEADPAUT attribute to *NO. The resolution to the final issue with propagating adopted authority takes a bit more explaining.
I won't bore you with the details, but back in the day when I was still the team leader of the (then) AS/400 security team, we received a request to control who could create programs and service programs that used adopted authority. That's when the QUSEADPAUT system value came into existence. If you add the name of an authorization list to this system value, any program you create or change will have the USEADPAUT attribute set to *NO unless you have *USE authority or greater to this list. Don't assign an authorization list or grant users or *PUBLIC( *USE) or greater to the list and their programs get created with the default setting of USEADPAUT(*YES). Another aid to protecting against this type of Trojan horse insertion is to set the *PUBLIC authority of all libraries higher in the library list than your application libraries (i.e., in the system portion of the library list) to *PUBLIC(*USE). This rarely causes can issue. Users can use objects in the library but can't add a new object (e.g., a program) to the library.
Earlier, I said that I often use adopted authority when working with our clients. One way I use adopted authority is when I'm reworking the security scheme of our clients' application—moving away from wide-open *PUBLIC authority on database files—or when application providers require application users to be a member of the profile that owns the application or have *ALLOBJ (gasp! It still makes me shudder to think vendors actually require this!). In these scenarios, I configure the application programs to adopt—typically all of them, with the exceptions such as ones previously described. Some feel these may pose a risk, that users (typically programmers) can call the programs—knowing they adopt authority—and then exploit the adopted authority. Fair enough. So what do you do if you want a bit more control over when and who can access the programs that adopt? Here are some options:
- Assign an authorization list to the QUSEADPAUT system value and authorize only your change management profile, not your programmers.
- Secure the programs with an authorization list, set the *PUBLIC authority of the list to *EXCLUDE, and authorize the application user group but not the programmers. This will prevent them from calling a program. They will need a special profile to gain access to the programs, perhaps through a utility that elevates privileges or through a profile that's only enabled when a trouble ticket is opened.
- Building on this scenario, secure the data with a different authorization list. If programmers need regular access to production for debugging purposes, grant them *USE authority to the authorization list securing the data. This allows them to view the data. However, if they have to modify the data, only allow them to so through a formal elevated-privilege process.
- A variation on this whole scenario is to not have the application adopt at all. Rather, have a user's initial menu adopt a profile that has been given *ALL to the authorization list securing the data and *USE to the authorization list securing the programs. That way, you can be assured that an application program could never be called to exploit an application program adopting authority. Programmers have an initial program that adopts a profile that's been given *USE authority to both the data and program authorization lists. The problem with this scenario is when the process submits a job. Adopted authority is lost because a submitted job starts a whole new program stack. So in this case, you have to re-establish the adopted authority. The process of finding all of the programs that submit a job or do a transfer control can be quite messy (time-consuming and error-prone). For this reason, this option is not often implemented.
Final Thoughts
Just because a program adopts doesn't mean it has to adopt QSECOFR or even a profile that has *ALLOBJ. A program can be configured to adopt regardless of its owner. When helping our clients rework their application security scheme, I set the programs to adopt but never have the application be owned by a profile that has *ALLOBJ much less QSECOFR. That said, there may be times when you have a task for which the operating system requires the power of *ALLOBJ or perhaps even QSECOFR. This is where extreme caution must be exercised. If there's a task that requires this much power, write a program that performs only that task and then ends. That way, there is no risk of the power continuing to be available to subsequent programs.
I hope this article has provided you with some insights on adopted authority so that you can decide for yourself whether adopted authority is your friend…or your foe.
LATEST COMMENTS
MC Press Online