IBM Support

FTP Exit Program: Server Example

Troubleshooting


Problem

This note documents an example of an FTP exit program.

Resolving The Problem

To secure the system from FTP access, it is suggested that you use object security (GRTOBJAUT, EDTOBJAUT, and so on). This works fine in theory; however, in practice, you probably want everything except certain directories or even certain files secured. In cases like that, you would have to go around "de-permitting" everything on the system to the user profiles that will be accessing your system using FTP. Another way to implement security with FTP is to use an Exit Program. Exit programs can give additional restrictions -- they cannot grant more authority than the user would have if they were to sign on to the IBM System i system in an interactive job. However, in the case of restricting a user to just a few items on the iSeries family system, this is exactly what we want.

In the OS/400 TCP/IP Configuration and Reference V4R2 (SC41-5420-01), there are some example exit programs for FTP. The available ones are as follows:

Manual
Section Title
I.10.5 Sample FTP Server Logon Exit Program (C Language)
I.11.9 Sample FTP Server Logon Exit Program (CL) for Anonymous FTP
I.11.10 Sample FTP Server Request Validation Exit Program for Anonymous FTP

The last two are written in CL, and the first is written in the C language. Here is presented another example of a Server Request Validation Exit program for FTP written in CL. The rules it implements are:
o All users may list the directory or library they are in.
o No users can create or delete directories, rename objects, or run commands on the System i system.
o User TPA may only CD (change directory) to library XZS2039 and may only download member FTPEXIT from file SOURCE. All other activities will be rejected.
o User Anonymous may only CD to a directory in the /pub hierarchy, may download anything from there, and may upload to directory /pub/upload, and may do no other activity.
o Other users are allowed to change to any directory, download or upload files that they are permitted to access with their operating system user profiles.
This program also sends a message to message queue QUSRSYS/FTPMSGQ telling what activity was requested, and if the activity was not allowed. The message queue must be created before the exit program runs, or it will abort.

Step 1: After the program has been modified to your requirements, and compiled, register the exit program:

WRKREGINF QIBM_QTMF_SERVER_REQ

This will bring up a screen similar to the following:
 
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_QTMF_SERVER_REQ  VLRQ0100     *YES     FTP Server Request Validation
                                                                               


                                                                        Bottom
Command                                                                      
===> _________________________________________________________________________
F3=Exit   F4=Prompt   F9=Retrieve   F12=Cancel    
                            

Step 2: Select Option 8, to Work with Exit Programs.
 
                   Work with Exit Programs              
                                                               
Exit point:   QIBM_QTMF_SERVER_REQ     Format:   VLRQ0100      
                                                               
Type options, press Enter.                                      
  1=Add   4=Remove   5=Display   10=Replace                    
                                                               
              Exit                                              
            Program     Exit                                    
Opt          Number     Program        Library                  

                                                               
                                                               

                                                                 Bottom
Command                                                        
===>
                                                                 
F3=Exit   F4=Prompt   F5=Refresh   F9=Retrieve   F12=Cancel        

Step 3: Enter Option 1, and fill in the name of the exit program and the library it resides in. Press the Enter key.

The program is now registered and will be invoked every time an FTP request comes into your system.

The Sample Program

