From 6309077509a8221b1b298ba9dd05143908f9939c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 21 Aug 2010 01:51:16 +0200 Subject: [PATCH] log: pass SCM_CREDENTIALS when logging to syslog --- fixme | 15 +++++++++++++++ src/log.c | 17 +++++++++++++++++ src/logger.c | 51 ++++++++++++++++++++++++++++++++++++++------------- src/manager.c | 2 +- 4 files changed, 71 insertions(+), 14 deletions(-) diff --git a/fixme b/fixme index 2ff9a80a..2aa4dc62 100644 --- a/fixme +++ b/fixme @@ -58,6 +58,20 @@ * bash completion a la gdbus +* use sulogin + +* [Install] section rausmachen für early boot krams, uznd per default nach /lib linken + +* s/Exited/Process/ in systemctl status + +* systemctl status: "active since 5min" + +* systemctl list-jobs deps anzeigen + +* /etc/systemd/system.conf: mounten per default option + +* ConditionFileExists=, ConditionKernelCommandLine=, ConditionEnvironment= mit ! + External: * place /etc/inittab with explaining blurb. @@ -103,6 +117,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=617327 -- gpm https://bugzilla.redhat.com/show_bug.cgi?id=617330 -- pcsc-lite https://bugzilla.redhat.com/show_bug.cgi?id=617321 -- audit https://bugzilla.redhat.com/show_bug.cgi?id=617316 -- abrt +http://sources.redhat.com/bugzilla/show_bug.cgi?id=11930 -- glibc Regularly: diff --git a/src/log.c b/src/log.c index d0d98ddf..729b9ea4 100644 --- a/src/log.c +++ b/src/log.c @@ -249,6 +249,11 @@ static int write_to_syslog( char header_priority[16], header_time[64], header_pid[16]; struct iovec iovec[5]; struct msghdr msghdr; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + struct ucred *ucred; time_t t; struct tm *tm; @@ -275,9 +280,21 @@ static int write_to_syslog( IOVEC_SET_STRING(iovec[3], header_pid); IOVEC_SET_STRING(iovec[4], buffer); + zero(control); + control.cmsghdr.cmsg_level = SOL_SOCKET; + control.cmsghdr.cmsg_type = SCM_CREDENTIALS; + control.cmsghdr.cmsg_len = CMSG_LEN(sizeof(struct ucred)); + + ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr); + ucred->pid = getpid(); + ucred->uid = getuid(); + ucred->gid = getgid(); + zero(msghdr); msghdr.msg_iov = iovec; msghdr.msg_iovlen = ELEMENTSOF(iovec); + msghdr.msg_control = &control; + msghdr.msg_controllen = control.cmsghdr.cmsg_len; if (sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL) < 0) return -errno; diff --git a/src/logger.c b/src/logger.c index 64ac2140..95d58fc1 100644 --- a/src/logger.c +++ b/src/logger.c @@ -81,6 +81,7 @@ struct Stream { char *process; pid_t pid; uid_t uid; + gid_t gid; bool prefix; @@ -151,6 +152,21 @@ static int stream_log(Stream *s, char *p, usec_t ts) { if (s->target == STREAM_SYSLOG) { struct msghdr msghdr; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + struct ucred *ucred; + + zero(control); + control.cmsghdr.cmsg_level = SOL_SOCKET; + control.cmsghdr.cmsg_type = SCM_CREDENTIALS; + control.cmsghdr.cmsg_len = CMSG_LEN(sizeof(struct ucred)); + + ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr); + ucred->pid = s->pid; + ucred->uid = s->uid; + ucred->gid = s->gid; IOVEC_SET_STRING(iovec[1], header_time); IOVEC_SET_STRING(iovec[2], s->process); @@ -160,6 +176,8 @@ static int stream_log(Stream *s, char *p, usec_t ts) { zero(msghdr); msghdr.msg_iov = iovec; msghdr.msg_iovlen = ELEMENTSOF(iovec); + msghdr.msg_control = &control; + msghdr.msg_controllen = control.cmsghdr.cmsg_len; if (sendmsg(s->server->syslog_fd, &msghdr, MSG_NOSIGNAL) < 0) return -errno; @@ -208,12 +226,12 @@ static int stream_line(Stream *s, char *p, usec_t ts) { case STREAM_PRIORITY: if ((r = safe_atoi(p, &s->priority)) < 0) { - log_warning("Failed to parse log priority line: %s", strerror(errno)); + log_warning("Failed to parse log priority line: %m"); return r; } if (s->priority < 0) { - log_warning("Log priority negative: %s", strerror(errno)); + log_warning("Log priority negative: %m"); return -ERANGE; } @@ -284,7 +302,7 @@ static int stream_process(Stream *s, usec_t ts) { if (errno == EAGAIN) return 0; - log_warning("Failed to read from stream: %s", strerror(errno)); + log_warning("Failed to read from stream: %m"); return -1; } @@ -373,6 +391,7 @@ static int stream_new(Server *s, int server_fd) { stream->pid = ucred.pid; stream->uid = ucred.uid; + stream->gid = ucred.gid; stream->server = s; LIST_PREPEND(Stream, stream, s->streams, stream); @@ -424,7 +443,7 @@ static int server_init(Server *s, unsigned n_sockets) { if ((s->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) { r = -errno; - log_error("Failed to create epoll object: %s", strerror(errno)); + log_error("Failed to create epoll object: %m"); goto fail; } @@ -445,19 +464,25 @@ static int server_init(Server *s, unsigned n_sockets) { goto fail; } + /* We use ev.data.ptr instead of ev.data.fd here, + * since on 64bit archs fd is 32bit while a pointer is + * 64bit. To make sure we can easily distuingish fd + * values and pointer values we want to make sure to + * write the full field unconditionally. */ + zero(ev); ev.events = EPOLLIN; - ev.data.ptr = UINT_TO_PTR(fd); + ev.data.ptr = INT_TO_PTR(fd); if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { r = -errno; - log_error("Failed to add server fd to epoll object: %s", strerror(errno)); + log_error("Failed to add server fd to epoll object: %m"); goto fail; } } if ((s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { r = -errno; - log_error("Failed to create log fd: %s", strerror(errno)); + log_error("Failed to create log fd: %m"); goto fail; } @@ -467,13 +492,13 @@ static int server_init(Server *s, unsigned n_sockets) { if (connect(s->syslog_fd, &sa.sa, sizeof(sa)) < 0) { r = -errno; - log_error("Failed to connect log socket to /dev/log: %s", strerror(errno)); + log_error("Failed to connect log socket to /dev/log: %m"); goto fail; } /* /dev/kmsg logging is strictly optional */ if ((s->kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) - log_warning("Failed to open /dev/kmsg for logging, disabling kernel log buffer support: %s", strerror(errno)); + log_warning("Failed to open /dev/kmsg for logging, disabling kernel log buffer support: %m"); return 0; @@ -493,15 +518,15 @@ static int process_event(Server *s, struct epoll_event *ev) { * first 4k usually are part of a seperate null pointer * dereference page. */ - if (PTR_TO_UINT(ev->data.ptr) >= SD_LISTEN_FDS_START && - PTR_TO_UINT(ev->data.ptr) < SD_LISTEN_FDS_START+s->n_server_fd) { + if (PTR_TO_INT(ev->data.ptr) >= SD_LISTEN_FDS_START && + PTR_TO_INT(ev->data.ptr) < SD_LISTEN_FDS_START+(int)s->n_server_fd) { if (ev->events != EPOLLIN) { log_info("Got invalid event from epoll. (1)"); return -EIO; } - if ((r = stream_new(s, PTR_TO_UINT(ev->data.ptr))) < 0) { + if ((r = stream_new(s, PTR_TO_INT(ev->data.ptr))) < 0) { log_info("Failed to accept new connection: %s", strerror(-r)); return r; } @@ -579,7 +604,7 @@ int main(int argc, char *argv[]) { if (errno == EINTR) continue; - log_error("epoll_wait() failed: %s", strerror(errno)); + log_error("epoll_wait() failed: %m"); goto fail; } diff --git a/src/manager.c b/src/manager.c index 900a00a6..09b2c789 100644 --- a/src/manager.c +++ b/src/manager.c @@ -1931,7 +1931,7 @@ static int manager_process_signal_fd(Manager *m) { if (n >= 0) return -EIO; - if (errno == EAGAIN) + if (errno == EINTR || errno == EAGAIN) break; return -errno; -- 2.39.5