顯示具有 EXITPGM 標籤的文章。 顯示所有文章
顯示具有 EXITPGM 標籤的文章。 顯示所有文章

星期一, 11月 27, 2023

AS/400 Journal ODBC Exit Program

Following code from AS/400 Journal ODBC Security

Attach this program to QIBM_QZDA_INIT exit point.?This program handles the ODBC security by rejecting request to users who are not authorized to the ODBC *AUTL.?Make sure you create the ODBC authorization list first.



/*------------------------------------------------------------------*/
/*                                                                  */
/*  System name  . . . :‚  Technical Support                       €*/
/*  Module/Program . . :‚  EXTDBSE                                 €*/
/*  Text . . . . . . . :‚  Exit program for Database Server entry  €*/
/*                                                                  */
/*  Author . . . . . . :‚  Alex Nubla                              €*/
/*  Creation date. . . :‚  10/13/98                                €*/
/*  Description  . . . :   This is the exit point program for       */
/*                         QIBM_QZDA_INIT.                          */
/*                         This program handles the ODBC security   */
/*                         by rejecting requests from users who     */
/*                         are not authorized in ODBC authorization */
/*                         list                                     */
/*                                                                  */
/*------------------------------------------------------------------*/
             pgm        (&Okay         /* 1=Allow; 0=Reject     */   +
                         &Request  )   /* Parameter Structure   */

/*--------------------------------------------------------*/
/*  declaration                                           */
/*--------------------------------------------------------*/
             dcl        &Okay      *char    1
             dcl        &Request   *char   34

             dcl        &User      *char   10
             dcl        &SvrId     *char   10
             dcl        &Format    *char    8
             dcl        &Func      *char    4

/*--------------------------------------------------------*/
/*  error message variables                               */
/*--------------------------------------------------------*/
             dcl        &error     *lgl                   /* std err */
             dcl        &msgid     *char    7             /* std err */
             dcl        &msgkey    *char    4             /* std err */
             dcl        &msgdta    *char  100             /* std err */
             dcl        &msgf      *char   10             /* std err */
             dcl        &msgflib   *char   10             /* std err */
             dcl        &msgtyp    *char   10  '*DIAG'    /* std err */
             dcl        &msgtypctr *char    4 X'00000001' /* std err */
             dcl        &pgmmsgq   *char   10  '*'        /* std err */
             dcl        &stkctr    *char    4 X'00000001' /* std err */
             dcl        &errbytes  *char    4 X'00000000' /* std err */

             monmsg     msgid(cpf0000) exec(goto error)

             chgvar     &User      %sst(&Request    1   10)
             chgvar     &SvrId     %sst(&Request   11   10)
             chgvar     &Format    %sst(&Request   21    8)
             chgvar     &Func      %sst(&Request   28    4)

/*--------------------------------------------------------*/
/*  Check if user has *USE authority to ODBC              */
/*--------------------------------------------------------*/
             chgvar     &Okay      '1'

             addlible   techlib    *last
             monmsg     cpf0000

             chkaut     user(&User)         +
                         obj(ODBC)          +
                         objtype(*AUTL)     +
                         aut(*USE)
             monmsg     cpf9802             exec(do)
               chgvar     &Okay      '0'
             enddo

             Goto       End

/*--------------------------------------------------------*/
/*  error routine:                                        */
/*--------------------------------------------------------*/
 error:
             if         &error     (goto errordone)
               else      chgvar       &error  '1'
          /*----------------------------------------------*/
          /*  move all *DIAG message to *PRV program queue*/
          /*----------------------------------------------*/
             call       QMHMOVPM   (&msgkey      +
                                    &msgtyp      +
                                    &msgtypctr   +
                                    &pgmmsgq     +
                                    &stkctr      +
                                    &errbytes)
          /*----------------------------------------------*/
          /*  resend the last *ESCAPE message             */
          /*----------------------------------------------*/
 errordone:
             call       QMHRSNEM   (&msgkey      +
                                    &errbytes)
             monmsg     cpf0000    exec(do)
               sndpgmmsg  msgid(cpf3cf2) msgf(QCFPMSG) +
                            msgdta('QMHRSNEM') msgtype(*escape)
               monmsg     cpf0000
             enddo
 end:        endpgm




AS/400 Journal - FTP Exit Program

Following code from AS/400 Journal https://www.oocities.org/siliconvalley/Pines/5581/ftpsec.htm

File Transfer Protocol (FTP)

File Transfer Protocol (FTP) requires the user to provide a user ID and password (in a secured environment). FTP also verifies that a user profile has authority to any file that is to be transferred. You access this function using the STRTCPFTP or FTP command, or by connecting to the AS/400 FTP Server using another system’s FTP client.

Controlling FTP Access

  • Be aware that there are security issues that comes with FTP clients who accesses the system. Our object security scheme might not provide detailed enough protection when we allow FTP to our system. For example, when a user has the authority to view a file (*USE authority), the user can also download a copy of the file to a PC or another system. I have added FTP exit programs to restrict the FTP operations that users can perform.
    Note: FTP exits are available since V3R2.
  • FTP provides a remote-command capability. The FTP subcommand is equivalent to having a command line on the system. The FTP Request Validation Exit Program for the server rejects remote-command unless properly authorized.
  • Another security glitch in FTP is that passwords are not encrypted when they are sent between the client system and the server system. Passwords may be vulnerable through line sniffing.
  • User can access objects in the IFS (integrated file system) with FTP. We must ensure that our authority scheme for the IFS is adequate.
  • The system value QMAXSIGN does not apply to FTP. Within FTP, the connections ends after 5 unsuccessful attemps, but the user can just QUIT and re-attempt to sign back on. FTP users have unlimited attempts to break in the system.

FTP Server Logon Exit Program -- FTPLOGON

The purpose of the server logon exit program is to allow or deny the users to log on based on 
the User Id, Password or Client IP Address. The FTPLOGON program validates the user id who logs 
on the server. The user must be authorized to the authorization list FTPLOGON, and have at least 
*USE authority. We are also tracking "anonymous" user id, logging their E-mail address for their 
password. The FTPLOGON program sends a message to QSYSOPR & QHST with the user id and E-mail address.

The program continues but since "ANONYMOUS" is not a valid user id, the FTP fails. We may substitute 
another user id to replace the ANONYMOUS user id.

The program also validates the Client IP address against all valid IP address found in the Host Table. 
You may access the Host table entries from the CFGTCP menu. Option 10, Work with TCP/IP host table 
entries, enables us to add host IP address and their associated host names to the host table. The host 
table is stored in member HOST of the file QATOCHOST in library QUSRSYS. The Host table must be identical 
throughout the network. The FTPLOGON program denies any client IP address not found in the host table.

The FTPLOGON program accepts 7 input parameters and returns 4 output parameters. Based on the input 
parameters, FTPLOGON determines what parameters to validate. FTPLOGON program enables the initial 
current library to be set by allowing the current library listed in the input parameter to be overriden. 
FTPLOGON sets the return code output parameter to indicate whether or not to allow the server is to 
continue logon operation. Different return codes are available to enable alternative ways of processing 
the logon and initializing the current library.

