From: Wietse Venema Date: Sat, 14 Aug 2021 05:00:00 +0000 (-0500) Subject: postfix-3.7-20210814 X-Git-Tag: v3.7.0-RC1~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=49d0c275b7404753ba2c2281c5196d6a00486b09;p=thirdparty%2Fpostfix.git postfix-3.7-20210814 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index f42b7c42f..6fd01ea07 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -25708,3 +25708,24 @@ Apologies for any names omitted. 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. diff --git a/postfix/conf/postfix-files b/postfix/conf/postfix-files index 4ed9d1f7c..7174b7a9e 100644 --- a/postfix/conf/postfix-files +++ b/postfix/conf/postfix-files @@ -132,7 +132,7 @@ $command_directory/postconf:f:root:-:755 $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 diff --git a/postfix/html/postlog.1.html b/postfix/html/postlog.1.html index c37560f2a..d3c038f49 100644 --- a/postfix/html/postlog.1.html +++ b/postfix/html/postlog.1.html @@ -47,37 +47,43 @@ POSTLOG(1) POSTLOG(1) -v Enable verbose logging for debugging purposes. Multiple -v options make the software increasingly verbose. +SECURITY + The postlog(1) command is designed to run with set-groupid privileges, + so that it can connect to the postlogd(8) daemon process (Postfix 3.7 + and later; earlier implementations of this command must not have + set-groupid or set-userid permissions). + ENVIRONMENT MAIL_CONFIG Directory with the main.cf file. CONFIGURATION PARAMETERS - The following main.cf parameters are especially relevant to this pro- + The following main.cf parameters are especially relevant to this pro- gram. - The text below provides only a parameter summary. See postconf(5) for + The text below provides only a parameter summary. See postconf(5) for more details including examples. config_directory (see 'postconf -d' output) - The default location of the Postfix main.cf and master.cf con- + The default location of the Postfix main.cf and master.cf con- figuration files. import_environment (see 'postconf -d' output) - 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. syslog_facility (mail) The syslog facility of Postfix logging. syslog_name (see 'postconf -d' output) - 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: maillog_file (empty) - The name of an optional logfile that is written by the Postfix + The name of an optional logfile that is written by the Postfix postlogd(8) service. postlog_service_name (postlog) @@ -91,6 +97,9 @@ POSTLOG(1) POSTLOG(1) LICENSE The Secure Mailer license must be distributed with this software. +HISTORY + The postlog(1) command was introduced with Postfix version 3.4. + AUTHOR(S) Wietse Venema IBM T.J. Watson Research diff --git a/postfix/man/man1/postlog.1 b/postfix/man/man1/postlog.1 index 87f537d18..406a3a3b8 100644 --- a/postfix/man/man1/postlog.1 +++ b/postfix/man/man1/postlog.1 @@ -48,6 +48,16 @@ is used when none is specified. .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 @@ -96,6 +106,11 @@ syslogd(8), system logging .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 diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 9fcfbb4ab..0ff7c0c47 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * 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 diff --git a/postfix/src/postlog/postlog.c b/postfix/src/postlog/postlog.c index 0ad22b65f..db03cec00 100644 --- a/postfix/src/postlog/postlog.c +++ b/postfix/src/postlog/postlog.c @@ -42,6 +42,14 @@ /* .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 @@ -82,6 +90,9 @@ /* .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 @@ -117,6 +128,7 @@ #include #include #include +#include /* Global library. */ @@ -129,6 +141,32 @@ /* 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. */ @@ -149,6 +187,8 @@ static struct level_table level_table[] = { 0, }; +#define POSTLOG_CMD "postlog" + /* level_map - lookup facility or severity value */ static int level_map(char *name) @@ -221,8 +261,10 @@ int main(int argc, char **argv) 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); @@ -234,7 +276,10 @@ int main(int argc, char **argv) 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) { @@ -252,7 +297,7 @@ int main(int argc, char **argv) level = level_map(optarg); break; case 't': - tag = optarg; + tag = optarg; /* sanitized below */ break; case 'v': msg_verbose++; @@ -265,12 +310,27 @@ int main(int argc, char **argv) * 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 @@ -280,6 +340,17 @@ int main(int argc, char **argv) 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. */ diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 403459052..82e1ad2fb 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -5730,7 +5730,7 @@ static void smtpd_proto(SMTPD_STATE *state) && (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; diff --git a/postfix/src/util/inet_connect.c b/postfix/src/util/inet_connect.c index 4c8aa3cfe..591283ef2 100644 --- a/postfix/src/util/inet_connect.c +++ b/postfix/src/util/inet_connect.c @@ -101,8 +101,8 @@ int inet_connect(const char *addr, int block_mode, int timeout) 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();