Fork me on GitHub

ZDOSU : Isn't it awesome being special?

With great power there must also come ... great responsibility!

As a professional Mainframe Systems Programmer one needs extreme authorizations on the system from time to time. Sometimes it's to be able to restore data you are not authorized for by default, sometimes it's so you can add some security settings. At other times it's just to perform some rudimentary display commands or install or configure some product.

At most shops security on The Mainframe is very tight. At some sites Systems Programmers are not allowed to be "SPECIAL" or "OPERATIONS". This mostly means only the security guys are authorized to change security settings, resulting in tedious and longer turn-around times for projects than need be. (Depending on the competence level of your security guys your milage may vary). On the other hand, if your shop has a setup where you the Systems Programmer are entitled to be "SPECIAL" this means you always have FULL AUTHORITY on the system, making you think twice before doing anything, because you're hardly ever blocked by security settings. This may result in unwanted (and mostly unplanned) results.

A committee is a group that keeps minutes and loses hours

Why not have both? We at zdevops firmly believe a Systems Programmer needs to be "SPECIAL" or "OPERATIONS" from time to time. We also believe it's extremely dangerous to always have FULL AUTHORITY on the system. But we also think procedures and corporate cumberness should not have a negative impact on a Systems Programmer's effectiveness.

I've got sudo on my machine....

On the newer *nix platforms it's a common thing to "su" before altering 'critical' settings. The module presented in this repository does somewhat of the same thing. It provides a mechanism to temporarily gain "SPECIAL" or "OPERATIONS" attributes allowing the caller to perfrom some actions normally not allowed by SAF.

...this stuff is ancient

This functionality has been about since the start of time (epoch-wise at least I'd say) and we at zdevops.com are by no means trying to claim credit for it. We're not dropping any names here, but references to code like this were made at the turn of the century. This data is still available at the CBT site. If you really start searching I willing to bet you will find some actual 'punch-cards' with code like this.... We're merely expanding and sharing things thought of by others because, quite frankly, we don't want to see this information lost. And judging by the ever increasing average age of the Mainframe Systems Programmers chances are this knowledge might get lost in time forever.

What does it do?

Basically this module will add or remove "SPECIAL" or "OPERATIONS" attributes from your 'current session'. Because of the extreme consequences this might have RACF is used to permit usage of this module. Without the proper PERMIT this program does virtually less than IEFBR14. With the proper authorization however, this module will grant the caller with the powers of "SPECIAL" and/or "OPERATIONS". And we all know the famous Stan Lee quote when it comes to "great powers".

How do I get this running?

Hold your horses there. Before you can even start 'installing' and using this module there are a couple of requirements that need to be fullfilled before you can start:

Installing via SMP/e

Head on over to our repository on github and download ZDO1207 from the SMPE directory. Don't worry, we will hardly release more than one USERMOD per month, so you're save with the naming convention we use. Once you've downloaded the USERMOD you need to upload it to your Mainframe.

Once uploaded to your Mainframe (make sure to send it ASCII, and place it in FB 80 dataset) you need to RECEIVE and APPLY it.

Performing the receive

For some of us there are no secrets within SMP/e, others just copy and paste from existing jobs. To make sure this 'documentation' is as complete as possible we present you with the following JCL.

//S1          EXEC PGM=GIMSMP,
//            PARM='PROCESS=WAIT',
//            REGION=0M,
//            DYNAMNBR=120
//SMPCS1   DD DSN=LOCATION.OF.YOUR.CSI,
//            DISP=SHR
//SMPCNTL  DD *
  SET BOUNDARY (GLOBAL).
  RECEIVE SYSMODS SELECT(ZDO1207).
//SMPPTFIN DD DSN=LOCATION.WHERE.YOU.UPLOADED,
//            DISP=(SHR,KEEP) 

If all goes well, this job should return with messages like these :

GIM22701I    RECEIVE PROCESSING WAS SUCCESSFUL FOR SYSMOD ZDO1207.
GIM20501I    RECEIVE PROCESSING IS COMPLETE. THE HIGHEST RETURN CODE WAS 00.

Applying the usermod

Once succesfully received all you need to do is APPLY the USERMOD. Yet again we need to put GIMSMP to work. The following JCL serves as an example.
//S1          EXEC PGM=GIMSMP,
//            PARM='PROCESS=WAIT',
//            REGION=0M,
//            DYNAMNBR=120
//SMPCS1   DD DSN=LOCATION.OF.YOUR.CSI,
//            DISP=SHR
//SMPCNTL  DD *
  SET BOUNDARY (TARGETZONE).
  APPLY SELECT(ZDO1207) RETRY(YES).

Once applied your very own 'ZDOSU' will be present in SYS1.LINKLIB (or whatever you changed your LINKLIB DDDEF to in SMP/e). If you prefer to store this module at a different location, you can either change the USERMOD or use the source file (as provided in the repo) and build your own 'compile & link' JCL.

Allowing users or groups to execute the module

As stated, this module requires RACF authorization to perform it's magic. This 'functionality' is there for a reason. Without it any user(!!) could upgrade himself to become "SPECIAL". Because this just give us shivers down our spine, we require users to have read to the 'ZDEVOPS.AUTH.*' profile in the FACILITY class. In order to grant a user (or group) access to the module you need to PERMIT them to the resource. An example is shown below:

/* Define the profile */
RDEFINE FACILITY ZDEVOPS.AUTH.* UACC(NONE) 
SETROPTS RACLIST(FACILITY) REFRESH 

/* Permit a user/group and refresh */
PERMIT ZDEVOPS.AUTH.* CLASS(FACILITY) ID(xxxx) ACC(READ) 
SETROPTS RACLIST(FACILITY) REFRESH

Usage

ZDOSU can be used from within a batch job (JCL) and in TSO.
//MYJOB       JOB,'Example job'
//*           RUN A JOB WITH SPECIAL (SO WE CAN DO RACF AND THINGS)
//STEP01 EXEC PGM=ZDOSU,PARM='SPECIAL'
//*           THIS WILL SET SPECIAL BIT IN ACEE
//STEP02 EXEC PGM=IKJEFT01
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  ..
  .. add your RACF COMMANDS
  ..

If you want to be able to call this module from within TSO make sure to add the program to the authorized programs in your IKJTSOxx member.
...
AUTHPGM NAMES(            /* AUTHORIZED PROGRAMS */ +
   ..                  +
   IRRUT100            +
   IRRUT200            +
   ZDOSU)                 /* ADD THIS LINE */

Messages and Logging

Due to the potential dangerous effect as a result of using this module every invocation of the program will be logged in SYSLOG. This is message ZDOSU0000I : EXECUTION STARTED.
From SYSLOG one can determine the originating address space, providing you with a basic audit trail towards the executing user.

There are however a couple more messages this module can generate. For completeness sake all of them are provided below.

ZDOSU0000I : EXECUTION STARTED
This message is written to SYSLOG only and indicates usage of the module.
This happens regardless of success or failure. Provides basic audit trail.

ZDOSU1000E : PARAMETER ERROR
ZDOSU needs to be called with a parameter. This parameter can be one of:
- SPECIAL (set SPECIAL)
- OPERATIONS (set OPERATIONS)
- NOSPECIAL (remove SPECIAL)
- NOOPERATIONS (remoce OPERATIONS)
Failure to provide this parameter results in this message.

ZDOSU2000E : ZDEVOPS.AUTH.* NOT DEFINED
Because of the nasty nature of this module we are performing a RACROUTE
to the profile 'ZDEVOPS.AUTH.*' in the FACILITY-class. If this profile
has not been defined the module terminates with this message.

ZDOSU3000E : USAGE NOT PERMITTED
User has no access to ZDEVOPS.AUTH.* in FACILITY-class. Module terminates.

These are all the messages ZDOSU can potentially generate. It should serve as a guide to using the module

Inside scoop

So how is it done? ZDOSU is written in ASSEMBLY and therefore extremely awesome and efficient. You can easily head on over to the repository at GitHub and awe at the code there. Below you will find some snippets from the source. This will most likely be parsed succesfully by ASMA90, however it is not the not full version. We urge you always download sources from the GitHub repository.

That being said, here's the code :

ZDOSU    CSECT
         BAKR  14,0                    PUSH REGISTERS
         LR    12,15                   LOAD ENTRY ADDRESS INTO R12
         USING ZDOSU,12                ESTABLISH ADDRESSABILITY
         L     2,0(1)                  LOAD PARM POINTER
         LH    3,0(2)                  R3:=PARM LENGTH
         CH    3,=H'6'                 LESS THAN 6 ?
         BL    ZDOSUE1                 BRANCH TO ERROR :)
         LA    3,2(2)                  LOAD PARM DATA ADDRESS
