View but Not Copy
Question: I would like my users to be able to view source files in our production library but not copy from it into another library. Since copying into a programmer or test library is the first step in making a change, I want to know up front that a change is being contemplated. Is there a way to do this?
Answer: The problem that you describe is a classic computer science problem. If you allow a user to view data, can you restrict how that user uses the data? The purists answer is no. The technically feasible answer is maybe. You should first understand that when you allow a user to view source code, you are essentially permitting a copy of that source to be sent to that users screen. Once the code is on a users screen, that user can cut and paste that code into another editor and bypass your security restrictions.
Realistically, however, most application programs are large enough to discourage (but not prevent) users from going through this tedious process. If this is an acceptable risk for you, then you could provide your users with an adopted authority program that gives them the ability to view the source through the SEU browser. Figure 1 shows a sample program that accomplishes this task. Make sure that the user profile whose authority you adopt has no more than *USE authority to the source files, because SEU provides access to a command line, and you would not want to give users full access to the data through a combination of adopted authority and command line access. For more information on how to properly secure an adopted authority program, refer to Security Patrol: Watching QSECOFR in the January 2001 issue of MC.
In the course of researching your question, several of my colleagues questioned why you were concerned about a users ability to re-create program objects. If you are trying to prevent users from replacing production programs, there is a better way to do this. Do not give your users the ability to delete production programs. If users have only *USE authority to a production program (which is all the authority users need to execute a program), they cant replace the production program with any changed version that they may have made.
Another reason not to prevent users from reading source code is efficiency. Smart users know the value in copying code from existing programs when they are building a new program. If you prevent your team from copying code, you may be sentencing them to
reinvent the wheel with every program that they write. So, let users read the source, but just secure the production environment from unauthorized changes, and youll be fine.
Controlling *JOBCTL Special Authority
Question: We are splitting users into two environments and would like to secure job control special authority (*JOBCTL). For example, some users will require *JOBCTL to selective job queues, but other users defined with *JOBCTL should not have any access to the same job queue, while a third group of users needs access to all job queues. Ive attempted to test different scenarios but have been unsuccessful. Could you please advise me as to how this can be accomplished?
Answer: Lucky for you, OS/400 was designed from the start as a multi-user and even multi-company operating system, so what youre asking for is really quite easy to accomplish. I understand why many users are confused by Job Queue authority, because it follows different rules than other OS/400 objects.
First, I will review what *JOBCTL authority provides. *JOBCTL special authority allows a user to display, change, cancel, hold, and release every entry on any out queue or job queue that was created with the Operator Controlled OPRCTL(*YES) parameter set. The *OPRCTL parameter on an out queue or job queue specifies that any user with *JOBCTL special authority need not have any private OS/400 authority to that queue in order to work with the entries on the queue. If users have *JOBCTL special authority, they can work with entries on the queue even if their OS/400 authority is set to *EXCLUDE.
If users do not have *JOBCTL special authority, or if the queue was created with OPRCTL(*YES), users must have OS/400 object-level authority (of the *USE, *CHANGE, *ALL variety) to see or work with entries on a queue.
Of course, the easiest way to affect your change is to remove *JOBCTL authority from all of the profiles except those that need access to all queues. But, Ill assume that there is another reason why these users need *JOBCTL and propose an additional solution.
Break your users into three categories that Ill designate as USERA, USERB, and SYSOP. USERA needs access to JOBQA but not JOBQB. USERB should not have access JOBQA but does need access to JOBQB. And SYSOP needs access to all job queues. Start by creating JOBQA with the OPRCTL(*NO) parameter, and then edit the object authorities (EDTOBJAUT) for that job queue object. The authority to JOBQA should be set to USERA = *CHANGE and *PUBLIC = *EXCLUDE. JOBQB will also be defined as OPRCTL(*NO), and its object authorities should be set to USERB = *CHANGE and *PUBLIC = *EXCLUDE. With the OPRCTL(NO) flag set, the *JOBCTL special authority will provide no special access to these queues. USERA and USERB will be forced to rely on their object authorities to the queues and, if they fall under *PUBLIC, will be excluded.
That leaves the SYSOP profile. Give SYSOP not just *JOBCTL but also *SPLCTL special authority. *SPLCTL acts like *ALLOBJ special authority, only *SPLCTL concentrates its power on spooling (JOB and OUT) queues. The *SPLCTL special authority is not hampered by either the OPRCTL parameter or by regular OS/400 object authorities when it comes to accessing job queues, and so it is appropriate for only those users who need unrestricted access to all queues.
The plan mentioned above works just as well for out queues as it does for job queues. If users must have *JOBCTL authority, this security plan will restrict users to only those queues that they ought to see.
Stopping ODBC Updates
Question: I have an exit program in the QIBM_QZDA_SQL1 exit point that has been running without incident for years. My exit-program only allows reads to the database because the exit program scans for the SQL SELECT statement in the input request. If the
first six bytes of the input request are SELECT, the exit program allows the transaction. If the first six bytes are anything else like UPDATE or INSERT, the exit program rejects them. Now I have a user who is using Microsoft Access to run a SELECT with a UNION ALL SQL statement. All of a sudden, the exit program wont allow it. This user had no problems running this query before, and he runs it every month. What is going on?
Answer: There could be any number of causes, but the first thing I would do is dump the users inbound request to a log file and see if, in fact, the string SELECT is in the first six characters, as you expect. I bet that the SELECT statement is either not the first statement, or the ODBC request has offset the SELECT statement by a character or two. You should also note that a Select or a SelECt statement would also not pass your edit. Any of these items could cause your program to fail.
What you have discovered is just one of the problems with trying to parse the SQL string in an exit program for the purposes of limiting function. Because of the length and variable nature of SQL statements, its extremely difficult to accomplish SQL parsing with any certainty. When youre talking about security, I believe certainty is required.
If the case is that the users wholly uppercase SELECT request does not occupy positions 1 to 6 of the SQL string, you can then move on to solving your next problem: really securing your data. An SQL statement that begins with a SELECT statement (regardless of its relative position) can have one or more UPDATE, INSERT, or other such statements after the select. It is not only usual but also likely to have an UPDATE SQL statement embedded in an SQL SELECT statement. Because you are only checking the first six characters, your exit program would not block these updates to your database.
If you continue down this path, you are going to have to scan the entire incoming data string for key phrases such as UPDATE, INSERT, and the like. In order to do this well, youll want to attach your exit program to the newer, 32K QIBM_QZDA_SQL2 exit point rather than the older, 512-byte QIBM_ QZDA_SQL1 exit point that you are using. The QIBM_QZDA_SQL2 exit point provides the full 32K bytes of data for incoming SQL statements (the maximum allowed by the SQL standard) rather than the 512 bytes provided by the QIBM_QZDA_SQL1 exit point. I dont recommend using the QIBM_QZDA_SQL1 exit point, because it is just too easy to fool an exit program that only checks the first 512 bytes of an SQL statement.
In any case, if you are parsing the ODBC exit points incoming string, youve got the twin difficulties of getting it right and making it perform. Another approach would be to use the IBM swap profile APIs to change the authority that the user runs under. (See the Security Patrol column in the January 2001 issue of MC for more information on swap profile APIs.) Using this approach, you could define a network profile that has read-only access to your database and then have your exit program swap to that network profile whenever a user executes an ODBC statement. This way, OS/400 would be preventing ODBC updates to your database, rather than you trying to teach your exit program all the ins and outs of OS/400 object-level security.
Moving to QSECURITY Level 40
Question: We are considering moving from level 20 to level 30 then to level 40. Can you provide any guidance, articles, publications, tips, or advice?
Answer: If you are moving from QSECURITY level 20, dont stop at QSECURITY level 30; proceed directly to 40. The majority of the challenges that you will face are in the move off of QSECURITY level 30, whereas the difficulties of moving from 30 to 40 are relatively trivial (and easier to spot). For mor information, see "Security Patrol: Take Security to the Next Level" in the October 2000 issue of MC.
REFERENCES AND RELATED MATERIALS
OS/400 Security Reference V4R4 (SC41-5302-03, CD-ROM QB3ALC03)
PGM PARM( &SrcF &Lib &Mbr &Type )
DCL &Lib *CHAR 10
DCL &Mbr *CHAR 10
DCL &Srcf *CHAR 10
DCL &Type *CHAR 10
STRSEU SRCFILE(&Lib/&SrcF) SRCMBR(&Mbr) TYPE(&Type) OPTION(5)
MONMSG CPF0000 Goto Exit
Figure 1: Use a program such as this to help provide adopted authority to SEU.