Home | History | Annotate | Line # | Download | only in local
      1 /*	$NetBSD: local.c,v 1.6 2026/05/09 18:49:17 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	local 8
      6 /* SUMMARY
      7 /*	Postfix local mail delivery
      8 /* SYNOPSIS
      9 /*	\fBlocal\fR [generic Postfix daemon options]
     10 /* DESCRIPTION
     11 /*	The \fBlocal\fR(8) daemon processes delivery requests from the
     12 /*	Postfix queue manager to deliver mail to local recipients.
     13 /*	Each delivery request specifies a queue file, a sender address,
     14 /*	a domain or host to deliver to, and one or more recipients.
     15 /*	This program expects to be run from the \fBmaster\fR(8) process
     16 /*	manager.
     17 /*
     18 /*	The \fBlocal\fR(8) daemon updates queue files and marks recipients
     19 /*	as finished, or it informs the queue manager that delivery should
     20 /*	be tried again at a later time. Delivery status reports are sent
     21 /*	to the \fBbounce\fR(8), \fBdefer\fR(8) or \fBtrace\fR(8) daemon as
     22 /*	appropriate.
     23 /* CASE FOLDING
     24 /* .ad
     25 /* .fi
     26 /*	All delivery decisions are made using the bare recipient
     27 /*	name (i.e. the address localpart), folded to lower case.
     28 /*	See also under ADDRESS EXTENSION below for a few exceptions.
     29 /* SYSTEM-WIDE AND USER-LEVEL ALIASING
     30 /* .ad
     31 /* .fi
     32 /*	The system administrator can set up one or more system-wide
     33 /*	\fBsendmail\fR-style alias databases.
     34 /*	Users can have \fBsendmail\fR-style ~/.\fBforward\fR files.
     35 /*	Mail for \fIname\fR is delivered to the alias \fIname\fR, to
     36 /*	destinations in ~\fIname\fR/.\fBforward\fR, to the mailbox owned
     37 /*	by the user \fIname\fR, or it is sent back as undeliverable.
     38 /*
     39 /*	The system administrator can specify a comma/space separated list
     40 /*	of ~\fR/.\fBforward\fR like files through the \fBforward_path\fR
     41 /*	configuration parameter. Upon delivery, the local delivery agent
     42 /*	tries each pathname in the list until a file is found.
     43 /*
     44 /*	Delivery via ~/.\fBforward\fR files is done with the privileges
     45 /*	of the recipient.
     46 /*	Thus, ~/.\fBforward\fR like files must be readable by the
     47 /*	recipient, and their parent directory needs to have "execute"
     48 /*	permission for the recipient.
     49 /*
     50 /*	The \fBforward_path\fR parameter is subject to interpolation of
     51 /*	\fB$user\fR (recipient username), \fB$home\fR (recipient home
     52 /*	directory), \fB$shell\fR (recipient shell), \fB$recipient\fR
     53 /*	(complete recipient address), \fB$extension\fR (recipient address
     54 /*	extension), \fB$domain\fR (recipient domain), \fB$local\fR
     55 /*	(entire recipient address localpart) and
     56 /*	\fB$recipient_delimiter.\fR The forms \fI${name?value}\fR
     57 /*	and \fI${name?{value}}\fR (Postfix 3.0 and later) expand
     58 /*	conditionally to \fIvalue\fR when \fI$name\fR is defined,
     59 /*	and the forms \fI${name:value}\fR \fI${name:{value}}\fR
     60 /*	(Postfix 3.0 and later) expand conditionally to \fIvalue\fR
     61 /*	when \fI$name\fR is not defined.  The form
     62 /*	\fI${name?{value1}:{value2}}\fR (Postfix 3.0 and later)
     63 /*	expands conditionally to \fIvalue1\fR when \fI$name\fR is
     64 /*	defined, or \fIvalue2\fR otherwise. Characters that may
     65 /*	have special meaning to the shell or file system are replaced
     66 /*	with underscores. The list of acceptable characters is
     67 /*	specified with the \fBforward_expansion_filter\fR configuration
     68 /*	parameter.
     69 /*
     70 /*	An alias or ~/.\fBforward\fR file may list any combination of external
     71 /*	commands, destination file names, \fB:include:\fR directives, or
     72 /*	mail addresses.
     73 /*	See \fBaliases\fR(5) for a precise description. Each line in a
     74 /*	user's .\fBforward\fR file has the same syntax as the right-hand part
     75 /*	of an alias.
     76 /*
     77 /*	When an address is found in its own alias expansion, delivery is
     78 /*	made to the user instead. When a user is listed in the user's own
     79 /*	~/.\fBforward\fR file, delivery is made to the user's mailbox instead.
     80 /*	An empty ~/.\fBforward\fR file means do not forward mail.
     81 /*
     82 /*	In order to prevent the mail system from using up unreasonable
     83 /*	amounts of memory, input records read from \fB:include:\fR or from
     84 /*	~/.\fBforward\fR files are broken up into chunks of length
     85 /*	\fBline_length_limit\fR.
     86 /*
     87 /*	While expanding aliases, ~/.\fBforward\fR files, and so on, the
     88 /*	program attempts to avoid duplicate deliveries. The
     89 /*	\fBduplicate_filter_limit\fR configuration parameter limits the
     90 /*	number of remembered recipients.
     91 /* MAIL FORWARDING
     92 /* .ad
     93 /* .fi
     94 /*	For the sake of reliability, forwarded mail is re-submitted as
     95 /*	a new message, so that each recipient has a separate on-file
     96 /*	delivery status record.
     97 /*
     98 /*	In order to stop mail forwarding loops early, the software adds an
     99 /*	optional
    100 /*	\fBDelivered-To:\fR header with the final envelope recipient address. If
    101 /*	mail arrives for a recipient that is already listed in a
    102 /*	\fBDelivered-To:\fR header, the message is bounced.
    103 /* MAILBOX DELIVERY
    104 /* .ad
    105 /* .fi
    106 /*	The default per-user mailbox is a file in the UNIX mail spool
    107 /*	directory (\fB/var/mail/\fIuser\fR or \fB/var/spool/mail/\fIuser\fR);
    108 /*	the location can be specified with the \fBmail_spool_directory\fR
    109 /*	configuration parameter. Specify a name ending in \fB/\fR for
    110 /*	\fBqmail\fR-compatible \fBmaildir\fR delivery.
    111 /*
    112 /*	Alternatively, the per-user mailbox can be a file in the user's home
    113 /*	directory with a name specified via the \fBhome_mailbox\fR
    114 /*	configuration parameter. Specify a relative path name. Specify a name
    115 /*	ending in \fB/\fR for \fBqmail\fR-compatible \fBmaildir\fR delivery.
    116 /*
    117 /*	Mailbox delivery can be delegated to an external command specified
    118 /*	with the \fBmailbox_command_maps\fR and \fBmailbox_command\fR
    119 /*	configuration parameters. The command
    120 /*	executes with the privileges of the recipient user (exceptions:
    121 /*	secondary groups are not enabled; in case of delivery as root,
    122 /*	the command executes with the privileges of \fBdefault_privs\fR).
    123 /*
    124 /*	Mailbox delivery can be delegated to alternative message transports
    125 /*	specified in the \fBmaster.cf\fR file.
    126 /*	The \fBmailbox_transport_maps\fR and \fBmailbox_transport\fR
    127 /*	configuration parameters specify an optional
    128 /*	message transport that is to be used for all local recipients,
    129 /*	regardless of whether they are found in the UNIX passwd database.
    130 /*	The \fBfallback_transport_maps\fR and
    131 /*	\fBfallback_transport\fR parameters specify an optional
    132 /*	message transport
    133 /*	for recipients that are not found in the aliases(5) or UNIX
    134 /*	passwd database.
    135 /*
    136 /*	In the case of UNIX-style mailbox delivery,
    137 /*	the \fBlocal\fR(8) daemon prepends a "\fBFrom \fIsender time_stamp\fR"
    138 /*	envelope header to each message, prepends an
    139 /*	\fBX-Original-To:\fR header with the recipient address as given to
    140 /*	Postfix, prepends an
    141 /*	optional \fBDelivered-To:\fR header
    142 /*	with the final envelope recipient address, prepends a \fBReturn-Path:\fR
    143 /*	header with the envelope sender address, prepends a \fB>\fR character
    144 /*	to lines beginning with "\fBFrom \fR", and appends an empty line.
    145 /*	The mailbox is locked for exclusive access while delivery is in
    146 /*	progress. In case of problems, an attempt is made to truncate the
    147 /*	mailbox to its original length.
    148 /*
    149 /*	In the case of \fBmaildir\fR delivery, the local daemon prepends
    150 /*	an optional
    151 /*	\fBDelivered-To:\fR header with the final envelope recipient address,
    152 /*	prepends an
    153 /*	\fBX-Original-To:\fR header with the recipient address as given to
    154 /*	Postfix,
    155 /*	and prepends a \fBReturn-Path:\fR header with the envelope sender
    156 /*	address.
    157 /* EXTERNAL COMMAND DELIVERY
    158 /* .ad
    159 /* .fi
    160 /*	The \fBallow_mail_to_commands\fR configuration parameter restricts
    161 /*	delivery to external commands. The default setting (\fBalias,
    162 /*	forward\fR) forbids command destinations in \fB:include:\fR files.
    163 /*
    164 /*	Optionally, the process working directory is changed to the path
    165 /*	specified with \fBcommand_execution_directory\fR (Postfix 2.2 and
    166 /*	later). Failure to change directory causes mail to be deferred.
    167 /*
    168 /*	The \fBcommand_execution_directory\fR parameter value is subject
    169 /*	to interpolation of \fB$user\fR (recipient username),
    170 /*	\fB$home\fR (recipient home directory), \fB$shell\fR
    171 /*	(recipient shell), \fB$recipient\fR (complete recipient
    172 /*	address), \fB$extension\fR (recipient address extension),
    173 /*	\fB$domain\fR (recipient domain), \fB$local\fR (entire
    174 /*	recipient address localpart) and \fB$recipient_delimiter.\fR
    175 /*	The forms \fI${name?value}\fR and \fI${name?{value}}\fR
    176 /*	(Postfix 3.0 and later) expand conditionally to \fIvalue\fR
    177 /*	when \fI$name\fR is defined, and the forms \fI${name:value}\fR
    178 /*	and \fI${name:{value}}\fR (Postfix 3.0 and later) expand
    179 /*	conditionally to \fIvalue\fR when \fI$name\fR is not defined.
    180 /*	The form \fI${name?{value1}:{value2}}\fR (Postfix 3.0 and
    181 /*	later) expands conditionally to \fIvalue1\fR when \fI$name\fR
    182 /*	is defined, or \fIvalue2\fR otherwise. Characters that may
    183 /*	have special meaning to the shell or file system are replaced
    184 /*	with underscores. The list of acceptable characters
    185 /*	is specified with the \fBexecution_directory_expansion_filter\fR
    186 /*	configuration parameter.
    187 /*
    188 /*	The command is executed directly where possible. Assistance by the
    189 /*	shell (\fB/bin/sh\fR on UNIX systems) is used only when the command
    190 /*	contains shell magic characters, or when the command invokes a shell
    191 /*	built-in command.
    192 /*
    193 /*	A limited amount of command output (standard output and standard
    194 /*	error) is captured for inclusion with non-delivery status reports.
    195 /*	A command is forcibly terminated if it does not complete within
    196 /*	\fBcommand_time_limit\fR seconds.  Command exit status codes are
    197 /*	expected to follow the conventions defined in <\fBsysexits.h\fR>.
    198 /*	Exit status 0 means normal successful completion.
    199 /*
    200 /*	Postfix version 2.3 and later support RFC 3463-style enhanced
    201 /*	status codes.  If a command terminates with a non-zero exit
    202 /*	status, and the command output begins with an enhanced
    203 /*	status code, this status code takes precedence over the
    204 /*	non-zero exit status.
    205 /*
    206 /*	A limited amount of message context is exported via environment
    207 /*	variables. Characters that may have special meaning to the shell
    208 /*	are replaced with underscores.  The list of acceptable characters
    209 /*	is specified with the \fBcommand_expansion_filter\fR configuration
    210 /*	parameter.
    211 /* .IP \fBSHELL\fR
    212 /*	The envelope recipient user's login shell.
    213 /* .IP \fBHOME\fR
    214 /*	The envelope recipient user's home directory.
    215 /* .IP \fBUSER\fR
    216 /*	The bare envelope recipient name.
    217 /* .IP \fBEXTENSION\fR
    218 /*	The optional envelope recipient address extension.
    219 /* .IP \fBDOMAIN\fR
    220 /*	The envelope recipient address domain part.
    221 /* .IP \fBLOGNAME\fR
    222 /*	The bare envelope recipient name.
    223 /* .IP \fBLOCAL\fR
    224 /*	The entire envelope recipient address localpart (text to
    225 /*	the left of the rightmost @ character).
    226 /* .IP \fBORIGINAL_RECIPIENT\fR
    227 /*	The entire envelope recipient address, before any address
    228 /*	rewriting or aliasing (Postfix 2.5 and later).
    229 /* .IP \fBRECIPIENT\fR
    230 /*	The entire envelope recipient address.
    231 /* .IP \fBSENDER\fR
    232 /*	The entire envelope sender address.
    233 /* .IP \fBENVID\fR
    234 /*	The optional RFC 3461 envelope ID. Available as of Postfix
    235 /*	3.9.
    236 /* .PP
    237 /*	Additional remote client information is made available via
    238 /*	the following environment variables:
    239 /* .IP \fBCLIENT_ADDRESS\fR
    240 /*	Remote client network address. Available as of Postfix 2.2.
    241 /* .IP \fBCLIENT_HELO\fR
    242 /*	Remote client EHLO command parameter. Available as of Postfix 2.2.
    243 /* .IP \fBCLIENT_HOSTNAME\fR
    244 /*	Remote client hostname. Available as of Postfix 2.2.
    245 /* .IP \fBCLIENT_PROTOCOL\fR
    246 /*	Remote client protocol. Available as of Postfix 2.2.
    247 /* .IP \fBSASL_METHOD\fR
    248 /*	SASL authentication method specified in the
    249 /*	remote client AUTH command. Available as of Postfix 2.2.
    250 /* .IP \fBSASL_SENDER\fR
    251 /*	SASL sender address specified in the remote client MAIL
    252 /*	FROM command. Available as of Postfix 2.2.
    253 /* .IP \fBSASL_USERNAME\fR
    254 /*	SASL username specified in the remote client AUTH command.
    255 /*	Available as of Postfix 2.2.
    256 /* .PP
    257 /*	The \fBPATH\fR environment variable is always reset to a
    258 /*	system-dependent default path, and environment variables
    259 /*	whose names are blessed by the \fBexport_environment\fR
    260 /*	configuration parameter are exported unchanged.
    261 /*
    262 /*	The current working directory is the mail queue directory.
    263 /*
    264 /*	The \fBlocal\fR(8) daemon prepends a "\fBFrom \fIsender time_stamp\fR"
    265 /*	envelope header to each message, prepends an
    266 /*	\fBX-Original-To:\fR header with the recipient address as given to
    267 /*	Postfix, prepends an
    268 /*	optional \fBDelivered-To:\fR
    269 /*	header with the final recipient envelope address, prepends a
    270 /*	\fBReturn-Path:\fR header with the sender envelope address,
    271 /*	and appends no empty line.
    272 /* EXTERNAL FILE DELIVERY
    273 /* .ad
    274 /* .fi
    275 /*	The delivery format depends on the destination filename syntax.
    276 /*	The default is to use UNIX-style mailbox format.  Specify a name
    277 /*	ending in \fB/\fR for \fBqmail\fR-compatible \fBmaildir\fR delivery.
    278 /*
    279 /*	The \fBallow_mail_to_files\fR configuration parameter restricts
    280 /*	delivery to external files. The default setting (\fBalias,
    281 /*	forward\fR) forbids file destinations in \fB:include:\fR files.
    282 /*
    283 /*	In the case of UNIX-style mailbox delivery,
    284 /*	the \fBlocal\fR(8) daemon prepends a "\fBFrom \fIsender time_stamp\fR"
    285 /*	envelope header to each message, prepends an
    286 /*	\fBX-Original-To:\fR header with the recipient address as given to
    287 /*	Postfix, prepends an
    288 /*	optional \fBDelivered-To:\fR
    289 /*	header with the final recipient envelope address, prepends a \fB>\fR
    290 /*	character to lines beginning with "\fBFrom \fR", and appends an
    291 /*	empty line.
    292 /*	The envelope sender address is available in the \fBReturn-Path:\fR
    293 /*	header.
    294 /*	When the destination is a regular file, it is locked for exclusive
    295 /*	access while delivery is in progress. In case of problems, an attempt
    296 /*	is made to truncate a regular file to its original length.
    297 /*
    298 /*	In the case of \fBmaildir\fR delivery, the local daemon prepends
    299 /*	an optional
    300 /*	\fBDelivered-To:\fR header with the final envelope recipient address,
    301 /*	and prepends an
    302 /*	\fBX-Original-To:\fR header with the recipient address as given to
    303 /*	Postfix.
    304 /*	The envelope sender address is available in the \fBReturn-Path:\fR
    305 /*	header.
    306 /* ADDRESS EXTENSION
    307 /* .ad
    308 /* .fi
    309 /*	The optional \fBrecipient_delimiter\fR configuration parameter
    310 /*	specifies how to separate address extensions from local recipient
    311 /*	names.
    312 /*
    313 /*	For example, with "\fBrecipient_delimiter = +\fR", mail for
    314 /*	\fIname\fR+\fIfoo\fR is delivered to the alias \fIname\fR+\fIfoo\fR
    315 /*	or to the alias \fIname\fR, to the destinations listed in
    316 /*	~\fIname\fR/.\fBforward\fR+\fIfoo\fR or in ~\fIname\fR/.\fBforward\fR,
    317 /*	to the mailbox owned by the user \fIname\fR, or it is sent back as
    318 /*	undeliverable.
    319 /* DELIVERY RIGHTS
    320 /* .ad
    321 /* .fi
    322 /*	Deliveries to external files and external commands are made with
    323 /*	the rights of the receiving user on whose behalf the delivery is made.
    324 /*	In the absence of a user context, the \fBlocal\fR(8) daemon uses the
    325 /*	owner rights of the \fB:include:\fR file or alias database.
    326 /*	When those files are owned by the superuser, delivery is made with
    327 /*	the rights specified with the \fBdefault_privs\fR configuration
    328 /*	parameter.
    329 /* STANDARDS
    330 /*	RFC 822 (ARPA Internet Text Messages)
    331 /*	RFC 3463 (Enhanced status codes)
    332 /* DIAGNOSTICS
    333 /*	Problems and transactions are logged to \fBsyslogd\fR(8)
    334 /*	or \fBpostlogd\fR(8).
    335 /*	Corrupted message files are marked so that the queue
    336 /*	manager can move them to the \fBcorrupt\fR queue afterwards.
    337 /*
    338 /*	Depending on the setting of the \fBnotify_classes\fR parameter,
    339 /*	the postmaster is notified of bounces and of other trouble.
    340 /* SECURITY
    341 /* .ad
    342 /* .fi
    343 /*	The \fBlocal\fR(8) delivery agent needs a dual personality
    344 /*	1) to access the private Postfix queue and IPC mechanisms,
    345 /*	2) to impersonate the recipient and deliver to recipient-specified
    346 /*	files or commands. It is therefore security sensitive.
    347 /*
    348 /*	The \fBlocal\fR(8) delivery agent disallows regular expression
    349 /*	substitution of $1 etc. in \fBalias_maps\fR, because that
    350 /*	would open a security hole.
    351 /*
    352 /*	The \fBlocal\fR(8) delivery agent will silently ignore
    353 /*	requests to use the \fBproxymap\fR(8) server within
    354 /*	\fBalias_maps\fR. Instead it will open the table directly.
    355 /*	Before Postfix version 2.2, the \fBlocal\fR(8) delivery
    356 /*	agent will terminate with a fatal error.
    357 /* BUGS
    358 /*	For security reasons, the message delivery status of external commands
    359 /*	or of external files is never checkpointed to file. As a result,
    360 /*	the program may occasionally deliver more than once to a command or
    361 /*	external file. Better safe than sorry.
    362 /*
    363 /*	Mutually-recursive aliases or ~/.\fBforward\fR files are not detected
    364 /*	early.  The resulting mail forwarding loop is broken by the use of the
    365 /*	\fBDelivered-To:\fR message header.
    366 /* CONFIGURATION PARAMETERS
    367 /* .ad
    368 /* .fi
    369 /*	Changes to \fBmain.cf\fR are picked up automatically, as \fBlocal\fR(8)
    370 /*	processes run for only a limited amount of time. Use the command
    371 /*	"\fBpostfix reload\fR" to speed up a change.
    372 /*
    373 /*	The text below provides only a parameter summary. See
    374 /*	\fBpostconf\fR(5) for more details including examples.
    375 /* COMPATIBILITY CONTROLS
    376 /* .ad
    377 /* .fi
    378 /* .IP "\fBbiff (yes)\fR"
    379 /*	Whether or not to use the local biff service.
    380 /* .IP "\fBexpand_owner_alias (no)\fR"
    381 /*	When delivering to an alias "\fIaliasname\fR" that has an
    382 /*	"owner-\fIaliasname\fR" companion alias, set the envelope sender
    383 /*	address to the expansion of the "owner-\fIaliasname\fR" alias.
    384 /* .IP "\fBowner_request_special (yes)\fR"
    385 /*	Enable special treatment for owner-\fIlistname\fR entries in the
    386 /*	\fBaliases\fR(5) file, and don't split owner-\fIlistname\fR and
    387 /*	\fIlistname\fR-request address localparts when the recipient_delimiter
    388 /*	is set to "-".
    389 /* .IP "\fBsun_mailtool_compatibility (no)\fR"
    390 /*	Obsolete SUN mailtool compatibility feature.
    391 /* .PP
    392 /*	Available in Postfix version 2.3 and later:
    393 /* .IP "\fBfrozen_delivered_to (yes)\fR"
    394 /*	Update the \fBlocal\fR(8) delivery agent's idea of the Delivered-To:
    395 /*	address (see prepend_delivered_header) only once, at the start of
    396 /*	a delivery attempt; do not update the Delivered-To: address while
    397 /*	expanding aliases or .forward files.
    398 /* .PP
    399 /*	Available in Postfix version 2.5.3 and later:
    400 /* .IP "\fBstrict_mailbox_ownership (yes)\fR"
    401 /*	Defer delivery when a mailbox file is not owned by its recipient.
    402 /* .IP "\fBreset_owner_alias (no)\fR"
    403 /*	Reset the \fBlocal\fR(8) delivery agent's idea of the owner-alias
    404 /*	attribute, when delivering mail to a child alias that does not have
    405 /*	its own owner alias.
    406 /* .PP
    407 /*	Available in Postfix version 3.0 and later:
    408 /* .IP "\fBlocal_delivery_status_filter ($default_delivery_status_filter)\fR"
    409 /*	Optional filter for the \fBlocal\fR(8) delivery agent to change the
    410 /*	status code or explanatory text of successful or unsuccessful
    411 /*	deliveries.
    412 /* DELIVERY METHOD CONTROLS
    413 /* .ad
    414 /* .fi
    415 /*	The precedence of \fBlocal\fR(8) delivery methods from high to low is:
    416 /*	aliases, .forward files, mailbox_transport_maps,
    417 /*	mailbox_transport, mailbox_command_maps, mailbox_command,
    418 /*	home_mailbox, mail_spool_directory, fallback_transport_maps,
    419 /*	fallback_transport, and luser_relay.
    420 /* .IP "\fBalias_maps (see 'postconf -d' output)\fR"
    421 /*	Optional lookup tables that are searched only with an email address
    422 /*	localpart (no domain) and that apply only to \fBlocal\fR(8) recipients;
    423 /*	this is unlike virtual_alias_maps that are often searched with a
    424 /*	full email address (including domain) and that apply to all recipients:
    425 /*	\fBlocal\fR(8), virtual, and remote.
    426 /* .IP "\fBforward_path (see 'postconf -d' output)\fR"
    427 /*	The \fBlocal\fR(8) delivery agent search list for finding a .forward
    428 /*	file with user-specified delivery methods.
    429 /* .IP "\fBmailbox_transport_maps (empty)\fR"
    430 /*	Optional lookup tables with per-recipient message delivery
    431 /*	transports to use for \fBlocal\fR(8) mailbox delivery, whether or not the
    432 /*	recipients are found in the UNIX passwd database.
    433 /* .IP "\fBmailbox_transport (empty)\fR"
    434 /*	Optional message delivery transport that the \fBlocal\fR(8) delivery
    435 /*	agent should use for mailbox delivery to all local recipients,
    436 /*	whether or not they are found in the UNIX passwd database.
    437 /* .IP "\fBmailbox_command_maps (empty)\fR"
    438 /*	Optional lookup tables with per-recipient external commands to use
    439 /*	for \fBlocal\fR(8) mailbox delivery.
    440 /* .IP "\fBmailbox_command (empty)\fR"
    441 /*	Optional external command that the \fBlocal\fR(8) delivery agent should
    442 /*	use for mailbox delivery.
    443 /* .IP "\fBhome_mailbox (empty)\fR"
    444 /*	Optional pathname of a mailbox file relative to a \fBlocal\fR(8) user's
    445 /*	home directory.
    446 /* .IP "\fBmail_spool_directory (see 'postconf -d' output)\fR"
    447 /*	The directory where \fBlocal\fR(8) UNIX-style mailboxes are kept.
    448 /* .IP "\fBfallback_transport_maps (empty)\fR"
    449 /*	Optional lookup tables with per-recipient message delivery
    450 /*	transports for recipients that the \fBlocal\fR(8) delivery agent could
    451 /*	not find in the \fBaliases\fR(5) or UNIX password database.
    452 /* .IP "\fBfallback_transport (empty)\fR"
    453 /*	Optional message delivery transport that the \fBlocal\fR(8) delivery
    454 /*	agent should use for names that are not found in the \fBaliases\fR(5)
    455 /*	or UNIX password database.
    456 /* .IP "\fBluser_relay (empty)\fR"
    457 /*	Optional catch-all destination for unknown \fBlocal\fR(8) recipients.
    458 /* .PP
    459 /*	Available in Postfix version 2.2 and later:
    460 /* .IP "\fBcommand_execution_directory (empty)\fR"
    461 /*	The \fBlocal\fR(8) delivery agent working directory for delivery to
    462 /*	external commands.
    463 /* MAILBOX LOCKING CONTROLS
    464 /* .ad
    465 /* .fi
    466 /* .IP "\fBdeliver_lock_attempts (20)\fR"
    467 /*	The maximal number of attempts to acquire an exclusive lock on a
    468 /*	mailbox file or \fBbounce\fR(8) logfile.
    469 /* .IP "\fBdeliver_lock_delay (1s)\fR"
    470 /*	The time between attempts to acquire an exclusive lock on a mailbox
    471 /*	file or \fBbounce\fR(8) logfile.
    472 /* .IP "\fBstale_lock_time (500s)\fR"
    473 /*	The time after which a stale exclusive mailbox lockfile is removed.
    474 /* .IP "\fBmailbox_delivery_lock (see 'postconf -d' output)\fR"
    475 /*	How to lock a UNIX-style \fBlocal\fR(8) mailbox before attempting delivery.
    476 /* RESOURCE AND RATE CONTROLS
    477 /* .ad
    478 /* .fi
    479 /* .IP "\fBcommand_time_limit (1000s)\fR"
    480 /*	Time limit for delivery to external commands.
    481 /* .IP "\fBduplicate_filter_limit (1000)\fR"
    482 /*	The maximal number of addresses remembered by the address
    483 /*	duplicate filter for \fBaliases\fR(5) or \fBvirtual\fR(5) alias expansion, or
    484 /*	for \fBshowq\fR(8) queue displays.
    485 /* .IP "\fBmailbox_size_limit (51200000)\fR"
    486 /*	The maximal size of any \fBlocal\fR(8) individual mailbox or maildir
    487 /*	file, or zero (no limit).
    488 /* .PP
    489 /*	Implemented in the qmgr(8) daemon:
    490 /* .IP "\fBlocal_destination_concurrency_limit (2)\fR"
    491 /*	The maximal number of parallel deliveries via the local mail
    492 /*	delivery transport to the same recipient (when
    493 /*	"local_destination_recipient_limit = 1") or the maximal number of
    494 /*	parallel deliveries to the same local domain (when
    495 /*	"local_destination_recipient_limit > 1").
    496 /* .IP "\fBlocal_destination_recipient_limit (1)\fR"
    497 /*	The maximal number of recipients per message delivery via the
    498 /*	local mail delivery transport.
    499 /* SECURITY CONTROLS
    500 /* .ad
    501 /* .fi
    502 /* .IP "\fBallow_mail_to_commands (alias, forward)\fR"
    503 /*	Restrict \fBlocal\fR(8) mail delivery to external commands.
    504 /* .IP "\fBallow_mail_to_files (alias, forward)\fR"
    505 /*	Restrict \fBlocal\fR(8) mail delivery to external files.
    506 /* .IP "\fBcommand_expansion_filter (see 'postconf -d' output)\fR"
    507 /*	Restrict the characters that the \fBlocal\fR(8) delivery agent allows in
    508 /*	$name expansions of $mailbox_command and $command_execution_directory.
    509 /* .IP "\fBdefault_privs (nobody)\fR"
    510 /*	The default rights used by the \fBlocal\fR(8) delivery agent for delivery
    511 /*	to an external file or command.
    512 /* .IP "\fBforward_expansion_filter (see 'postconf -d' output)\fR"
    513 /*	Restrict the characters that the \fBlocal\fR(8) delivery agent allows in
    514 /*	$name expansions of $forward_path.
    515 /* .PP
    516 /*	Available in Postfix version 2.2 and later:
    517 /* .IP "\fBexecution_directory_expansion_filter (see 'postconf -d' output)\fR"
    518 /*	Restrict the characters that the \fBlocal\fR(8) delivery agent allows
    519 /*	in $name expansions of $command_execution_directory.
    520 /* .PP
    521 /*	Available in Postfix version 2.5.3 and later:
    522 /* .IP "\fBstrict_mailbox_ownership (yes)\fR"
    523 /*	Defer delivery when a mailbox file is not owned by its recipient.
    524 /* MISCELLANEOUS CONTROLS
    525 /* .ad
    526 /* .fi
    527 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
    528 /*	The default location of the Postfix main.cf and master.cf
    529 /*	configuration files.
    530 /* .IP "\fBdaemon_timeout (18000s)\fR"
    531 /*	How much time a Postfix daemon process may take to handle a
    532 /*	request before it is terminated by a built-in watchdog timer.
    533 /* .IP "\fBdelay_logging_resolution_limit (2)\fR"
    534 /*	The maximal number of digits after the decimal point when logging
    535 /*	delay values.
    536 /* .IP "\fBexport_environment (see 'postconf -d' output)\fR"
    537 /*	The list of environment variables that a Postfix process will export
    538 /*	to non-Postfix processes.
    539 /* .IP "\fBipc_timeout (3600s)\fR"
    540 /*	The time limit for sending or receiving information over an internal
    541 /*	communication channel.
    542 /* .IP "\fBlocal_command_shell (empty)\fR"
    543 /*	Optional shell program for \fBlocal\fR(8) delivery to non-Postfix commands.
    544 /* .IP "\fBmax_idle (100s)\fR"
    545 /*	The maximum amount of time that an idle Postfix daemon process waits
    546 /*	for an incoming connection before terminating voluntarily.
    547 /* .IP "\fBmax_use (100)\fR"
    548 /*	The maximal number of incoming connections that a Postfix daemon
    549 /*	process will service before terminating voluntarily.
    550 /* .IP "\fBprepend_delivered_header (command, file, forward)\fR"
    551 /*	The message delivery contexts where the Postfix \fBlocal\fR(8) delivery
    552 /*	agent prepends a Delivered-To:  message header with the address
    553 /*	that the mail was delivered to.
    554 /* .IP "\fBprocess_id (read-only)\fR"
    555 /*	The process ID of a Postfix command or daemon process.
    556 /* .IP "\fBprocess_name (read-only)\fR"
    557 /*	The process name of a Postfix command or daemon process.
    558 /* .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR"
    559 /*	What address lookup tables copy an address extension from the lookup
    560 /*	key to the lookup result.
    561 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
    562 /*	The location of the Postfix top-level queue directory.
    563 /* .IP "\fBrecipient_delimiter (empty)\fR"
    564 /*	The set of characters that can separate an email address
    565 /*	localpart, user name, or a .forward file name from its extension.
    566 /* .IP "\fBrequire_home_directory (no)\fR"
    567 /*	Require that a \fBlocal\fR(8) recipient's home directory exists
    568 /*	before mail delivery is attempted.
    569 /* .IP "\fBsyslog_facility (mail)\fR"
    570 /*	The syslog facility of Postfix logging.
    571 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
    572 /*	A prefix that is prepended to the process name in syslog
    573 /*	records, so that, for example, "smtpd" becomes "prefix/smtpd".
    574 /* .PP
    575 /*	Available in Postfix version 3.3 and later:
    576 /* .IP "\fBenable_original_recipient (yes)\fR"
    577 /*	Enable support for the original recipient address after an
    578 /*	address is rewritten to a different address (for example with
    579 /*	aliasing or with canonical mapping).
    580 /* .IP "\fBservice_name (read-only)\fR"
    581 /*	The master.cf service name of a Postfix daemon process.
    582 /* .PP
    583 /*	Available in Postfix 3.5 and later:
    584 /* .IP "\fBinfo_log_address_format (external)\fR"
    585 /*	The email address form that will be used in non-debug logging
    586 /*	(info, warning, etc.).
    587 /* FILES
    588 /*	The following are examples; details differ between systems.
    589 /*	$HOME/.forward, per-user aliasing
    590 /*	/etc/aliases, system-wide alias database
    591 /*	/var/spool/mail, system mailboxes
    592 /* SEE ALSO
    593 /*	qmgr(8), queue manager
    594 /*	bounce(8), delivery status reports
    595 /*	newaliases(1), create/update alias database
    596 /*	postalias(1), create/update alias database
    597 /*	aliases(5), format of alias database
    598 /*	postconf(5), configuration parameters
    599 /*	master(5), generic daemon options
    600 /*	postlogd(8), Postfix logging
    601 /*	syslogd(8), system logging
    602 /* LICENSE
    603 /* .ad
    604 /* .fi
    605 /*	The Secure Mailer license must be distributed with this software.
    606 /* HISTORY
    607 /* .ad
    608 /* .fi
    609 /*	The \fBDelivered-To:\fR message header appears in the \fBqmail\fR
    610 /*	system by Daniel Bernstein.
    611 /*
    612 /*	The \fImaildir\fR structure appears in the \fBqmail\fR system
    613 /*	by Daniel Bernstein.
    614 /* AUTHOR(S)
    615 /*	Wietse Venema
    616 /*	IBM T.J. Watson Research
    617 /*	P.O. Box 704
    618 /*	Yorktown Heights, NY 10598, USA
    619 /*
    620 /*	Wietse Venema
    621 /*	Google, Inc.
    622 /*	111 8th Avenue
    623 /*	New York, NY 10011, USA
    624 /*
    625 /*	Wietse Venema
    626 /*	porcupine.org
    627 /*--*/
    628 
    629 /* System library. */
    630 
    631 #include <sys_defs.h>
    632 #include <unistd.h>
    633 #include <stdlib.h>
    634 #include <string.h>
    635 #include <fcntl.h>
    636 #ifdef USE_PATHS_H
    637 #include <paths.h>
    638 #endif
    639 
    640 /* Utility library. */
    641 
    642 #include <msg.h>
    643 #include <mymalloc.h>
    644 #include <htable.h>
    645 #include <vstring.h>
    646 #include <vstream.h>
    647 #include <iostuff.h>
    648 #include <name_mask.h>
    649 #include <set_eugid.h>
    650 #include <dict.h>
    651 
    652 /* Global library. */
    653 
    654 #include <recipient_list.h>
    655 #include <deliver_request.h>
    656 #include <deliver_completed.h>
    657 #include <mail_params.h>
    658 #include <mail_addr.h>
    659 #include <mail_conf.h>
    660 #include <been_here.h>
    661 #include <mail_params.h>
    662 #include <mail_version.h>
    663 #include <ext_prop.h>
    664 #include <maps.h>
    665 #include <flush_clnt.h>
    666 
    667 /* Single server skeleton. */
    668 
    669 #include <mail_server.h>
    670 
    671 /* Application-specific. */
    672 
    673 #include "local.h"
    674 
    675  /*
    676   * Tunable parameters.
    677   */
    678 char   *var_allow_commands;
    679 char   *var_allow_files;
    680 char   *var_alias_maps;
    681 int     var_dup_filter_limit;
    682 int     var_command_maxtime;		/* You can now leave this here. */
    683 char   *var_home_mailbox;
    684 char   *var_mailbox_command;
    685 char   *var_mailbox_cmd_maps;
    686 char   *var_rcpt_fdelim;
    687 char   *var_local_cmd_shell;
    688 char   *var_luser_relay;
    689 bool    var_biff;
    690 char   *var_mail_spool_dir;
    691 char   *var_mailbox_transport;
    692 char   *var_mbox_transp_maps;
    693 char   *var_fallback_transport;
    694 char   *var_fbck_transp_maps;
    695 char   *var_exec_directory;
    696 char   *var_exec_exp_filter;
    697 char   *var_forward_path;
    698 char   *var_cmd_exp_filter;
    699 char   *var_fwd_exp_filter;
    700 char   *var_prop_extension;
    701 bool    var_exp_own_alias;
    702 char   *var_deliver_hdr;
    703 bool    var_stat_home_dir;
    704 bool    var_mailtool_compat;
    705 char   *var_mailbox_lock;
    706 long    var_mailbox_limit;
    707 bool    var_frozen_delivered;
    708 bool    var_reset_owner_attr;
    709 bool    var_strict_mbox_owner;
    710 
    711 int     local_cmd_deliver_mask;
    712 int     local_file_deliver_mask;
    713 int     local_ext_prop_mask;
    714 int     local_deliver_hdr_mask;
    715 int     local_mbox_lock_mask;
    716 MAPS   *alias_maps;
    717 char   *var_local_dsn_filter;
    718 
    719 /* local_deliver - deliver message with extreme prejudice */
    720 
    721 static int local_deliver(DELIVER_REQUEST *rqst, char *service)
    722 {
    723     const char *myname = "local_deliver";
    724     RECIPIENT *rcpt_end = rqst->rcpt_list.info + rqst->rcpt_list.len;
    725     RECIPIENT *rcpt;
    726     int     rcpt_stat;
    727     int     msg_stat;
    728     LOCAL_STATE state;
    729     USER_ATTR usr_attr;
    730 
    731     if (msg_verbose)
    732 	msg_info("local_deliver: %s from %s", rqst->queue_id, rqst->sender);
    733 
    734     /*
    735      * Initialize the delivery attributes that are not recipient specific.
    736      * While messages are being delivered and while aliases or forward files
    737      * are being expanded, this attribute list is being changed constantly.
    738      * For this reason, the list is passed on by value (except when it is
    739      * being initialized :-), so that there is no need to undo attribute
    740      * changes made by lower-level routines. The alias/include/forward
    741      * expansion attribute list is part of a tree with self and parent
    742      * references (see the EXPAND_ATTR definitions). The user-specific
    743      * attributes are security sensitive, and are therefore kept separate.
    744      * All this results in a noticeable level of clumsiness, but passing
    745      * things around by value gives good protection against accidental change
    746      * by subroutines.
    747      */
    748     state.level = 0;
    749     deliver_attr_init(&state.msg_attr);
    750     state.msg_attr.queue_name = rqst->queue_name;
    751     state.msg_attr.queue_id = rqst->queue_id;
    752     state.msg_attr.fp = rqst->fp;
    753     state.msg_attr.offset = rqst->data_offset;
    754     state.msg_attr.encoding = rqst->encoding;
    755     state.msg_attr.sendopts = rqst->sendopts;
    756     state.msg_attr.sender = rqst->sender;
    757     state.msg_attr.dsn_envid = rqst->dsn_envid;
    758     state.msg_attr.dsn_ret = rqst->dsn_ret;
    759     state.msg_attr.relay = service;
    760     state.msg_attr.msg_stats = rqst->msg_stats;
    761     state.msg_attr.request = rqst;
    762     RESET_OWNER_ATTR(state.msg_attr, state.level);
    763     RESET_USER_ATTR(usr_attr, state.level);
    764     state.loop_info = delivered_hdr_init(rqst->fp, rqst->data_offset,
    765 					 FOLD_ADDR_ALL);
    766     state.request = rqst;
    767 
    768     /*
    769      * Iterate over each recipient named in the delivery request. When the
    770      * mail delivery status for a given recipient is definite (i.e. bounced
    771      * or delivered), update the message queue file and cross off the
    772      * recipient. Update the per-message delivery status.
    773      */
    774     for (msg_stat = 0, rcpt = rqst->rcpt_list.info; rcpt < rcpt_end; rcpt++) {
    775 	state.dup_filter = been_here_init(var_dup_filter_limit, BH_FLAG_FOLD);
    776 	forward_init();
    777 	state.msg_attr.rcpt = *rcpt;
    778 	rcpt_stat = deliver_recipient(state, usr_attr);
    779 	rcpt_stat |= forward_finish(rqst, state.msg_attr, rcpt_stat);
    780 	if (rcpt_stat == 0 && (rqst->flags & DEL_REQ_FLAG_SUCCESS))
    781 	    deliver_completed(state.msg_attr.fp, rcpt->offset);
    782 	been_here_free(state.dup_filter);
    783 	msg_stat |= rcpt_stat;
    784     }
    785 
    786     /*
    787      * Clean up.
    788      */
    789     delivered_hdr_free(state.loop_info);
    790     deliver_attr_free(&state.msg_attr);
    791 
    792     return (msg_stat);
    793 }
    794 
    795 /* local_service - perform service for client */
    796 
    797 static void local_service(VSTREAM *stream, char *service, char **argv)
    798 {
    799     DELIVER_REQUEST *request;
    800     int     status;
    801 
    802     /*
    803      * Sanity check. This service takes no command-line arguments.
    804      */
    805     if (argv[0])
    806 	msg_fatal("unexpected command-line argument: %s", argv[0]);
    807 
    808     /*
    809      * This routine runs whenever a client connects to the UNIX-domain socket
    810      * that is dedicated to local mail delivery service. What we see below is
    811      * a little protocol to (1) tell the client that we are ready, (2) read a
    812      * delivery request from the client, and (3) report the completion status
    813      * of that request.
    814      */
    815     if ((request = deliver_request_read(stream)) != 0) {
    816 	status = local_deliver(request, service);
    817 	deliver_request_done(stream, request, status);
    818     }
    819 }
    820 
    821 /* local_mask_init - initialize delivery restrictions */
    822 
    823 static void local_mask_init(void)
    824 {
    825     static const NAME_MASK file_mask[] = {
    826 	"alias", EXPAND_TYPE_ALIAS,
    827 	"forward", EXPAND_TYPE_FWD,
    828 	"include", EXPAND_TYPE_INCL,
    829 	0,
    830     };
    831     static const NAME_MASK command_mask[] = {
    832 	"alias", EXPAND_TYPE_ALIAS,
    833 	"forward", EXPAND_TYPE_FWD,
    834 	"include", EXPAND_TYPE_INCL,
    835 	0,
    836     };
    837     static const NAME_MASK deliver_mask[] = {
    838 	"command", DELIVER_HDR_CMD,
    839 	"file", DELIVER_HDR_FILE,
    840 	"forward", DELIVER_HDR_FWD,
    841 	0,
    842     };
    843 
    844     local_file_deliver_mask = name_mask(VAR_ALLOW_FILES, file_mask,
    845 					var_allow_files);
    846     local_cmd_deliver_mask = name_mask(VAR_ALLOW_COMMANDS, command_mask,
    847 				       var_allow_commands);
    848     local_ext_prop_mask =
    849 	ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension);
    850     local_deliver_hdr_mask = name_mask(VAR_DELIVER_HDR, deliver_mask,
    851 				       var_deliver_hdr);
    852     local_mbox_lock_mask = mbox_lock_mask(var_mailbox_lock);
    853     if (var_mailtool_compat) {
    854 	msg_warn("%s: deprecated parameter, use \"%s = dotlock\" instead",
    855 		 VAR_MAILTOOL_COMPAT, VAR_MAILBOX_LOCK);
    856 	local_mbox_lock_mask &= MBOX_DOT_LOCK;
    857     }
    858     if (local_mbox_lock_mask == 0)
    859 	msg_fatal("parameter %s specifies no applicable mailbox locking method",
    860 		  VAR_MAILBOX_LOCK);
    861 }
    862 
    863 /* pre_accept - see if tables have changed */
    864 
    865 static void pre_accept(char *unused_name, char **unused_argv)
    866 {
    867     const char *table;
    868 
    869     if ((table = dict_changed_name()) != 0) {
    870 	msg_info("table %s has changed -- restarting", table);
    871 	exit(0);
    872     }
    873 }
    874 
    875 /* post_init - post-jail initialization */
    876 
    877 static void post_init(char *unused_name, char **unused_argv)
    878 {
    879 
    880     /*
    881      * Drop privileges most of the time, and set up delivery restrictions.
    882      */
    883     set_eugid(var_owner_uid, var_owner_gid);
    884     local_mask_init();
    885 }
    886 
    887 /* pre_init - pre-jail initialization */
    888 
    889 static void pre_init(char *unused_name, char **unused_argv)
    890 {
    891 
    892     /*
    893      * Reset the file size limit from the message size limit to the mailbox
    894      * size limit. XXX This still isn't accurate because the file size limit
    895      * also affects delivery to command.
    896      *
    897      * A file size limit protects the machine against runaway software errors.
    898      * It is not suitable to enforce mail quota, because users can get around
    899      * mail quota by delivering to /file/name or to |command.
    900      *
    901      * We can't have mailbox size limit smaller than the message size limit,
    902      * because that prohibits the delivery agent from updating the queue
    903      * file.
    904      */
    905     if (ENFORCING_SIZE_LIMIT(var_mailbox_limit)) {
    906 	if (!ENFORCING_SIZE_LIMIT(var_message_limit))
    907 	    msg_fatal("configuration error: %s is limited but %s is "
    908 		      "unlimited", VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
    909 	if (var_mailbox_limit < var_message_limit)
    910 	    msg_fatal("configuration error: %s is smaller than %s",
    911 		      VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
    912 	set_file_limit(var_mailbox_limit);
    913     }
    914     alias_maps = maps_create("aliases", var_alias_maps,
    915 			     DICT_FLAG_LOCK | DICT_FLAG_PARANOID
    916 			     | DICT_FLAG_FOLD_FIX
    917 			     | DICT_FLAG_UTF8_REQUEST);
    918 
    919     flush_init();
    920 }
    921 
    922 MAIL_VERSION_STAMP_DECLARE;
    923 
    924 /* main - pass control to the single-threaded skeleton */
    925 
    926 int     main(int argc, char **argv)
    927 {
    928     static const CONFIG_TIME_TABLE time_table[] = {
    929 	VAR_COMMAND_MAXTIME, DEF_COMMAND_MAXTIME, &var_command_maxtime, 1, 0,
    930 	0,
    931     };
    932     static const CONFIG_INT_TABLE int_table[] = {
    933 	VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
    934 	0,
    935     };
    936     static const CONFIG_LONG_TABLE long_table[] = {
    937 	VAR_MAILBOX_LIMIT, DEF_MAILBOX_LIMIT, &var_mailbox_limit, 0, 0,
    938 	0,
    939     };
    940     static const CONFIG_STR_TABLE str_table[] = {
    941 	VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0,
    942 	VAR_HOME_MAILBOX, DEF_HOME_MAILBOX, &var_home_mailbox, 0, 0,
    943 	VAR_ALLOW_COMMANDS, DEF_ALLOW_COMMANDS, &var_allow_commands, 0, 0,
    944 	VAR_ALLOW_FILES, DEF_ALLOW_FILES, &var_allow_files, 0, 0,
    945 	VAR_LOCAL_CMD_SHELL, DEF_LOCAL_CMD_SHELL, &var_local_cmd_shell, 0, 0,
    946 	VAR_MAIL_SPOOL_DIR, DEF_MAIL_SPOOL_DIR, &var_mail_spool_dir, 0, 0,
    947 	VAR_MAILBOX_TRANSP, DEF_MAILBOX_TRANSP, &var_mailbox_transport, 0, 0,
    948 	VAR_MBOX_TRANSP_MAPS, DEF_MBOX_TRANSP_MAPS, &var_mbox_transp_maps, 0, 0,
    949 	VAR_FALLBACK_TRANSP, DEF_FALLBACK_TRANSP, &var_fallback_transport, 0, 0,
    950 	VAR_FBCK_TRANSP_MAPS, DEF_FBCK_TRANSP_MAPS, &var_fbck_transp_maps, 0, 0,
    951 	VAR_CMD_EXP_FILTER, DEF_CMD_EXP_FILTER, &var_cmd_exp_filter, 1, 0,
    952 	VAR_FWD_EXP_FILTER, DEF_FWD_EXP_FILTER, &var_fwd_exp_filter, 1, 0,
    953 	VAR_EXEC_EXP_FILTER, DEF_EXEC_EXP_FILTER, &var_exec_exp_filter, 1, 0,
    954 	VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0,
    955 	VAR_DELIVER_HDR, DEF_DELIVER_HDR, &var_deliver_hdr, 0, 0,
    956 	VAR_MAILBOX_LOCK, DEF_MAILBOX_LOCK, &var_mailbox_lock, 1, 0,
    957 	VAR_MAILBOX_CMD_MAPS, DEF_MAILBOX_CMD_MAPS, &var_mailbox_cmd_maps, 0, 0,
    958 	VAR_LOCAL_DSN_FILTER, DEF_LOCAL_DSN_FILTER, &var_local_dsn_filter, 0, 0,
    959 	0,
    960     };
    961     static const CONFIG_BOOL_TABLE bool_table[] = {
    962 	VAR_BIFF, DEF_BIFF, &var_biff,
    963 	VAR_EXP_OWN_ALIAS, DEF_EXP_OWN_ALIAS, &var_exp_own_alias,
    964 	VAR_STAT_HOME_DIR, DEF_STAT_HOME_DIR, &var_stat_home_dir,
    965 	VAR_MAILTOOL_COMPAT, DEF_MAILTOOL_COMPAT, &var_mailtool_compat,
    966 	VAR_FROZEN_DELIVERED, DEF_FROZEN_DELIVERED, &var_frozen_delivered,
    967 	VAR_RESET_OWNER_ATTR, DEF_RESET_OWNER_ATTR, &var_reset_owner_attr,
    968 	VAR_STRICT_MBOX_OWNER, DEF_STRICT_MBOX_OWNER, &var_strict_mbox_owner,
    969 	0,
    970     };
    971 
    972     /* Suppress $name expansion upon loading. */
    973     static const CONFIG_RAW_TABLE raw_table[] = {
    974 	VAR_EXEC_DIRECTORY, DEF_EXEC_DIRECTORY, &var_exec_directory, 0, 0,
    975 	VAR_FORWARD_PATH, DEF_FORWARD_PATH, &var_forward_path, 0, 0,
    976 	VAR_MAILBOX_COMMAND, DEF_MAILBOX_COMMAND, &var_mailbox_command, 0, 0,
    977 	VAR_LUSER_RELAY, DEF_LUSER_RELAY, &var_luser_relay, 0, 0,
    978 	0,
    979     };
    980 
    981     /*
    982      * Fingerprint executables and core dumps.
    983      */
    984     MAIL_VERSION_STAMP_ALLOCATE;
    985 
    986     single_server_main(argc, argv, local_service,
    987 		       CA_MAIL_SERVER_INT_TABLE(int_table),
    988 		       CA_MAIL_SERVER_LONG_TABLE(long_table),
    989 		       CA_MAIL_SERVER_STR_TABLE(str_table),
    990 		       CA_MAIL_SERVER_RAW_TABLE(raw_table),
    991 		       CA_MAIL_SERVER_BOOL_TABLE(bool_table),
    992 		       CA_MAIL_SERVER_TIME_TABLE(time_table),
    993 		       CA_MAIL_SERVER_PRE_INIT(pre_init),
    994 		       CA_MAIL_SERVER_POST_INIT(post_init),
    995 		       CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
    996 		       CA_MAIL_SERVER_PRIVILEGED,
    997 		       CA_MAIL_SERVER_BOUNCE_INIT(VAR_LOCAL_DSN_FILTER,
    998 						  &var_local_dsn_filter),
    999 		       0);
   1000 }
   1001