Use the SMTP server exit to check and subsequently accept or reject mail inbound from a TCP/IP network or mail outbound from the JES spool. For example, you can code an exit to check the MAIL FROM: string on outbound mail or to control the influx of unwanted inbound mail (commonly referred to as spam).
_________________________________________________________________
If SAF token information is requested, the field EZBPTOKP contains the address of the token. However, this field can be zero if the SMTP server was unable to retrieve the SAF token from JES. The exit program needs to be coded to handle this situation. The SAF token length is 80 bytes and the SAF token version is 1. The SAF token provides information about the submitting user ID and the submitter node of the JES data. This data can be compared to the sender information about the MAIL FROM: string. For more information about what is provided in the SAF token, see the RUTKN information in z/OS Security Server RACF Data Areas.
_________________________________________________________________
_________________________________________________________________
When mail is rejected by the SMTP exit program for the JES connection ID, it is always returned to the POSTMASTER. The POSTMASTER must determine what happens to the rejected JES data. After the SMTP exit program rejects the JES data, the entire spool file is rejected, which might include multiple notes. Depending on how the JES data is spooled, this might be a large amount of data.
The POSTMASTER can modify the data and resend it to SMTP, or it can discard the data. The SMTP exit program policies determine whether or not the POSTMASTER receives large quantities of mail that require review. When the SMTP exit program rejects mail from a TCP/IP connection, the remote SMTP client determines what happens to the rejected mail. In this case, the mail becomes undeliverable and might be returned to the originator.
_________________________________________________________________
If you run the exit program in both directions, performance might be impacted.
If the SMTP server receives mail from a TCP/IP network, and then sends it out on a TCP/IP connection (relaying the mail), the SMTP server invokes the exit program only one time on the inbound path.
The exit should be written in Assembler Language. Standard z/OS® Assembler entry and exit linkage must be used. See z/OS MVS Programming: Assembler Services Guide for the linkage conventions.
The exit is invoked with the settings shown in Table 1.
Authorization | Problem state |
---|---|
Dispatchable Unit Mode | Task |
Cross memory mode | PASN=HASN |
Amode | 31–bit |
ASC mode | Primary address space control (ASC) mode |
Interrupt status | Enabled for interrupts |
Locks | Unlocked |
The exits input parameter list contains the information shown in Table 2. An assembler macro is available to provide you with a DSECT describing this area. The name of the macro is EZBZSMTP and the macro resides in SEZACMAC. It enables an optional label but has no operands. It provides symbolic names for the 3 return codes and 18 action codes. The labels are as shown in Table 2.
Label name | Width/Value | Description |
---|---|---|
Parameter list variables | ||
EZBZSMTP | DSECT Name | |
EZBPVERS (See note 1) | 1 Fullword | Version number |
EZBPACTN (See note 2) | 1 Fullword | Action code |
EZBPUSER (See note 3) | 1 Fullword | Returned Reg15 of initialization call |
EZBPCNID (See note 4) | 1 Fullword | Connection ID |
EZBPTOKP (See note 17) | 1 Fullword | Address of SAF (security) token |
2 Fullwords | Reserved for future use | |
EZBPIPV4 (See note 6) | 1 Fullword | IP addr of remote SMTP |
EZBPDLEN (See note 7) | 1 Fullword | Length of data in buffer |
EZBPBUFF (See note 8) | 1 Fullword | Buffer address |
Constants | ||
EZBRAGN | 0 | Return code to continue |
EZBRACC | 4 | Return code to accept mail |
EZBRREJ | 8 | Return code to reject mail |
Action codes | ||
EZBAINIT | 1 | Initialization call (See note 9) |
EZBATERM | 2 | Termination call (See note 10) |
EZBADATA | 3 | SMTP DATA command |
EZBAEXPN | 4 | SMTP EXPN (expand) command |
EZBAHELO | 5 | SMTP HELO (hello) command |
EZBAHELP | 6 | SMTP HELP command |
EZBAMAIL | 7 | SMTP MAIL command |
EZBANOOP | 8 | SMTP NOOP command (See note 11) |
EZBAQUEU | 9 | IBM® SMTP QUEU (queue) command |
EZBAQUIT | 10 | SMTP QUIT command (See note 12) |
EZBARCPT | 11 | SMTP RCPT (recipient) command |
EZBARSET | 12 | SMTP RSET (Reset) command (See note 13) |
EZBATICK | 13 | IBM SMTP TICK command |
EZBAVERB | 14 | IBM SMTP VERB command |
EZBAVRFY | 15 | SMTP VRFY (Verify) command |
EZBADBUF | 16 | Data buffer (See note 14) |
EZBAEODB | 17 | End of data buffers (last chance) (See note 15) |
EZBACONN | 18 | End of connection (See note 16) |
There are two control invocations of the SMTP user exit. One for initialization, and the other for termination. On return from the initialization call, the contents of register 15 is treated as a 4-byte user token that is returned on all other exit invocations. See Table 2 for more information. The user token is not used by SMTP, but only passed on subsequent calls to allow a reentrant exit to have static data (using getmain or some other method). It is expected that certain data sets might be read during the initialization call and that tables of known spamming Internet addresses might be constructed at this time for later use. The termination call allows report generation or any other clean-up activity that the exit might do prior to the stopping of SMTPPROC under normal termination logic.
There are three supported return code values which the exit program might set. For certain action codes such as initialization (EZBAINT), termination (EZBATERM) and end of connection (EZBACONN) the return code value is ignored. The returned value and expected meanings are as follows:
Return codes that are not valid are converted to a 0, and the exit is called again.
The connection identifier is a unique number during the life of the connection. You can use it to distinguish between multiple concurrent connections that can be present. Each has its own state information in SMTPPROC, and if the exit wants to keep any state information, this field can be used to keep each message's state separate. Connection identifiers normally become available for reuse after a QUIT command or the end of connection (action code 18), or both, occur. They normally first appear with a HELO command.
The buffer contents for action codes 3 through 15 contain the SMTP command.
The buffer contains data that has been translated using the EBCDIC encoding tables configured for the SMTPPROC. Data buffers might not be in English and might contain NLS characters.
Unknown commands are rejected by SMTPPROC and the exit is not called. The buffer normally contains the SMTP command. See RFC 821 for exact spellings and format.
The initialization and termination calls do not have a connection number. The return code from the initialization call is not checked, but placed in the ezbpuser field. The return code from the termination call is moot. These calls are always active if the exit is active.
Interaction between SMTP and user exit program
During an active connection, SMTP determines whether the user exit program is called again based on the return code passed back to SMTP from the previous invocation of the exit.
The user exit is not called again for the affected connection until the resetting action codes are received, and only if the ezbracc or the ezbrrej return codes are received from the exit from a connection-oriented call. The accept or reject state might remain in effect for only the current call however.
In Table 3, the following codes are not sent to the exit if the current state is accept or reject and do not change the state.
Action code | Value |
---|---|
3 | DATA |
4 | EXPN |
6 | HELP |
8 | NOOP |
9 | QUEU |
11 | RCPT |
13 | TICK |
14 | VERB |
15 | VRFY |
16 | data buffers |
In Table 4, the following codes are not sent to the exit, but they ensure that the next command (if any) goes to the exit as it resets the next state to ezbragn.
Action code | Value |
---|---|
10 | QUIT |
12 | RSET |
17 | End of data buffers (final chance) |
In Table 5, the following is always sent to the exit if it is active, and the return code received determines the new state.
Action code | Value |
---|---|
5 | HELO |
7 | |
18 | Connection closed (termination of individual connection). Connection number available for reuse and state is reset to ezbragn. |