SUBMIT(8)

πŸ“¦
version 2.0.6 Β· 3 versions
, in ubuntu stonking

🌸 SUBMIT(8) 🌸

okay so bestie, you clicked into the SUBMIT(8) corner of the manual πŸ’– and this whole page is credited to S. Varshavchik. Strap in, it's giving mail server internals and honestly? iconic. πŸ¦‹


πŸ’– NAME πŸ’–

submit β€” Submit a new message to the Courier mail server ✨


πŸ“œ SYNOPSIS πŸ“œ

/usr/bin/submit [-expn=address] [-vrfy=address] [-vhost=address] [-bcc]
                [-delay=n] [-rfc3848=type] {module} {"type; hostid"}

🌈 DESCRIPTION 🌈

okay so the submit program is the girl that hands messages over to the Courier mail server for processing. She is not for the end user, bestie, not even a little πŸ’…. She's used by the Courier mail server input modules only. Her global read and execute permissions are turned off, so literally the only way to run her is from a process that's a member of the courier group. And plot twist β€” submit is installed in the /usr/lib/courier/courier directory, not where you'd expect. 🫢

submit always takes, like, exactly two command line arguments after any options. No more, no less:

  • module β€” this one names the module that's running the submit command. It has to be one of the module names the Courier mail server already knows about, like local, or esmtp. This argument is the one bossing around the address rewriting rules.
  • "type; hostid" β€” one single argument (yes, quotes and all) that IDs where the message came from. It has to be suitable for the Remote-MTA: header in delivery status notifications, the way RFC 1894 says so. When a message shows up via ESMTP, this argument is typically "dns; helohost (hostname [ip.address])". πŸŽ€

Then comes the option menu, and the submit program takes all of these:

  • -expn=address β€” don't accept a message, "expand" the address instead. If the address you gave matches a locally-defined alias, submit prints all the addresses it expands to. If it does not match a locally-defined alias, the address just gets displayed by itself. no drama. 🌷
  • -vrfy=address β€” don't accept a message, verify the address instead. submit prints a suitable message and sets the exit code to say whether that address is valid or not. Here's the flow, bestie: if the address matches a local alias β†’ submit says valid, exits. If it doesn't match a local alias, submit checks whether any output protocol module can deliver it β†’ if yes, valid, exits. Otherwise? submit prints a "User unknown" error message and exits. πŸ’€
  • -bcc β€” if no recipients are given, grab the recipient list from Bcc: headers only. Normally, when no recipients are specified, submit reads recipients from the To:, Cc: and Bcc: headers (and Bcc: headers always get removed, periodt). The -bcc option makes it ignore To: and Cc: headers for that purpose. Heads up though β€” this option is ignored if an explicit recipient list is specified (see below). πŸ™ˆ
  • -delay=n β€” wait n seconds before delivering the message. If you don't specify it, delivery starts after waiting however long the /etc/courier/submitdelay configuration time says (default: 0 seconds β€” immediate delivery, no waiting around 😌).
  • -rfc3848=text β€” specify the RFC 3848 transmission type label to be included in the message's β€œReceived:” header.
  • -vhost=address β€” append β€œ.address” to names of all configuration files Courier reads while processing this message.

πŸ“¬ RESPONSES FROM SUBMIT πŸ“¬

Every single reply from submit follows the format of SMTP responses, as defined in RFC822. Let's summarise because the girlies need the TL;DR ✨

The responses are one or more lines long. Every line in the response except the last one is: a three-digit numerical code, a dash, then arbitrary text. The last line (or the only line of the response) starts with a three-digit numerical code, a single space, and arbitrary text. πŸ”₯

The first digit of that numerical code is the vibe check β€” it tells you success or failure:

  • first digit is 5 β†’ permanent failure 😭
  • first digit is 4 β†’ temporary failure (the message or the address should be resubmitted later, so like, try again bestie)
  • first digit is anything that isn't 4 or 5 β†’ success, or acceptance πŸ‘‘

πŸ’Œ MESSAGE SUBMISSION πŸ’Œ

Unless either the -expn or the -vrfy option is specified, submit reads the message envelope and contents from standard input, like this. All input and output to submit consists of newline-terminated (NOT carriage return/newline terminated) lines of text. newline girlies only, no CRLF energy. πŸ’…

submit reads the first line of text, which specifies the envelope sender address. That line is formatted like:

address<tab>format<tab>envid

<tab> there is the ASCII tab character, mhm. The address may be an empty string, optionally followed by tab, then format, another tab, then envid.

format is one or more characters that specify delivery status notification processing, and other message options. Breaking it down:

  • F β€” delivery status notifications should include the entire message
  • H β€” just the headers of the message should be included
  • neither F nor H present β€” no preference, she's chill
  • S{keyword} β€” specifies the optional SECURITY extension keyword for this message
  • V β€” sets the VERP extension flag for this message
  • 8 β€” a flag saying the message was received via SMTP with a SMTPUTF8 keyword, and this prepends β€œUTF8” to the transmission type passed in via -rfc3848

envid is the original message envelope ID, which will show up on any delivery status notifications. NOTE: envid must be specified using xtext encoding (see the relevant RFCs). πŸ“Ž

