summaryrefslogtreecommitdiffstats
path: root/src/postlog
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 16:18:56 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 16:18:56 +0000
commitb7c15c31519dc44c1f691e0466badd556ffe9423 (patch)
treef944572f288bab482a615e09af627d9a2b6727d8 /src/postlog
parentInitial commit. (diff)
downloadpostfix-upstream.tar.xz
postfix-upstream.zip
Adding upstream version 3.7.10.upstream/3.7.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
l---------src/postlog/.indent.pro1
-rw-r--r--src/postlog/.printfck25
-rw-r--r--src/postlog/Makefile.in84
-rw-r--r--src/postlog/postlog.c372
-rw-r--r--src/postlogd/Makefile.in79
-rw-r--r--src/postlogd/postlogd.c267
6 files changed, 828 insertions, 0 deletions
diff --git a/src/postlog/.indent.pro b/src/postlog/.indent.pro
new file mode 120000
index 0000000..5c837ec
--- /dev/null
+++ b/src/postlog/.indent.pro
@@ -0,0 +1 @@
+../../.indent.pro \ No newline at end of file
diff --git a/src/postlog/.printfck b/src/postlog/.printfck
new file mode 100644
index 0000000..66016ed
--- /dev/null
+++ b/src/postlog/.printfck
@@ -0,0 +1,25 @@
+been_here_xt 2 0
+bounce_append 5 0
+cleanup_out_format 1 0
+defer_append 5 0
+mail_command 1 0
+mail_print 1 0
+msg_error 0 0
+msg_fatal 0 0
+msg_info 0 0
+msg_panic 0 0
+msg_warn 0 0
+opened 4 0
+post_mail_fprintf 1 0
+qmgr_message_bounce 2 0
+rec_fprintf 2 0
+sent 4 0
+smtp_cmd 1 0
+smtp_mesg_fail 2 0
+smtp_printf 1 0
+smtp_rcpt_fail 3 0
+smtp_site_fail 2 0
+udp_syslog 1 0
+vstream_fprintf 1 0
+vstream_printf 0 0
+vstring_sprintf 1 0
diff --git a/src/postlog/Makefile.in b/src/postlog/Makefile.in
new file mode 100644
index 0000000..297eae2
--- /dev/null
+++ b/src/postlog/Makefile.in
@@ -0,0 +1,84 @@
+SHELL = /bin/sh
+SRCS = postlog.c
+OBJS = postlog.o
+HDRS =
+TESTSRC =
+DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
+CFLAGS = $(DEBUG) $(OPT) $(DEFS)
+FILES = Makefile $(SRCS) $(HDRS)
+INC_DIR = ../../include
+TESTPROG=
+PROG = postlog
+LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
+ ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
+
+.c.o:; $(CC) $(CFLAGS) -c $*.c
+
+$(PROG): $(OBJS) $(LIBS)
+ $(CC) $(CFLAGS) $(SHLIB_RPATH) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
+
+$(OBJS): ../../conf/makedefs.out
+
+Makefile: Makefile.in
+ cat ../../conf/makedefs.out $? >$@
+
+test: $(TESTPROG)
+
+tests:
+
+root_tests:
+
+update: ../../bin/$(PROG)
+
+../../bin/$(PROG): $(PROG)
+ cp $(PROG) ../../bin
+
+printfck: $(OBJS) $(PROG)
+ rm -rf printfck
+ mkdir printfck
+ sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
+ set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
+ cd printfck; make "INC_DIR=../../../include" `cd ..; ls *.o`
+
+shar:
+ @shar $(FILES)
+
+lint:
+ lint $(SRCS)
+
+clean:
+ rm -f *.o *core $(PROG) $(TESTPROG) junk
+ rm -rf printfck
+
+tidy: clean
+
+depend: $(MAKES)
+ (sed '1,/^# do not edit/!d' Makefile.in; \
+ set -e; for i in [a-z][a-z0-9]*.c; do \
+ $(CC) -E $(DEFS) $(INCL) $$i | grep -v '[<>]' | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
+ -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' \
+ -e 's/o: \.\//o: /' -e p -e '}' ; \
+ done | LANG=C sort -u) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
+
+# do not edit below this line - it is generated by 'make depend'
+postlog.o: ../../include/argv.h
+postlog.o: ../../include/check_arg.h
+postlog.o: ../../include/clean_env.h
+postlog.o: ../../include/mail_conf.h
+postlog.o: ../../include/mail_params.h
+postlog.o: ../../include/mail_parm_split.h
+postlog.o: ../../include/mail_task.h
+postlog.o: ../../include/mail_version.h
+postlog.o: ../../include/maillog_client.h
+postlog.o: ../../include/msg.h
+postlog.o: ../../include/msg_output.h
+postlog.o: ../../include/msg_vstream.h
+postlog.o: ../../include/stringops.h
+postlog.o: ../../include/sys_defs.h
+postlog.o: ../../include/vbuf.h
+postlog.o: ../../include/vstream.h
+postlog.o: ../../include/vstring.h
+postlog.o: ../../include/vstring_vstream.h
+postlog.o: ../../include/warn_stat.h
+postlog.o: postlog.c
diff --git a/src/postlog/postlog.c b/src/postlog/postlog.c
new file mode 100644
index 0000000..eddc432
--- /dev/null
+++ b/src/postlog/postlog.c
@@ -0,0 +1,372 @@
+/*++
+/* NAME
+/* postlog 1
+/* SUMMARY
+/* Postfix-compatible logging utility
+/* SYNOPSIS
+/* .fi
+/* .ad
+/* \fBpostlog\fR [\fB-iv\fR] [\fB-c \fIconfig_dir\fR]
+/* [\fB-p \fIpriority\fR] [\fB-t \fItag\fR] [\fItext...\fR]
+/* DESCRIPTION
+/* The \fBpostlog\fR(1) command implements a Postfix-compatible logging
+/* interface for use in, for example, shell scripts.
+/*
+/* By default, \fBpostlog\fR(1) logs the \fItext\fR given on the command
+/* line as one record. If no \fItext\fR is specified on the command
+/* line, \fBpostlog\fR(1) reads from standard input and logs each input
+/* line as one record.
+/*
+/* By default, logging is sent to \fBsyslogd\fR(8) or
+/* \fBpostlogd\fR(8); when the
+/* standard error stream is connected to a terminal, logging
+/* is sent there as well.
+/*
+/* The following options are implemented:
+/* .IP "\fB-c \fIconfig_dir\fR"
+/* Read the \fBmain.cf\fR configuration file in the named directory
+/* instead of the default configuration directory.
+/* .IP "\fB-i\fR (obsolete)"
+/* Include the process ID in the logging tag. This flag is ignored as
+/* of Postfix 3.4, where the PID is always included.
+/* .IP "\fB-p \fIpriority\fR (default: \fBinfo\fR)"
+/* Specifies the logging severity: \fBinfo\fR, \fBwarn\fR,
+/* \fBerror\fR, \fBfatal\fR, or \fBpanic\fR. With Postfix 3.1
+/* and later, the program will pause for 1 second after reporting
+/* a \fBfatal\fR or \fBpanic\fR condition, just like other
+/* Postfix programs.
+/* .IP "\fB-t \fItag\fR"
+/* Specifies the logging tag, that is, the identifying name that
+/* appears at the beginning of each logging record. A default tag
+/* 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.
+/* 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
+/* .IP MAIL_CONFIG
+/* Directory with the \fBmain.cf\fR file.
+/* CONFIGURATION PARAMETERS
+/* .ad
+/* .fi
+/* The following \fBmain.cf\fR parameters are especially relevant to
+/* this program.
+/*
+/* The text below provides only a parameter summary. See
+/* \fBpostconf\fR(5) for more details including examples.
+/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
+/* The default location of the Postfix main.cf and master.cf
+/* configuration files.
+/* .IP "\fBimport_environment (see 'postconf -d' output)\fR"
+/* The list of environment parameters that a privileged Postfix
+/* process will import from a non-Postfix parent process, or name=value
+/* environment overrides.
+/* .IP "\fBsyslog_facility (mail)\fR"
+/* The syslog facility of Postfix logging.
+/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
+/* A prefix that is prepended to the process name in syslog
+/* records, so that, for example, "smtpd" becomes "prefix/smtpd".
+/* .PP
+/* Available in Postfix 3.4 and later:
+/* .IP "\fBmaillog_file (empty)\fR"
+/* The name of an optional logfile that is written by the Postfix
+/* \fBpostlogd\fR(8) service.
+/* .IP "\fBpostlog_service_name (postlog)\fR"
+/* The name of the \fBpostlogd\fR(8) service entry in master.cf.
+/* SEE ALSO
+/* postconf(5), configuration parameters
+/* postlogd(8), Postfix logging
+/* syslogd(8), system logging
+/* LICENSE
+/* .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
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstring.h>
+#include <vstream.h>
+#include <vstring_vstream.h>
+#include <msg_output.h>
+#include <msg_vstream.h>
+#include <warn_stat.h>
+#include <clean_env.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <mail_params.h> /* XXX right place for LOG_FACILITY? */
+#include <mail_version.h>
+#include <mail_conf.h>
+#include <mail_task.h>
+#include <mail_parm_split.h>
+#include <maillog_client.h>
+
+/* 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.
+ */
+struct level_table {
+ char *name;
+ int level;
+};
+
+static struct level_table level_table[] = {
+ "info", MSG_INFO,
+ "warn", MSG_WARN,
+ "warning", MSG_WARN,
+ "error", MSG_ERROR,
+ "err", MSG_ERROR,
+ "fatal", MSG_FATAL,
+ "crit", MSG_FATAL,
+ "panic", MSG_PANIC,
+ 0,
+};
+
+#define POSTLOG_CMD "postlog"
+
+/* level_map - lookup facility or severity value */
+
+static int level_map(char *name)
+{
+ struct level_table *t;
+
+ for (t = level_table; t->name; t++)
+ if (strcasecmp(t->name, name) == 0)
+ return (t->level);
+ msg_fatal("bad severity: \"%s\"", name);
+}
+
+/* log_argv - log the command line */
+
+static void log_argv(int level, char **argv)
+{
+ VSTRING *buf = vstring_alloc(100);
+
+ while (*argv) {
+ vstring_strcat(buf, *argv++);
+ if (*argv)
+ vstring_strcat(buf, " ");
+ }
+ msg_printf(level, "%s", vstring_str(buf));
+ vstring_free(buf);
+}
+
+/* log_stream - log lines from a stream */
+
+static void log_stream(int level, VSTREAM *fp)
+{
+ VSTRING *buf = vstring_alloc(100);
+
+ while (vstring_get_nonl(buf, fp) != VSTREAM_EOF)
+ msg_printf(level, "%s", vstring_str(buf));
+ vstring_free(buf);
+}
+
+MAIL_VERSION_STAMP_DECLARE;
+
+/* main - logger */
+
+int main(int argc, char **argv)
+{
+ struct stat st;
+ int fd;
+ int ch;
+ const char *tag;
+ char *unsanitized_tag;
+ int level = MSG_INFO;
+ ARGV *import_env;
+
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
+ /*
+ * Be consistent with file permissions.
+ */
+ umask(022);
+
+ /*
+ * To minimize confusion, make sure that the standard file descriptors
+ * are open before opening anything else. XXX Work around for 44BSD where
+ * fstat can return EBADF on an open file descriptor.
+ */
+ for (fd = 0; fd < 3; fd++)
+ if (fstat(fd, &st) == -1
+ && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
+ msg_fatal("open /dev/null: %m");
+
+ /*
+ * 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);
+ maillog_client_init(tag, MAILLOG_CLIENT_FLAG_LOGWRITER_FALLBACK);
+
+ /*
+ * Check the Postfix library version as soon as we enable logging.
+ */
+ MAIL_VERSION_CHECK;
+
+ /*
+ * 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.
+ */
+ unsanitized_tag = 0;
+ while ((ch = GETOPT(argc, argv, "c:ip:t:v")) > 0) {
+ switch (ch) {
+ default:
+ msg_fatal("usage: %s [-c config_dir] [-i] [-p priority] [-t tag] [-v] [text]", argv[0]);
+ break;
+ case 'c':
+ if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
+ msg_fatal("out of memory");
+ break;
+ case 'i':
+ break;
+ case 'p':
+ level = level_map(optarg);
+ break;
+ case 't':
+ unsanitized_tag = optarg;
+ break;
+ case 'v':
+ msg_verbose++;
+ break;
+ }
+ }
+
+ /*
+ * Process the main.cf file. This may change the syslog_name setting and
+ * may require that mail_task() be re-evaluated.
+ */
+ mail_conf_read();
+ /* 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);
+ clean_env(import_env->argv);
+ argv_free(import_env);
+
+ /*
+ * Sanitize the user-specified tag. The result depends on the value of
+ * var_smtputf8_enable, therefore this code is after the mail_conf_read()
+ * call.
+ */
+ if (unsanitized_tag != 0)
+ tag = printable(unsanitized_tag, '?');
+
+ /*
+ * Re-initialize the logging, this time with the tag specified in main.cf
+ * or on the command line.
+ */
+ if (isatty(STDERR_FILENO))
+ 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.
+ */
+ if (argc > optind) {
+ log_argv(level, argv + optind);
+ } else {
+ log_stream(level, VSTREAM_IN);
+ }
+
+ /*
+ * Consistency with msg(3) functions.
+ */
+ if (level >= MSG_FATAL)
+ sleep(1);
+ exit(0);
+}
diff --git a/src/postlogd/Makefile.in b/src/postlogd/Makefile.in
new file mode 100644
index 0000000..21fad76
--- /dev/null
+++ b/src/postlogd/Makefile.in
@@ -0,0 +1,79 @@
+SHELL = /bin/sh
+SRCS = postlogd.c
+OBJS = postlogd.o
+HDRS =
+TESTSRC =
+DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
+CFLAGS = $(DEBUG) $(OPT) $(DEFS)
+TESTPROG=
+PROG = postlogd
+INC_DIR = ../../include
+LIBS = ../../lib/lib$(LIB_PREFIX)dns$(LIB_SUFFIX) \
+ ../../lib/lib$(LIB_PREFIX)master$(LIB_SUFFIX) \
+ ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
+ ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
+
+.c.o:; $(CC) $(CFLAGS) -c $*.c
+
+$(PROG): $(OBJS) $(LIBS)
+ $(CC) $(CFLAGS) $(SHLIB_RPATH) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
+
+$(OBJS): ../../conf/makedefs.out
+
+Makefile: Makefile.in
+ cat ../../conf/makedefs.out $? >$@
+
+test: $(TESTPROG)
+
+tests: test
+
+root_tests:
+
+update: ../../libexec/$(PROG)
+
+../../libexec/$(PROG): $(PROG)
+ cp $(PROG) ../../libexec
+
+printfck: $(OBJS) $(PROG)
+ rm -rf printfck
+ mkdir printfck
+ sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
+ set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
+ cd printfck; make "INC_DIR=../../../include" `cd ..; ls *.o`
+
+lint:
+ lint $(DEFS) $(SRCS) $(LINTFIX)
+
+clean:
+ rm -f *.o *core $(PROG) $(TESTPROG) junk
+ rm -rf printfck
+
+tidy: clean
+
+depend: $(MAKES)
+ (sed '1,/^# do not edit/!d' Makefile.in; \
+ set -e; for i in [a-z][a-z0-9]*.c; do \
+ $(CC) -E $(DEFS) $(INCL) $$i | grep -v '[<>]' | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
+ -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' \
+ -e 's/o: \.\//o: /' -e p -e '}' ; \
+ done | LANG=C sort -u) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
+ @$(EXPORT) make -f Makefile.in Makefile 1>&2
+
+# do not edit below this line - it is generated by 'make depend'
+postlogd.o: ../../include/check_arg.h
+postlogd.o: ../../include/htable.h
+postlogd.o: ../../include/logwriter.h
+postlogd.o: ../../include/mail_conf.h
+postlogd.o: ../../include/mail_params.h
+postlogd.o: ../../include/mail_server.h
+postlogd.o: ../../include/mail_task.h
+postlogd.o: ../../include/mail_version.h
+postlogd.o: ../../include/maillog_client.h
+postlogd.o: ../../include/msg.h
+postlogd.o: ../../include/msg_logger.h
+postlogd.o: ../../include/stringops.h
+postlogd.o: ../../include/sys_defs.h
+postlogd.o: ../../include/vbuf.h
+postlogd.o: ../../include/vstream.h
+postlogd.o: ../../include/vstring.h
+postlogd.o: postlogd.c
diff --git a/src/postlogd/postlogd.c b/src/postlogd/postlogd.c
new file mode 100644
index 0000000..902cbe5
--- /dev/null
+++ b/src/postlogd/postlogd.c
@@ -0,0 +1,267 @@
+/*++
+/* NAME
+/* postlogd 8
+/* SUMMARY
+/* Postfix internal log server
+/* SYNOPSIS
+/* \fBpostlogd\fR [generic Postfix daemon options]
+/* DESCRIPTION
+/* This program logs events on behalf of Postfix programs
+/* when the maillog configuration parameter specifies a non-empty
+/* value.
+/* BUGS
+/* Non-daemon Postfix programs don't know that they should log
+/* to the internal logging service before they have processed
+/* command-line options and main.cf parameters. These programs
+/* still log earlier events to the syslog service.
+/*
+/* If Postfix is down, the non-daemon programs \fBpostfix\fR(1),
+/* \fBpostsuper\fR(1), \fBpostmulti\fR(1), and \fBpostlog\fR(1),
+/* will log directly to \fB$maillog_file\fR. These programs
+/* expect to run with root privileges, for example during
+/* Postfix start-up, reload, or shutdown.
+/*
+/* Other non-daemon Postfix programs will never write directly to
+/* \fB$maillog_file\fR (also, logging to stdout would interfere
+/* with the operation of some of these programs). These programs
+/* can log to \fBpostlogd\fR(8) if they are run by the super-user,
+/* or if their executable file has set-gid permission. Do not
+/* set this permission on programs other than \fBpostdrop\fR(1),
+/* \fBpostqueue\fR(1) and (Postfix >= 3.7) \fBpostlog\fR(1).
+/* CONFIGURATION PARAMETERS
+/* .ad
+/* .fi
+/* Changes to \fBmain.cf\fR are picked up automatically, as
+/* \fBpostlogd\fR(8) processes run for only a limited amount
+/* of time. Use the command "\fBpostfix reload\fR" to speed
+/* up a change.
+/*
+/* The text below provides only a parameter summary. See
+/* \fBpostconf\fR(5) for more details including examples.
+/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
+/* The default location of the Postfix main.cf and master.cf
+/* configuration files.
+/* .IP "\fBmaillog_file (empty)\fR"
+/* The name of an optional logfile that is written by the Postfix
+/* \fBpostlogd\fR(8) service.
+/* .IP "\fBprocess_id (read-only)\fR"
+/* The process ID of a Postfix command or daemon process.
+/* .IP "\fBprocess_name (read-only)\fR"
+/* The process name of a Postfix command or daemon process.
+/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
+/* A prefix that is prepended to the process name in syslog
+/* records, so that, for example, "smtpd" becomes "prefix/smtpd".
+/* .IP "\fBservice_name (read-only)\fR"
+/* The master.cf service name of a Postfix daemon process.
+/* .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.
+/* SEE ALSO
+/* postconf(5), configuration parameters
+/* syslogd(8), system logging
+/* README_FILES
+/* .ad
+/* .fi
+/* Use "\fBpostconf readme_directory\fR" or
+/* "\fBpostconf html_directory\fR" to locate this information.
+/* .na
+/* .nf
+/* MAILLOG_README, Postfix logging to file or stdout
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* HISTORY
+/* .ad
+/* .fi
+/* This service was introduced with Postfix version 3.4.
+/* AUTHOR(S)
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
+
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+
+ /*
+ * Utility library.
+ */
+#include <logwriter.h>
+#include <msg.h>
+#include <msg_logger.h>
+#include <stringops.h>
+#include <vstream.h>
+
+ /*
+ * Global library.
+ */
+#include <mail_params.h>
+#include <mail_task.h>
+#include <mail_version.h>
+#include <maillog_client.h>
+
+ /*
+ * Server skeleton.
+ */
+#include <mail_server.h>
+
+ /*
+ * Tunable parameters.
+ */
+int var_postlogd_watchdog;
+
+ /*
+ * Silly little macros.
+ */
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+ /*
+ * Logfile stream.
+ */
+static VSTREAM *postlogd_stream = 0;
+
+/* postlogd_fallback - log messages from postlogd(8) itself */
+
+static void postlogd_fallback(const char *buf)
+{
+ (void) logwriter_write(postlogd_stream, buf, strlen(buf));
+}
+
+/* postlogd_service - perform service for client */
+
+static void postlogd_service(char *buf, ssize_t len, char *unused_service,
+ char **unused_argv)
+{
+
+ if (postlogd_stream) {
+ (void) logwriter_write(postlogd_stream, buf, len);
+ }
+
+ /*
+ * After a configuration change that removes the maillog_file pathname,
+ * this service may still receive messages (after "postfix reload" or
+ * after process refresh) from programs that use the old maillog_file
+ * setting. Redirect those messages to the current logging mechanism.
+ */
+ else {
+ char *bp = buf;
+ char *progname_pid;
+
+ /*
+ * Avoid surprises: strip off the date, time, host, and program[pid]:
+ * prefix that were prepended by msg_logger(3). Then, hope that the
+ * current logging driver suppresses its own PID, when it sees that
+ * there is a PID embedded in the 'program name'.
+ */
+ (void) mystrtok(&bp, CHARS_SPACE); /* month */
+ (void) mystrtok(&bp, CHARS_SPACE); /* day */
+ (void) mystrtok(&bp, CHARS_SPACE); /* time */
+ (void) mystrtok(&bp, CHARS_SPACE); /* host */
+ progname_pid = mystrtok(&bp, ":" CHARS_SPACE); /* name[pid] sans ':' */
+ bp += strspn(bp, CHARS_SPACE);
+ if (progname_pid)
+ maillog_client_init(progname_pid, MAILLOG_CLIENT_FLAG_NONE);
+ msg_info("%.*s", (int) (len - (bp - buf)), bp);
+
+ /*
+ * Restore the program name, in case postlogd(8) needs to log
+ * something about itself. We have to call maillog_client_init() in
+ * any case, because neither msg_syslog_init() nor openlog() make a
+ * copy of the name argument. We can't leave that pointing into the
+ * middle of the above message buffer.
+ */
+ maillog_client_init(mail_task((char *) 0), MAILLOG_CLIENT_FLAG_NONE);
+ }
+}
+
+/* pre_jail_init - pre-jail handling */
+
+static void pre_jail_init(char *unused_service_name, char **argv)
+{
+
+ /*
+ * During process initialization, the postlogd daemon will log events to
+ * the postlog socket, so that they can be logged to file later. Once the
+ * postlogd daemon is handling requests, it will stop logging to the
+ * postlog socket and will instead write to the logfile, to avoid
+ * infinite recursion.
+ */
+
+ /*
+ * Sanity check. This service takes no command-line arguments.
+ */
+ if (argv[0])
+ msg_fatal("unexpected command-line argument: %s", argv[0]);
+
+ /*
+ * After a configuration change that removes the maillog_file pathname,
+ * this service may still receive messages from processes that still use
+ * the old configuration. Those messages will have to be redirected to
+ * the current logging subsystem.
+ */
+ if (*var_maillog_file != 0) {
+
+ /*
+ * Instantiate the logwriter or bust.
+ */
+ postlogd_stream = logwriter_open_or_die(var_maillog_file);
+
+ /*
+ * Inform the msg_logger client to stop using the postlog socket, and
+ * to call our logwriter.
+ */
+ msg_logger_control(CA_MSG_LOGGER_CTL_FALLBACK_ONLY,
+ CA_MSG_LOGGER_CTL_FALLBACK_FN(postlogd_fallback),
+ CA_MSG_LOGGER_CTL_END);
+ }
+}
+
+/* post_jail_init - post-jail initialization */
+
+static void post_jail_init(char *unused_name, char **unused_argv)
+{
+
+ /*
+ * Prevent automatic process suicide after a limited number of client
+ * requests. It is OK to terminate after a limited amount of idle time.
+ */
+ var_use_limit = 0;
+}
+
+MAIL_VERSION_STAMP_DECLARE;
+
+/* main - pass control to the multi-threaded skeleton */
+
+int main(int argc, char **argv)
+{
+ static const CONFIG_TIME_TABLE time_table[] = {
+ VAR_POSTLOGD_WATCHDOG, DEF_POSTLOGD_WATCHDOG, &var_postlogd_watchdog, 10, 0,
+ 0,
+ };
+
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
+ /*
+ * This is a datagram service, not a stream service, so that postlogd can
+ * restart immediately after "postfix reload" without requiring clients
+ * to resend messages. Those messages remain queued in the kernel until a
+ * new postlogd process retrieves them. It would be unreasonable to
+ * require that clients retransmit logs, especially in the case of a
+ * fatal or panic error.
+ */
+ dgram_server_main(argc, argv, postlogd_service,
+ CA_MAIL_SERVER_TIME_TABLE(time_table),
+ CA_MAIL_SERVER_PRE_INIT(pre_jail_init),
+ CA_MAIL_SERVER_POST_INIT(post_jail_init),
+ CA_MAIL_SERVER_SOLITARY,
+ CA_MAIL_SERVER_WATCHDOG(&var_postlogd_watchdog),
+ 0);
+}