NOTE: The FTPLOGON program allows the FTP to continue from either an invalid IP address, 
or users not authorized to FTPLOGON authorization list. 
Change the program to reject (remove the *@@@@@ comment line) the logon to stop the FTP log on. 
A special user id ZFTP is used to bypass FTP security.

      /TITLE FTPLOGON  Firewall Program for FTP Server Logon
      *--------------------------------------------------------------*
      *  Programmers Group & Management Resources   Copyright  1999  *
      *                                                              *
      *                           \\\\\\\                            *
      *                          ( o   o )                           *
      *---------------------oOOO----(_)----OOOo----------------------*
      *                                                              *
      *  System name. . :  Security                                  *
      *  Module/Program :  FTPLOGON                                  *
      *  Text . . . . . :  Firewall for FTP Server Logon             *
      *                                                              *
      *  Author . . . . :  Alex Nubla                                *
      *  Description. . :  This program must be added to the exit    *
      *                    point QIBM_QTMF_SVR_LOGON for format      *
      *                    TCPL0100.                                 *
      *                                                              *
      *                   OOOOO              OOOOO                   *
      *                   (    )             (    )                  *
      *--------------------(   )-------------(   )-------------------*
      *                     (_)               (_)                    *
      *                                                              *
      * Modification Log :                                           *
      *                                                              *
      *           Task  Programmer/                                  *
      *   Date     No.  Description                                  *
      * -------- ------ -------------------------------------------- *
      * 10/15/98        Alex Nubla                                   *
      *                 Creation Date                                *
      *                                                              *
      *--------------------------------------------------------------*
      *                                                              *
      * Modules:                                                     *
      *                                                              *
      * 1. FTPLOGON   RPGLE    FTP Server Logon Exit Program         *
      *                                                              *
      * Service Programs:                                            *
      *                                                              *
      * 1. *NONE                                                     *
      *                                                              *
      * Programs:                                                    *
      *                                                              *
      * 1. *NONE                                                     *
      *                                                              *
      *--------------------------------------------------------------*
      *                                                              *
      *  APIs Used:                                                  *
      *                                                              *
      *  QSYRUSRA      Retrieve user authority to object             *
      *                                                              *
      *--------------------------------------------------------------*
     H COPYRIGHT('(C) Alex Nubla of PGMR, Inc.  1999')
      ****************************************************************
      *  F I L E   D E S C R I P T I O N   S P E C I F I C A T I O N *
      ****************************************************************
     FQATOCHOST IF   E           K DISK
      *
      *  Host Table by IP address
      *
      *--------------------------------------------------------------*
     D/EJECT
      ****************************************************************
      *       D E F I N I T I O N     S P E C I F I C A T I O N      *
      ****************************************************************

      *--------------------------------------------------------------*
      *
      *  Retrieve user authority to Object (QSYRUSRA) API
      *
     D@RtnObjAut       DS            93
     D  @UA2byte                      9B 0 Inz
     D  @UA2avail                     9B 0 Inz
     D  @UA2ObjAut                   10    Inz
      *
     D @UA2Len         S              9B 0 Inz(93)
     D @UA2Format      S              8    Inz('USRA0100')
     D @UA2User        S             10    Inz
     D @UA2Object      S             20    Inz('FTPLOGON  QSYS      ')
     D @UA2OType       S             10    Inz('*AUTL')

      *--------------------------------------------------------------*
      *
      *  TCP/IP Application Server Logon Exit Point Interface
      *
      * *------------------------------------------------------------*
      * |  1 | Application identifier      | Input  | Binary(4)      |
      * |    |                             |        |                |
      * |    |  1 = FTP server program     |        |                |
      * |    |  2 = REXEC server program   |        |                |
      * |    |                             |        |                |
      * |----+------------+----------------+--------+----------------|
      * |  2 | User identifier             | Input  | Char(*)        |
      * |----+------------+----------------+--------+----------------|
      * |  3 | Length of user identifier   | Input  | Binary(4)      |
      * |----+------------+----------------+--------+----------------|
      * |  4 | Authentication string       | Input  | Char(*)        |
      * |----+------------+----------------+--------+----------------|
      * |  5 | Length of authentication    | Input  | Binary(4)      |
      * |    | string                      |        |                |
      * |----+------------+----------------+--------+----------------|
      * |  6 | Client IP address           | Input  | Char(*)        |
      * |----+------------+----------------+--------+----------------|
      * |  7 | Length of client IP address | Input  | Binary(4)      |
      * |----+------------+----------------+--------+----------------|
      * |  8 | Return code                 | Output | Binary(4)      |
      * |    |                             |        |                |
      * |    |  0 = Reject Logon           |        |                |
      * |    |  1 = Continue Logon         |        |                |
      * |    |  2 = Continue Logon,        |        |                |
      * |    |      override current       |        |                |
      * |    |      library                |        |                |
      * |    |  3 = Continue Logon,        |        |                |
      * |    |      override user prf,     |        |                |
      * |    |      password               |        |                |
      * |    |  4 = Continue Logon,        |        |                |
      * |    |      override user prf,     |        |                |
      * |    |      password, current      |        |                |
      * |    |      library                |        |                |
      * |    |  5 = Accept logon with      |        |                |
      * |    |      user prf returned      |        |                |
      * |    |  6 = Accept logon with      |        |                |
      * |    |      user prf returned,     |        |                |
      * |    |      override current       |        |                |
      * |    |      library                |        |                |
      * |    |                             |        |                |
      * |----+------------+----------------+--------+----------------|
      * |  9 | User profile                | Output | Char(10)       |
      * |----+------------+----------------+--------+----------------|
      * | 10 | Password                    | Output | Char(10)       |
      * |----+------------+----------------+--------+----------------|
      * | 11 | Initial current library     | Output | Char(10)       |
      * *------------------------------------------------------------*
      *
      *     Exit Point:  QIBM_QTMF_SVR_LOGON
      *                  QIBM_QTMX_SVR_LOGON
      *
     D AppId           S              9B 0
     D UserId          S            999
     D UserIdLen       S              9B 0
     D Authen          S            999
     D AuthenLen       S              9B 0
     D IpAddr          S             15
     D IpAddrLen       S              9B 0
     D RtnCode         S              9B 0
     D User            S             10
     D Password        S             10
     D CurrLib         S             10

     D Email           S             30
     D FTPUser         S             10
     D Message         S             52
     D FullJob         S             28

      *--------------------------------------------------------------*
      *
      *  Record structure for error code parameter
      *
     D@ErrData         DS
     D  @BytesProv                    9B 0 Inz(200)
     D  @BytesAval                    9B 0
     D  @ExcpId                       7
     D  @Reserved1                    1
     D  @ExcpData                   184

      *--------------------------------------------------------------*
      *
      *  Constants
      *
     D Special         C                   'ZFTP'
     D Anonymous       C                   'ANONYMOUS '
     D LogMsg1         C                   'ANONYMOUS ('
     D LogMsg2         C                   ') try to logon FTP'
     D LogMsg3         C                   ' logon to FTP'
     D @Sign           C                   '@'
     D Warn1           C                   ' SECURITY VIOLATION:               '
     D Warn2           C                   ' =================================-
     D                                     =================='
     D Warn3           C                   ' Invalid IP Address of FTP Logon. -
     D                                     Check the ff:'
     D Warn4           C                   ' Not authorized to FTPLOGON *AUTL.-
     D                                      Check the ff:'
     D Reject          C                   0
     D Continue        C                   1
     D Accept          C                   5
      *
     C/EJECT
      ****************************************************************
      *     C A L C U L A T I O N     S P E C I F I C A T I O N      *
      ****************************************************************
      *
     C     *Entry        Plist
      *
      * Input parameters
     C                   Parm                    AppId
     C                   Parm                    UserId
     C                   Parm                    UserIdLen
     C                   Parm                    Authen
     C                   Parm                    AuthenLen
     C                   Parm                    IpAddr
     C                   Parm                    IpAddrLen
      *
      * Return parameters
     C                   Parm                    RtnCode
     C                   Parm                    User
     C                   Parm                    Password
     C                   Parm                    CurrLib
      *
      *----------------------------------------------------*
      *  Check user id requesting the FTP                  *
      *----------------------------------------------------*
     C                   If        UserIdLen   > *Zeros
     C                   Eval      FtpUser     = %Subst(UserId: 1: UserIdLen)
     C                   EndIf
      *
     C                   Select
      *----------------------------------------------------*
      *  ANONYMOUS user log on                             *
      *----------------------------------------------------*
     C                   When      FtpUser     = Anonymous
     C                   Exsr      $Anonym
     C                   Other
      *----------------------------------------------------*
      *  Is user authorized to FTPLOGON *AUTL              *
      *----------------------------------------------------*
     C                   Exsr      $Autl
     C                   EndSl
      *
     C                   Eval      *InLR       = *On
     C                   Return
      /EJECT
      ****************************************************************
      *                    S U B R O U T I N E S                     *
      ****************************************************************
      /SPACE
      *==============================================================*
      *                                                              *
      *  Anonymous user log on                                       *
      *                                                              *
     C     $Anonym       Begsr
      *==============================================================*
      *----------------------------------------------------*
      *  We may want ANONYMOUS user id in the fututre -    *
      *  if so, create the user id use by "PUBLIC" user.   *
      *  For now, it will abend because ANONYMOUS is not a *
      *  valid AS/400 id. Read I.7 Anonymous FTP of        *
      *  OS/400 TCP/IP Configuration & Reference Manual.   *
      *----------------------------------------------------*

      *         *------------------------------------------*
      *         *  email address follows ANONYMOUS         *
      *         *------------------------------------------*
     C     @Sign         Scan      Authen:2                               88
     C                   If        *In88
      *
      *          if we allow "PUBLIC" FTP, change this code
      *            to use the "PUBLIC" user id.
      *
     C                   Eval      User        = FtpUser
     C                   Eval      RtnCode     = Accept
     C                   Eval      Email       = %Subst(Authen: 1: AuthenLen)
     C                   Eval      Message     = LogMsg1          +
     C                                           %Trimr(Email)    +
     C                                           LogMsg2
     C     Message       Dsply     'QSYSOPR'
     C                   Else
     C                   Eval      RtnCode     = Reject
     C                   EndIf
      *
      *
     C     #Anonym       Endsr
      /SPACE
      *==============================================================*
      *                                                              *
      *  Authorized to FTPLOGON *AUTL?                               *
      *                                                              *
     C     $Autl         Begsr
      *==============================================================*
      *----------------------------------------------------*
      *  User must be authorized to FTPLOGON *AUTL.        *
      *----------------------------------------------------*
     C                   Reset                   @RtnObjAut
     C                   Reset                   @UA2Len
     C                   Reset                   @UA2Format
     C                   Eval      @UA2User    = FtpUser
     C                   Call      'QSYRUSRA'
     C                   Parm                    @RtnObjAut
     C                   Parm                    @UA2Len
     C                   Parm                    @UA2Format
     C                   Parm                    @UA2User
     C                   Parm                    @UA2Object
     C                   Parm                    @UA2OType
     C                   Parm                    @ErrData
      *         *------------------------------------------*
      *         *  Not authorized to FTPLOGON *AUTL.       *
      *         *  If we want to prevent the FTP for the   *
      *         *  user, use the Reject statement instead. *
      *         *------------------------------------------*
     C                   If        @UA2ObjAut  = '*EXCLUDE'
     C                   Eval      RtnCode     = Continue
      *@@@@@@@@          Eval      RtnCode     = Reject
     C     Warn2         Dsply     'QSYSOPR'
     C                   Eval      Message     = %Trimr(Warn1)     +
     C                                           ' USER ID INVALID'
     C     Message       Dsply     'QSYSOPR'
     C     Warn4         Dsply     'QSYSOPR'
     C                   Eval      Message     = '   User Id   : ' +  FtpUser
     C     Message       Dsply     'QSYSOPR'
     C                   Eval      Internet    = %Subst(IpAddr: 1: IpAddrLen)
     C                   Eval      Message     = '   IP Address: ' +  Internet
     C     Message       Dsply     'QSYSOPR'
     C     Warn2         Dsply     'QSYSOPR'
      *
     C                   Else
      *         *------------------------------------------*
      *         *  if authorized, validate IP              *
      *         *------------------------------------------*
     C                   Exsr      $ValidIp
     C                   EndIf
      *
     C     #Autl         Endsr
      /SPACE
      *==============================================================*
      *                                                              *
      *  Validate the FTP Client IP Address                          *
      *                                                              *
     C     $ValidIp      Begsr
      *==============================================================*
      *----------------------------------------------------*
      *  Validate the IP address the FTP request is coming *
      *  in from. The IP must be registered as one of the  *
      *  host tables.  GO CFGTCP and take option 10 to     *
      *  enter new host in the table.                      *
      *----------------------------------------------------*
      *
     C                   Eval      Internet    = %Subst(IpAddr: 1: IpAddrLen)
     C     Internet      Chain     QATOCHOST                          40
     C                   If        Not *In40
     C                   Eval      RtnCode     = Continue
     C                   If        FtpUser    <> Special
     C                   Eval      Message     = %Trimr(FtpUser)   +  LogMsg3
     C     Message       Dsply     'QSYSOPR'
     C                   EndIf
      *
     C                   Else
      *         *------------------------------------------*
      *         *  Invalid Client IP Address.              *
      *         *  If we want to prevent the FTP for the   *
      *         *  user, use the Reject statement instead. *
      *         *------------------------------------------*
     C                   Eval      RtnCode     = Continue
      *@@@@@@@@          Eval      RtnCode     = Reject
     C     Warn2         Dsply     'QSYSOPR'
     C                   Eval      Message     = %Trimr(Warn1)     +
     C                                           ' CLIENT IP ADDRESS INVALID'
     C     Message       Dsply     'QSYSOPR'
     C     Warn3         Dsply     'QSYSOPR'
     C                   Eval      Message     = '   IP Address: ' +  Internet
     C     Message       Dsply     'QSYSOPR'
     C                   Eval      Message     = '   User Id   : ' +  FtpUser
     C     Message       Dsply     'QSYSOPR'
     C     Warn2         Dsply     'QSYSOPR'
     C                   EndIf
      *
     C     #ValidIp      Endsr


