diff options
author | Karel Zak | 2015-10-29 11:18:21 +0100 |
---|---|---|
committer | Karel Zak | 2015-10-29 11:18:21 +0100 |
commit | 27a9eb5359c13e403cee2f89c0545c892b5327e3 (patch) | |
tree | 4a8b99aa7967e7e009b3a41bb1c99036fa77288a /misc-utils/logger.c | |
parent | logger: use iovec for all message (diff) | |
download | kernel-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.c | 28 |
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")); } |