chiark / gitweb /
journal: pass the *pid* to sd_pid_get_owner_uid()
[elogind.git] / src / journal / journald-server.c
index 1375d7a98e2c6e2d1a7f8a8a4c19fbfa4811fa12..364ab0f113f615bfc137a4723947ca67d710123c 100644 (file)
@@ -34,6 +34,7 @@
 #include <systemd/sd-login.h>
 #endif
 
+#include "fileio.h"
 #include "mkdir.h"
 #include "hashmap.h"
 #include "journal-file.h"
@@ -173,7 +174,7 @@ static uint64_t available_space(Server *s) {
 }
 
 static void server_read_file_gid(Server *s) {
-        const char *adm = "adm";
+        const char *g = "systemd-journal";
         int r;
 
         assert(s);
@@ -181,9 +182,9 @@ static void server_read_file_gid(Server *s) {
         if (s->file_gid_valid)
                 return;
 
-        r = get_group_creds(&adm, &s->file_gid);
+        r = get_group_creds(&g, &s->file_gid);
         if (r < 0)
-                log_warning("Failed to resolve 'adm' group: %s", strerror(-r));
+                log_warning("Failed to resolve '%s' group: %s", g, strerror(-r));
 
         /* if we couldn't read the gid, then it will be 0, but that's
          * fine and we shouldn't try to resolve the group again, so
@@ -514,9 +515,8 @@ static void dispatch_message_real(
         sd_id128_t id;
         int r;
         char *t;
-        uid_t loginuid = 0, realuid = 0;
-        uid_t journal_uid;
-        bool loginuid_valid = false;
+        uid_t realuid = 0, owner = 0, journal_uid;
+        bool owner_valid = false;
 
         assert(s);
         assert(iovec);
@@ -525,9 +525,7 @@ static void dispatch_message_real(
 
         if (ucred) {
                 uint32_t audit;
-#ifdef HAVE_LOGIND
-                uid_t owner;
-#endif
+                uid_t loginuid;
 
                 realuid = ucred->uid;
 
@@ -573,11 +571,9 @@ static void dispatch_message_real(
                                 IOVEC_SET_STRING(iovec[n++], audit_session);
 
                 r = audit_loginuid_from_pid(ucred->pid, &loginuid);
-                if (r >= 0) {
-                        loginuid_valid = true;
+                if (r >= 0)
                         if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0)
                                 IOVEC_SET_STRING(iovec[n++], audit_loginuid);
-                }
 
                 t = shortened_cgroup_path(ucred->pid);
                 if (t) {
@@ -597,9 +593,11 @@ static void dispatch_message_real(
                                 IOVEC_SET_STRING(iovec[n++], session);
                 }
 
-                if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0)
+                if (sd_pid_get_owner_uid(ucred->pid, &owner) >= 0) {
+                        owner_valid = true;
                         if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0)
                                 IOVEC_SET_STRING(iovec[n++], owner_uid);
+                }
 #endif
 
                 if (cg_pid_get_unit(ucred->pid, &t) >= 0) {
@@ -622,9 +620,7 @@ static void dispatch_message_real(
                 if (label) {
                         selinux_context = malloc(sizeof("_SELINUX_CONTEXT=") + label_len);
                         if (selinux_context) {
-                                memcpy(selinux_context, "_SELINUX_CONTEXT=", sizeof("_SELINUX_CONTEXT=")-1);
-                                memcpy(selinux_context+sizeof("_SELINUX_CONTEXT=")-1, label, label_len);
-                                selinux_context[sizeof("_SELINUX_CONTEXT=")-1+label_len] = 0;
+                                *((char*) mempcpy(stpcpy(selinux_context, "_SELINUX_CONTEXT="), label, label_len)) = 0;
                                 IOVEC_SET_STRING(iovec[n++], selinux_context);
                         }
                 } else {
@@ -634,7 +630,6 @@ static void dispatch_message_real(
                                 selinux_context = strappend("_SELINUX_CONTEXT=", con);
                                 if (selinux_context)
                                         IOVEC_SET_STRING(iovec[n++], selinux_context);
-
                                 freecon(con);
                         }
                 }
@@ -670,12 +665,19 @@ static void dispatch_message_real(
 
         assert(n <= m);
 
-        if (s->split_mode == SPLIT_NONE)
-                journal_uid = 0;
-        else if (s->split_mode == SPLIT_UID || realuid == 0 || !loginuid_valid)
+        if (s->split_mode == SPLIT_UID && realuid > 0)
+                /* Split up strictly by any UID */
                 journal_uid = realuid;
+        else if (s->split_mode == SPLIT_LOGIN && realuid > 0 && owner_valid && owner > 0)
+                /* Split up by login UIDs, this avoids creation of
+                 * individual journals for system UIDs.  We do this
+                 * only if the realuid is not root, in order not to
+                 * accidentally leak privileged information to the
+                 * user that is logged by a privileged process that is
+                 * part of an unprivileged session.*/
+                journal_uid = owner;
         else
-                journal_uid = loginuid;
+                journal_uid = 0;
 
         write_to_journal(s, journal_uid, iovec, n);
 }
@@ -1309,6 +1311,12 @@ int server_init(Server *s) {
 
         server_parse_config_file(s);
         server_parse_proc_cmdline(s);
+        if (!!s->rate_limit_interval ^ !!s->rate_limit_burst) {
+                log_debug("Setting both rate limit interval and burst from %llu,%u to 0,0",
+                          (long long unsigned) s->rate_limit_interval,
+                          s->rate_limit_burst);
+                s->rate_limit_interval = s->rate_limit_burst = 0;
+        }
 
         mkdir_p("/run/systemd/journal", 0755);
 
@@ -1395,7 +1403,8 @@ int server_init(Server *s) {
         if (!s->udev)
                 return -ENOMEM;
 
-        s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst);
+        s->rate_limit = journal_rate_limit_new(s->rate_limit_interval,
+                                               s->rate_limit_burst);
         if (!s->rate_limit)
                 return -ENOMEM;