tls/tls_proxy_client_print.c, tls/tls_proxy_context_print.c,
tls/tls_proxy.h, tls/tls_proxy_server_print.c, util/argv_attr.h,
util/argv_attr_print.c, util/attr.h.
+
+20210810
+
+ Pedantism: the Postfix SMTP server now replies with status
+ 500 when a command is not recogized (status 502 is applicable
+ when a command is recognized but not implemented). File:
+ smtpd/smtpd.c.
+
+ Wordsmithing: in inet_connect() replaced "host/service xxx/yyy
+ not found" with "host or service xxx:yyy not found". The former
+ suggests UNIX-domain pathname syntax which is confusing. File:
+ until/inet_connect.c.
+
+20210814
+
+ To make the maillog_file feature more useful, the postlog(1)
+ command is now set-gid postdrop, so that unprivileged
+ programs can write logging through the postlogd(8) daemon.
+ Adopted some code from postqueue(1) and postdrop(1) to
+ harden postlog(1) against privilege escalation attacks.
+ Files: postlog/postlog.c, conf/postfix-files.
$command_directory/postfix:f:root:-:755
$command_directory/postkick:f:root:-:755
$command_directory/postlock:f:root:-:755
-$command_directory/postlog:f:root:-:755
+$command_directory/postlog:f:root:$setgid_group:2755:u
$command_directory/postmap:f:root:-:755
$command_directory/postmulti:f:root:-:755
$command_directory/postsuper:f:root:-:755
<b>-v</b> Enable verbose logging for debugging purposes. Multiple <b>-v</b>
options make the software increasingly verbose.
+<b>SECURITY</b>
+ The <a href="postlog.1.html"><b>postlog</b>(1)</a> command is designed to run with set-groupid privileges,
+ so that it can connect to the <a href="postlogd.8.html"><b>postlogd</b>(8)</a> daemon process (Postfix 3.7
+ and later; earlier implementations of this command must not have
+ set-groupid or set-userid permissions).
+
<b>ENVIRONMENT</b>
MAIL_CONFIG
Directory with the <a href="postconf.5.html"><b>main.cf</b></a> file.
<b>CONFIGURATION PARAMETERS</b>
- The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
+ The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
gram.
- The text below provides only a parameter summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for
+ The text below provides only a parameter summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for
more details including examples.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
figuration files.
<b><a href="postconf.5.html#import_environment">import_environment</a> (see 'postconf -d' output)</b>
- The list of environment parameters that a privileged Postfix
- process will import from a non-Postfix parent process, or
+ The list of environment parameters that a privileged Postfix
+ process will import from a non-Postfix parent process, or
name=value environment overrides.
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
- A prefix that is prepended to the process name in syslog
+ A prefix that is prepended to the process name in syslog
records, so that, for example, "smtpd" becomes "prefix/smtpd".
Available in Postfix 3.4 and later:
<b><a href="postconf.5.html#maillog_file">maillog_file</a> (empty)</b>
- The name of an optional logfile that is written by the Postfix
+ The name of an optional logfile that is written by the Postfix
<a href="postlogd.8.html"><b>postlogd</b>(8)</a> service.
<b><a href="postconf.5.html#postlog_service_name">postlog_service_name</a> (postlog)</b>
<b>LICENSE</b>
The Secure Mailer license must be distributed with this software.
+<b>HISTORY</b>
+ The <a href="postlog.1.html"><b>postlog</b>(1)</a> command was introduced with Postfix version 3.4.
+
<b>AUTHOR(S)</b>
Wietse Venema
IBM T.J. Watson Research
.IP \fB\-v\fR
Enable verbose logging for debugging purposes. Multiple \fB\-v\fR
options make the software increasingly verbose.
+.SH "SECURITY"
+.na
+.nf
+.ad
+.fi
+The \fBpostlog\fR(1) command is designed to run with
+set\-groupid privileges, so that it can connect to the
+\fBpostlogd\fR(8) daemon process (Postfix 3.7 and later;
+earlier implementations of this command must not have
+set\-groupid or set\-userid permissions).
.SH "ENVIRONMENT"
.na
.nf
.ad
.fi
The Secure Mailer license must be distributed with this software.
+.SH HISTORY
+.ad
+.fi
+The \fBpostlog\fR(1) command was introduced with Postfix
+version 3.4.
.SH "AUTHOR(S)"
.na
.nf
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20210807"
+#define MAIL_RELEASE_DATE "20210814"
#define MAIL_VERSION_NUMBER "3.7"
#ifdef SNAPSHOT
/* .IP \fB-v\fR
/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
/* options make the software increasingly verbose.
+/* SECURITY
+/* .ad
+/* .fi
+/* The \fBpostlog\fR(1) command is designed to run with
+/* set-groupid privileges, so that it can connect to the
+/* \fBpostlogd\fR(8) daemon process (Postfix 3.7 and later;
+/* earlier implementations of this command must not have
+/* set-groupid or set-userid permissions).
/* ENVIRONMENT
/* .ad
/* .fi
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
+/* HISTORY
+/* The \fBpostlog\fR(1) command was introduced with Postfix
+/* version 3.4.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
#include <msg_vstream.h>
#include <warn_stat.h>
#include <clean_env.h>
+#include <stringops.h>
/* Global library. */
/* Application-specific. */
+ /*
+ * WARNING WARNING WARNING
+ *
+ * This software is designed to run set-gid. In order to avoid exploitation of
+ * privilege, this software should not run any external commands, nor should
+ * it take any information from the user, unless that information can be
+ * properly sanitized. To get an idea of how much information a process can
+ * inherit from a potentially hostile user, examine all the members of the
+ * process structure (typically, in /usr/include/sys/proc.h): the current
+ * directory, open files, timers, signals, environment, command line, umask,
+ * and so on.
+ */
+
+ /*
+ * Access lists.
+ */
+#if 0
+char *var_postlog_acl;
+
+X static const CONFIG_STR_TABLE str_table[] = {
+ X VAR_POSTLOG_ACL, DEF_POSTLOG_ACL, &var_postlog_acl, 0, 0,
+ X 0,
+X};
+
+#endif
+
/*
* Support for the severity level mapping.
*/
0,
};
+#define POSTLOG_CMD "postlog"
+
/* level_map - lookup facility or severity value */
static int level_map(char *name)
msg_fatal("open /dev/null: %m");
/*
- * Set up diagnostics.
+ * Set up diagnostics. Censor the process name: it is provided by the
+ * user.
*/
+ argv[0] = POSTLOG_CMD;
tag = mail_task(argv[0]);
if (isatty(STDERR_FILENO))
msg_vstream_init(tag, VSTREAM_ERR);
MAIL_VERSION_CHECK;
/*
- * Parse switches.
+ * Parse switches. This program is set-gid and must sanitize all
+ * command-line parameters. The configuration directory argument is
+ * validated by the mail configuration read routine. Don't do complex
+ * things until we have completed initializations.
*/
tag = 0;
while ((ch = GETOPT(argc, argv, "c:ip:t:v")) > 0) {
level = level_map(optarg);
break;
case 't':
- tag = optarg;
+ tag = optarg; /* sanitized below */
break;
case 'v':
msg_verbose++;
* may require that mail_task() be re-evaluated.
*/
mail_conf_read();
- /* Enforce consistent operation of different Postfix parts. */
+ /* Re-evaluate mail_task() after reading main.cf. */
+ maillog_client_init(mail_task(POSTLOG_CMD), MAILLOG_CLIENT_FLAG_NONE);
+#if 0
+ mail_dict_init(); /* proxy, sql, ldap */
+ get_mail_conf_str_table(str_table);
+#endif
+
+ /*
+ * This program is designed to be set-gid, which makes it a potential
+ * target for attack. Strip and optionally override the process
+ * environment so that we don't have to trust the C library.
+ */
import_env = mail_parm_split(VAR_IMPORT_ENVIRON, var_import_environ);
- update_env(import_env->argv);
+ clean_env(import_env->argv);
argv_free(import_env);
if (tag == 0)
+ /* Use sanitized command name. */
tag = mail_task(argv[0]);
+ else
+ /* Sanitize user-specified tag, depends on var_smtputf8_enable. */
+ (void) printable(tag, '?');
/*
* Re-initialize the logging, this time with the tag specified in main.cf
msg_vstream_init(tag, VSTREAM_ERR);
maillog_client_init(tag, MAILLOG_CLIENT_FLAG_LOGWRITER_FALLBACK);
+#if 0
+ uid_t uid = getuid();
+
+ if (uid != 0 && uid != var_owner_uid
+ && (errstr = check_user_acl_byuid(VAR_SHOWQ_ACL, var_showq_acl,
+ uid)) != 0)
+ msg_fatal_status(EX_NOPERM,
+ "User %s(%ld) is not allowed to invoke 'postlog'",
+ errstr, (long) uid);
+#endif
+
/*
* Log the command line or log lines from standard input.
*/
&& (err = check_milter_reply(state, err)) != 0) {
smtpd_chat_reply(state, "%s", err);
} else
- smtpd_chat_reply(state, "502 5.5.2 Error: command not recognized");
+ smtpd_chat_reply(state, "500 5.5.2 Error: command not recognized");
state->error_mask |= MAIL_ERROR_PROTOCOL;
state->error_count++;
continue;
if ((parse_err = host_port(buf, &host, "localhost", &port, (char *) 0)) != 0)
msg_fatal("%s: %s", addr, parse_err);
if ((aierr = hostname_to_sockaddr(host, port, SOCK_STREAM, &res0)) != 0)
- msg_fatal("host/service %s/%s not found: %s",
- host, port, MAI_STRERROR(aierr));
+ msg_fatal("host or service %s not found: %s",
+ addr, MAI_STRERROR(aierr));
myfree(buf);
proto_info = inet_proto_info();