FTP Request Validation Exit Program

The FTP request validation exit program determines whether to allow or deny permission of FTP 
operation based either on user id, client IP address, operation being requested, or 
directory/file/library affected. The FTPRQSVLD program is used for this exit program for both 
client and server request.

Requested operations are permitted or denied based on the returned "Allow operation" output 
parameter. For example, the FTP application calls FTPRQSVLD with a request to PUT (write/update) 
to this file? FTPRQSVLD determines whether the request is accepted and returns the "Allow operation" 
return code to the FTP application. If it is denied, the FTP application issues a message that state 
that the operation is rejected.

The exit program may also indicate that the FTP request will always be allowed or always denied 
for a particular user. When always allowed or always denied is returned, the FTP application will 
not call the exit program again for the same request during the user session.

The FTPRQSVLD program accepts 7 input parameters and returns 1 output parameter. Based on the
input parameter, FTPRQSVLD can determine what type of FTP operation is being requested, For 
operation containing name of library or file name, FTPRQSVLD allows the operation if the 
library requested is a "Test" type library. For "Production" type library, the FTP request is 
rejected. FTP request requiring execution of CL commands are all rejected.

      /TITLE FTPRQSVLD  Firewall Program for FTP Request Validation
      *--------------------------------------------------------------*
      *  Programmers Group & Management Resources   Copyright  1999  *
      *                                                              *
      *                           \\\\\\\                            *
      *                          ( o   o )                           *
      *---------------------oOOO----(_)----OOOo----------------------*
      *                                                              *
      *  System name. . :  Security                                  *
      *  System name. . :  Technical Support                         *
      *  Module/Program :  FTPRQSVLD                                 *
      *  Text . . . . . :  Firewall for FTP Request Validation       *
      *                                                              *
      *  Author . . . . :  Alex Nubla                                *
      *  Description. . :  This program must be added to the exit    *
      *                    point QIBM_QTMF_CLIENT_REQ and            *
      *                    QIBM_QTMF_SERVER_REQ.                     *
      *                                                              *
      *                   OOOOO              OOOOO                   *
      *                   (    )             (    )                  *
      *--------------------(   )-------------(   )-------------------*
      *                     (_)               (_)                    *
      *                                                              *
      * Modification Log :                                           *
      *                                                              *
      *           Task  Programmer/                                  *
      *   Date     No.  Description                                  *
      * -------- ------ -------------------------------------------- *
      * 10/19/98        Alex Nubla                                   *
      *                 Creation Date                                *
      *                                                              *
      *--------------------------------------------------------------*
      *                                                              *
      * Modules:                                                     *
      *                                                              *
      * 1. FTPRQSVLD  RPGLE    FTP Request Validation Exit Program   *
      *                                                              *
      * Service Programs:                                            *
      *                                                              *
      * 1. *NONE                                                     *
      *                                                              *
      * Programs:                                                    *
      *                                                              *
      * 1. *NONE                                                     *
      *                                                              *
      *--------------------------------------------------------------*
      *                                                              *
      *  APIs Used:                                                  *
      *                                                              *
      *  QSYRUSRA      Retrieve user authority to object             *
      *                                                              *
      *--------------------------------------------------------------*
     H COPYRIGHT('(C) Alex Nubla of PGMR, Inc.  1998')
     D/EJECT
      ****************************************************************
      *       D E F I N I T I O N     S P E C I F I C A T I O N      *
      ****************************************************************

      *--------------------------------------------------------------*
      *
      *  Retrieve user authority to Object (QSYRUSRA) API
      *
     D@RtnObjAut       DS            93
     D  @UA2byte                      9B 0 Inz
     D  @UA2avail                     9B 0 Inz
     D  @UA2ObjAut                   10    Inz
      *
     D @UA2Len         S              9B 0 Inz(93)
     D @UA2Format      S              8    Inz('USRA0100')
     D @UA2User        S             10    Inz
     D @UA2Object      S             20    Inz('FTPLOGON  QSYS      ')
     D @UA2OType       S             10    Inz('*AUTL')

      *--------------------------------------------------------------*
      *
      *  Retrieve library description (QLIRLIBD) API
      *
     D@RtnLibDsc       DS            33
     D  @LDByte                       9B 0 Inz
     D  @LDAvail                      9B 0 Inz
     D  @LDLenRtn                     9B 0 Inz
     D  @LDLenAvail                   9B 0 Inz
     D  @LDRecord                    17    Inz
     D   @LDRLen                      9B 0 overlay(@LDRecord:  1)
     D   @LDRKey                      9B 0 overlay(@LDRecord:  5)
     D   @LDRSize                     9B 0 overlay(@LDRecord:  9)
     D   @LDRType                     1    overlay(@LDRecord: 13)
      *
     D@RtvAttr         DS
     D  @AttrElm                      9B 0 Inz(1)
     D  @ReqKey                       9B 0 Inz(1)
      *
     D @LDLen          S              9B 0 Inz(33)
     D FtpLib          S             10    Inz
     D FtpPath         S            256    Inz
     D Str             S              5S 0 Inz
     D Pos             S              5S 0 Inz
     D Len             S              5S 0 Inz
      *
     D Production      C                   '0'
     D Test            C                   '1'

      *--------------------------------------------------------------*
      *
      *  Record structure for error code parameter
      *
     D@ErrData         DS
     D  @BytesProv                    9B 0 Inz(200)
     D  @BytesAval                    9B 0
     D  @ExcpId                       7
     D  @Reserved1                    1
     D  @ExcpData                   184

      *--------------------------------------------------------------*
      *
      *  TCP/IP Application Request Validation Exit Point Interface
      *
      * *------------------------------------------------------------*
      * |  1 | Application identifier      | Input  | Binary(4)      |
      * |    |                             |        |                |
      * |    |  0 = FTP client program     |        |                |
      * |    |  1 = FTP server program     |        |                |
      * |    |                             |        |                |
      * |----+------------+----------------+--------+----------------|
      * |  2 | Operations identified       | Input  | Binary(4)      |
      * |    |                             |        |                |
      * |    |  0 = Session initialization |        |                |
      * |    |  1 = Directory/library      |        |                |
      * |    |      creation               |        |                |
      * |    |  2 = Directory/library      |        |                |
      * |    |      deletion               |        |                |
      * |    |  3 = Set current directory  |        |                |
      * |    |  4 = List files             |        |                |
      * |    |  5 = File deletion          |        |                |
      * |    |  6 = Sending file           |        |                |
      * |    |  7 = Receiving file         |        |                |
      * |    |  8 = Renaming file          |        |                |
      * |    |  9 = Execute CL command     |        |                |
      * |    |                             |        |                |
      * |----+------------+----------------+--------+----------------|
      * |  3 | User profile                | Input  | Char(10)       |
      * |----+------------+----------------+--------+----------------|
      * |  4 | Remote IP address           | Input  | Char(*)        |
      * |----+------------+----------------+--------+----------------|
      * |  5 | Length of remote IP address | Input  | Binary(4)      |
      * |----+------------+----------------+--------+----------------|
      * |  6 | Operation-specific          | Input  | Char(*)        |
      * |    | information                 |        |                |
      * |----+------------+----------------+--------+----------------|
      * |  7 | Length of                   | Input  | Binary(4)      |
      * |    | operation-specific          |        |                |
      * |    | information                 |        |                |
      * |----+------------+----------------+--------+----------------|
      * |  8 | Allow operation             | Output | Binary(4)      |
      * |    |                             |        |                |
      * |    | -1 = Never allow the        |        |                |
      * |    |      operation identifier   |        |                |
      * |    |  0 = Reject the operation   |        |                |
      * |    |  1 = Allow the operation    |        |                |
      * |    |  2 = Always allow this      |        |                |
      * |    |      operation identifier   |        |                |
      * |    |                             |        |                |
      * *------------------------------------------------------------*
      *
      *     Exit Point:  QIBM_QTMF_CLIENT_REQ
      *                  QIBM_QTMF_SERVER_REQ
      *                  QIBM_QTMX_SERVER_REQ
      *                  QIBM_QTOD_SERVER_REQ
      *
     D AppId           S              9B 0
     D OperRqs         S              9B 0
     D User            S             10
     D IpAddr          S             15
     D IpAddrLen       S              9B 0
     D OperInf         S            999
     D OperInfLen      S              9B 0
     D AllowOper       S              9B 0
     D FullJob         S             26

     D SessionInz      C                   0
     D MakeDir         C                   1
     D DelDir          C                   2
     D ChgDir          C                   3
     D ListFile        C                   4
     D DelFile         C                   5
     D PutFile         C                   6
     D GetFile         C                   7
     D RnmFile         C                   8
     D SysCmd          C                   9
     D NeverAllow      C                   -1
     D Reject          C                   0
     D Allow           C                   1
     D AlwaysAllw      C                   2

      *--------------------------------------------------------------*
      *
      *  Standalone fields
      *
     D Message         S             52
     D Internet        S             15

      *--------------------------------------------------------------*
      *
      *  Constants
      *
     D @LO             C                   'abcdefghijklmnopqrstuvwxyz'
     D @UP             C                   'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
      *
     D Client          C                   0
     D Server          C                   1
      *
     D Warn1           C                   ' FTP REQUEST:                      '
     D Warn2           C                   ' =================================-
     D                                     =================='
     D Warn3           C                   ' The following info was logged fro-
     D                                     m the Server:'
      *
     D Anonymous       C                   'ANONYMOUS '
     D Special         C                   'ZFTP'
     D Qtcp            C                   'QTCP'
     D QsysLib         C                   '/QSYS.LIB/'
     D DotLib          C                   '.LIB'
     C/EJECT
      ****************************************************************
      *     C A L C U L A T I O N     S P E C I F I C A T I O N      *
      ****************************************************************
      *
     C     *Entry        Plist
      *
      * Input parameters
     C                   Parm                    AppId
     C                   Parm                    OperRqs
     C                   Parm                    User
     C                   Parm                    IpAddr
     C                   Parm                    IpAddrLen
     C                   Parm                    OperInf
     C                   Parm                    OperInfLen
      *
      * Return parameters
     C                   Parm                    AllowOper
      *
     C                   Eval      AllowOper   = Allow
     C                   If        User       <> Special   and
     C                             User       <> Qtcp
      *----------------------------------------------------*
      *  Determine client or server request                *
      *----------------------------------------------------*
