TSO AUTHORIZATION TABLES (c) Copyright 2009 by Sam Golob. All rights reserved. TSO sessions rely on a set of tables containing program names, when they test a TSO user's ability to run an APF-authorized program, or an APF-authorized TSO command, or when they test if a TSO command can be executed under TSO-in-batch. People outside of IBM do not generally possess definitive information about where these tables actually are, although they have general knowledge about how to change them. In this article, I hope to put most doubts to rest, and after reading this article, you should have a very good idea about your TSO session's authorization tables, where they are, and how they got there. HISTORY OF THE AUTH TABLES In the "ancient" days, before TSO/E, which many of us still remember, the four CSECTs: IKJEFTE2 (AUTHCMD), IKJEFTE8 (AUTHPGM), IKJEFTAP (AUTHTSF - which didn't exist then), and IKJEFTNS (NOTBKGND), were linkedited into the IKJEFT02 load module (mainline TSO). So I learned a trick about what you should do, if you want to expand which programs you would like authorized in your own TSO session. The trick was to make your own copy of the IKJEFT02 load module, stick it in an APF-authorized STEPLIB that was in your TSO LOGON PROC, and linkedit your own copies of the IKJTFTE2 and IKJEFTE8 CSECTs, in particular, into that copy of IKJEFT02. This worked fine and did the job. You had your own personal command and program authorizations, which the other TSO users did not have. And that is what you, as the "system doctor", needed to have, as opposed to what the "ordinary users" needed. However, there was one problem. When normal maintenance came in from the monthly PUT tapes, and hit the other CSECTs in IKJEFT02, or else if a new version of TSO came out, either your own individual copy of IKJEFT02 didn't get the maintenance, or else you'd have to copy it over again, and re-linkedit the IKJEFTE2 and IKJEFTE8 CSECTs back again. If you didn't do that, the result would be that your own TSO session would become backleveled, often to the point where you'd get some abends that you didn't really want. Arrive TSO/E, with one improvement (among many other non-related ones). The four CSECTs: IKJEFTE2, IKJEFTE8, IKJEFTNS, and IKJEFTAP were taken out of IKJEFT02 and inserted into their own load module, which was called IKJTABLS. IKJTABLS didn't contain any executable code--it just contained program list tables. The trick for the special use of your own IKJTABLS was similar to that for IKJEFT02. If the IKJTABLS load module was present in an APF-authorized STEPLIB in your TSO session, it would override the same-named CSECTs that were in LPALIB or wherever (which the public would use), and you yourself could get your own personal special TSO command authorization. But this time, the authorization tables, being in a completely separate load module, were independent of which TSO/E release level and maintenance level you were running. The "auth CSECTs" were no longer connected to "mainline TSO", and when changing them, you would not interfere with applying normal TSO maintenance. So TSO itself was now in sync with current maintenance, and you had your own personal "auth tables" too. This was a much better situation than before. The next improvement in TSO/E came because of the push within IBM, spurred on by banks and other institutions which had to remain up for 24 X 7, to eliminate IPLs. In the late 80's and early 90's, IBM made a big effort to convert hard-coded tables that were created at IPL time, to dynamically created tables in common storage, that could be re-created at any time after IPL, usually via an operator command. Around this time, the IKJTSOxx PARMLIB member was created. It was given the capability of renewing a copy of the TSO auth tables in common storage, at any time, via the PARMLIB UPDATE(xx) TSO command. The advantage of this was obvious, making it possible for installations to authorize commands and programs to TSO, whenever they wanted to do so, even in-between IPLs. Later on, with TSO/E Release 3 (corresponding to z/OS 1.3), the SET IKJTSO=xx operator command was also introduced, and was given the same power and action as the PARMLIB UPDATE(xx) TSO command. The PARMLIB UPDATE(xx) facility was created first. I think that's because IBM wanted to give this "dynamic auth" capability to systems programmers only, but later they relented, and realized that you need an operator command too, sometimes. Again, the advantage of the operator SET command, is that you don't need to have a TSO session up when you need to change something. In modern z/OS systems, the default auth tables in the system are created from the default PARMLIB member IKJTSO00, or whatever IKJTSOxx member is pointed to, by the active IEASYSxx member. So at this point, we have to realize that "everybody else's" TSO/E authorizations come from the PARMLIB member IKJTSOxx that is currently active. Nevertheless, if your session's TSO/E authorizations come from a copy of the IKJTABLS load module that is in an APF-authorized STEPLIB, they will STILL COMPLETELY OVERRIDE the default tables. That is because your TSO session's LWA pointed-to tables were copied from your STEPLIB load library at LOGON time, instead of being copied from the PARMLIB-created copies of the tables in common storage. We'll see how this works, a bit later on. However, if the PARMLIB member IKJTSOxx does NOT contain one of the keywords: AUTHCMD, AUTHPGM, AUTHTSF, or NOTBKGND, then that respective table is defaulted from its copy in IKJTABLS that is in LPALIB. Again, if your session has an authorized STEPLIB with IKJTABLS, then your STEPLIB's IKJTABLS will override any other default table that is in the environment. We'll discuss all these facts in much greater detail later. TABLE LENGTHS AND TABLE DELIMITERS At this point, I just want to interrupt the discussion to talk about the lengths of the tables that were created by the PARMLIB TSO command (or by the SET IKJTSO=xx operator command). When the PARMLIB processing creates one of its incore tables in common storage, the length of the created table is measured, and it is recorded in the CTLT control block (some details to be discussed later). When the auth tables are created (for a user's TSO session) via their being copied from an IKJTABLS load module in STEPLIB, no lengths of tables are recorded in the system. This is a big difference. So the question is, if no table lengths are recorded, how does the system "know" where the table ends? Answer is, that all the TSO auth tables are delimited by a blank table entry. In other words, if the program name is 8 blanks, then all table entries after that point, are ignored, and the table is deemed to end at the blank entry. This is a VERY important fact for us to know. Since we have the possibility of an "auth table" coming from any of several origins, there have to be "flags" in the system, telling you how to deal with that particular copy of that particular table. The Logon Work Area (LWA), which we'll talk about later, contains such flags to deal with a TSO session's auth tables that come from various origins. But in any case, the bottom line is that A BLANK TABLE ENTRY WILL ALWAYS DELIMIT THE TABLE, no matter what its origin was. YOUR OWN COPY OF THE AUTH TABLES Consider this. It is almost universally true that when you set up an entry in a PARMLIB member (that is actively being used by the system), this entry gets translated into some information that is in an MVS control block in storage somewhere, usually in common storage. And the system itself "knows" how to get to that information, through an established path. To summarize: Information in a PARMLIB member will (almost) always translate into information in common storage, which the system can get to, via a known path. There's a problem with information in common storage, especially when it comes to TSO. The TSO developers always have to consider a case where a thousand TSO users are trying to LOGON to their TSO sessions at the same time. In a very large installation, it might happen, and the TSO developers have to consider this "boundary condition" (so to speak) as being one of their developmental constraints. What happens when a thousand users (or any other large number) are trying to get to common resources? There will be contention somewhere, and there will be a backup in trying to get to some of the (common) resources that are shared by all (or many) of these TSO sessions. One solution to this general problem, is to give each TSO user his or her own copy of a resource, rather than for the user to continually try and access the common resource. Then, contention (by many users) for the common resource is minimized or eliminated. This happened with the TSO authorization tables: IKJEFTE2, IKJEFTE8, IKJEFTAP, and IKJEFTNS (AUTHCMD, AUTHPGM, AUTHTSF, and NOTBKGND respectively). At one point in time, the TSO developers decided to GIVE EACH TSO SESSION its OWN COPY of these authorization tables. The "individual copy" of these authorization tables is created within the userid's address space at LOGON time, in Key 0, Subpool 252 storage, and they are pointed to by address fields in the Logon Work Area (LWA) which is also created for each TSO userid at LOGON time. Each TSO userid has its own unique Logon Work Area that was created for it. And the LWA-pointed-to copies of the authorization tables are the ones which your TSO session actually refers to! Most people don't know this. I ran a survey test question among old MVS veterans with 25 years of experience or more. Most of them did not know where the "real" TSO authorization tables were! Getting back to the subject, how do the individual copies of the TSO "auth tables" get there? At LOGON time, they are copied into GETMAINed storage in Key 0, Subpool 252 from any of several sources. As far as I can determine, the IKJEFTP1 TSO initialization module (executed at LOGON time) performs this construction process. Where are the tables copied from? Under usual circumstances, they are copied from either of two places. One place, is from the "common storage" tables that are created from the active IKJTSOxx PARMLIB member. If the keywords AUTHCMD, AUTHPGM, AUTHTSF, and NOTBKGND were coded in the IKJTSOxx PARMLIB member, together with an appropriate list of program names, then "TSO system initialization" at IPL time will create several areas in common storage which contain these tables. These areas can be "renewed" or "re-created" whenever you do a PARMLIB UPDATE(xx) TSO command, or a SET IKJTSO=xx operator command, provided that you have changed the list of names in the IKJTSOxx member. If you do not issue a(nother) PARMLIB UPDATE(xx) command or a(nother) SET IKJTSO=xx command, then these tables remain in place, in common storage, for the duration of the IPL. When a TSO user does its LOGON, the "auth tables" are usually copied from the "common storage" version of these tables, which are intended for "most TSO users". I'll talk about the "second possible place" soon, where it's possible for your TSO session to get its "auth tables". For the record, if you really want to know where the "common storage" versions of the "auth tables" are, you do as follows: The CVT has an address pointer to the TSVT (TSO Vector Table) at +X'9C' from the CVT. The TSVT points to the TPVT (TSO Parmlib Vector Table) at +X'4C' from the TSVT. The TPVT points to the CTLT control block at +X'14'. And the CTLT points to the rest of the table addresses. The TPVT and CTLT are not documented by IBM for public use, and IBM doesn't give out macros in the macro libraries which describe them. However, approximate descriptions of these control blocks, which were figured out by users, can be found on CBT Tape File 731 in the MODGEN member, or in CBT File 492 in the SHOWMACS member. So the macros IKJTPVT and IKJCTLT in CBT Tape File 731 or File 492 will do the job very well, for us. I have written several commands: ADIS, ASUB, and LSLT, which can be found as load modules in the LOADLIB member of CBT File 185, that can display and/or directly manipulate the "common storage" version of the "auth tables". The second possible place for your TSO session to get its tables copied from, will happen if two circumstances are true. First, the TSO session's LOGON PROC (i.e. it's JCL) has to contain a STEPLIB DD to an APF-authorized load library. Second, a properly linkedited copy of the IKJTABLS load module must be present in the STEPLIB library, with one, several, or all, of the CSECTs IKJEFTE2, IKJEFTE8, IKJEFTAP, and IKJEFTNS present. In that case, TSO LOGON (the IKJEFTP1 program which creates your session) will copy the "auth tables" individually from the appropriate CSECT in the IKJTABLS load module that's in your authorized STEPLIB library, and put that table into Key 0, Subpool 252 storage, pointed to by the Logon Work Area. Remember now, that the LWA version of the "auth tables" are the ones which your TSO session actually uses. So if your TSO session has an APF-authorized load library as a STEPLIB in its LOGON PROC, with an IKJTABLS load module in it, then LOGON DOES NOT GET THAT TABLE from the "common storage" copy. Therefore the STEPLIB version of the table will COMPLETELY OVERRIDE the version of that table in common storage, which was created by the (active) PARMLIB member IKJTSOxx. Thus we see that your "auth tables" for your TSO session can come from one of two places, EITHER, OR, BUT NOT BOTH! What if AUTHCMD, AUTHPGM, AUTHTSF, or NOTBKGND are NOT coded in the IKJTSOxx PARMLIB member? And additionally, there is no authorized STEPLIB library, or it doesn't contain an IKJTABLS load module? Then what happens? In THAT case, the LWA will NOT point to the appropriate table in Key 0, Subpool 252 storage. But it will merely point to the appropriate default CSECT: IKJEFTE2, IKJEFTE8, IKJEFTAP, or IKJEFTNS that is in the copy of IKJTABLS that is in LPALIB. In that case, the LPALIB version of the table will be the one which your session uses. NEW WAYS OF LOADING TSO AUTH TABLES Dan Dalby has written a marvelous "dynamic" STEPLIB command (found in CBT Tape File 452) which can perform the creation of a STEPLIB in a TSO session, exactly the way IBM does it with JCL. This STEPLIB command has to be APF-authorized, but once it is, and you've used it, you've given your TSO session access to programs that it wouldn't otherwise have had access to. If Dan's STEPLIB command is executed against an APF-authorized load library, the effect is exactly as if you have an APF-authorized STEPLIB in the JCL, but there is one great big difference when it comes to loading the auth tables into your TSO session. Dan's STEPLIB command was not in effect at your session's LOGON time. If you have an authorized STEPLIB, statically coded in the LOGON PROC, it WAS there at LOGON time. Therefore, if the authorized STEPLIB was there at LOGON time, and it has an IKJTABLS load module in it, the auth tables come from IKJTABLS. But if the STEPLIB was NOT there at LOGON time, then the tables still come from the "common storage" tables that were created from the active IKJTSOxx PARMLIB member. Therefore, even though you have executed Dan's STEPLIB command against an APF-authorized load library that contains a big IKJTABLS member, you don't have all the power you need to execute all the programs, because you are still using the "common storage auth tables" and not the (presumably bigger) tables that were coded in the STEPLIB. How can we "dynamically load" the STEPLIB, and then "dynamically load" the tables after that? Dan and I have independently written two programs which will do this. Dan's program is called LWATMGR (LWA Table Manager). My program is called LLWA, or (re)Load the LWA. These two programs can load a fresh set of auth tables, from any of 3 different sources, into Key 0 Subpool 252 storage in your TSO session's address space, and then re-point the LWA pointers and flags to properly point to the new tables. Your TSO session will then honor the new tables, and not the old ones. In addition to my LLWA program, I have written another program called TSUB, which manipulates pre-existing auth tables that are pointed to by the LWA. In functionality, LWATMGR will approximately equal the combined capabilities of LLWA and TSUB. But they do have non-overlapping capabilities too, so it would pay for you to learn about all three programs. These programs are found in the CBT Tape collection (at www.cbttape.org on the Updates Page) in File 797. In order to get full capability with your "auth tables" later, you will have to pre-authorize just two programs in the AUTHCMD table. These would be either STEPLIB and LWATMGR, or STEPLIB and LLWA. Actually, if you have LLWA or LWATMGR loaded into an authorized load library already, that your TSO session has access to, you just have to pre-authorize either one of these, and you can include STEPLIB in the AUTHCMD (IKJEFTE2) list in your new freshly loaded tables. So what we do, is to use LLWA or LWATMGR to load a fresh set of auth tables for your own TSO session. And then, it doesn't matter what auth tables your TSO session used before. The combined action of the STEPLIB program and either LLWA or LWATMGR will then exactly duplicate the effect of an authorized STEPLIB in your LOGON PROC, without your actually needing to have a special LOGON PROC for yourself. SOURCES OF AUTH TABLES FOR RELOADING Both the LLWA and LWATMGR programs can load a new set of auth tables from either of 3 sources: An IKJTABLS-like load module, an IKJTSOxx-like LRECL=80 PARMLIB-like dataset (sequential or a pds member), or a raw list of program names, with LRECL=8. This list of names is as "bare-bones" a piece of input as you'll ever need, and it takes very little disk space to store it. In addition, the LLWA program can convert either load library input, or PARMLIB-like input into the LRECL=8 list input, so you can conveniently store the lists away. The LRECL=8 list input is most fascinating, in my view. You specify which table is being loaded, with a special 8-byte header. For the IKJEFTE2 table, the header in the list, is ---E2---. For the IKJEFTE8 table, the header entry is ---E8---. And similarly, ---AP--- and ---NS--- will cause the reloading of those respective tables, with all the program name entries that follow that header (until encountering either the next header, or the end-of-file). Again, the LLWA program can convert either load-module input or PARMLIB-like input into LRECL=8 "name list" input. For details as to how to run the LWATMGR, LLWA, and TSUB programs, please see CBT Tape File 797, which has source code for all of them, as well as HELP members for them. My recommendation would be to store all of your auth tables as LRECL=8 lists, as members of a pds. The pds will take up very little room. For example if the blocksize of the pds is 6000, then 750 table entries will fit in just one block. Therefore, the data to rebuild all of your auth tables will probably fit into just one block of data. Now that's compact! If you want to hide your lists and store them offsite, just put the pds into TSO XMIT format and download it in BINARY to a PC, giving the XMIT-format dataset any name you want. You can sort-merge all of your auth tables to get one big list. Or else, you can just load "specialty tables" as the need arises. You've got a lot of power here. THE EFFECT OF PARMLIB UPDATE(xx) There's one more fact here, which you should know about. There are flags in the LWA for each of the four tables, saying whether they were loaded into your TSO session (presumably at LOGON time) from PARMLIB or from a STEPLIB. If the flag bit is 0, that table was presumed to be loaded from PARMLIB. If that flag bit is 1, then the table is presumed to have been loaded from STEPLIB. What happens to the tables for your TSO session, when a PARMLIB UPDATE(xx) is done, to change one or more of the tables? Well, IBM would like that every active TSO session should use the new tables. So the PARMLIB command goes around, across address spaces, visits each active TSO session, and looks at each of its auth tables. If the LWA flag for that table says that it came from PARMLIB, then the PARMLIB command replaces the given table with a new one, dynamically. So the effect is that if OUR new tables were marked as if they came from PARMLIB, then a PARMLIB UPDATE(xx) command would overlay our work with the common tables again. Therefore, both the LLWA and LWATMGR commands will mark their newly created tables as if they came from STEPLIB rather than PARMLIB, so a PARMLIB UPDATE(xx) command would not re-overlay them. An additional consequence comes out from this. PARMLIB UPDATE(xx) has the effect of making a global change to the auth tables. Suppose we only want to test a new set of auth tables on one session! Then we use either the LWATMGR or LLWA commands to limit the effect of the new auth table(s) to just the session that invoked them. This way, we have a LOCAL change and not a GLOBAL change. Thus we can use the new LLWA and/or LWATMGR commands to test a new auth table on only one TSO userid, without consequences for the rest of the TSO sessions in the LPAR. SUMMARY The TSO authorization tables (AUTHCMD, AUTHPGM, AUTHTSF and NOTBKGND) which your TSO session uses, are local tables in your own address space, that were either copied from the "common storage" tables, created from the IKJTSOxx PARMLIB member, or were copied from an IKJTABLS load module in a STEPLIB that is APF-authorized to your TSO session. The active tables are pointed to, and described, by addresses and flags in the LWA (Logon Work Area) which is unique to your TSO session. Your TSO session's auth tables are created during LOGON processing, at LOGON time, by the IKJEFTP1 program. These can be replaced later, by either of the authorized TSO commands, LLWA or LWATMGR, which can be found on the CBT collection (www.cbttape.org) on the Updates page, in File 797. The LLWA and LWATMGR programs can take new table input in three formats: load module input, PARMLIB member type input, or LRECL=8 name list input. See File 797 for the details. It is my experience that your auth tables are most conveniently stored in LRECL=8 input, as members of a pds. The LLWA program can convert auth table input from either load module format or PARMLIB-like format into LRECL=8 list format, for convenient storage and later use. I hope that this article will open your minds to being able to customize your TSO environment better, and with more flexibility. Your role as "system doctors" will be greatly enhanced by this knowledge and by these new capabilities. Best of luck to all of you.