Unlike some other MTAs, qmail distinguishes between injected mail, new messages entered into the mail system, and relayed mail, which is delivered from somewhere else. The difference is that injected mail needs to have its headers cleaned up, while relayed mail doesn't. Configuring qmail to clean up injected mail isn't hard, but depending on your setup, there are several possible ways to handle it. The new-inject package contains two programs: new-inject, which is a replacement for qmail-inject, and ofmipd (Old Fashioned Mail Injection Protocol Daemon), an SMTP daemon that includes the functions of new-inject. Although you can survive without new-inject, it's easy to install and I encourage you to use it. 6.2.1 Accepting and Cleaning Up Locally Injected MailThe usual ways to inject local mail are to feed it to qmail-inject or sendmail. Both do the cleanup automatically. (The qmail version of sendmail is a small wrapper that runs qmail-inject.) Because new-inject is almost completely upward compatible with qmail-inject, use it in place of qmail-inject: # cd /var/qmail/bin # mv qmail-inject qmail-inject.old # ln new-inject qmail-inject (I've saved the old qmail-inject as qmail-inject.old in case there turned out to be some application that needed exactly qmail-inject's features, but after a year, I have yet to need it.) Some programs inject local mail by opening an SMTP connection to the loopback address 127.0.0.1. If you've installed an SMTP listener following the instructions in Chapter 4, injecting mail via that route already works, but without any cleanup. There are two alternatives to clean up mail injected by SMTP: adjusting the setup of the regular SMTP server to detour locally injected mail through a cleanup program or setting up a separate SMTP daemon running ofmipd to receive locally originating mail. I discuss both options later in the chapter. The standard way to give a freshly created message to qmail for delivery is to use qmail-inject or its replacement new-inject. Both programs accept a message from the standard input, clean up and complete the headers without modifying the message body, construct the envelope information from the message and command arguments, and pass the result to qmail-queue for delivery. A combination of flags on the command line and environment variables give you some control over the header rewriting and control where it gets the envelope addresses. In the following discussion capitalized names refer to environment variables passed to qmail-inject or new-inject. The QMAILINJECT environment variable, if it exists, contains a string of letters from the set cfimrs that control the header rewriting, as described later. new-inject also accepts the uppercase letters FIMRS with the equivalent meanings and also accepts command-line --FIMRS flags. For testing purposes, the --n flag causes the rewritten message to be copied to standard output rather than queued. To show the envelope addresses, new-inject prefixes Envelope-Sender: and Envelope-Recipients: headers, while qmail-inject puts the sender address in a Return-Path: line but doesn't do anything with the recipient addresses. 6.2.1.1 Setting the envelope addressesLike sendmail, qmail-inject and new-inject can take the recipient addresses from the command line, from the message itself, or both. In the absence of any flags or with the --A flag, they deliver the message to the addresses on the command line if there are any, otherwise to the addresses in the To:, Cc:, Bcc:, and Apparently-To: (a sendmail-ism). new-inject uses Envelope-Recipients: line(s), if any exist, in preference to those headers. The --a flag says to use only command-line addresses, --h says to use only the header recipients, and --H says to use both. All addresses are rewritten as described in Section 6.2.1.3. The envelope sender address is taken from the --f flag if present. Otherwise, unless the environment flag "s" is set, it uses Envelope-Sender: (new-inject only) or Return-Path:. If those headers aren't present, the user part of the sender is taken from QMAILSUSER, QMAILUSER, MAILUSER, USER, or LOGNAME. The host part is taken from QMAILSHOST, QMAILHOST, or MAILHOST, or if none of those are set, the defaulthost control file. The environment flags "m" and "r" handle Variable Envelope Return Paths (VERP), a way to encode information about the message and its sender in the envelope return address to aid bounce processing. (VERP is discussed at length in Chapter 14.) If environment flag "m" is set, it appends a dash, the time in seconds, a dot, and the process ID as a per-message VERP. If environment flag "r" is set, it rewrites the sender address for the per-recipient VERP (described in Chapter 14). Either or both kinds of VERP can be present; for example, if the sender fred@example.com might be turned into fred-1059105280.24559-@example.com-@[ ]. Note that neither kind of VERP is done if the sender is set explicitly with --f; in that case it's up to you to put whatever you want into the sender string. 6.2.1.2 Header rewritingBoth qmail-inject and new-inject rewrite most message headers:
6.2.1.3 Address rewritingAddresses in the message headers are rewritten into a standard form. (Envelope addresses aren't rewritten, other than with the VERP options discussed earlier. If the envelope recipients are taken from the headers, it uses the rewritten versions.) The rewriting involves adding or completing the domain. Qmail's rewriting rules work best in an environment with multiple subdomains, such as a university where each department has its own subdomain (so fred@alchemy.bigu.edu and fred@phrenology.bigu.edu are different addresses, and on-campus users would likely abbreviate them as fred@alchemy and fred@phrenology). If an address has no host part at all, it adds a default hostname from QMAILDEFAULTHOST, or the contents of defaulthost or me. If the host part (whether it came from the previous step or was already present) contains no dot, it adds a dot and QMAILDEFAULTDOMAIN, or the contents of defaultdomain or me. If the host part ends with a plus sign, it changes the plus to a dot and adds QMAILPLUSDOMAIN, or the contents of plusdomain or me. In the usual case of "flat" addressing where all the addresses are in the second or third-level domain, both defaulthost and defaultdomain should contain that domain. In the aforementioned campus example, defaulthost should contain the name of the local subdomain (such as alchemy.bigu.edu), and defaultdomain should contain the main domain (such as bigu.edu) so that short addresses like fred@alchemy and fred@phrenology work. Plus addresses are for the more esoteric situation where there are multicomponent subaddresses, so a user can type fred@lead.alchemy+ and have that turn into fred@lead.alchemy.bigu.edu. new-inject has a more elaborate rewriting system controlled by patterns from rewrite (or if it exists, the file named by QMAILREWRITE.) See the rewriting(5) manpage for details. I don't recommend doing more elaborate rewriting, because that makes the addresses your users type into their MTAs different from the ones that the rest of the world uses, causing great confusion when they tell their friends to write to jerry@boam and it doesn't work because that address is locally rewritten into jerry@bo.am.bigcorp.com. However, rewriting is useful to compensate for users who insist on writing to stevec@aol when they mean stevec@aol.com. 6.2.2 Passing in Large Numbers of AddressesThe simplest way to send mail to a list of addresses is to put all the addresses in a file, and then either directly or, more likely, via a mailing list manager (such as ezmlm, majordomo, or mailman) type: new-inject -a $(cat mylist) << EOF To: mylist Subject: Free beer Look behind the coffee machine at 5 PM EOF This works as long as the list of addresses remains small enough to fit on a command line. The To: address in the message, which is normally the address of the list, is ignored for delivery purposes. But what happens when the list doesn't fit on a command line? A typical command-line limit is 20 K, which only fits a thousand 20-character addresses not a very big list. The usual way to get around the command-line limit is to queue the message directly, either by running qmail-queue or by connecting to the local port 25 SMTP daemon to send the mail. They both work, but they have the disadvantage of doing no header cleanup. Can we run new-inject and give it thousands of addresses? Yes. The obvious approach is to put all the addresses on Bcc: lines, because they're normally copied into the envelope and deleted. But the problem is that addresses on the To: and Cc: lines are copied into the envelope as well. The To: address is generally the address of the list itself, so this is a fairly efficient route to a mail loop.[1] Instead, put the addresses into Envelope-Recipients: headers at the top of the message, either one huge line with addresses separated by commas (like all parts of qmail, it allocates line buffers to be as big as they need to be so there's no limit on line length) or in multiple header lines. Either way, all of the recipients will be extracted from those headers, and then the rest of the message will be cleaned up and sent on its way to all the recipients.
|