After reading that first line of text, submit prints a response (see "RESPONSES FROM SUBMIT", above). If the response is a failure, submit terminates immediately, done, goodbye 😭. Otherwise, submit then reads one or more envelope recipients.

Each envelope recipient gets read as a single non-empty line of text, formatted like:

address<tab>dsn<tab>oreceipient

address is a non-empty recipient E-mail address, optionally followed by the tab character, then zero or more characters specifying dsn, then a tab character, then the oreceipient value.

dsn is zero or more of these characters:

  • S β€” send a delivery status notification upon a successful delivery to this address
  • F β€” send a DSN upon a failed delivery
  • D β€” send a DSN upon a mail delay
  • N β€” never send a DSN

oreceipient is the "Original Recipient", as specified in RFC1894, except that it is not encoded using xtext encoding, but in unencoded UTF-8. 🧚

submit will print a response to each recipient (see "RESPONSES FROM SUBMIT", above). If at least one recipient address has been successfully specified, a blank line is read to specify end of recipient list, followed by the entire message, headers and body. yes, the whole thing. 🌺

A single blank line terminates the list of recipients. That is followed by the message itself, all the way until end of file.

And plot twist β€” that blank line can be present before even the first recipient is specified. If so, submit obtains the list of recipients from the message's headers instead. main character flexibility ✨

submit reads the message headers and body until end-of-file. Then, submit prints a response (see above) indicating whether or not the message was accepted for delivery, and terminates. πŸ’«


πŸ”„ ADDRESS REWRITING πŸ”„

Every recipient address β€” whether it was specified explicitly, or obtained from the message headers β€” gets rewritten according to the rewriting rules specified by the input module. And each address in the headers of the message gets rewritten too. Everybody gets a glow-up. πŸ’…

After rewriting each recipient address, submit searches the aliases.dat file for this address, to see if it represents a locally defined alias. She looks in:

  • /usr/lib/courier/courier/modules/module/aliases.dat
  • /etc/courier/aliases.dat

(actual locations may be changed by the system administrator, so don't come for her if they're different on your box πŸ™ˆ)

If the address is found, the recipient address gets replaced by the addresses defined in the aliases.dat file. slay. πŸŽ€


🌿 ENVIRONMENT VARIABLES 🌿

submit also reads these environment variables to further specify how the message is to be processed:

  • BLOCK β€” if this variable is set to a non-empty value, submit will reject every recipient (in effect, rejecting the message). The contents of the environment variable will be used as the error message. πŸ’€
  • DSNENVID β€” if envid is not specified, or is blank, and this environment variable is defined, the contents of this variable are used as the original envelope id field for DSNs. Heads up: DSNENVID is copied verbatim into the Original-Envelope-Id field (if the message is relayed to another MTA, the Courier mail server automatically xtext-encodes it). πŸ“Ž
  • DSNNOTIFY β€” if the dsn field for a recipient is empty, the contents of this environment variable are used in its place. Also, if the recipient list is read from the headers, the contents of this environment variable are used to set the dsn setting. ✨
  • DSNRET β€” if the format field for this message is empty, the contents of this environment variable are used in its place.
  • NOADDDATE β€” normally the Courier mail server adds a Date: header to the message if it doesn't have one. If this environment variable is set, the Courier mail server will not add a Date: header. πŸ•°οΈ
  • NOADDMSGID β€” normally the Courier mail server adds a Message-Id: header to the message if it doesn't have it. If this environment variable is set, the Courier mail server will not add a Message-Id: header. πŸ†”
  • NOADDRREWRITE β€” normally the Courier mail server rewrites addresses in the From:, To:, and Cc: header fields. If this environment variable is set to 1, the Courier mail server will not rewrite them. If it is set to a higher value, the Courier mail server will only rewrite it if no DKIM-Signature: header field was found. πŸ”
  • MIME β€” normally the Courier mail server adds any missing RFC2045 headers to the message. The MIME environment variable can be set to the following values: none - do not do any RFC2045 processing whatsoever; 7bit - if the message contains any 8-bit text, convert it to quoted-printable encoding; 8bit -if the message contains any quoted-printable encoded text that can be representing as 8bit-encoded text, then convert it to 8bit encoding. 🌈

πŸ‘€ SEE ALSO πŸ‘€


πŸ‘‘ AUTHOR πŸ‘‘

Sam Varshavchik &nbsp;&nbsp;&nbsp;&nbsp;Author


πŸ“ NOTES πŸ“

  1. courierpop3d(8) β€” https://www.courier-mta.org/courierpop3d.html
  2. couriertcpd(8) β€” https://www.courier-mta.org/couriertcpd.html
  3. authlib(7) β€” https://www.courier-mta.org/authlib.html

and that's the whole page bestie, no cap πŸ’– this was Courier Mail Server, dated 01/10/2026, filed under SUBMIT(8) β€” go forth and submit responsibly, mwah 🫢✨

πŸ“¦ where this page comes from
  • ubuntu stonking: courier-mta 2.0.6-1 Β· GPL-3+~with-OpenSSL-exception
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms