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:
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:
Step 2: Select Option 8, to Work with Exit Programs.
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
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. |
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
Was this topic helpful?
Document Information
Modified date:
15 September 2020
UID
nas8N1018050