B01  C                   Select
      *         *------------------------------------------*
      *         *  Client FTP request                      *
      *         *------------------------------------------*
     C                   When      AppId       = Client
     C                   Exsr      $ClientRq
      *         *------------------------------------------*
      *         *  Server FTP request                      *
      *         *------------------------------------------*
     C                   When      AppId       = Server
     C                   Exsr      $ServerRq
E01  C                   EndSl
      *
E01  C                   EndIf
      *
     C                   Eval      *InLR       = *On
     C                   Return
      /EJECT
      ****************************************************************
      *                    S U B R O U T I N E S                     *
      ****************************************************************
      /SPACE
      *==============================================================*
      *                                                              *
      *  Validate FTP Client Request                                 *
      *                                                              *
     C     $ClientRq     BegSr
      *==============================================================*
      *----------------------------------------------------*
      *  Validate client request (job on this server)      *
      *----------------------------------------------------*
     C                   Select
      *         *------------------------------------------*
      *         *  Rejected requests                       *
      *         *------------------------------------------*
     C                   When      OperRqs     = MakeDir   or
     C                             OperRqs     = DelDir    or
     C                             OperRqs     = DelFile   or
     C                             OperRqs     = RnmFile   or
     C                             OperRqs     = SysCmd
     C                   Eval      AllowOper   = NeverAllow
      *
      *         *------------------------------------------*
      *         *  Accepted requests - have the server     *
      *         *  system validate our request.            *
      *         *------------------------------------------*
     C                   When      OperRqs     = ChgDir    or
     C                             OperRqs     = ListFile  or
     C                             OperRqs     = PutFile   or
     C                             OperRqs     = GetFile
     C                   Eval      AllowOper   = Allow
E02  C                   EndSl
      *
     C     #ClientRq     EndSr
     C/EJECT
      *==============================================================*
      *                                                              *
      *  Validate FTP Server Request                                 *
      *                                                              *
     C     $ServerRq     BegSr
      *==============================================================*
      *----------------------------------------------------*
      *  User id accepted at this point                    *
      *----------------------------------------------------*
      *
B02  C                   Select
      *         *------------------------------------------*
      *         *  Rejected requests                       *
      *         *------------------------------------------*
     C                   When      OperRqs     = MakeDir   or
     C                             OperRqs     = DelDir    or
     C                             OperRqs     = DelFile   or
     C                             OperRqs     = RnmFile   or
     C                             OperRqs     = SysCmd
     C                   Eval      AllowOper   = NeverAllow
      *
      *         *------------------------------------------*
      *         *  Accepted requests - only for TEST type  *
      *         *  library.                                *
      *         *------------------------------------------*
     C                   When      OperRqs     = ChgDir    or
     C                             OperRqs     = ListFile  or
     C                             OperRqs     = PutFile   or
     C                             OperRqs     = GetFile
     C                   Eval      AllowOper   = Allow
      *
     C                   Reset                   FtpLib
     C                   Eval      FtpPath     = %Subst(OperInf: 1: OperInfLen)
     C     @Lo:@Up       Xlate     FtpPath       FtpPath
     C     QSysLib       Scan      FtpPath       Pos                      90
      *
     C                   If        *In90
     C                   Eval      Str         = Pos + 10
     C     DotLib        Scan      FtpPath:Str   Pos                      89
     C                   If        *In89
     C                   Eval      Len         = Pos - Str
     C                   Eval      FtpLib      = %Subst(FtpPath: Str: Len)
     C                   Else
     C                   Eval      FtpLib      = 'QSYS'
     C                   EndIf
      *
     C                   Call      'QLIRLIBD'
     C                   Parm                    @RtnLibDsc
     C                   Parm                    @LDLen
     C                   Parm                    FtpLib
     C                   Parm                    @RtvAttr
     C                   Parm                    @ErrData
      *
     C                   If        @LDRType    = Production
     C                   Eval      AllowOper   = Reject
     C                   Else
      *         *------------------------------------------*
      *         *  Log the request to QSYSOPR              *
      *         *------------------------------------------*
     C     Warn2         Dsply     'QSYSOPR'
     C                   Select
     C                   When      OperRqs     = ChgDir
     C                   Eval      Message     = %Trimr(Warn1)     +
     C                                           ' CHANGE DIRECTORY'
     C                   When      OperRqs     = ListFile
     C                   Eval      Message     = %Trimr(Warn1)     +
     C                                           ' LIST THE NAMES'
     C                   When      OperRqs     = PutFile
     C                   Eval      Message     = %Trimr(Warn1)     +
     C                                           ' COPY OUR PATH TO REMOTE IP'
     C                   When      OperRqs     = GetFile
     C                   Eval      Message     = %Trimr(Warn1)     +
     C                                           ' COPY FROM IP INTO OUR PATH'
     C                   EndSl
     C     Message       Dsply     'QSYSOPR'
     C     Warn3         Dsply     'QSYSOPR'
     C                   Eval      Message     = '   User Id   : ' +  User
     C     Message       Dsply     'QSYSOPR'
     C                   Eval      Internet    = %Subst(IpAddr: 1: IpAddrLen)
     C                   Eval      Message     = '   IP Address: ' +  Internet
     C     Message       Dsply     'QSYSOPR'
     C                   Eval      Message     = '   Path Rqs  : '
     C     Message       Dsply     'QSYSOPR'
     C                   Eval      Message     = '   ' + FtpPath
     C     Message       Dsply     'QSYSOPR'
     C     Warn2         Dsply     'QSYSOPR'
     C                   EndIf
     C                   EndIf
      *
     C                   Other
      *         *------------------------------------------*
      *         *  If this is a secured system, use the    *
      *         *  Reject statement instead.               *
      *         *------------------------------------------*
     C                   Eval      AllowOper   = Allow
      *@@@@@@@@          Eval      AllowOper   = Reject
E02  C                   EndSl
      *
     C     #ServerRq     EndSr



星期四, 11月 09, 2023

2013-12-17 如何將 CPYTOPCD 指令所產生的文件檔案同步複製至另一部 AS/400的相同目錄中?


如何將 CPYTOPCD 指令所產生的文件檔案同步複製至另一部 AS/400的相同目錄中?
(How to synchronize CPYTOPCD PC document to another AS/400 Folder)

ile  : QCLSRC

Member: CPY2PCDXPC

Type  : CLP

Usage : Change CL source &TCPHOST value to your target AS/400 host name
        CRTCLPGM QGPL/CPY2PCDXPC TGTRLS(V7R1M0)
OS    : V7R1 later
        Check PTF SI45985 
        DSPPTF LICPGM(5770SS1) SELECT(SI45985)
        


/* ==================================================================*/
/*                                                                   */
/*  Program . . : CPY2PCDXPC                                         */
/*  Description : CPYTOPCD Command Exit Program                      */
/*  Author  . . : Vengoal Chang                                      */
/*  Published . : AS400ePaper                                        */
/*  Date  . . . : December 17, 2013                                  */
/*                                                                   */
/*  Program function:  Copy PC Document to Another AS/400            */
/*                                                                   */
/*  Usage:                                                           */
/*                                                                   */
/*  ADDEXITPGM EXITPNT(QIBM_QCA_RTV_COMMAND)                         */
/*     FORMAT(RTVC0100) PGMNBR(*LOW)                                 */
/*     PGM(QGPL/CPY2PCDXPC)                                          */
/*     PGMDTA(*JOB 30 'CPYTOPCD  QSYS      *AFTER    ')              */
/*                                                                   */
/*  Compile options:                                                 */
/*    Change CL  &TCPHOST value to your target AS/400 host name      */
/*    CrtClPgm   Pgm( QGPL/CPY2PCDXPC )                              */
/*               SrcFile( QCLSRC )                                   */
/*               SrcMbr( *PGM )                                      */
/*               Log( *YES )                                         */
/*                                                                   */
/* ================================================================= */
    Pgm   ( &Cmd_Info )

    Dcl   &Cmd_Info   *Char  4000
    Dcl   &Ep_Name    *Char    20  Stg( *Defined )  DefVar(&Cmd_Info 1)
    Dcl   &Ep_Format  *Char     8  Stg( *Defined )  DefVar(&Cmd_Info 21)
    Dcl   &Cmd_Name   *Char    10  Stg( *Defined )  DefVar(&Cmd_Info 29)
    Dcl   &Cmd_Lib    *Char    10  Stg( *Defined )  DefVar(&Cmd_Info 39)
    Dcl   &Reserved1  *Char     2  Stg( *Defined )  DefVar(&Cmd_Info 49)
    Dcl   &Before_Aft *Char     1  Stg( *Defined )  DefVar(&Cmd_Info 51)
    Dcl   &Reserved2  *Char     1  Stg( *Defined )  DefVar(&Cmd_Info 52)
    Dcl   &Off_InlCmd *Int         Stg( *Defined )  DefVar(&Cmd_Info 53)
    Dcl   &Len_InlCmd *Int         Stg( *Defined )  DefVar(&Cmd_Info 57)
    Dcl   &Off_RplCmd *Int         Stg( *Defined )  DefVar(&Cmd_Info 61)
    Dcl   &Len_RplCmd *Int         Stg( *Defined )  DefVar(&Cmd_Info 65)
    Dcl   &Off_Prx    *Int         Stg( *Defined )  DefVar(&Cmd_Info 69)
    Dcl   &Nbr_Prx    *Int         Stg( *Defined )  DefVar(&Cmd_Info 73)
    Dcl   &Offset     *Int
    Dcl   &Length     *Int
    Dcl   &Cmd        *Char   256
    Dcl   &ToFlr      *Char    63
    Dcl   &ToDoc      *Char    12
    Dcl   &PKD_INLCMD *Dec     (3 0)
    Dcl   &STRPOS     *Dec     (3 0) VALUE(1)
    Dcl   &LEN_OPTION *Dec     (3 0) VALUE(7)
    Dcl   &RESULT     *Dec     (3 0)
    Dcl   &STRLEN     *Dec     (3 0)
    Dcl   "E      *Char     1    VALUE(X'7D')
    Dcl   &TCPHOST    *Char    10    VALUE('AS400HOST')
    Dcl   &CPYSTR     *Char   256
    Dcl   &CPYSTRLEN  *Dec    (15 5) VALUE(256)
    Dcl   &MDSTR      *Char   256
    Dcl   &I          *Int
    Dcl   &MsgTxt     *Char   256
    Dcl   &MsgId      *Char     7
    Dcl   &FromMbr    *Char    10
    Dcl   &File       *Char    10
    Dcl   &FileLib    *Char    10
    Dcl   &FileLibStr *Char    21
    Dcl   &PKD_FrmF   *dec     (3 0)
    Dcl   &IfsObj     *Char   256
    Dcl   &RtnValDec  *dec     (5 0)
    Dcl   &DirName    *Char   256

     MonMsg (CPC0000 CPD0000 CPF0000 HAE0000) *N  (GOTO ERROR)


     If       ( &BEFORE_AFT *EQ '1' ) Do
     If       ( &OFF_RPLCMD = 0 )     Do
     ChgVar     &OFFSET      ( &OFF_INLCMD + 1 )
     ChgVar     &LENGTH      &LEN_INLCMD
     EndDo
     Else Do
     ChgVar     &OFFSET      (&OFF_RPLCMD + 1)
     ChgVar     &LENGTH      &LEN_RPLCMD
     EndDo
     EndDo

     If       ( &CMD_NAME *EQ 'CPYTOPCD  ') Do
     ChgVar     &CMD         %SST(&CMD_INFO &OFFSET &LENGTH)
     ChgVar     &PKD_INLCMD  &LENGTH

/*-- Search FROMFILE: -----------------------------------------------*/
     ChgVar     &STRPOS      1
     ChgVar     &LEN_OPTION  9
     CALL       QCLSCAN    ( &CMD                                    +
                             &PKD_INLCMD                             +
                             &STRPOS                                 +
                             'FROMFILE('                             +
                             &LEN_OPTION                             +
                             '0'                                     +
                             '0'                                     +
                             ' '                                     +
                             &RESULT)

     If  (&Result > 0 )  Do
     ChgVar     &STRPOS      &RESULT
     ChgVar     &LEN_OPTION  1
     CALL       QCLSCAN    ( &CMD                                    +
                             &PKD_INLCMD                             +
                             &STRPOS                                 +
                             ')'                                     +
                             &LEN_OPTION                             +
                             '0'                                     +
                             '0'                                     +
                             ' '                                     +
                             &RESULT)
     ChgVar     &STRPOS      (&STRPOS + 9)
     ChgVar     &STRLEN      (&RESULT - &STRPOS)
     ChgVar     &FileLibStr  %SST(&CMD &STRPOS &STRLEN)

     ChgVar     &STRPOS      1
     ChgVar     &PKD_FrmF    21
     ChgVar     &LEN_OPTION  1
     CALL       QCLSCAN    ( &FileLibStr                             +
                             &PKD_FrmF                               +
                             &STRPOS                                 +
                             '/'                                     +
                             &LEN_OPTION                             +
                             '0'                                     +
                             '0'                                     +
                             ' '                                     +
                             &RESULT)
     If  ( &Result > 0 )  Do
     ChgVar     &STRLEN      (&RESULT - 1)
     ChgVar     &FileLib     %SST(&FileLibStr 1 &StrLen)
     ChgVar     &STRPOS      (&RESULT + 1)
     ChgVar     &File        %SST(&FileLibStr &StrPos 10)
     RtvMbrD    File(&FILELIB/&FILE) RtnLib(&FILELIB)
     MonMsg     CPF0000      *N       (Goto Return)
     EndDo
     Else  Do
     ChgVar     &File        %SST(&FileLibStr 1 10)
     RtvMbrD    File(&FILE) RtnLib(&FILELIB)
     MonMsg     CPF0000      *N       (Goto Return)
     EndDo

     ChkObj     Obj(&FILELIB/&FILE) ObjType(*FILE)
     MonMsg     CPF0000      *N       (Goto Return)
     EndDo

