summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-08-21 01:51:16 +0200
committerLennart Poettering <lennart@poettering.net>2010-08-21 01:51:16 +0200
commit6309077509a8221b1b298ba9dd05143908f9939c (patch)
tree0bfbdd884af9ced3f977b027ce6cbd962cdcc485 /src
parent5845b46ba3883fe0b21217c65f41383eb52cddb6 (diff)
log: pass SCM_CREDENTIALS when logging to syslog
Diffstat (limited to 'src')
-rw-r--r--src/log.c17
-rw-r--r--src/logger.c51
-rw-r--r--src/manager.c2
3 files changed, 56 insertions, 14 deletions
diff --git a/src/log.c b/src/log.c
index d0d98ddf75..729b9ea4f6 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 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;