FTPEXIT:    +
 PGM PARM(&APPID &OPID &USRPRF &REMOTEIP &REMOTELEN &OPINFO &OPLEN &OK)
 DCL &APPID     *CHAR 4       /* APPLICATION ID, BINARY NUM    */
 DCL &OPID      *CHAR 4       /* OPERATION ID, BINARY NUMBER   */
 DCL &OPNUM     *DEC  4       /* OPERATION ID, USABLE IN CL    */
 DCL &USRPRF    *CHAR 10      /* USER PROFILE USING FTP        */
 DCL &REMOTEIP  *CHAR 251     /* IP ADDRESS                    */
 DCL &REMOTELEN *CHAR 4       /* LENGTH OF PREVIOUS PARAMETER  */
 DCL &OPINFO    *CHAR 251     /* OP SPECIFIC INFORMATION       */
 DCL &OPLEN     *CHAR 4       /* LENGTH OF PREVIOUS PARAMETER  */
 DCL &OK        *CHAR 4       /* CONFIRMATION SIGNAL           */


  DCL &RLEN      *DEC  10      /* ROUTE LENGTH VALUE AS DECIMAL */
 DCL &OLEN      *DEC  10      /* LENGTH VALUE IN A DECIMAL FORM*/

  /* CONSTANTS  USED FOR PARAMETER VALUES                       */

  /* ALLOWABLE VALUES FOR APPID                                 */
 DCL &CLIENT    *CHAR 4  VALUE(X'00000000') /* FTP CLIENT      */
 DCL &SERVER    *CHAR 4  VALUE(X'00000001') /* FTP SERVER      */
 DCL &REXEC     *CHAR 4  VALUE(X'00000002') /* REXEC SERVER PGM*/
 DCL &TFTP      *CHAR 4  VALUE(X'00000003') /* TFTP SERVER PGM */


  /* ALLOWABLE VALUES FOR OPID  FOR FTP CLIENT OR FTP SERVER    */
 DCL &STR       *CHAR 4  VALUE(X'00000000') /* START FTP       */
 DCL &MKD       *CHAR 4  VALUE(X'00000001') /* MAKE DIRECTORY  */
 DCL &RMD       *CHAR 4  VALUE(X'00000002') /* DLT  DIRECTORY  */
 DCL &CD        *CHAR 4  VALUE(X'00000003') /* SET  DIRECTORY  */
 DCL &DIR       *CHAR 4  VALUE(X'00000004') /* LIST DIRECTORY  */
 DCL &DELE      *CHAR 4  VALUE(X'00000005') /* DELETE FILE     */
 DCL &GET       *CHAR 4  VALUE(X'00000006') /* SEND FILE       */
 DCL &PUT       *CHAR 4  VALUE(X'00000007') /* GET FILE        */
 DCL &REN       *CHAR 4  VALUE(X'00000008') /* RENAME FILE     */
 DCL &SYS       *CHAR 4  VALUE(X'00000009') /* EXECUTE COMMAND */


  /* ALLOWABLE VALUES FOR OK                                    */
 DCL &NONEVER   *CHAR 4  VALUE(X'FFFFFFFF') /* NEVER ALLOW OP  */
 DCL &NO        *CHAR 4  VALUE(X'00000000') /* DISALLOW FTP    */
 DCL &YES       *CHAR 4  VALUE(X'00000001') /* ALLOW FTP       */
 DCL &YESYES    *CHAR 4  VALUE(X'00000002') /* ALLWAYS ALLOW   */


  /* VARIABLES FOR THE MESSAGE THAT SAYS WHAT'S HAPPENING       */
 DCL &ACTIONS   *CHAR 56  VALUE(+
          'MKDIR RMDIR CD    DIR   DLT   GET   PUT   RENAM   CMD   ')
 DCL &AINDEX    *DEC 4
 DCL &MSG       *CHAR 150                   /* PARAMS FOR  MSG*/
 DCL &MSGLEN    *DEC  4   VALUE(10)         /* LENGTH OF MESSAGE */



  /* CONVERT THE LENGTH PARAMETERS FROM BINARY TO DECIMAL      */
 CHGVAR &RLEN %BIN(&REMOTELEN)
 CHGVAR &OLEN %BIN(&OPLEN)
 CHGVAR &OPNUM %BIN(&OPID)


 /* CODE FOR EACH OPERATION IS IN A SEPARATE IF BLOCK          */

 IF (&STR  = &OPID) DO    /* START FTP                         */
  CHGVAR &OK &YES        /* LET FTP AT LEAST START            */
  ENDDO
ELSE DO /* CREATE A MESSAGE DESCRIBING WHAT THE USER IS DOING */
 CHGVAR &AINDEX (((&OPNUM-1)*6)+1)
 CHGVAR &MSG 'FTP ACTION '
 CHGVAR %SST(&MSG 12 6) %SST(&ACTIONS &AINDEX 6)
 CHGVAR %SST(&MSG 17 10) 'FROM USER '
 CHGVAR %SST(&MSG 27 10) &USRPRF
 CHGVAR %SST(&MSG 37 14) 'AGAINST OBJECT '
 CHGVAR %SST(&MSG 52 &OLEN) &OPINFO
 CHGVAR &MSGLEN (53+&OLEN)


             SNDPGMMSG  MSGID(CPF9897) MSGF(QSYS/QCPFMSG) +
                       MSGDTA(&MSG) TOMSGQ(QUSRSYS/FTPMSGQ)
  ENDDO


 /* DIFFERENT CODE SECTIONS FOR EACH DIFFERENT FTP ACTION      */
