diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-08-21 01:51:16 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-08-21 01:51:16 +0200 |
commit | 6309077509a8221b1b298ba9dd05143908f9939c (patch) | |
tree | 0bfbdd884af9ced3f977b027ce6cbd962cdcc485 /src | |
parent | 5845b46ba3883fe0b21217c65f41383eb52cddb6 (diff) |
log: pass SCM_CREDENTIALS when logging to syslog
Diffstat (limited to 'src')
-rw-r--r-- | src/log.c | 17 | ||||
-rw-r--r-- | src/logger.c | 51 | ||||
-rw-r--r-- | src/manager.c | 2 |
3 files changed, 56 insertions, 14 deletions
@@ -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 64ac21404a..95d58fc1b3 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 900a00a6f5..09b2c789ed 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; |