/*-- Search TOFLR:  -------------------------------------------------*/
     ChgVar     &LEN_OPTION  6
     CALL       QCLSCAN    ( &CMD                                    +
                             &PKD_INLCMD                             +
                             &STRPOS                                 +
                             'TOFLR('                                +
                             &LEN_OPTION                             +
                             '0'                                     +
                             '0'                                     +
                             ' '                                     +
                             &RESULT)

     ChgVar     &STRPOS      &RESULT
     ChgVar     &LEN_OPTION  1
     CALL       QCLSCAN    ( &CMD                                    +
                             &PKD_INLCMD                             +
                             &STRPOS                                 +
                             ')'                                     +
                             &LEN_OPTION                             +
                             '0'                                     +
                             '0'                                     +
                             ' '                                     +
                             &RESULT)
     ChgVar     &STRPOS      (&STRPOS + 6)
     ChgVar     &STRLEN      (&RESULT - &STRPOS)
     ChgVar     &TOFLR       %SST(&CMD &STRPOS &STRLEN)

     DoFor      &I           1       63
      If        (%SST(&TOFLR &I 1) *EQ "E) +
         ChgVar  %SST(&TOFLR &I 1) ' '
     EndDo
     ChgVar     &ToFlr       %Trim(&ToFlr)

/*-- Search FROMMBR: ------------------------------------------------*/
     ChgVar     &STRPOS      1
     ChgVar     &LEN_OPTION  8
     CALL       QCLSCAN    ( &CMD                                    +
                             &PKD_INLCMD                             +
                             &STRPOS                                 +
                             'FROMMBR('                              +
                             &LEN_OPTION                             +
                             '0'                                     +
                             '0'                                     +
                             ' '                                     +
                             &RESULT)

     If  (&Result > 0 )  Do
     ChgVar     &STRPOS      &RESULT
     ChgVar     &LEN_OPTION  1
     CALL       QCLSCAN    ( &CMD                                    +
                             &PKD_INLCMD                             +
                             &STRPOS                                 +
                             ')'                                     +
                             &LEN_OPTION                             +
                             '0'                                     +
                             '0'                                     +
                             ' '                                     +
                             &RESULT)
     ChgVar     &STRPOS      (&STRPOS + 8)
     ChgVar     &STRLEN      (&RESULT - &STRPOS)
     ChgVar     &FromMbr     %SST(&CMD &STRPOS &STRLEN)

     If  ( &FromMbr = '*FIRST' )  Do
     RtvMbrD    File(&FILELIB/&FILE) Mbr(*FIRST) RtnMbr(&FromMbr)
     MonMsg     CPF0000      *N       (Goto Return)
     EndDo
     Else  Do
     RtvMbrD    File(&FILELIB/&FILE) Mbr(&FromMbr) RtnMbr(&FromMbr)
     MonMsg     CPF0000      *N       (Goto Return)
     EndDo

     EndDo
     Else Do
     RtvMbrD    File(&FILELIB/&FILE) Mbr(*FIRST) RtnMbr(&FromMbr)
     MonMsg     CPF0000      *N       (Goto Return)
     EndDo

/*-- Search TODOC:  -------------------------------------------------*/
     ChgVar     &STRPOS      1
     ChgVar     &LEN_OPTION  6
     CALL       QCLSCAN    ( &CMD                                    +
                             &PKD_INLCMD                             +
                             &STRPOS                                 +
                             'TODOC('                                +
                             &LEN_OPTION                             +
                             '0'                                     +
                             '0'                                     +
                             ' '                                     +
                             &RESULT)

     If  (&Result > 0 )  Do
     ChgVar     &STRPOS      &RESULT
     ChgVar     &LEN_OPTION  1
     CALL       QCLSCAN    ( &CMD                                    +
                             &PKD_INLCMD                             +
                             &STRPOS                                 +
                             ')'                                     +
                             &LEN_OPTION                             +
                             '0'                                     +
                             '0'                                     +
                             ' '                                     +
                             &RESULT)
     ChgVar     &STRPOS      (&STRPOS + 6)
     ChgVar     &STRLEN      (&RESULT - &STRPOS)
     ChgVar     &TODOC       %SST(&CMD &STRPOS &STRLEN)
     If  ( &FromMbr = '*FROMMBR' )  Do
     ChgVar     &TODOC       &FromMbr
     EndDo
     EndDo
     Else  Do
     ChgVar     &TODOC       &FromMbr
     EndDo

     DoFor      &I           1       12
      If        (%SST(&ToDoc &I 1) *EQ "E) +
         ChgVar  %SST(&ToDoc &I 1) ' '
     EndDo
     ChgVar     &ToDoc       %Trim(&ToDoc)

/*-------------------------------------------------------------------*/
/*-- Check IFS Object exist ? ---------------------------------------*/
/*--   The IFS object must exist before CPY operation, because the   */
/*--   exit program run after CPYTOPCD completed.                    */
/*--   But that command completed :                                  */
/*--   1. normal completed.                => We do CPY for this     */
/*--   2. normal completed with exception. => We ignore this         */
/*-------------------------------------------------------------------*/
     ChgVar     &IfsObj      ('/QDLS/' *CAT +
                              &TOFLR *TCAT '/' *CAT &TODOC)
     Call       ChkIfsObj    (&IfsObj &RtnValDec)
     If  (&RtnValDec *NE 0 )  (Goto Return)


     ChgVar     &CpyStr      ('CPY OBJ(' *CAT "E *CAT +
                              '/QDLS/' *CAT +
                              &TOFLR *TCAT '/' *CAT &TODOC *TCAT +
                              "E *CAT ')' *BCAT               +
                              'TODIR(' *CAT "E *CAT  +
                              '/QFileSvr.400/' *CAT &TCPHOST *TCAT +
                              '/QDLS/' *CAT  +
                              &TOFLR *TCAT   +
                              "E *CAT ')' *BCAT +
                              'DTAFMT(*BINARY) REPLACE(*YES)')

     SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&CpyStr) -
                TOUSR(*SYSOPR)

     ChgVar     &MDSTR       ( '/QFileSvr.400/' *CAT &TCPHOST )
     MD         &MDSTR
     MonMsg     CPFA0A0

     Call       QCMDEXC    ( &CPYSTR                                 +
                             &CPYSTRLEN                              +
                           )

     EndDo

 Return:
     Return

/*-- Error handling:  -----------------------------------------------*/
 Error:
     DmpClPgm

     Call      QMHMOVPM    ( '    '                                  +
                             '*DIAG'                                 +
                             x'00000001'                             +
                             '*PGMBDY'                               +
                             x'00000001'                             +
                             x'0000000800000000'                     +
                           )

     Call      QMHRSNEM    ( '    '                                  +
                             x'0000000800000000'                     +
                           )

 EndPgm:
     ChgVar     &DirName     ('/QFileSvr.400/' *CAT &TCPHOST)
     Rmdir      dir(&DirName) Rmvlnk(*Yes)
     EndPgm


File  : QCLSRC

Member: CHKIFSOBJ

Type  : CLLE

Usage : CRTBNDCL CHKIFSOBJ


Pgm    (&IfsObj  &RtnValDec)

  Dcl       VAR(&IFSOBJ)     TYPE(*CHAR) LEN(256)
  Dcl       VAR(&IFSOBJS)    TYPE(*CHAR) LEN(256)
  Dcl       VAR(&RTNVALBIN)  TYPE(*CHAR) LEN(4)
  Dcl       VAR(&RTNVALDEC)  TYPE(*DEC) LEN(5 0)
  Dcl       VAR(&PATH)       TYPE(*CHAR) LEN(100)
  Dcl       VAR(&RECEIVER)   TYPE(*CHAR) LEN(4096)
  Dcl       VAR(&NULL)       TYPE(*CHAR) LEN(1) VALUE(X'00')
  Dcl       VAR(&OBJTYPE)    TYPE(*CHAR) LEN(7)

  ChgVar     &IFSOBJS        &IFSOBJ
  ChgVar     &IFSOBJ         (&IFSOBJ *TCAT &NULL)

  CallPrc    Prc('stat') Parm(&IFSOBJ &RECEIVER) +
               RtnVal(%BIN(&RTNVALBIN))

  ChgVar     &RtnValDec      (%BIN( &RTNVALBIN ))


  If  (&RtnValDec *NE 0) THEN(SNDPGMMSG +
               MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('IFS +
               Object ' *CAT &IFSOBJS *TCAT ' not found') +
               MSGTYPE(*DIAG))

EndPgm



參考資訊:

This new support allows you to designate a program that is to be called when the command processing program (CPP) of a CL command completes.
This new support—which is available as PTFs for V5R4 (SI45987), 6.1 (SI45986), and 7.1 (SI45985).
The CL Corner: New Support for CL Commands Lets You Know When a Command Ends




星期三, 11月 08, 2023

2008-10-20 如何記錄 Command CHGSYSVAL 的使用?


如何記錄 Command CHGSYSVAL 的使用?

原則上系統已經提供稽核日誌 (Audit journal)方式記錄任何更改系統值的行為。但那是要啟動稽核功能才有效,
況且啟動稽核功能也會對系統效能有些許影響。那要如何在不啟動稽核功能下,記錄Command CHGSYSVAL 的使用。

當使用 CHGSYSVAL 更改任何系統值,系統會寫一筆 MSGID CPF1806 訊系至 QHST History log,但是卻未寫入 QSYSOPR,
這使得要找是誰更改了系統值,都必須使用 DSPLOG MSGID(CPF1806)查詢,所以要如何將使用 CHGSYSVAL 的紀錄寫入 
QSYSOPR中?使用 Command Exit Point QIBM_QCA_CHG_COMMAND 指定程式記錄指令 CHGSYSVAL 的使用。
下述範例會將 CHGSYSVAL 指令執行字串送至 QSYSOPR。


File  : QCLSRC
Member: CHGCMDEXIT
Type  : CLP
Usage : CRTCLPGM PGM(your-lib/CHGCMDEXIT)
        ADDEXITPGM EXITPNT(QIBM_QCA_CHG_COMMAND) FORMAT(CHGC0100)   
                   PGMNBR(*LOW) PGM(your-library/CHGCMDEXIT)        
                   PGMDTA(*JOB 20 'CHGSYSVAL QSYS      ')           
        使用 CHGSYSVAL 更改系統值,DSPMSG QSYSOPR 會看到類似下述 Change system value 訊息:
        *** Change system value : 732619/VENGOAL/QPADEV001T CHGSYSVAL SYSVAL(QPFRADJ) VALUE('1'). 
        
        若欲移除設定執行:
        WRKREGINF
        
                              Work with Registration Information                       
                                                                               
Type options, press Enter.                                                     
  5=Display exit point   8=Work with exit programs                             
                                                                               
                           Exit                                                
     Exit                  Point                                               
Opt  Point                 Format    Registered  Text                          
 8   QIBM_QCA_CHG_COMMAND  CHGC0100     *YES     Change command exit programs  
     QIBM_QCA_RTV_COMMAND  RTVC0100     *YES     Retrieve command exit program 
     QIBM_QDB_OPEN         DBOP0100     *YES     Open Database File Exit Progr 
     QIBM_QHQ_DTAQ         DTAQ0100     *YES     Original Data Queue Server    
     QIBM_QIMG_TRANSFORMS  XFRM0100     *YES                                   
     QIBM_QJO_DLT_JRNRCV   DRCV0100     *YES     Delete Journal Receiver       
     QIBM_QLZP_LICENSE     LICM0100     *YES     Original License Mgmt Server  
     QIBM_QMF_MESSAGE      MESS0100     *YES     Original Message Server       
     QIBM_QMH_REPLY_INQ    RPYI0100     *YES     Handle reply to inquiry messa 
     QIBM_QNPS_ENTRY       ENTR0100     *YES     Network Print Server - entry  
     QIBM_QNPS_SPLF        SPLF0100     *YES     Network Print Server - spool  
                                                                       More... 
Command                                                                        
===>                                                                           
F3=Exit   F4=Prompt   F9=Retrieve   F12=Cancel                                 

                           Work with Exit Programs                             
                                                                               
Exit point:   QIBM_QCA_CHG_COMMAND     Format:   CHGC0100                      
                                                                               
Type options, press Enter.                                                     
  1=Add   4=Remove   5=Display   10=Replace                                    
                                                                               
              Exit                                                             
            Program     Exit                                                   
Opt          Number     Program        Library                                 
                                                                               
4                 1     CHGCMDEXIT     EXITPGM                                 
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                                                        Bottom 
Command                                                                        
===>                                                                           
F3=Exit   F4=Prompt   F5=Refresh   F9=Retrieve   F12=Cancel                    


或執行        RMVEXITPGM EXITPNT(QIBM_QCA_CHG_COMMAND) FORMAT(CHGC0100) PGMNBR(1)                       

/******************************************************************/
/*  Use the following CL command to create the CHGCMDEXIT pgm     */
/*  in a library of your choice.                                  */
/*                                                                */
/*    CRTCLPGM PGM(your-library/CHGCMDEXIT)                       */
/*             SRCFILE(your-library/source-file)                  */
/*                                                                */
/*  Use the following CL command to cause the CHGCMDEXIT pgm      */
/*  to be called each time anyone uses the CRTRPGPGM CL command.  */
/*                                                                */
/*    ADDEXITPGM EXITPNT(QIBM_QCA_CHG_COMMAND) FORMAT(CHGC0100)   */
/*               PGMNBR(*LOW) PGM(your-library/CHGCMDEXIT)        */
/*               PGMDTA(*JOB 20 'CHGSYSVAL QSYS      ')           */
/*                                                                */
/******************************************************************/
             PGM        PARM(&EXITINFO &RPLCMD &RPLLEN)
             DCL        &EXITINFO *CHAR 4000
             DCL        &RPLCMD   *CHAR 3950
             DCL        &RPLLEN   *CHAR 4
             DCL        &ALWCHG  *CHAR 1 /* change allowed ? */
             DCL        &OFFSET  *DEC (6 0) /* offset to command */
             DCL        &CMDLEN  *DEC (6 0) /* length of command */
             DCL        &CHGSYSVAL *CHAR 9 'CHGSYSVAL'
             DCL        &MSGTXT    *CHAR 256
             DCL        &JOB       *CHAR 10
             DCL        &JOBUSR    *CHAR 10
             DCL        &JOBNBR    *CHAR  6

             CHGVAR     VAR(%BIN(&RPLLEN)) VALUE(0) /* set return +
                          parameter to indicate the command has +
                          not been changed yet */

      /*  Extract values from the input parameter structure.     */
             CHGVAR     VAR(&ALWCHG) VALUE(%SST(&EXITINFO 49 1)) +
                          /* get command is allowed to be +
                          changed indicator */
             CHGVAR     VAR(&OFFSET) VALUE(%BIN(&EXITINFO 53 4)) +
                          /* get offset to command string */
             CHGVAR     VAR(&OFFSET) VALUE(&OFFSET + 1) /* add +
                          1 because CL offset start at 1 +
                          instead of 0 */
             CHGVAR     VAR(&CMDLEN) VALUE(%BIN(&EXITINFO 57 4)) +
                          /* get length of command string */

             IF         COND(&CMDLEN > 3930) THEN(RETURN) /* exit +
                          if the command is too big to fit in +
                          the return variable */

             CHGVAR     VAR(&RPLCMD) VALUE(%SST(&EXITINFO &OFFSET +
                          &CMDLEN)) /* copy input command to +
                          output parameter */

             IF         (&CMDLEN > 9 *AND  +
                         %SST(&RPLCMD 1 9) *EQ &CHGSYSVAL) DO
             RTVJOBA    JOB(&JOB) USER(&JOBUSR) NBR(&JOBNBR)
                         CHGVAR &MSGTXT +
                               ('*** Change system value :' *BCAT +
          &JOBNBR *CAT '/' *CAT &JOBUSR *TCAT '/' *CAT &JOB *BCAT +
                                 %SST(&RPLCMD 1 &CMDLEN))
             SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&MSGTXT) +
                          TOUSR(*SYSOPR)
             ENDDO



             ENDPGM




星期二, 11月 07, 2023

2006-03-23 如何限制 SYSREQ (System request) 功能 ?


如何限制 SYSREQ (System request) 功能 ?

                               System Request                                 
                                                            System:   xxxxxxx  
Select one of the following:                                                   
                                                                               
     1. Display sign on for alternative job                                    
     2. End previous request                                                   
     3. Display current job                                                    
     4. Display messages                                                       
     5. Send a message                                                         
     6. Display system operator messages                                       
     7. Display work station user                                              
                                                                               
    80. Disconnect job                                                         
                                                                               
    90. Sign off                                                               
                                                                               
                                                !
                               
                                                                        Bottom 
Selection                                                                      
                                                                               
                                                                               
F3=Exit   F12=Cancel                                                           
(C) COPYRIGHT IBM CORP. 1980, 2002.                                            
========================================================================================
這些選項相關的指令放置於訊息檔 QCPFMSG 的 MSGID CPX2313 中, 可以由 DSPMSGD CPX2313取得,

                       Select Message Details to Display                        
                                                             System:   xxxxxxx  
 Message ID . . . . . . . . . :   CPX2313                                       
 Message file . . . . . . . . :   QCPFMSG                                       
   Library  . . . . . . . . . :     QSYS                                        
 Message text . . . . . . . . :   ENDRQS     WRKJOB     DSPMSG     SNDMSG     SI
GNOFF    DSPMSG     DSCJOB     DSPWSUSR   ENDRDBRQS                             
                                                                                
 Select one of the following:                                                   
                                                                                
      1. Display message text                                                   
                                                                                
      5. Display message attributes                                             
                                                                                
     30. All of the above                                                       
                                                          !
                      
                                                                                
                                                                                
                                                                                
 Selection                                                                      
                                                                                
                                                                                
 F3=Exit   F12=Cancel                                                           
========================================================================================
其中選項 1 是開啟第二個 SignOn 畫面, 便於同時有兩個工作互相切換,此時當然只有一個工作是
執行中,另一個在背景等待 SYSREQ 1 切換能繼續執行.

選項 2 (ENDRQS) 是終止目前執行中的作業, 這個功能最令 IT 人員既愛又恨, 因為它可以將某些不
正常執行的線上作業馬上終止, 但是一般使用者若是使用這個功能時, 就令人討厭了, 因為它也會造
成正常作業因為不正常結束導致 IT 人員需要做其他相關回復動作.

選項 3 (DSPJOB)是顯示目前作業的相關屬性, 或檢視報表. 這可以透過 WRKMSG QCPFMSG 找到 
CPX2313 使用選項 2 更改 DSPJOB 為 WRKJOB, 相信管理目前工作相關報表會很好用, 不過要記住更換
時, 不能多於六個英文字, 因為這個訊息中每個指令的內容長度是固定的, 所以 DSPJOB 可以改 WRKJOB.

其餘的我就不多說了.

有些應用軟體或環境需要限制 SYSREQ (System request) 所有功能, 應該要如何做呢 ?

這就需要透過系統提供的 System Request Exit Point: QIBM_QWT_SYSREQPGMS(V3R7 開始才有)
及設定 User Profile 才能達成.

      * 要啟用時, 需將 Exit program 加入 Exit point:
      *       ADDEXITPGM EXITPNT(QIBM_QWT_SYSREQPGMS) 
      *                 FORMAT(SREQ0100) PGMNBR(1) 
      *                 PGM(QGPL/SYSREQEXIT)
      * 要取消此功能時請使用下列指令移除 
      *       RMVEXITPGM EXITPNT(QIBM_QWT_SYSREQPGMS) FORMAT(SREQ0100) PGMNBR(1)
      
      * 設定要限制某些人存取 SYSREQ 功能
      * 限制!
     ==> CALL SETATNINF ('user-profile' '1')
      * 解除限制 ==> CALL SETATNINF ('user-profule' '0')


File  : QRPGLESRC
Member: SYSREQEXIT
Type  : RPGLE
Usage : CRTBNDRPG PGM(SYSREQEXIT)


      ****************************************************************************
      *
      *  To compile:  CRTBNDRPG PGM(QGPL/SYSREQEXIT) SRCFILE(xxx/QRPGLESRC)
      *                 SRCMBR(SYSREQEXIT)
      *
      ****************************************************************************
      * Attach this program to the Exit Point: QIBM_QWT_SYSREQPGMS
      * Use WRKREGINF to add the exit program to QIBM_QWT_SYSREQPGMS or
      *
      *  For any users that you wish to deny access to the attention key menu
      *  set the paramater SysReqDsp to anything other than 1.
      *
      *  NOTE: To enable this exit program to be called, you must set the user
      *        profile so that it will look for this exit program. You do that
      *        by calling the API QWTSETPX for each user profile and tell it which
      *        of the eight possible exit programs can be called for this exit
      *        point, which one to call for that profile.
      *
      *        The RPGLE program named xxx/SETATNINF can be called, passing
      *        to it as a parameter the user profile you wish to block from using
      *        the attention key menu.
      ****************************************************************************
      *
     H Debug
      *
     DPgmDs           SDS
     D JobName               244    253
     D UserName              254    263
     D JobNumber             264    269

      **-- API error data structure:  ----------------------------------
     D ApiError        Ds
     D  AeBytPrv                      10i 0 Inz( %Size( ApiError ))
     D  AeBytAvl                     10i 0
     D  AeExcpId                      7a
     D           !
                     1a
     D  AeExcpDta                   128a

      **-- Send message:  ----------------------------------------------
     D SndMsg          Pr                  ExtPgm( 'QMHSNDDM' )
     D  SmMsgId                       7a   Const
     D  SmMsgFq                      20a   Const
     D  SmMsgDta                    512a   Const Options( *VarSize )
     D  SmMsgDtaLen                  10i 0 Const
     D  SmMsgTyp                     10a   Const
     D  SmMsgQq                    1000a   Const Options( *VarSize )
     D  SmMsgQnbr                    10i 0 Const
     D  SmMsgQrpy                    20a   Const
     D  SmMsgKey                      4a
     D  SmError                      10i 0 Const

     D SysReqDsp       S             10i 0
     D SysUsrDta       S            128a
     D MsgKey          s              4a
     D Msg_Str         S            256

      *=====================================================================
     C     *Entry        Plist
     C                   Parm                    SysReqDsp
     C                   Parm                    SysUsrDta
      *
     C                   Eval      SysReqDsp = 0
      *
      * Send Info message
      *
     C                   Eval      Msg_Str = '** User ' + %trim(UserName) +
     C                                       ' is not authorized to ' +
     C                                       'System request function!'
     C                   Callp(e)  SndMsg(
     C                             'CPF9897':'QCPFMSG   *LIBL     ':
     C                             msg_str: 256 :
     C                             '*INFO  ':
     C                             'QSYSOPR   *LIBL      ':
     C                             1: *blanks : msgkey :
     C                             0)
     C*                            ApiError)
     C
      *
     C                   Eval      *Inlr = *On