IF (&MKD  = &OPID) DO    /* OPTION IS MAKE A DIRECTORY        */
  CHGVAR &OK &NO         /* NO DIRECTORY CREATION ALLOWED     */
  ENDDO


 IF (&RMD  = &OPID) DO    /* DELETE DIRECTORY                  */
  CHGVAR &OK &NO         /* DON'T ALLOW DIRECTORY DELETION    */
  ENDDO


 IF (&CD   = &OPID) DO    /* SET CURRENT DIRECTORY             */
  /* USER 'TPA' MAY ONLY GO TO AS/400 LIBRARY XZS2039         */
  IF (&USRPRF = 'TPA') THEN(DO)
    IF (%SST(&OPINFO 1 &OLEN) *NE '/QSYS.LIB/XZS2039.LIB') +
    THEN(DO)
      CHGVAR &OK &NO    /* USER TPA CAN ONLY GO TO XZS2039    */
      SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) TOMSGQ(QUSRSYS/FTPMSGQ) +
                 MSGDTA('TPA ATTEMPTED TO CD TO A DIFFERENT LIBRARY')
      ENDDO  /* TPA CHANGED DIRECTORY TO CORRECT LIBRARY      */
    ELSE CHGVAR &OK &YES
    ENDDO
  ELSE DO                 /* NOT USER TPA, PROCESS ANONYMOUS  */
    IF (&USRPRF = 'ANONYMOUS') +
    THEN(DO)
      IF  (%SST(&OPINFO 1 4) *NE '/pub') +
      THEN(DO)
        CHGVAR &OK &NO
        SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) TOMSGQ(QUSRSYS/FTPMSGQ) +
                  MSGDTA('ANONYMOUS TRYING TO GET NON-PUB DIRECTORY')
        ENDDO
        CHGVAR &OK &YES   /* ANONYMOUS CAN GO TO /PUB         */
      ENDDO
    ELSE CHGVAR &OK &YES    /* OTHERS CAN GO ANYWHERE         */

     ENDDO
  ENDDO


 IF (&DIR  = &OPID) DO    /* GET LIST OF FILES IN DIRECTORY    */
  CHGVAR &OK &YES        /* ALLOW IT                          */
  ENDDO


 IF (&DELE = &OPID) DO    /* DELETE FILE                       */
  CHGVAR &OK &NO         /* NO FILE DELETION ALLOWED          */
  ENDDO


 IF (&GET  = &OPID) DO    /* GET A FILE                        */
  IF ((&USRPRF = 'TPA') *AND  +
      (%SST(&OPINFO 1 &OLEN) *NE +
       '/QSYS.LIB/XZS2039.LIB/SOURCE.FILE/FTPEXIT.MBR' )) +
  THEN( DO )   /* USER TPA CAN ONLY GET THAT FILE             */
    CHGVAR &OK &NO    /* SO DISALLOW OTHER GETS               */
    SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +
               MSGDTA('TPA NOT ALLOWED TO GET FILE') TOMSGQ(QUSRSYS/FTPMSGQ)
    ENDDO
  ELSE DO    /* USER 'ANONYMOUS' CAN ONLY GET FILES FROM /PUB */
    IF ((&USRPRF = 'ANONYMOUS') *AND   +
        (%SST(&OPINFO 1 4) *NE '/pub')) +
    THEN(DO)
      CHGVAR &OK &NO
      SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) +
                MSGDTA('ANONYMOUS TRYING TO GET FILE NOT ON /PUB') +
                TOMSGQ(QUSRSYS/FTPMSGQ)
      ENDDO
    ELSE CHGVAR &OK &YES    /* OTHERS CAN GET ANYTHING        */
    ENDDO
  ENDDO


 IF (&PUT  = &OPID) DO    /* PUT FILES ON SYSTEM               */
  /* ANONYMOUS USERS CAN ONLY PUT FILES ON /pub/upload/       */
  IF ((&USRPRF = 'ANONYMOUS') *AND   +
      (%SST(&OPINFO 1 12) *NE '/pub/upload/')) +
  THEN(DO)
    CHGVAR &OK &NO
    SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) TOMSGQ(QUSRSYS/FTPMSGQ) +
              MSGDTA('ANONYMOUS TRYING TO PUT FILES OTHER THAN /upload')
    ENDDO
  ELSE IF (&USRPRF = 'TPA') +
  THEN(DO)
    CHGVAR &OK &NO
    SNDPGMMSG MSGID(CPF9898) MSGF(QSYS/QCPFMSG) +
              MSGDTA('TPA ATTEMPTED TO PUT A FILE') +
              TOMSGQ(QUSRSYS/FTPMSGQ)
    ENDDO
  ELSE CHGVAR &OK &YES    /* OTHERWISE, OK.                   */
  ENDDO


 IF (&REN  = &OPID) DO    /* RENAME A FILE                     */
  CHGVAR &OK &NO         /* FILE RENAMES NOT ALLOWED          */
  ENDDO


 IF (&SYS  = &OPID) DO    /* EXECUTE AS/400 COMMAND            */
  CHGVAR &OK &NO         /* COMMANDS NOT ALLOWED VIA FTP      */
  ENDDO


 ENDPGM

[{"Type":"MASTER","Line of Business":{"code":"LOB57","label":"Power"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SWG60","label":"IBM i"},"Platform":[{"code":"PF012","label":"IBM i"}],"Version":"7.1.0"}]

Historical Number

16055109

Document Information

Modified date:
15 September 2020

UID

nas8N1018050