mailbox - zmailer local delivery transport agent
mailbox [ -c channel ] [ -h localpart ] [ -l logfile ] [ -8abDCHPrSVX ]
mailbox is a ZMailer transport agent which is usually only run by the scheduler(8) program to deliver mail to local user mailbox files. The mailbox program must be run with root privileges and invoked with the same current directory as the scheduler, namely POSTOFFICE/transport.
Recipient addresses are processed as follows:
- Strip doublequotes around the address, if any. |
- Strip prefixing backslashes, if any. |
- If the address starts with a '|', the rest of the recipient address string is interpreted as a shell command to be run. - If the address starts with a '/', the recipient address is a filename to append the message to. - Otherwise the recipient address must be a local user id. - If user is not found, and the first character of the address is a capital letter, the entire address is folded to lowercase and the user lookup is retried. |
If delivering to a user mailbox (MAILBOX/userid) which doesn't exist, mailbox will try to create it. If the MAILBOX directory is mounted from a remote system this will succeed if the directory is groupwritable.
Some sanity checks are done on deliveries to files and mailboxes:
- The file being delivered to must have 1 link only, and must be either /dev/null or a regular file. - The file lock must be held. (See below for a chapter about locks.) |
There is a further sanity check on mailbox deliveries, namely if the mailbox is not empty the mailbox program will enforce 2 newlines as a separator before the message to be delivered. This guarantees that User Agents, like Mail(1), can find the abouttobe delivered message even if the current contents of the mailbox is corrupt.
When delivering to a process (by starting a Bourne shell to execute a specified command line), the environment is set up to contain several variables which are listed below at the ``Subprogram Environment Variables'' section. The SIGINT and SIGHUP signals are ignored, but SIGTERM is treated normally. If the process dumps core, it will be retried later. Subprocess exit codes are interpreted according to <sysexits.h> codes, and of those EX_NOPERM, EX_UNAVAILABLE, EX_NOHOST, EX_NOUSER, and EX_DATAERR are treated as permanent errors, all others are treated as temporary failures.
The actual data delivered to a file, mailbox, or process, is identical. It consists of the concationation of a UUCP style separator line, the message header specified in the message control file, and the message body from the original message file. The separator line starts with "From " and is followed by the sender address and a timestamp.
After all deliveries and just before exiting, the mailbox process will poke comsat(8C) in case recipients have turned on biff(1). The program may be compiled to look in the rwho files on the system for recipient names logged onto neighbouring hosts, in which case the comsat on the remote host will be poked. Even if this compiletime option is enabled, this will only be done for users that have a .rbiff file in their home directory. (Unless an 'DRBIFF_ALWAYS' compile option is used.)
-c channel -h "localpart" |
specifies which channel name should be keyed on. The default is local. specifies which of the possible multiple recipients is to be picked this time. Default is "none", which selects all local channel recipients, however when the routing is done with scripts storing some tokens (other than "-") into the "host"part, it is possible to process "hostwise", i.e. so that each user has his/her own lockstate, and not |
just everybody hang on the same lock(s).. |
-l logfile |
preexisting mailbox size in bytes, number of bytes appended, and the file name or command line delivered to. |
-V -a |
prints a version message and exits. the access time on mailbox files is, by default, preserved across delivery, so that programs such as login(1) can determine if new mail has arrived. This option disables the above action. |
|
-b -r -8 |
disables biff notification. disables remote biff notification (if supported). enables MIMEQPdecoder to decode incoming MIMEemail with QuotedPrintable encoded characters. |
|
-M |
enables the creation of MMDFstyle mailfolder in the incoming mail folder. The default is "classic" UNIXstyle folder. |
|
-C |
Canonify username by using internally version of username received in pw_name field of the getpwnam() call result. |
|
-D[D] |
For a user with is abcdef, one -D will place the mailbox file into directory $MAILBOX/a/abcdef. With -DD the mailbox file will be placed into directory: $MAILBOX/a/b/abcdef. |
|
-P[P] |
This uses much of similar method as -D[D] option, but directory names are derived from much more smoothly distributing hash function over user names, namely: pjwhash32(). With one -P, the calculated hash value is used by formula: 'A'+(hash % 26) to produce one midlevel directory. With -PP the formula is more complex: upper directory uses formula: 'A' + (hash / 26) % 26 and lower uses formula: 'A'+(hash % 26) The result of these -P[P] derived directory paths is something like: $MAILBOX/X/username or $MAILBOX/Y/X/username |
|
-X[X] |
This is similar to -P[P] option, but used hash function is crc32(). Resulting distribution is slightly different, and in fact quite smooth. |
|
-S |
This option enables ``ReturnReceiptTo:'' message header recognition and processing along with sending receipt to given address. (Newer sendmails don't anymore support this facility per default..) |
This program reads in processable file names relative to the current working directory of the scheduler (namely: $POSTIOFFICE/transport/). Optionally on the same line the scheduler may tell which host is to be looked for from the recipients of the message.
relativespoolpath [ <TAB> hostname ] |
This program produces diagnostic output on the standard output. Normal diagnostic output is of the form:
id/offset<TAB>notifydata<TAB>status message |
where id is the inode number of the message file, offset is a byte offset within its control file where the address being reported on is kept, status is one of ok, error, or deferred, and the message is descriptive text associated with the report. The text is terminated by a linefeed. Any other format (as might be produced by subprocesses) is passed to standard output for logging in the scheduler log.
The exit status is a code from <sysexits.h>.
Locking scheme used at the system is configurable at the runtime, and has separate parameters for mailboxes, and files. The data is configurable with zenv variable
MBOXLOCKS at which following characters have meanins:
`:' |
Separates mailbox locks, and filelocks at the string. The left side has mailbox locks, and the right side has locks for other regular files. (Files with explicit paths defined.) |
|
`.' |
For mailboxes only: Does ``dotlock'' (userid.lock), or (at Sun Solaris) maillock() mechanism. |
|
`F' |
If the system has flock() system call, uses it to lock the entire file. (Ignored at systems without flock()!) |
|
`L' |
If the system has lockf() system call, uses it to lock the entire file. (Ignored at systems without lockf()!) |
Locks are acquired in the same order as the key characters are listed.
Default for the lockf() capable systems is:
You can choose insane combinations of lock mechanisms, which at some systems cause locks to fail always, like at Linux2.0 series where program must not use both lockf() and flock() locks.
It is extremely important, that selected locking methods are same throughout the system at all programs trying to acquire locks on mail spools.
The default location for user mailbox files varies per systems, but usually it is one of: /var/mail, /var/spool/mail, This may be modified by setting the variable MAILBOX in /etc/zmailer.conf to the directory containing user mailbox files, for example /usr/spool/mail. This is best done in the ZMailer SiteConfig file.
Variable MBOXLOCKS is used to define locking schemes used for mailbox spool files, and separately for other regular files.
Like all parts of the ZMailer, the mailbox chooses to err into overtly cautious side. In case of pipes being run under the mailbox, the program in pipe is started thru /bin/sh with severely sanitized environment variables, and with only file descriptors STDIN, STDOUT, and STDERR. Programs are refused from running, if address analysis has found suspicuous data; external messages can't directly run programs, nor those addresses that have had a security breach detected during .forward, or other aliasing analysis. (Same applies also with writing into explicitly named files.)
The pipe subprogram is run with userid it gets thru the address privilege analysis during message routing, and it gets the groupid thru lookup of: getpwuid(uid). That is, if you have multiple usernames with same uid, there are no guarantees as to which of them is used for the gid entry.
The pipe subprogram is started without use of /bin/sh command line interpreter (i.e. "system()" call), when the command line begins with slash, and does not contain characters: `$' and '>'. If any of those rules is not fulfilled, the subprogram is started with ``/bin/sh c "$cmdlinestr"'' call. This allows running pipes with carefully formed parameters, when the mailbox program is running inside shellless chroot environment.
The mailbox sets following environment variables for the subprograms it runs in the pipes:
HOME |
The homedirectory path is taken from abovementioned getpwuid() lookup. |
|
USER SENDER |
Likewise the textual username. is the incoming "MAIL FROM:<..>" address without brackets. For an incoming error message, value "<>" is used. |
|
ORCPT |
when present, is the XTEXT encoded ORCPT value received at the message injection into this system. See RFC 1891 for details. |
|
ENVID |
when present, is the XTEXT encoded ENVID value received at the message injection into this system. See RFC 1891 for details. |
ZCONFIG |
is the location of the ZMailer ZENV file. |
|
MSGSPOOLID |
Is the message spoolid in the ZMailer; subprograms may use this info in cooperation with ZMailer to e.g. syslog(3) what they have done to the arrived message. |
|
MESSAGEID |
Is the RFC 822 "MessageID:" header data as possibly copied into the control file; another item to support syslog(3) at programs. |
|
MAILBIN MAILSHARE PATH |
is the value from ZENV. is the value from ZENV. is the value from ZENV, or "/usr/bin:/bin:/usr/ucb" in case no ZENV value is available. |
|
SHELL IFS TZ |
is constant value: "/bin/sh". is constant value: " tn". is value from scheduler's environment variables via normal environment inheritance rules. Supposedly that of systemwide timezone setting. Available to subprogram only if set when the mailbox was started. |
/etc/zmailer.conf
/var/spool/postoffice (POSTOFFICE)
/var/mail (MAILBOX)
scheduler(8), comsat(8C), biff(1), flock(2), Mail(1), mboxpath(1)
This program authored and copyright by:
Rayan Zachariassen <rayan@cs.toronto.edu>
Extensive modifications by:
Matti Aarnio <mea@nic.funet.fi>