ZDOSULG  WTO   'ZD0000I : EXECUTION STARTED!',ROUTCDE=(9)
ZDOSU00  RACROUTE REQUEST=AUTH,WORKA=WA,ENTITYX=ENTITYX,RELEASE=1.9,   *
               ATTR=READ,CLASS='FACILITY',MSGSUPP=NO
RETURN   PR                            POP REGISTERS AND RETURN
ZDOSUE1  WTO   'ZDO1000E : PARAMETER ERROR',ROUTCDE=(11)
         LA    15,4
         B     RETURN
         LTORG
ZDOSUE2  WTO   'ZDO2000E : ZDEVOPS.AUTH.* NOT DEFINED',ROUTCDE=(11)
         LA    15,4
         B     RETURN
         LTORG
ZDOSUE3  WTO   'ZDO3000E : USAGE NOT PERMITTED',ROUTCDE=(11)
         LA    15,4
         B     RETURN
         LTORG
WA       DS    CL512
ENTITYX  DC    H'0',H'14',C'ZDEVOPS.'
RESSUF   DC    CL5'AUTH.*'
         END   ZDOSU

Wrapping it up

Seeing as you've read all the way past the source-code we will get a bit more nerdy on the whole z/OS thing. Every address space succesfully executing ZDOSU (with PARM='SPECIAL') will have it's "SPECIAL" flag waving in the wind. There's virtually nothing this address space cannot do......

By walking down the ASXB tree we can end up at the ACEE and flip some bits in that area.

Before the program decides to flip some bits, it first issues a RACROUTE to test if the current user has READ on ZDEVOPS.AUTH.* in the facility class. It also checks if there's an argument of at least 6 bytes (SPEC,OPER,NOSPEC,NOOPER). And even before all this has happend a message was written to SYSLOG (route code 9) providing information for an audit trail regarding invocations of the progam. After that, it's a piece of pie to flip the appropriate bits.

So there you go, instant SPECIAL for your Mainframe environment. Make sure to use and implement this 'tool' with the appropriate care. We for one love using this on our RD4Z:UT environment. It let's us work on the system as a 'regular' user yet giving us the powers to instantly add (or remove) certain pesky security settings without the constant dread of being 'SPECIAL' all the time.

Feel free to leave your comments below

comments powered by Disqus


This GitHub repository is part of a project maintained by zdevops.com. This documentation is proudly hosted on GitHub Pages. Theme based on work by orderedlist.We do not accept any liability as a result of implementing this functionalty. You have been warned.............