summaryrefslogtreecommitdiffstats
path: root/misc-utils/logger.c
diff options
context:
space:
mode:
authorKarel Zak2015-10-29 11:18:21 +0100
committerKarel Zak2015-10-29 11:18:21 +0100
commit27a9eb5359c13e403cee2f89c0545c892b5327e3 (patch)
tree4a8b99aa7967e7e009b3a41bb1c99036fa77288a /misc-utils/logger.c
parentlogger: use iovec for all message (diff)
downloadkernel-qcow2-util-linux-27a9eb5359c13e403cee2f89c0545c892b5327e3.tar.gz
kernel-qcow2-util-linux-27a9eb5359c13e403cee2f89c0545c892b5327e3.tar.xz
kernel-qcow2-util-linux-27a9eb5359c13e403cee2f89c0545c892b5327e3.zip
logger: use --id as local socket credentials
If you have really paranoid syslog (or systemd who listens on /dev/log) then it replaces in the message PID with a real PID from socket header credentials: # echo $PPID 1550 # logger -p info --stderr --id=$PPID "This is message baby!" <14>Oct 29 11:22:13 kzak[1550]: This is message baby! # journald -n 1 Oct 29 11:22:13 ws kzak[22100]: This is message baby! ^^^^^ This patch forces kernel to accept another *valid* PID if logger(1) executed with root permissions; improved version: # logger -p info --stderr --id=$PPID "This is message baby!" <14>Oct 29 11:26:00 kzak[1550]: This is message baby! # journald -n 1 Oct 29 11:26:00 ws kzak[1550]: This is message baby! Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils/logger.c')
-rw-r--r--misc-utils/logger.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/misc-utils/logger.c b/misc-utils/logger.c
index d5683b691..e4cb12ae9 100644
--- a/misc-utils/logger.c
+++ b/misc-utils/logger.c
@@ -51,6 +51,8 @@
#include <netdb.h>
#include <getopt.h>
#include <pwd.h>
+#include <sys/types.h>
+#include <signal.h>
#include "all-io.h"
#include "c.h"
@@ -444,6 +446,12 @@ static void write_output(const struct logger_ctl *ctl, const char *const msg)
if (!ctl->noact) {
struct msghdr msg = { 0 };
+ struct cmsghdr *cmhp;
+ struct ucred *cred;
+ union {
+ struct cmsghdr cmh;
+ char control[CMSG_SPACE(sizeof(struct ucred))];
+ } cbuf;
/* 4) add extra \n to make sure message is terminated */
if ((ctl->socket_type == TYPE_TCP) && !ctl->octet_count)
@@ -452,6 +460,26 @@ static void write_output(const struct logger_ctl *ctl, const char *const msg)
msg.msg_iov = iov;
msg.msg_iovlen = iovlen;
+ /* syslog/journald may follow local socket credentials rather
+ * than in the message PID. If we use --id as root than we can
+ * force kernel to accept another valid PID than the real logger(1)
+ * PID.
+ */
+ if (ctl->pid && !ctl->server && ctl->pid != getpid()
+ && geteuid() == 0 && kill(ctl->pid, 0) == 0) {
+
+ msg.msg_control = cbuf.control;
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred)); //sizeof(cbuf);
+
+ cmhp = CMSG_FIRSTHDR(&msg);
+ cmhp->cmsg_len = CMSG_LEN(sizeof(struct ucred));
+ cmhp->cmsg_level = SOL_SOCKET;
+ cmhp->cmsg_type = SCM_CREDENTIALS;
+ cred = (struct ucred *) CMSG_DATA(cmhp);
+
+ cred->pid = ctl->pid;
+ }
+
if (sendmsg(ctl->fd, &msg, 0) < 0)
warn(_("send message failed"));
}