Document Management, EDI Software, MICR Check Printing, ACH Payment Solutions






About the Author:

ken graap

Ken Graap, iSeries / System i expert, has been answering Search400.com's member questions for more than five years. Ken has seen many of the same issues and concerns asked over and over. Therefore, we've compiled the top 10 questions asked about system i backup and recovery for you.

Forms/Document Output

View Quick Overview of Document Output Solution


Laser Checks/ePayment

View Quick Overview of Payment Solution


EDI and XML Integration


Document Management

View Quick Demo of Document Management Solution

 Home> Articles > System i Administrator Tips: Top 10 Q&As

System i Administrator Tips: Top 10 Q&As


Article courtesy of Search400.com
By Ken Graap Top Ten Questions

  1. Creating a command shortcut for WRKOUTQ PRT03

  2. Moving a spool files from one system to another

  3. Editing a word document stored in an IFS shared directory

  4. Setting up Remote Journaling between two i5 servers

  5. Control the creation of job logs on your system

  6. Distribute copies of spool files to several different printers

  7. Set up you i5 system to forward email to a corporate email system

  8. Secure production data from PUBLIC access

  9. Run as another user without having to sign on as that user

  10. Set up secure access to a command line from an interactive job


1. Creating a command shortcut for WRKOUTQ PRT03

I need to create a command shortcut for WRKOUTQ PRT03. How do you recommend I do this?

I would suggest that you create a simple command using the QCMDEXC API and then passing it a "constant" value, like this:

/*                                                 */ 
/* CRTCMD CMD(QGPL/WQ3) PGM(QSYS/QCMDEXC) */
/* SRCFILE(Your_Srclib/QCMDSRC) */
/* */
CMD PROMPT('WRKOUTQ PRT03')
PARM KWD(CMD) TYPE(*CHAR) LEN(20)
CONSTANT('wrkoutq
outq(prt03)')
PARM KWD(LEN) TYPE(*DEC) LEN(15 5)
CONSTANT(20)

       
Have any other "shortcuts" you would like to create? Consider using this technique instead of creating duplicate system commands.

topReturn to Table of Contents


 

2. Moving a spool files from one system to another

I need to move spool files from one system (V4R4) to another (V5R3). Is there an easy way to do this?

Let's assume that your two systems are connected via TCP/IP. Then all you would have to do is create a remote *OUTQ on the V4R4 system pointing to an *OUTQ on the V5R3 system. Any spool file placed on this remote *OUTQ would then be sent to the V5R3 system.

Here is and example for creating a remote *OUTQ:

CRTOUTQ OUTQ(mylib/remoteoutq) -- The *OUTQ on the V4R4 system.
RMTSYS(v5r3sys) -- The DNS name for the V5R3 system. 
RMTPRTQ('mylib/v5r3outq') -- The *OUTQ on the V5R3 system.
AUOSTRWTR(1) CNNTYPE(*IP) DESTTYPE(*OS400)


Note: If the writer associated with this remote *OUTQ needs to be restarted for any reason, you would have to use the STRRMTWTR command instead of the STRPRTWTR command.

topReturn to Table of Contents




3. Editing a word document stored in an IFS shared directory

When I edit a Word document stored in an IFS shared directory, the Word program's temporary files aren't being deleted after I save the document. Why can't Word clean up after itself when using the IFS?

What I believe is happening is that the authority to the IFS directory you are creating your documents in is insufficient.

When a user creates a new file in an IFS directory they become the owner of the file and therefore have all data rights, but the OBJECT authority assigned to the file is based on the authority of the directory it is placed in.

Here are the rules:

  1. The owner for the new object has the same object authorities that the owner of the parent directory has to the parent directory.
  2. The primary group for the new object has the same object authorities that the primary group of the parent directory has to the parent directory.
  3. *PUBLIC has the same object authorities to the new object that it has to the parent directory.

In your word processing example, the word processing program creates a temporary file when a file is created or opened for edit. When the user finally saves the document and exits, the PC program attempts to rename the most current temporary file to the original file name. If the user's objects didn't get sufficient private authority from the parent directory (which I suspect they aren't) then this operation can't be completed.

So, check to see whom the OWNER of the parent directory is and what authority they have to it because this will be the authority assigned to any new object created in that directory.

If the OWNER of the directory is different than the user creating the object in the directory (which is probably the case) then the *PUBLIC authority setting comes into play.

The simplest fix to your problem may be to assign *PUBLIC authority, such as:

             Data    --Object Authorities--
User Authority Exist Mgt Alter Ref *PUBLIC *RX X


Oh, by the way, here is IBM's explanation of "mgt object authority":

The object authorities that the user has to the object.
An "X" in the column indicates that the user has the specified object authority to the object named. The specific object authorities are:

Mgt
Object management authority provides authority to specify security, to move or rename the object, and to add members if the object is a database file.



topReturn to Table of Contents




4. Setting up Remote Journaling between two i5 servers

How can I set up Remote Journaling between two i5 servers?

This is easier that you might think.

First of all, you will need to establish a TCP/IP connection between the two machines. This could just be an Internet connection. My guess is that you have already done this.

To enable Remote Journaling you would do the following:

  1. Define Journaling on the SOURCE system. For Example:
    1. Create a message queue to receive journal messages:
      CRTMSGQ MSGQ(QGPL/LAWJRN)
      TEXT('Lawson journal messages')

    2. Create a journal receiver in the proper journal receiver library:
      CRTJRNRCV JRNRCV(JRNRCVLAW/LAW2JR0001)
      THRESHOLD(1000000)

    3. Create a journal referencing the receiver just created:
      CRTJRN JRN(LAWP1FILES/LAWP1JRN) JRNRCV(JRNRCVLAW/LAW2JR0001)+
      MSGQ(QGPL/LAWJRN) MNGRCV(*SYSTEM) DLTRCV(*NO) +
      RCVSIZOPT(*RMVINTENT *MAXOPT2)

  2. Create a Relational Database entry to identify the DB on the system you wish to journal to.

    For Example:
    ADDRDBDIRE RDB(REMOTESYS)
    RMTLOCNAME('10.10.10.110' *IP)
    TEXT('My Remote system')

  3. Create a Remote Journal.

    For Example:
    ADDRMTJRN RDB(REMOTESYS)
    SRCJRN(LAWP1FILES/LAWP1JRN)
    TGTJRN(RMTJRN/LAWP1JRN)
    RMTRCVLIB(RMTJRN)
    TEXT('Remote journal for LAWP1FILES')

  4. Decide what objects you want to journal and start journaling them.

  5. Manage your remote journaling environment.

topReturn to Table of Contents




5. How can I set up journaling for my production files?

How can I control the creation of job logs on my system?

There are several components to how job logs are created on a the system.

The message logging parameters determine what kind of information will be collected:

Message logging:                 LOG                          
  Level  . . . . . . . . . . . .                4             
  Severity . . . . . . . . . . .                00            
  Text . . . . . . . . . . . . .                *NOLIST     
Log CL program commands  . . . . LOGCLPGM       *NO   


I won't go into all the specifics related to these values, but if the message logging 'TEXT' parameter is set to *NOLIST a job log will only be created if the job ends abnormally. If the job completes normally, no job log will be created.

This is the same whether the job is an interactive or batch job.

If any value other than *NOLIST is specified for the message logging 'TEXT' parameter in a batch job, a job log will always be produced, whether the job ends normally or abnormally.

This works differently for interactive jobs though. In order to conserve disk space the SIGNOFF command has been defined as:

                               Sign Off (SIGNOFF)        
Type choices, press Enter.                              
Job log  . . . . . . . . . . . . LOG            *NOLIST    
Drop line  . . . . . . . . . . . DROP           *DEVD      
End connection . . . . . . . . . ENDCNN         *NO  


So, by default, when an interactive job is ended normally, no joblog will be produced.

However, if the interactive job ends abnormally a joblog and most likely a program dump, will be produced.

If you want to force the creation of a job log from an interactive job you can do it in one of two ways.

  1. When you sign off enter SIGNOFF LOG(*LIST).
  2. Prior to signing off enter DSPJOBLOG OUTPUT(*PRINT).
When one of these options is used a job log is created.

On V5R4 of OS400 the job log creation process has been enhanced. To review the changes, following this link.

topReturn to Table of Contents




6. Distribute copies of spool files to several different printers

I need to distribute copies of spool files to several different printers. Is there an easy way to do this without having to purchase additional software for my system?

Yes, I think there is a "simple" process for distributing copies of spool files to different printers using just basic OS/400 commands and definitions.

With just a few simple user profiles, distribution entries and the SNDNETSPLF command you can create a spool file distribution system.

You'll find the pieces in a past tip of mine"Distribute spool files to printers easily."


topReturn to Table of Contents




7. Why does my BRMS backup process run hours longer than before I used BRMS?

How would I set up my i5 system to forward email to my corporate email system?

To enable email forwarding from your i5 server requires that you do a couple of things.

First, you need to change the System directory Attributes via the CHGSYSDIRA command:

CHGSYSDIRA USRDFNFLD((FORWARDING *NONE *ADD *ADDRESS 256)   
(FWDSRVLVL *NONE *ADD *MSFSRVLVL 1))




This sets up the User defined fields like this:


Change System Dir Attributes (CHGSYSDIRA) 




Type choices, press Enter.

User-defined fields:                         USRDFNFLD 
  Field name . . . . . . . . . .                FORWARDING 
  Product ID . . . . . . . . . .                *NONE
  Function . . . . . . . . . . .                *KEEP
  Field type . . . . . . . . . .                *ADDRESS
  Maximum field length . . . . .                256
  Field name . . . . . . . . . .                FWDSRVLVL
  Product ID . . . . . . . . . .                *NONE
  Function . . . . . . . . . . .                *KEEP
  Field type . . . . . . . . . .                *MSFSRVLVL
  Maximum field length . . . . .                001 

Next you need to define where to forward email to for each user's directory entry. In this example, I will define that any email delivered to i5 user KEG to be forwarded to their internet email address: keg@nwnatural.com

CHGDIRE USRID(KEG S02) USRDFNFLD((FORWARDING *NONE KEG@NWNATURAL.COM))
MSFSRVLVL(FWDSRVLVL *NONE) PREFADR(FORWARDING *NONE MIME)

This change can be verified from the DSPDIRE USRID(KEG S02) screen via the F20 key:

 Display User-Defined Fields        
                                                         
User ID/Address . . . . :   KEG       S02                 
                                                         
      FORWARDING           :  KEG@nwnatural.com  

With these configurations changes in place, any email sent to keg.s02@s02.gasco.com will be automatically forwarded to keg@nwnatural.com. This can be verified by reviewing the entries in the QZMF journal:

Message ID                       Job        User   Number Program
 ID 10E844A0605111113150000002142 QTSMTPSRVP QTCP  429585 QZMFXLOG


Date     Time     Data                             Comment
5/11/06 11:13:15 9 99 MSGID:
        11:13:15 9 9T MSG SIZE 3326
        11:13:15 9 94 LIN TO SRVR 198.5.59.26
        11:13:15 9 91 O keg@NWNATURAL.COM
        11:13:15 9 92 R
        11:13:15 9 97 SRVR TO QTMSINQ
        11:13:15 7 7A QTMSINQ TO BRSR
        11:13:15 7 7H BRSR TO MSF
        11:13:15 7 71 O keg@NWNATURAL.COM
        11:13:15 7 72 R
        11:13:15 1                              MSF message create
        11:13:16 P P2 R chg to SNADS, can parse                ...
        11:13:16 H H1 01A1                 KEG     S02      01B...
        11:13:16 5 00001  00001
        11:13:16 P P2 R SMTP MsgFwd KEG@nwnatural.com
        11:13:17 C C6 FWD TO QTMSOUTQ
        11:13:17 C C1 O keg@NWNATURAL.COM
        11:13:17 C C2 R
        11:13:17 8 8B QTMSOUTQ TO CLNT
        11:13:17 2 000010000100000
        11:13:17 8 88 DLVED 198.5.59.26        Successful delivery
        11:13:17 8 82 R

That's all there is to it.


topReturn to Table of Contents




8. Secure production data from PUBLIC access

How can I secure production data from PUBLIC access, on a system used for both production and development work?

One solution would be to set up two partitions on your system, production and development. However, sometimes this isn't possible for a number of reasons.

Another solution is to utilize OS/400 security to create separate application environments within a single partition.

This can be done using Adopted Authority and Application Access programs.


Environment:

  1. Access to the production environment is denied to the public by default (*PUBLIC *EXCLUDE)
  2. The change management profile (CHANGEMGT) will have *ALL access to production objects. Source, Data and Programs.
  3. Development users will be able to READ production source.
  4. All users can EXECUTE production programs to allow for testing with development data.
  5. CHANGE access to production data, will be granted to authorized production users through a Production Application Access program set to adopt authority.
Implementation:

Production source files will be owned by user profile PRODSRC

The libraries and objects within the source libraries, will have *PUBLIC *AUTL authority defined and be secured by an authority list named PRDSRC

Authority granted through authority list PRDSRC will be:
*PUBLIC *EXCLUDE DEVELOPMENT *USE CHANGEMGT *ALL


This prevents general users from accessing production source files, but allows development users READ access. Of course the CHANGEMGT profile has all authority so it can be used to maintain the application.

Production application data will be owned by user profile PRODDATA

The libraries and objects within the libraries, will have *PUBLIC *AUTL authority defined and be secured by authority list PRDDATA

Authority granted through authority list PRDDATA will be:
PRODAAP *CHANGE *PUBLIC *EXCLUDE CHANGEMGT *ALL


This insures that production data is excluded from all but PRODAAP. Production uses will adopt this authority to access the data.

Production application programs will be owned by user profile PRODAPP

The libraries and objects within the application program libraries, will have *PUBLIC *AUTL authority defined and be secured by authority list PRDAPP

Authority granted through authority list PRDAPP will be:
*PUBLIC *USE CHANGEMGT *ALL

This provides access to the application code for all users. This is OK because they can only use these programs to access data they own (test data) unless they adopt authority from a Production Application Access program, and only production users have access to Production Application Access programs. CHANGEMGT has all authority so it can be used to maintain the application.

All production user profiles will have an initial program of PRDAAP defined.

Program PRDAAP will be owned by user profile PRODAPP and defined to adopt the program owner's authority - CHGPGM PGM(PRDAAP) USRPRF(*OWNER).

Authority to program PRDAAP will be:
*PUBLIC *EXCLUDE PRODUSER *USE

This is the KEY to the whole configuration. Only members of the PRODUSER group will be able to execute this Application Access program and adopt the authority necessary to access production data! Development and test users would have Application Access Programs that don't adopt authority and therefore they could not access production data even if they could modify their library lists.

Production Application Access programs will need to be created for each type of access, Interactive, Batch, ODBC etc. These programs will need to be set to adopt the authority for user PRODAAP too.

When a Production Application Access program is used, authority to production data is allowed via program adoption.

The following graphic illustrates this whole process.




topReturn to Table of Contents




9. Run as another user without having to sign on as that user

How can I run as another user without having to sign on as that user?

OS/400 does have API's that allow you to swap to another user profile within your current job. These programs are usually used to swap profiles within a server program, but you can use them to swap within your programs, too.

To maintain secure access to user profiles there are a few requirements that need to be met before you can perform a user swap.

First of all, the source and target user profiles will need to have *USE authority to the swapping API programs, QWTSETP & QSYGETPH. Both programs will need to have *USE access to each other before swapping can occur, too.

Once these requirements are satisfied, the following program could be used to swap to another program without having to supply a password:

Note: This program code is enhanced to monitor for errors and notify the System Administrator when they occur. These enhancements are optional to the swapping process, but it isn't a bad idea to monitor the use of a program like this.

             PGM        PARM(&NEWUSER)                               
/* ************************************************************** */ 
/*                                                                */ 
/* DECLARE PROGRAM VARIABLES                                      */ 
/*                                                                */ 
/* ************************************************************** */ 
             DCL        VAR(&USRPRF) TYPE(*CHAR) LEN(10)             
             DCL        VAR(&NEWUSER) TYPE(*CHAR) LEN(10)            
             DCL        VAR(&PRFHDL) TYPE(*CHAR) LEN(12)             
             DCL        VAR(&PRFHDLCUR) TYPE(*CHAR) LEN(12)          
             DCL        &ERRORSW *LGL                   /* Std err */
             DCL        &MSGID *CHAR LEN(7)             /* Std err */
             DCL        &MSGDTA *CHAR LEN(100)          /* Std err */
             DCL        &MSGF *CHAR LEN(10)             /* Std err */
             DCL        &MSGFLIB *CHAR LEN(10)          /* Std err */
/* ************************************************************** */
/*                                                                */
/* GLOBAL MESSAGE MONITOR                                         */
/*                                                                */
/* ************************************************************** */
           MONMSG     MSGID(CPF6801) /* Monitor for F3 from +      
                        command Prompt */                         
           MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(STDERR1))    
                                                                
   
           RTVJOBA    USER(&USRPRF)                                  
           SNDPGMMSG  MSG('User: "' *TCAT &USRPRF *TCAT '" is using +
                        RUNAS to swap to USRPRF: "' *TCAT +          
                        &NEWUSER *TCAT '"') TOMSGQ(CRITMSG)         
                                                                    
           CALL       PGM(QSYGETPH) PARM(*CURRENT '*NOPWD    ' +     
                        &PRFHDLCUR) /* Needed to swap back .... */   
                                                                     
           CALL       PGM(QSYGETPH) PARM(&NEWUSER '*NOPWD    ' +     
                        &PRFHDL)                                     
           MONMSG     MSGID(CPF22E9) EXEC(DO) /* Not enough +        
                        authority to SWAP. */                        
           SNDSTSMSG  MSG('You don''t have authority to swap to +    
                        USRPRF: "' *TCAT &NEWUSER *TCAT '"') DLY(3)  
             DLYJOB     DLY(3)                                       
             SNDSTSMSG  MSG('Contact the System Administrator - KEG +
                          or KKH...') DLY(5)                         
             DLYJOB     DLY(5)                                       
            SNDCOMPMSG  MSG('Contact the System Administrator - KEG +
                         or KKH...')                               
             SNDPGMMSG  MSG('User: "' *TCAT &USRPRF *TCAT '" tried + 
                          using RUNAS to swap to USRPRF: "' *TCAT +  
                          &NEWUSER *TCAT '". They were unable to +   
                          SWAP due to an authority issue.') +        
                          TOMSGQ(CRITMSG)                            
             GOTO       CMDLBL(END)                                  
             ENDDO                                                   
           MONMSG     MSGID(CPF22E4) EXEC(DO) /* Password expired */ 
           SNDSTSMSG  MSG('The password is expired for USRPRF: "' +  
                        *TCAT &NEWUSER *TCAT '"') DLY(3)             
             DLYJOB     DLY(3)                                       
             SNDSTSMSG  MSG('Contact the System Administrator - KEG +
                          or KKH...') DLY(5)                         
             DLYJOB     DLY(5)                                       
            SNDCOMPMSG  MSG('Contact the System Administrator - KEG +
                         or KKH...')                                 
           SNDPGMMSG  MSG('User: "' *TCAT &USRPRF *TCAT '" tried +   
                        using RUNAS to swap to USRPRF: "' *TCAT +    
                        &NEWUSER *TCAT '". They were unable to +     
                        SWAP because the password is expired.') +    
                        TOMSGQ(CRITMSG)                              
            GOTO       CMDLBL(END)                                  
            ENDDO                                                   
                                                                    
            SNDSTSMSG  MSG('Here we go, ready... set... SWAP +      
                         profiles!!!!') DLY(5)                      
            DLYJOB     DLY(5)                                       
                                                                   
            CALL       PGM(QWTSETP) PARM(&PRFHDL)                  
                                                                   
            CALL       PGM(GRTCMDAUD) /* Make sure commands are + 
                         being audited. */                        
                                                                  
            SNDSTSMSG  MSG('You are now running as user profile : +
                         "' *TCAT &NEWUSER *TCAT '"') +           
                         DLY(5)                                   
            DLYJOB     DLY(5)                                     
                                                                  
            SNDSTSMSG  MSG('You will now be prompted to change some +
                         Job/User Profile values.') DLY(5)        
            DLYJOB     DLY(5)                                    
                                                                
            ?          CHGJOB ?-JOB(*) ?-JOBPTY(*SAME) +        
                         ?-OUTPTY(*SAME) ?-PRTDEV(*SAME) +      
                         ??OUTQ(*SAME) ?-RUNPTY(*SAME) +          
                         ?-JOBQ(*SAME) ?-PRTTXT(*SAME) ?-LOG(*SAME +
                         *SAME *SAME) ?-LOGCLPGM(*SAME) +          
                         ?-INQMSGRPY(*SAME) ?-BRKMSG(*SAME) +      
                         ?-STSMSG(*SAME) ?-DDMCNV(*SAME) +         
                         ?-SCDDATE(*SAME) ?-SCDTIME(*SAME) +       
                         ?-DATE(*SAME) ?-DATFMT(*SAME) +           
                         ?-DATSEP(*SAME) ?-TIMSEP(*SAME) +       
                         ?-SWS(*SAME) ?-TIMESLICE(*SAME) +       
                         ?-PURGE(*SAME) ?-DFTWAIT(*SAME) +        
                         ?-DEVRCYACN(*SAME) ?-TSEPOOL(*SAME) +    
                         ?-PRTKEYFMT(*SAME) ?-SRTSEQ(*SAME) +   
                         ?-LANGID(*SAME) ?-CNTRYID(*SAME) +     
                         ?-CCSID(*SAME) ?-JOBMSGQFL(*SAME) +    
                         ?-DUPJOBOPT(*SELECT)                   
                                                                
           ?          CHGPRF ?-ASTLVL(*SAME) ?-CURLIB(*SAME) +
                         ?-INLPGM(*SAME) ?-INLMNU(*SAME) +    
                         ?-TEXT(*SAME) ?-KBDBUF(*SAME) +     
                         ?-JOBD(*SAME) ?-DOCPWD(*SAME) +     
                         ?-MSGQ(*SAME) ?-DLVRY(*SAME) ?-SEV(*SAME) +
                         ?-PRTDEV(*SAME) ??OUTQ(*SAME) +         
                         ?-ATNPGM(*SAME) ?-SRTSEQ(*SAME) +       
                         ?-LANGID(*SAME) ?-CNTRYID(*SAME) +      
                         ?-CCSID(*SAME) ?-CHRIDCTL(*SAME) +      
                         ?-SETJOBATR(*SAME) ?-LOCALE(*SAME) +    
                         ?-USROPT(*SAME) ?-HOMEDIR(*SAME)        
                                                                 
            ?          CHGLIBL                                   
                                                                 
            OVRPRTF    FILE(*PRTF) SPLFOWN(*JOB) /* Keep spool +
                        files with this job. */                
                                                                
            SNDSTSMSG  MSG('I'll now give you a command entry +
                         screen. Have fun!') DLY(5)          
            DLYJOB     DLY(5)                               
                                                          
            SNDSTSMSG  MSG('When finished, use F3 to return to your +
                         original user profile.') DLY(5)         
            DLYJOB     DLY(5)                                    
                                                                 
            CALL       PGM(QCMD) /* Present a command screen while +
                         running as the NEW user... */            
                                                                
            DSPJOBLOG  OUTPUT(*PRINT) /* Generate a joblog */       
                                                                    
            CALL       PGM(QWTSETP) PARM(&PRFHDLCUR)                
                                                                    
            SNDSTSMSG  MSG('You are now returning to user profile : +
                         "' *TCAT &USRPRF *TCAT '"') DLY(5)          
            DLYJOB     DLY(5)                                        
                                                                     
            SNDSTSMSG  MSG('You will now be allowed to reset some +
                         Job/User Profile values, if you want +    
                         to.') DLY(5)                              
            DLYJOB     DLY(5)                                       
                                                                    
            ?          CHGJOB ?-JOB(*) ?-JOBPTY(*SAME) +            
                        ?-OUTPTY(*SAME) ?-PRTDEV(*SAME) +          
                        ??OUTQ(*SAME) ?-RUNPTY(*SAME) +            
                        ?-JOBQ(*SAME) ?-PRTTXT(*SAME) ?-LOG(*SAME +
                        *SAME *SAME) ?-LOGCLPGM(*SAME) +       
                        ?-INQMSGRPY(*SAME) ?-BRKMSG(*SAME) +   
                        ?-STSMSG(*SAME) ?-DDMCNV(*SAME) +      
                        ?-SCDDATE(*SAME) ?-SCDTIME(*SAME) +    
                        ?-DATE(*SAME) ?-DATFMT(*SAME) +        
                        ?-DATSEP(*SAME) ?-TIMSEP(*SAME) +       
                        ?-SWS(*SAME) ?-TIMESLICE(*SAME) +      
                        ?-PURGE(*SAME) ?-DFTWAIT(*SAME) +      
                        ?-DEVRCYACN(*SAME) ?-TSEPOOL(*SAME) +    
                        ?-PRTKEYFMT(*SAME) ?-SRTSEQ(*SAME) +     
                        ?-LANGID(*SAME) ?-CNTRYID(*SAME) +       
                        ?-CCSID(*SAME) ?-JOBMSGQFL(*SAME) +      
                        ?-DUPJOBOPT(*SELECT)                     
                                                                
            ?          CHGLIBL                                    
                                                                 
            SNDSTSMSG  MSG('Welcome back!') DLY(3)                  
            DLYJOB     DLY(3)                                       
                                                                    
            SNDSTSMSG  MSG(*REMOVE)                                 
            SNDCOMPMSG MSG('Welcome back!')                         
                                                                    
            SNDPGMMSG  MSG('User: "' *TCAT &USRPRF *TCAT '" has +   
                         finished using RUNAS to swap to USRPRF: +  
                         "' *TCAT &NEWUSER *TCAT '"') TOMSGQ(CRITMSG)
                                                                    
/* ************************************************************** */
/*                                                                */
/* NORMAL END OF PROGRAM                                          */
/*                                                                */
/* ************************************************************** */
 END:        RETURN                                                 
/* ************************************************************** */
/*                                                                */
/* STANDARD ERROR PROCESSING                                      */
/*                                                                */
/* ************************************************************** */
 STDERR1:              /* Standard error handling routine */       
            IF         &ERRORSW SNDPGMMSG MSGID(CPF9999) +         
                       MSGF(QCPFMSG) MSGTYPE(*ESCAPE) /* Func chk */
            CHGVAR    &ERRORSW '1' /* Set to fail ir error occurs */
 STDERR2:   RCVMSG    MSGTYPE(*DIAG) MSGDTA(&MSGDTA) MSGID(&MSGID) +
                         MSGF(&MSGF) MSGFLIB(&MSGFLIB)              
            IF         (&MSGID *EQ '       ') GOTO STDERR3          
            SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +         
                         MSGDTA(&MSGDTA) MSGTYPE(*DIAG)             
            GOTO       STDERR2 /* Loop back for addl diagnostics */ 
 STDERR3:   RCVMSG    MSGTYPE(*EXCP) MSGDTA(&MSGDTA) MSGID(&MSGID) +
                         MSGF(&MSGF) MSGFLIB(&MSGFLIB)              
            SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +         
                         MSGDTA(&MSGDTA) MSGTYPE(*ESCAPE)           
            ENDPGM 



topReturn to Table of Contents




10. Set up secure access to a command line from an interactive job

How can I set up secure access to a command line from an interactive job?

One way to do this is to modify how the System Request menu works.

By default the System Request 90 option will execute the SIGNOFF command.

This option is defined by the contents of Message Description CPX2313, which can be found in message file QSYS/QCPFMSG

DMessage file  . . . . . . . . . :   QCPFMSG
Library . . . . .. . . . . . . . :   QSYS 
 Message IDs:          CPX2313                                   

CPX2313 Message . . . . : ENDRQS DSPJOB DSPMSG SNDMSG SIGNOFF DSPMSG DSCJOB DSPWSUSR ENDRDBRQS Severity . . . . . . . . . . . . . . . . . : SEV 0 Message level . . . . . . . . . . . . . . : LVL 04/10/99 65 Modification level . . . . . . . . . . . : 07/02/05 66 Alert option . . . . . . . . . . . . . . . : ALROPT *NO Log problem . . . . . . . . . . . . . . . : LOGPRB *NO Coded character set ID . . . . . . . . . . : CCSID 65535 . * * * * E N D O F L I S T I N G * * * * * FORWARDING : KEG@nwnatural.com


A simple command can be written that will check an authority list and call the command line API (QUSRCMDLN) if a user is authorized or just sign off the user if they aren't authorized to get a command line.

To implement this process do the following:

First define an authority list named SYSRQ90. Add the names of any individual user or group profiles you would like to give command line access via System Request 90, using the following commands:

For individual users: ADDAUTLE AUTL(SYSRQ90) USER(xxx) AUT(*USE)

For group profiles: ADDAUTLE AUTL(SYSRQ90) USER(xxx) AUT(*USE *AUTLMGT)

Next modify the CPX2313 message replacing SIGNOFF with SYSRQ90:

Do WRKMSGD CPX2313 and then use Option 2 to get the following prompt of the CHGMSGD command:

   Change Message Description (CHGMSGD)                    
                                                         
Type choices, press Enter.                               
                                                         
Message identifier . . . . . . . MSGID    > CPX2313       
Message file . . . . . . . . . . MSGF     > QCPFMSG       
  Library  . . . . . . . . . . .          >   QSYS        
First-level message text . . . . MSG       'ENDRQS   DSPJOB    DSPMSG
  SNDMSG     SYSRQ90    DSPMSG    DSCJOB   DSPWSUSR  ENDRDBRQS  '   


Make sure you don't change the spacing between the commands in this list. They have to be entered exactly as shown or System Request will not function correctly!

Create the following program and command:

CRTCLPGM PGM(QGPL/SYSRQ90)

Here is the program source:

/* ************************************************************** */
/* PROGRAM DESCRIPTION : WHEN A USER ENTERS SYSRQ 90 THIS PROGRAM */
/*                       IS CALLED. MESSAGE DESCRIPTION CPX2313   */
/*                       WAS UPDATED TO CALL THIS PROGRAM INSTEAD */
/*                       OF SIGNOFF                               */
/*                                                                */
/*                                                                */
/* SPECIAL COMPILE OPTIONS:   DON'T ALLOW ADOPTED AUTHORITY       */
/*                                                                */
/*                                                                */
/*           WRITTEN BY: KEN GRAAP 07/14/94                       */
/*           UPDATED BY:                                          */
/*                                                                */
/* ************************************************************** */
             PGM                                                    
/* ************************************************************** */
/*                                                                */
/* DECLARE PROGRAM VARIABLES                                      */
/*                                                                */
/* ************************************************************** */
             DCL        VAR(&USER) TYPE(*CHAR) LEN(10)              
             DCL        VAR(&GROUP) TYPE(*CHAR) LEN(10)             
             DCL        VAR(&READ) TYPE(*CHAR) LEN(10)              
             DCL        &ERRORSW *LGL                   /* Std err */
             DCL        &MSGID *CHAR LEN(7)             /* Std err */
             DCL        &MSGDTA *CHAR LEN(100)          /* Std err */
             DCL        &MSGF *CHAR LEN(10)             /* Std err */
             DCL        &MSGFLIB *CHAR LEN(10)          /* Std err */
/* ************************************************************** */
/*                                                                */
/* GLOBAL MESSAGE MONITOR                                         */
/*                                                                */
/* ************************************************************** */
             MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(STDERR1))   
/* ************************************************************** */
/*                                                                */
/* CALL QUSCMDLN IF THE USER IS AUTHORIZED TO USE THIS FUNCTION   */
/*                                                                */
/* ************************************************************** */
                                                                    
 
            RTVUSRPRF  RTNUSRPRF(&USER) GRPPRF(&GROUP)            
                                                                   
 USER:    RTVAUTLE   AUTL(SYSRQ90) USER(&USER) READ(&READ)      
          MONMSG     MSGID(CPF22A7 CPF22A8) EXEC(GOTO CMDLBL(GROUP))
                                                                   
                IF         COND(&READ *EQ *READ) THEN(DO)          
                 CALL       PGM(QSYS/QUSCMDLN)                     
                 GOTO       CMDLBL(END)                            
                ENDDO                                              
                                                                   
             GOTO       CMDLBL(SIGNOFF)                             
                                                                    
 GROUP:      IF         COND(&GROUP *EQ *NONE) THEN(GOTO +          
                          CMDLBL(SIGNOFF))                          
             RTVAUTLE   AUTL(SYSRQ90) USER(&GROUP) READ(&READ)      
             MONMSG     MSGID(CPF22A7 CPF22A8) EXEC(GOTO +           
                          CMDLBL(SIGNOFF))                           
                                                                     
                IF         COND(&READ *EQ *READ) THEN(DO)            
                 CALL       PGM(QSYS/QUSCMDLN)                       
                 GOTO       CMDLBL(END)                              
                ENDDO                                                
                                                                     
 SIGNOFF:    SIGNOFF    LOG(*LIST)                                   
                                                                     
/* ************************************************************** */
/*                                                                */
/* NORMAL END OF PROGRAM                                          */
/*                                                                */
/* ************************************************************** */
 END:        RETURN                                                 
/* ************************************************************** */
/*                                                                */
/* STANDARD ERROR PROCESSING                                      */
/*                                                                */
/* ************************************************************** */
 STDERR1:              /* Standard error handling routine */       
             IF        &ERRORSW SNDPGMMSG MSGID(CPF9999) +         
                        MSGF(QCPFMSG) MSGTYPE(*ESCAPE) /* Func chk */
             CHGVAR    &ERRORSW '1' /* Set to fail ir error occurs */
 STDERR2:    RCVMSG    MSGTYPE(*DIAG) MSGDTA(&MSGDTA) MSGID(&MSGID) +
                         MSGF(&MSGF) MSGFLIB(&MSGFLIB)              
             IF        (&MSGID *EQ '       ') GOTO STDERR3          
             SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +        
                         MSGDTA(&MSGDTA) MSGTYPE(*DIAG)             
             GOTO      STDERR2 /* Loop back for addl diagnostics */
 STDERR3:    RCVMSG    MSGTYPE(*EXCP) MSGDTA(&MSGDTA) MSGID(&MSGID) +
                         MSGF(&MSGF) MSGFLIB(&MSGFLIB)             
             SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +        
                          MSGDTA(&MSGDTA) MSGTYPE(*ESCAPE)          
             ENDPGM                                                 


CRTCMD CMD(QGPL/SYSRQ90) PGM(QGPL/SYSRQ90)

Here is the command source:

CMD PROMPT('System Request 90')

That's all there is to it. The next time a user does a SYSTEM REQUEST 90 option they will either be signed off, or they will get a command line, depending on if they are on the SYSRQ90 Authority List or not.

topReturn to Table of Contents

 

# # #

Article courtesy of Search400.com


ACOM Solutions
2455 Meadowbrook Parkway NW · Duluth, Georgia 30096
Phone: (770) 279-8955 · Fax: (770) 814-7011
©2008 ACOM Solutions, Inc. IBM Midrange, AS/400, iSeries, and OS/400 are registered trademarks of the IBM Corporation.