versus virtual aliasing, and inet_interfaces. Files:
proto/postconf.proto, proto/aliases, proto/virtual,
proto/ADDRESS_REWRITING_README.html.
+
+20230516
+
+ Bugfix (defect introduced: Postfix 3.4): the postlog(1)
+ command created a logfile with permissions 0644, but the
+ postlogd(8) daemon created it with permissions 0600, for
+ example after "postfix logrotate". The discrepancy is now
+ eliminated, and the permissions when creating a file are
+ now configurable with the "maillog_file_permissions"
+ parameter, default 0600 for backwards compatibility. Files:
+ mantools/postlink, proto/MAILLOG_README.html, proto/postconf.proto,
+ global/mail_params.c, global/mail_params.h, global/Makefile.in,
+ master/master.c, postlog/postlog.c, postlogd/postlogd.c,
+ util/logwriter.c, util/logwriter.h, util/Makefile.in,
+ util/vstream.c.
s;\bmail[-</bB>]*\n*[ <bB>]*log_file_compressor\b;<a href="postconf.5.html#maillog_file_compressor">$&</a>;g;
s;\bmail[-</bB>]*\n*[ <bB>]*log_file_prefixes\b;<a href="postconf.5.html#maillog_file_prefixes">$&</a>;g;
s;\bmail[-</bB>]*\n*[ <bB>]*log_file_rotate_suffix\b;<a href="postconf.5.html#maillog_file_rotate_suffix">$&</a>;g;
+ s;\bmail[-</bB>]*\n*[ <bB>]*log_file_permissions\b;<a href="postconf.5.html#maillog_file_permissions">$&</a>;g;
s;\bpostlog_service_name\b;<a href="postconf.5.html#postlog_service_name">$&</a>;g;
s;\bpostlogd_watchdog_timeout\b;<a href="postconf.5.html#postlogd_watchdog_timeout">$&</a>;g;
/var/log/postfix.log. See also the "<a href="#logrotate">Logfile
rotation</a>" section below for logfile management. </p>
+<p> In the example below, specifying maillog_file_permissions is
+optional (Postfix 3.9 and later). The default value is 0600, i.e.,
+only the super-user can access the file; the value 0644 also
+adds 'group' and 'other' read access. </p>
+
<blockquote>
<pre>
# postfix stop
# postconf maillog_file=/var/log/postfix.log
+# postconf maillog_file_permissions=0644 # (Postfix 3.9 and later)
# postfix start
</pre>
</blockquote>
program is configured with the maillog_file_compressor parameter
(default: gzip). </p>
+<li> <p> The next time it logs an event, postlogd(8) will create a
+new logfile, with permissions specified with the maillog_file_permissions
+parameter (default: 0600). </p>
+
</ul>
<p> Notes: </p>
<p> This feature is available in Postfix 3.4 and later. </p>
+%PARAM maillog_file_permissions 0600
+
+<p> The file access permissions that will be set when the file
+$maillog_file is created for the first time, or when the file is
+created after an existing file is rotated. Specify one of: <b>0600</b>
+(only super-user read/write access), <b>0640</b> (adds 'group' read
+access), or <b>0644</b> (also adds 'other' read access). The leading
+'0' is optional. </p>
+
+<p> This feature is available in Postfix 3.9 and later. </p>
+
%PARAM info_log_address_format external
<p> The email address form that will be used in non-debug logging
postfix postfix c
aliasing Files proto aliases proto virtual postfix postfix c
proto proto aliases proto virtual proto ADDRESS_REWRITING_README html
+ master master c postlog postlog c postlogd postlogd c
+ proto postconf proto proto aliases proto virtual
bytecount
ipproto
cw
+uncreate
mail_params.o: ../../include/inet_addr_list.h
mail_params.o: ../../include/inet_proto.h
mail_params.o: ../../include/iostuff.h
+mail_params.o: ../../include/logwriter.h
mail_params.o: ../../include/midna_domain.h
mail_params.o: ../../include/mkmap.h
mail_params.o: ../../include/msg.h
/* char *var_maillog_file_pfxs;
/* char *var_maillog_file_comp;
/* char *var_maillog_file_stamp;
+/* char *var_maillog_file_perms;
/* char *var_postlog_service;
/*
/* char *var_dnssec_probe;
#include <vstring_vstream.h>
#include <iostuff.h>
#include <midna_domain.h>
+#include <logwriter.h>
/* Global library. */
char *var_maillog_file_pfxs;
char *var_maillog_file_comp;
char *var_maillog_file_stamp;
+char *var_maillog_file_perms;
char *var_postlog_service;
char *var_dnssec_probe;
VAR_MAILLOG_FILE_PFXS, DEF_MAILLOG_FILE_PFXS, &var_maillog_file_pfxs, 1, 0,
VAR_MAILLOG_FILE_COMP, DEF_MAILLOG_FILE_COMP, &var_maillog_file_comp, 1, 0,
VAR_MAILLOG_FILE_STAMP, DEF_MAILLOG_FILE_STAMP, &var_maillog_file_stamp, 1, 0,
+ VAR_MAILLOG_FILE_PERMS, DEF_MAILLOG_FILE_PERMS, &var_maillog_file_perms, 1, 0,
VAR_POSTLOG_SERVICE, DEF_POSTLOG_SERVICE, &var_postlog_service, 1, 0,
VAR_DNSSEC_PROBE, DEF_DNSSEC_PROBE, &var_dnssec_probe, 0, 0,
VAR_KNOWN_TCP_PORTS, DEF_KNOWN_TCP_PORTS, &var_known_tcp_ports, 0, 0,
dict_db_cache_size = var_db_read_buf;
dict_lmdb_map_size = var_lmdb_map_size;
inet_windowsize = var_inet_windowsize;
+ if (set_logwriter_create_perms(var_maillog_file_perms) < 0)
+ msg_warn("ignoring bad permissions: %s = %s",
+ VAR_MAILLOG_FILE_PERMS, var_maillog_file_perms);
/*
* Variables whose defaults are determined at runtime, after other
#define DEF_MAILLOG_FILE_STAMP "%Y%m%d-%H%M%S"
extern char *var_maillog_file_stamp;
+#define VAR_MAILLOG_FILE_PERMS "maillog_file_permissions"
+#define DEF_MAILLOG_FILE_PERMS "0600"
+extern char *var_maillog_file_perms;
+
#define VAR_POSTLOG_SERVICE "postlog_service_name"
#define DEF_POSTLOG_SERVICE MAIL_SERVICE_POSTLOG
extern char *var_postlog_service;
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20230508"
+#define MAIL_RELEASE_DATE "20230516"
#define MAIL_VERSION_NUMBER "3.9"
#ifdef SNAPSHOT
/* The external command to execute when a Postfix daemon program is
/* invoked with the -D option.
/* .IP "\fBinet_interfaces (all)\fR"
-/* The network interface addresses that this mail system receives
+/* The local network interface addresses that this mail system receives
/* mail on.
/* .IP "\fBinet_protocols (see 'postconf -d output')\fR"
/* The Internet protocols Postfix will attempt to use when making
/* or accepting connections.
/* .IP "\fBimport_environment (see 'postconf -d' output)\fR"
-/* The list of environment parameters that a privileged Postfix
+/* The list of environment variables that a privileged Postfix
/* process will import from a non-Postfix parent process, or name=value
/* environment overrides.
/* .IP "\fBmail_owner (postfix)\fR"
vstring_sprintf(lock_path, "%s/%s.pid", DEF_PID_DIR, var_procname);
if (test_lock && access(vstring_str(lock_path), F_OK) < 0)
exit(0);
- lock_fp = open_lock(vstring_str(lock_path), O_RDWR | O_CREAT, 0644, why);
+ lock_fp = open_lock(vstring_str(lock_path), O_RDWR | O_CREAT, 0600, why);
if (test_lock)
exit(lock_fp ? 0 : 1);
if (lock_fp == 0)
vstring_sprintf(data_lock_path, "%s/%s.lock", var_data_dir, var_procname);
set_eugid(var_owner_uid, var_owner_gid);
data_lock_fp =
- open_lock(vstring_str(data_lock_path), O_RDWR | O_CREAT, 0644, why);
+ open_lock(vstring_str(data_lock_path), O_RDWR | O_CREAT, 0600, why);
set_ugid(getuid(), getgid());
if (data_lock_fp == 0)
msg_fatal("open lock file %s: %s",
/* \fBpostlogd\fR(8) service.
/* .IP "\fBpostlog_service_name (postlog)\fR"
/* The name of the \fBpostlogd\fR(8) service entry in master.cf.
+/* .PP
+/* Available in Postfix 3.9 and later:
+/* .IP "\fBmaillog_file_permissions (0600)\fR"
+/* The file access permissions that will be set when the file
+/* $maillog_file is created for the first time, or when the file is
+/* created after an existing file is rotated.
/* SEE ALSO
/* postconf(5), configuration parameters
/* postlogd(8), Postfix logging
/* .IP "\fBpostlogd_watchdog_timeout (10s)\fR"
/* How much time a \fBpostlogd\fR(8) process may take to process a request
/* before it is terminated by a built-in watchdog timer.
+/* .PP
+/* Available in Postfix 3.9 and later:
+/* .IP "\fBmaillog_file_permissions (0600)\fR"
+/* The file access permissions that will be set when the file
+/* $maillog_file is created for the first time, or when the file is
+/* created after an existing file is rotated.
/* SEE ALSO
/* postconf(5), configuration parameters
/* syslogd(8), system logging
logwriter.o: logwriter.h
logwriter.o: msg.h
logwriter.o: mymalloc.h
+logwriter.o: name_code.h
logwriter.o: safe_open.h
logwriter.o: sys_defs.h
logwriter.o: vbuf.h
/* const char *path,
/* const char *buffer,
/* ssize_t buflen)
+/*
+/* int set_logwriter_create_perms(
+/* const char *mode)
/* DESCRIPTION
/* This module manages a logfile writer.
/*
/* logwriter_one_shot() combines all the above operations. The
/* result is zero if successful, VSTREAM_EOF if any operation
/* failed.
+/*
+/* set_logwriter_create_perms() sets the file permissions that
+/* will be used when creating a logfile. Valid inputs are
+/* "644", "640", and "600". Leading zeros are allowed and
+/* ignored.
+/* DIAGNOSTICS
+/* Fatal error: logfile create error; warning: logfile permission
+/* change error. set_logwriter_create_perms() returns the file
+/* create permission if the request is valid, -1 otherwise.
/* LICENSE
/* .ad
/* .fi
#include <mymalloc.h>
#include <safe_open.h>
#include <vstream.h>
+#include <name_code.h>
/*
* Application-specific.
*/
+static int logwriter_perms = 0600;
/* logwriter_open_or_die - open logfile */
#define NO_CHOWN (-1)
#define NO_CHGRP (-1)
- fp = safe_open(path, O_CREAT | O_WRONLY | O_APPEND, 0644,
+ fp = safe_open(path, O_CREAT | O_WRONLY | O_APPEND, logwriter_perms,
NO_STATP, NO_CHOWN, NO_CHGRP, why);
if (fp == 0)
msg_fatal("open logfile '%s': %s", path, vstring_str(why));
err |= logwriter_close(fp);
return (err ? VSTREAM_EOF : 0);
}
+
+/* set_logwriter_create_perms - logfile permission control */
+
+int set_logwriter_create_perms(const char *mode_str)
+{
+ static const NAME_CODE sane_perms[] = {
+ "644", 0644,
+ "640", 0640,
+ "600", 0600,
+ 0, -1,
+ };
+ int perms;
+
+ if ((perms = name_code(sane_perms, NAME_CODE_FLAG_NONE,
+ mode_str + strspn(mode_str, "0"))) != -1)
+ logwriter_perms = perms;
+ return (perms);
+}
extern int logwriter_write(VSTREAM *, const char *, ssize_t);
extern int logwriter_close(VSTREAM *);
extern int logwriter_one_shot(const char *, const char *, ssize_t);
+extern int set_logwriter_create_perms(const char *);
/* LICENSE
/* .ad
/* System library. */
#include <sys_defs.h>
+#include <sys/stat.h>
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
#include <stdarg.h>
#include <stddef.h>
VSTREAM *stream;
int fd;
- if ((fd = open(path, flags, mode)) < 0) {
+ /*
+ * To set permissions on new files only, we need to distinguish between
+ * creating a new file and opening an existing one.
+ */
+#define open_create(path, flags, mode) \
+ open((path), (flags) | (O_CREAT | O_EXCL), (mode))
+#define open_exist(path, flags, mode) \
+ open((path), (flags) & ~(O_CREAT | O_EXCL), (mode))
+
+ switch (flags & (O_CREAT | O_EXCL)) {
+ case O_CREAT:
+ fd = open_exist(path, flags, mode);
+ if (fd < 0 && errno == ENOENT) {
+ fd = open_create(path, flags, mode);
+ if (fd >= 0) {
+ if (fchmod(fd, mode) < 0) /* can't uncreate */
+ msg_warn("fchmod %s 0%o: %m", path, (unsigned) mode);
+ } else if ( /* fd < 0 && */ errno == EEXIST)
+ fd = open_exist(path, flags, mode);
+ }
+ break;
+ case O_CREAT | O_EXCL:
+ fd = open(path, flags, mode);
+ if (fd >= 0)
+ if (fchmod(fd, mode) < 0) /* can't uncreate */
+ msg_warn("fchmod %s 0%o: %m", path, (unsigned) mode);
+ break;
+ default:
+ fd = open(path, flags, mode);
+ break;
+ }
+ if (fd < 0) {
return (0);
} else {
stream = vstream_fdopen(fd, flags);