1/*++
2/* NAME
3/*	postfix 1
4/* SUMMARY
5/*	Postfix control program
6/* SYNOPSIS
7/* .fi
8/*	\fBpostfix\fR [\fB-Dv\fR] [\fB-c \fIconfig_dir\fR] \fIcommand\fR
9/* DESCRIPTION
10/*	This command is reserved for the superuser. To submit mail,
11/*	use the Postfix \fBsendmail\fR(1) command.
12/*
13/*	The \fBpostfix\fR(1) command controls the operation of the Postfix
14/*	mail system: start or stop the \fBmaster\fR(8) daemon, do a health
15/*	check, and other maintenance.
16/*
17/*	By default, the \fBpostfix\fR(1) command sets up a standardized
18/*	environment and runs the \fBpostfix-script\fR shell script
19/*	to do the actual work.
20/*
21/*	However, when support for multiple Postfix instances is
22/*	configured, \fBpostfix\fR(1) executes the command specified
23/*	with the \fBmulti_instance_wrapper\fR configuration parameter.
24/*	This command will execute the \fIcommand\fR for each
25/*	applicable Postfix instance.
26/*
27/*	The following commands are implemented:
28/* .IP \fBcheck\fR
29/*	Warn about bad directory/file ownership or permissions,
30/*	and create missing directories.
31/* .IP \fBstart\fR
32/*	Start the Postfix mail system. This also runs the configuration
33/*	check described above.
34/* .IP \fBstop\fR
35/*	Stop the Postfix mail system in an orderly fashion. If
36/*	possible, running processes are allowed to terminate at
37/*	their earliest convenience.
38/* .sp
39/*	Note: in order to refresh the Postfix mail system after a
40/*	configuration change, do not use the \fBstart\fR and \fBstop\fR
41/*	commands in succession. Use the \fBreload\fR command instead.
42/* .IP \fBabort\fR
43/*	Stop the Postfix mail system abruptly. Running processes are
44/*	signaled to stop immediately.
45/* .IP \fBflush\fR
46/*	Force delivery: attempt to deliver every message in the deferred
47/*	mail queue. Normally, attempts to deliver delayed mail happen at
48/*	regular intervals, the interval doubling after each failed attempt.
49/* .sp
50/*	Warning: flushing undeliverable mail frequently will result in
51/*	poor delivery performance of all other mail.
52/* .IP \fBreload\fR
53/*	Re-read configuration files. Running processes terminate at their
54/*	earliest convenience.
55/* .IP \fBstatus\fR
56/*	Indicate if the Postfix mail system is currently running.
57/* .IP "\fBset-permissions\fR \fB[\fIname\fR=\fIvalue ...\fB]\fR
58/*	Set the ownership and permissions of Postfix related files and
59/*	directories, as specified in the \fBpostfix-files\fR file.
60/* .sp
61/*	Specify \fIname\fR=\fIvalue\fR to override and update specific
62/*	main.cf configuration parameters. Use this, for example, to
63/*	change the \fBmail_owner\fR or \fBsetgid_group\fR setting for an
64/*	already installed Postfix system.
65/* .sp
66/*	This feature is available in Postfix 2.1 and later.  With
67/*	Postfix 2.0 and earlier, use "\fB$config_directory/post-install
68/*	set-permissions\fR".
69/* .IP "\fBupgrade-configuration\fR \fB[\fIname\fR=\fIvalue ...\fB]\fR
70/*	Update the \fBmain.cf\fR and \fBmaster.cf\fR files with information
71/*	that Postfix needs in order to run: add or update services, and add
72/*	or update configuration parameter settings.
73/* .sp
74/*	Specify \fIname\fR=\fIvalue\fR to override and update specific
75/*	main.cf configuration parameters.
76/* .sp
77/*	This feature is available in Postfix 2.1 and later.  With
78/*	Postfix 2.0 and earlier, use "\fB$config_directory/post-install
79/*	upgrade-configuration\fR".
80/* .PP
81/*	The following options are implemented:
82/* .IP "\fB-c \fIconfig_dir\fR"
83/*	Read the \fBmain.cf\fR and \fBmaster.cf\fR configuration files in
84/*	the named directory instead of the default configuration directory.
85/*	Use this to distinguish between multiple Postfix instances on the
86/*	same host.
87/*
88/*	With Postfix 2.6 and later, this option forces the postfix(1)
89/*	command to operate on the specified Postfix instance only.
90/*	This behavior is inherited by postfix(1) commands that run
91/*	as a descendant of the current process.
92/* .IP "\fB-D\fR (with \fBpostfix start\fR only)"
93/*	Run each Postfix daemon under control of a debugger as specified
94/*	via the \fBdebugger_command\fR configuration parameter.
95/* .IP \fB-v\fR
96/*	Enable verbose logging for debugging purposes. Multiple \fB-v\fR
97/*	options make the software increasingly verbose.
98/* ENVIRONMENT
99/* .ad
100/* .fi
101/*	The \fBpostfix\fR(1) command exports the following environment
102/*	variables before executing the \fBpostfix-script\fR file:
103/* .IP \fBMAIL_CONFIG\fR
104/*	This is set when the -c command-line option is present.
105/*
106/*	With Postfix 2.6 and later, this environment variable forces
107/*	the postfix(1) command to operate on the specified Postfix
108/*	instance only.  This behavior is inherited by postfix(1)
109/*	commands that run as a descendant of the current process.
110/* .IP \fBMAIL_VERBOSE\fR
111/*	This is set when the -v command-line option is present.
112/* .IP \fBMAIL_DEBUG\fR
113/*	This is set when the -D command-line option is present.
114/* CONFIGURATION PARAMETERS
115/* .ad
116/* .fi
117/*	The following \fBmain.cf\fR configuration parameters are
118/*	exported as environment variables with the same names:
119/* .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
120/*	The location of all postfix administrative commands.
121/* .IP "\fBdaemon_directory (see 'postconf -d' output)\fR"
122/*	The directory with Postfix support programs and daemon programs.
123/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
124/*	The default location of the Postfix main.cf and master.cf
125/*	configuration files.
126/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
127/*	The location of the Postfix top-level queue directory.
128/* .IP "\fBmail_owner (postfix)\fR"
129/*	The UNIX system account that owns the Postfix queue and most Postfix
130/*	daemon processes.
131/* .IP "\fBsetgid_group (postdrop)\fR"
132/*	The group ownership of set-gid Postfix commands and of group-writable
133/*	Postfix directories.
134/* .IP "\fBsendmail_path (see 'postconf -d' output)\fR"
135/*	A Sendmail compatibility feature that specifies the location of
136/*	the Postfix \fBsendmail\fR(1) command.
137/* .IP "\fBnewaliases_path (see 'postconf -d' output)\fR"
138/*	Sendmail compatibility feature that specifies the location of the
139/*	\fBnewaliases\fR(1) command.
140/* .IP "\fBmailq_path (see 'postconf -d' output)\fR"
141/*	Sendmail compatibility feature that specifies where the Postfix
142/*	\fBmailq\fR(1) command is installed.
143/* .IP "\fBhtml_directory (see 'postconf -d' output)\fR"
144/*	The location of Postfix HTML files that describe how to build,
145/*	configure or operate a specific Postfix subsystem or feature.
146/* .IP "\fBmanpage_directory (see 'postconf -d' output)\fR"
147/*	Where the Postfix manual pages are installed.
148/* .IP "\fBreadme_directory (see 'postconf -d' output)\fR"
149/*	The location of Postfix README files that describe how to build,
150/*	configure or operate a specific Postfix subsystem or feature.
151/* .PP
152/*	Available in Postfix version 2.5 and later:
153/* .IP "\fBdata_directory (see 'postconf -d' output)\fR"
154/*	The directory with Postfix-writable data files (for example:
155/*	caches, pseudo-random numbers).
156/* .PP
157/*	Other configuration parameters:
158/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
159/*	The default location of the Postfix main.cf and master.cf
160/*	configuration files.
161/* .IP "\fBimport_environment (see 'postconf -d' output)\fR"
162/*	The list of environment parameters that a Postfix process will
163/*	import from a non-Postfix parent process.
164/* .IP "\fBsyslog_facility (mail)\fR"
165/*	The syslog facility of Postfix logging.
166/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
167/*	The mail system name that is prepended to the process name in syslog
168/*	records, so that "smtpd" becomes, for example, "postfix/smtpd".
169/* .PP
170/*	Available in Postfix version 2.6 and later:
171/* .IP "\fBmulti_instance_directories (empty)\fR"
172/*	An optional list of non-default Postfix configuration directories;
173/*	these directories belong to additional Postfix instances that share
174/*	the Postfix executable files and documentation with the default
175/*	Postfix instance, and that are started, stopped, etc., together
176/*	with the default Postfix instance.
177/* .IP "\fBmulti_instance_wrapper (empty)\fR"
178/*	The pathname of a multi-instance manager command that the
179/*	\fBpostfix\fR(1) command invokes when the multi_instance_directories
180/*	parameter value is non-empty.
181/* .IP "\fBmulti_instance_group (empty)\fR"
182/*	The optional instance group name of this Postfix instance.
183/* .IP "\fBmulti_instance_name (empty)\fR"
184/*	The optional instance name of this Postfix instance.
185/* .IP "\fBmulti_instance_enable (no)\fR"
186/*	Allow this Postfix instance to be started, stopped, etc., by a
187/*	multi-instance manager.
188/* FILES
189/* .ad
190/* .fi
191/*	Prior to Postfix version 2.6, all of the following files
192/*	were in \fB$config_directory\fR. Some files are now in
193/*	\fB$daemon_directory\fR so that they can be shared among
194/*	multiple instances that run the same Postfix version.
195/*
196/*	Use the command "\fBpostconf config_directory\fR" or
197/*	"\fBpostconf daemon_directory\fR" to expand the names
198/*	into their actual values.
199/* .na
200/* .nf
201/*
202/*	$config_directory/main.cf, Postfix configuration parameters
203/*	$config_directory/master.cf, Postfix daemon processes
204/*	$daemon_directory/postfix-files, file/directory permissions
205/*	$daemon_directory/postfix-script, administrative commands
206/*	$daemon_directory/post-install, post-installation configuration
207/* SEE ALSO
208/*	Commands:
209/*	postalias(1), create/update/query alias database
210/*	postcat(1), examine Postfix queue file
211/*	postconf(1), Postfix configuration utility
212/*	postfix(1), Postfix control program
213/*	postkick(1), trigger Postfix daemon
214/*	postlock(1), Postfix-compatible locking
215/*	postlog(1), Postfix-compatible logging
216/*	postmap(1), Postfix lookup table manager
217/*	postmulti(1), Postfix multi-instance manager
218/*	postqueue(1), Postfix mail queue control
219/*	postsuper(1), Postfix housekeeping
220/*	mailq(1), Sendmail compatibility interface
221/*	newaliases(1), Sendmail compatibility interface
222/*	sendmail(1), Sendmail compatibility interface
223/*
224/*	Postfix configuration:
225/*	bounce(5), Postfix bounce message templates
226/*	master(5), Postfix master.cf file syntax
227/*	postconf(5), Postfix main.cf file syntax
228/*	postfix-wrapper(5), Postfix multi-instance API
229/*
230/*	Table-driven mechanisms:
231/*	access(5), Postfix SMTP access control table
232/*	aliases(5), Postfix alias database
233/*	canonical(5), Postfix input address rewriting
234/*	generic(5), Postfix output address rewriting
235/*	header_checks(5), body_checks(5), Postfix content inspection
236/*	relocated(5), Users that have moved
237/*	transport(5), Postfix routing table
238/*	virtual(5), Postfix virtual aliasing
239/*
240/*	Table lookup mechanisms:
241/*	cidr_table(5), Associate CIDR pattern with value
242/*	ldap_table(5), Postfix LDAP client
243/*	lmdb_table(5), Postfix LMDB database driver
244/*	memcache_table(5), Postfix memcache client
245/*	mysql_table(5), Postfix MYSQL client
246/*	nisplus_table(5), Postfix NIS+ client
247/*	pcre_table(5), Associate PCRE pattern with value
248/*	pgsql_table(5), Postfix PostgreSQL client
249/*	regexp_table(5), Associate POSIX regexp pattern with value
250/*	socketmap_table(5), Postfix socketmap client
251/*	sqlite_table(5), Postfix SQLite database driver
252/*	tcp_table(5), Postfix client-server table lookup
253/*
254/*	Daemon processes:
255/*	anvil(8), Postfix connection/rate limiting
256/*	bounce(8), defer(8), trace(8), Delivery status reports
257/*	cleanup(8), canonicalize and enqueue message
258/*	discard(8), Postfix discard delivery agent
259/*	dnsblog(8), DNS black/whitelist logger
260/*	error(8), Postfix error delivery agent
261/*	flush(8), Postfix fast ETRN service
262/*	local(8), Postfix local delivery agent
263/*	master(8), Postfix master daemon
264/*	oqmgr(8), old Postfix queue manager
265/*	pickup(8), Postfix local mail pickup
266/*	pipe(8), deliver mail to non-Postfix command
267/*	postscreen(8), Postfix zombie blocker
268/*	proxymap(8), Postfix lookup table proxy server
269/*	qmgr(8), Postfix queue manager
270/*	qmqpd(8), Postfix QMQP server
271/*	scache(8), Postfix connection cache manager
272/*	showq(8), list Postfix mail queue
273/*	smtp(8), lmtp(8), Postfix SMTP+LMTP client
274/*	smtpd(8), Postfix SMTP server
275/*	spawn(8), run non-Postfix server
276/*	tlsmgr(8), Postfix TLS cache and randomness manager
277/*	tlsproxy(8), Postfix TLS proxy server
278/*	trivial-rewrite(8), Postfix address rewriting
279/*	verify(8), Postfix address verification
280/*	virtual(8), Postfix virtual delivery agent
281/*
282/*	Other:
283/*	syslogd(8), system logging
284/* README FILES
285/* .ad
286/* .fi
287/*	Use "\fBpostconf readme_directory\fR" or
288/*	"\fBpostconf html_directory\fR" to locate this information.
289/* .na
290/* .nf
291/*	OVERVIEW, overview of Postfix commands and processes
292/*	BASIC_CONFIGURATION_README, Postfix basic configuration
293/*	ADDRESS_REWRITING_README, Postfix address rewriting
294/*	SMTPD_ACCESS_README, SMTP relay/access control
295/*	CONTENT_INSPECTION_README, Postfix content inspection
296/*	QSHAPE_README, Postfix queue analysis
297/* LICENSE
298/* .ad
299/* .fi
300/*	The Secure Mailer license must be distributed with this software.
301/* AUTHOR(S)
302/*	Wietse Venema
303/*	IBM T.J. Watson Research
304/*	P.O. Box 704
305/*	Yorktown Heights, NY 10598, USA
306/*
307/*	TLS support by:
308/*	Lutz Jaenicke
309/*	Brandenburg University of Technology
310/*	Cottbus, Germany
311/*
312/*	Victor Duchovni
313/*	Morgan Stanley
314/*
315/*	SASL support originally by:
316/*	Till Franke
317/*	SuSE Rhein/Main AG
318/*	65760 Eschborn, Germany
319/*
320/*	LMTP support originally by:
321/*	Philip A. Prindeville
322/*	Mirapoint, Inc.
323/*	USA.
324/*
325/*	Amos Gouaux
326/*	University of Texas at Dallas
327/*	P.O. Box 830688, MC34
328/*	Richardson, TX 75083, USA
329/*
330/*	IPv6 support originally by:
331/*	Mark Huizer, Eindhoven University, The Netherlands
332/*	Jun-ichiro 'itojun' Hagino, KAME project, Japan
333/*	The Linux PLD project
334/*	Dean Strik, Eindhoven University, The Netherlands
335/*--*/
336
337/* System library. */
338
339#include <sys_defs.h>
340#include <sys/stat.h>
341#include <vstream.h>
342#include <stdlib.h>
343#include <unistd.h>
344#include <string.h>
345#include <fcntl.h>
346#include <syslog.h>
347#ifdef USE_PATHS_H
348#include <paths.h>
349#endif
350
351/* Utility library. */
352
353#include <msg.h>
354#include <msg_vstream.h>
355#include <msg_syslog.h>
356#include <stringops.h>
357#include <clean_env.h>
358#include <argv.h>
359#include <safe.h>
360#include <warn_stat.h>
361
362/* Global library. */
363
364#include <mail_conf.h>
365#include <mail_params.h>
366#include <mail_version.h>
367
368/* Additional installation parameters. */
369
370static char *var_sendmail_path;
371static char *var_mailq_path;
372static char *var_newalias_path;
373static char *var_manpage_dir;
374static char *var_sample_dir;
375static char *var_readme_dir;
376static char *var_html_dir;
377
378/* check_setenv - setenv() with extreme prejudice */
379
380static void check_setenv(char *name, char *value)
381{
382#define CLOBBER 1
383    if (setenv(name, value, CLOBBER) < 0)
384	msg_fatal("setenv: %m");
385}
386
387MAIL_VERSION_STAMP_DECLARE;
388
389/* main - run administrative script from controlled environment */
390
391int     main(int argc, char **argv)
392{
393    char   *script;
394    struct stat st;
395    char   *slash;
396    int     fd;
397    int     ch;
398    ARGV   *import_env;
399    static const CONFIG_STR_TABLE str_table[] = {
400	VAR_SENDMAIL_PATH, DEF_SENDMAIL_PATH, &var_sendmail_path, 1, 0,
401	VAR_MAILQ_PATH, DEF_MAILQ_PATH, &var_mailq_path, 1, 0,
402	VAR_NEWALIAS_PATH, DEF_NEWALIAS_PATH, &var_newalias_path, 1, 0,
403	VAR_MANPAGE_DIR, DEF_MANPAGE_DIR, &var_manpage_dir, 1, 0,
404	VAR_SAMPLE_DIR, DEF_SAMPLE_DIR, &var_sample_dir, 1, 0,
405	VAR_README_DIR, DEF_README_DIR, &var_readme_dir, 1, 0,
406	VAR_HTML_DIR, DEF_HTML_DIR, &var_html_dir, 1, 0,
407	0,
408    };
409    int     force_single_instance;
410    ARGV   *my_argv;
411
412    /*
413     * Fingerprint executables and core dumps.
414     */
415    MAIL_VERSION_STAMP_ALLOCATE;
416
417    /*
418     * Be consistent with file permissions.
419     */
420    umask(022);
421
422    /*
423     * To minimize confusion, make sure that the standard file descriptors
424     * are open before opening anything else. XXX Work around for 44BSD where
425     * fstat can return EBADF on an open file descriptor.
426     */
427    for (fd = 0; fd < 3; fd++)
428	if (fstat(fd, &st) == -1
429	    && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
430	    msg_fatal("open /dev/null: %m");
431
432    /*
433     * Set up diagnostics. XXX What if stdin is the system console during
434     * boot time? It seems a bad idea to log startup errors to the console.
435     * This is UNIX, a system that can run without hand holding.
436     */
437    if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
438	argv[0] = slash + 1;
439    if (isatty(STDERR_FILENO))
440	msg_vstream_init(argv[0], VSTREAM_ERR);
441    msg_syslog_init(argv[0], LOG_PID, LOG_FACILITY);
442
443    /*
444     * Check the Postfix library version as soon as we enable logging.
445     */
446    MAIL_VERSION_CHECK;
447
448    /*
449     * The mail system must be run by the superuser so it can revoke
450     * privileges for selected operations. That's right - it takes privileges
451     * to toss privileges.
452     */
453    if (getuid() != 0) {
454	msg_error("to submit mail, use the Postfix sendmail command");
455	msg_fatal("the postfix command is reserved for the superuser");
456    }
457    if (unsafe() != 0)
458	msg_fatal("the postfix command must not run as a set-uid process");
459
460    /*
461     * Parse switches.
462     */
463    while ((ch = GETOPT(argc, argv, "c:Dv")) > 0) {
464	switch (ch) {
465	default:
466	    msg_fatal("usage: %s [-c config_dir] [-Dv] command", argv[0]);
467	case 'c':
468	    if (*optarg != '/')
469		msg_fatal("-c requires absolute pathname");
470	    check_setenv(CONF_ENV_PATH, optarg);
471	    break;
472	case 'D':
473	    check_setenv(CONF_ENV_DEBUG, "");
474	    break;
475	case 'v':
476	    msg_verbose++;
477	    check_setenv(CONF_ENV_VERB, "");
478	    break;
479	}
480    }
481    force_single_instance = (getenv(CONF_ENV_PATH) != 0);
482
483    /*
484     * Copy a bunch of configuration parameters into the environment for easy
485     * access by the maintenance shell script.
486     */
487    mail_conf_read();
488    get_mail_conf_str_table(str_table);
489
490    /*
491     * Environment import filter, to enforce consistent behavior whether this
492     * command is started by hand, or at system boot time. This is necessary
493     * because some shell scripts use environment settings to override
494     * main.cf settings.
495     */
496    import_env = argv_split(var_import_environ, ", \t\r\n");
497    clean_env(import_env->argv);
498    argv_free(import_env);
499
500    check_setenv("PATH", ROOT_PATH);		/* sys_defs.h */
501    check_setenv(CONF_ENV_PATH, var_config_dir);/* mail_conf.h */
502
503    check_setenv(VAR_COMMAND_DIR, var_command_dir);	/* main.cf */
504    check_setenv(VAR_DAEMON_DIR, var_daemon_dir);	/* main.cf */
505    check_setenv(VAR_DATA_DIR, var_data_dir);	/* main.cf */
506    check_setenv(VAR_QUEUE_DIR, var_queue_dir);	/* main.cf */
507    check_setenv(VAR_CONFIG_DIR, var_config_dir);	/* main.cf */
508
509    /*
510     * Do we want to keep adding things here as shell scripts evolve?
511     */
512    check_setenv(VAR_MAIL_OWNER, var_mail_owner);	/* main.cf */
513    check_setenv(VAR_SGID_GROUP, var_sgid_group);	/* main.cf */
514    check_setenv(VAR_SENDMAIL_PATH, var_sendmail_path);	/* main.cf */
515    check_setenv(VAR_MAILQ_PATH, var_mailq_path);	/* main.cf */
516    check_setenv(VAR_NEWALIAS_PATH, var_newalias_path);	/* main.cf */
517    check_setenv(VAR_MANPAGE_DIR, var_manpage_dir);	/* main.cf */
518    check_setenv(VAR_SAMPLE_DIR, var_sample_dir);	/* main.cf */
519    check_setenv(VAR_README_DIR, var_readme_dir);	/* main.cf */
520    check_setenv(VAR_HTML_DIR, var_html_dir);	/* main.cf */
521
522    /*
523     * Make sure these directories exist. Run the maintenance scripts with as
524     * current directory the mail database.
525     */
526    if (chdir(var_command_dir))
527	msg_fatal("chdir(%s): %m", var_command_dir);
528    if (chdir(var_daemon_dir))
529	msg_fatal("chdir(%s): %m", var_daemon_dir);
530    if (chdir(var_queue_dir))
531	msg_fatal("chdir(%s): %m", var_queue_dir);
532
533    /*
534     * Run the management script.
535     */
536    if (force_single_instance
537	|| argv_split(var_multi_conf_dirs, "\t\r\n, ")->argc == 0) {
538	script = concatenate(var_daemon_dir, "/postfix-script", (char *) 0);
539	if (optind < 1)
540	    msg_panic("bad optind value");
541	argv[optind - 1] = script;
542	execvp(script, argv + optind - 1);
543	msg_fatal("%s: %m", script);
544    }
545
546    /*
547     * Hand off control to a multi-instance manager.
548     */
549    else {
550	if (*var_multi_wrapper == 0)
551	    msg_fatal("multi-instance support is requested, but %s is empty",
552		      VAR_MULTI_WRAPPER);
553	my_argv = argv_split(var_multi_wrapper, " \t\r\n");
554	do {
555	    argv_add(my_argv, argv[optind], (char *) 0);
556	} while (argv[optind++] != 0);
557	execvp(my_argv->argv[0], my_argv->argv);
558	msg_fatal("%s: %m", my_argv->argv[0]);
559    }
560}
561