chiark / gitweb /
log: pass SCM_CREDENTIALS when logging to syslog
authorLennart Poettering <lennart@poettering.net>
Fri, 20 Aug 2010 23:51:16 +0000 (01:51 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 20 Aug 2010 23:51:16 +0000 (01:51 +0200)
fixme
src/log.c
src/logger.c
src/manager.c

diff --git a/fixme b/fixme
index 2ff9a80ae36893773b03f109413de3d4c45a286f..2aa4dc62627f853a21c61723123b1d28d84d832e 100644 (file)
--- a/fixme
+++ b/fixme
 
 * 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:
 
index d0d98ddf753ac14bc97abc7708994e1cefd2c148..729b9ea4f6b2696f834459d20622e0caf082c85b 100644 (file)
--- 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;
index 64ac21404a5245d508e72d89fe74499a119b630e..95d58fc1b3d875cca408f159202621e86be91fdc 100644 (file)
@@ -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;
                 }
 
index 900a00a6f56eb8b8470a2dfd90bb3dfef9c2656c..09b2c789ed0c5de538f35ef07cd46a9fa61d366d 100644 (file)
@@ -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;