File  : QRPGLESRC
Member: SETATNINF
Type  : RPGLE
Usage : CRTBNDRPG PGM(SETATNINF)
        限制     ==> CALL SETATNINF ('user-profile' '1')
        解除限制 ==> CALL SETATNINF ('user-profule' '0')


      **************************************************************************
      * Sets User Profile Information for Attention Key Exit Program Processing
      *
      *    You MUST pass the user profile for that user to this
      *    program in order to change the profile for that user
      *
      **************************************************************************
      *
      *  To Create:  CrtBndRPG(xxx/SETATNINF)
      *
      ***************************************************************************
     H DFTACTGRP(*NO) BNDDIR('QC2LE')
      **----------------------------------------------------------------
      **  Set Profile Exit Programs API
      **
       **   Parameters:
      **      NumEnt = Number of Exit Program flags being passed in
      **    ExtFlags = Array of number of elements (1 to 8).
      **               - 0 = Don't Call
      **               - 1 = Yes Call
      **               - -1 = Do Not Change This Value
      **      Format = 'ATTN0100' - Preattention Key program processing flags
      **             = 'SREQ0100' - System Request program processing flags
      **      UserID = The user profile to update
      **   ErrorCode = API error code, used to return any errors.
      **
      **----------------------------------------------------------------
     D SetProfExt      PR                  ExtPgm('QWTSETPX')
     D   NumEnt                      10i 0 const
     D   ExtFlags                    10i 0 DIM(8) const
     D   Format                       8a   const
     D   UserID                      10A   const
     D   ErrorCode                32766A   options(*varsize: *nopass)


     D ErrDs           DS
!
     D  BytesPrv               1      4I 0 INZ(256)
     D  BytesAvl               5      8I 0 INZ(0)
     D  ErrMsgID               9     15
     D  Reserved              16     16
     D  ErrMsgDta             17    256

     DToUser           S             10a
     DEnable           S              1a 
      *
     C     *Entry        Plist
     C                   Parm                    ToUser
     C                   Parm                    Enable
      *
     c                   If        Enable = '1' 
     c                   callp     SetProfExt(1:1:'SREQ0100':ToUser:ErrDS)
     c                   callp     SetProfExt(1:1:'ATTN0100':ToUser:ErrDS)
     c                   Else                                             
     c                   callp     SetProfExt(1:0:'SREQ0100':ToUser:ErrDS)
     c                   callp     SetProfExt(1:0:'ATTN0100':ToUser:ErrDS)
     c                   EndIf                                            
     
     C                   Eval      *Inlr = *On