When Users Need to Create Duplicate Objects
Published: February 15, 2006
I just wrote a CL program that uses the Create Duplicate Object command (CRTDUPOBJ) to copy a file into a user's QTEMP library for test processing. However, every time my users run the CRTDUPOBJ command in that CL, it gives them a CPF2189 error (Not authorized to object), even though the users have *PUBLIC *USE authority to the object. What's going on here?
I've run into this problem before when running the following Create Duplicate Object command (CRTDUPOBJ):
CRTDUPOBJ OBJ(object_name) FROMLIB(library_name) OBJTYPE(*FILE) TOLIB(QTEMP) DATA(*YES)
The solution is simple. This is an authority issue, but it's a problem that deals with object authorities, not data authorities. Here's how it works.
When you give the *PUBLIC user *USE authority, it means that all users who don't have any other explicit authorities to an object will automatically gain the following data authorities on that object:
- Read authority: The user can access the information contained in an object
- Operational authority: The user can look at the object's attributes and perform any of the data operations that are specified in the data authorities
The reason your CRTDUPOBJ command isn't working is that your users need an additional object authority in order to duplicate the object. Specifically, they need Object Management authority (*OBJMGT) which, according to IBM, allows the user to specify security, move or rename the object, and to add members if the object is a database file. This authority is not explicitly given when you give the *PUBLIC user *USE authority, but it can easily be added from a 5250 green screen session when you execute the following Grant Object Authority command (GRTOBJAUT).
GRTOBJAUT OBJ(library/object) OBJTYPE(*FILE) USER(*PUBLIC) AUT(*OBJMGT)
Once your *PUBLIC user has *OBJMGT authority to the file to be duplicated, the CRTDUPOBJ command will work. IBM does not specify why you need *OBJMGT to perform this function, but my guess is that there is an underlying security condition at work here. If a user can create a duplicate object without having object management authority, it would be easy for a signed-on hacker or an unscrupulous user to create a copy of a critical file in a library that is higher in their library list than the original file, modify the copy's data, and then use the copy to modify other data files or produce restricted documents, which could allow them to perform unauthorized operations on valid data. By forcing the user to have *OBJMGT authority to the object, i5/OS may be insuring that the user has at least minimum management authority before allowing him to spawn a copy of the object.
But as you might guess, the ability to use CRTDUPOBJ in a production environment creates a security issue because in order to create and work with a duplicate file, you have also provided your *PUBLIC users with some other aspects of *OBJMGT authority that you might not want them to have; specifically, the abilities to grant security to the object, to move the object to another library, to rename the object, or to add members which can be overridden in production programs. So while you solved your initial problem of how to create a duplicate object in a controlled CL program, you leave other object vulnerabilities open.
If you absolutely need to use CRTDUPOBJ in a user program, I first recommend that you limit the number of people who use that program so that you can also limit the number of people who have *OBJMGT authority to the duplicated object. It's generally not a good idea to give the *PUBLIC user too much authority to any one file.
If you're looking for a different way to allow object duplication into QTEMP, a better (but not perfect) solution might be to dispense with using CRTDUPOBJ to make a copy of your file and use the Copy File command (CPYF) instead. If you run CPYF like this:
CPYF FROMFILE(library_name/object_name) TOFILE(QTEMP/object_name) MBROPT(*REPLACE) CRTFILE(*YES)
It will also create a copy of the file in QTEMP that your user can manipulate. In this situation, CPYF is functionally the same command as CRTDUPOBJ, but the difference here is that you do not have to give your *PUBLIC users *OBJMGT authority to perform this action. The user can create that copy with just the object authority that is provided with *USE authority.
Using CPYF dispenses with some of the problems that occur when your users have *OBJMGT authority, but it still makes it too easy to create an exact duplicate of almost any object the user has authority to. That's why you have to very careful with your security, and lock down your *PUBLIC users' ability to randomly add objects to any library that they aren't specifically authorized to.
Finally, if your software configuration allows it, the best solution for many authority problems like this is to insure that all your databases have *PUBLIC access of *EXCLUDE and then run your CRTDUPOBJ or CPYF command in a predefined CL program where the user running the program adopts the authority of the user who owns the program, creating an application-only access scenario. If you are able to create an application-only access environment, situations like this are no big problem because your users are only authorized to run programs, not to manipulate data; it's the program itself that is authorized to manipulate the data. This is the best way to secure applications, and I highly recommend looking into it to solve sticky security issues like this.
Controlling PC Access
Limiting *PUBLIC Access to i5/OS Objects, Part 1
Limiting *PUBLIC Access to i5/OS Objects, Part 2