X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fjournald.c;h=f924c9353b96a5bb0d4db1af2561b97691ebda56;hp=0194a1b8c9e60b32d3ecc03a9543f3442b4e2472;hb=7c8bbccd071a9a12efdd8a7770b53d7786eb3a9c;hpb=e6520a0fcebb4d5e07f4c81a51382501b0beb22f diff --git a/src/journal/journald.c b/src/journal/journald.c index 0194a1b8c..f924c9353 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -52,6 +52,10 @@ #include "acl-util.h" #endif +#ifdef HAVE_SELINUX +#include +#endif + #define USER_JOURNALS_MAX 1024 #define STDOUT_STREAMS_MAX 4096 @@ -64,7 +68,7 @@ #define SYSLOG_TIMEOUT_USEC (250*USEC_PER_MSEC) -#define N_IOVEC_META_FIELDS 16 +#define N_IOVEC_META_FIELDS 17 typedef enum StdoutStreamState { STDOUT_STREAM_IDENTIFIER, @@ -183,7 +187,26 @@ finish: return avail; } -static void fix_perms(JournalFile *f, uid_t uid) { +static void server_read_file_gid(Server *s) { + const char *adm = "adm"; + int r; + + assert(s); + + if (s->file_gid_valid) + return; + + r = get_group_creds(&adm, &s->file_gid); + if (r < 0) + log_warning("Failed to resolve 'adm' group: %s", 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 + * let's just pretend it worked right-away. */ + s->file_gid_valid = true; +} + +static void server_fix_perms(Server *s, JournalFile *f, uid_t uid) { int r; #ifdef HAVE_ACL acl_t acl; @@ -193,7 +216,9 @@ static void fix_perms(JournalFile *f, uid_t uid) { assert(f); - r = fchmod_and_fchown(f->fd, 0640, 0, 0); + server_read_file_gid(s); + + r = fchmod_and_fchown(f->fd, 0640, 0, s->file_gid); if (r < 0) log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r)); @@ -277,7 +302,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) { if (r < 0) return s->system_journal; - fix_perms(f, uid); + server_fix_perms(s, f, uid); f->metrics = s->system_metrics; f->compress = s->compress; @@ -415,7 +440,7 @@ static void dispatch_message_real(Server *s, *comm = NULL, *cmdline = NULL, *hostname = NULL, *audit_session = NULL, *audit_loginuid = NULL, *exe = NULL, *cgroup = NULL, *session = NULL, - *owner_uid = NULL, *unit = NULL; + *owner_uid = NULL, *unit = NULL, *selinux_context = NULL; char idbuf[33]; sd_id128_t id; @@ -433,6 +458,9 @@ static void dispatch_message_real(Server *s, if (ucred) { uint32_t audit; uid_t owner; +#ifdef HAVE_SELINUX + security_context_t con; +#endif realuid = ucred->uid; @@ -510,6 +538,16 @@ static void dispatch_message_real(Server *s, if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0) if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0) IOVEC_SET_STRING(iovec[n++], owner_uid); + +#ifdef HAVE_SELINUX + if (getpidcon(ucred->pid, &con) >= 0) { + selinux_context = strappend("_SELINUX_CONTEXT=", con); + if (selinux_context) + IOVEC_SET_STRING(iovec[n++], selinux_context); + + freecon(con); + } +#endif } if (tv) { @@ -581,6 +619,7 @@ retry: free(session); free(owner_uid); free(unit); + free(selinux_context); } static void driver_message(Server *s, sd_id128_t message_id, const char *format, ...) { @@ -713,6 +752,11 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0) return; + /* The socket is full? I guess the syslog implementation is + * too slow, and we shouldn't wait for that... */ + if (errno == EAGAIN) + return; + if (ucred && errno == ESRCH) { struct ucred u; @@ -726,6 +770,9 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0) return; + + if (errno == EAGAIN) + return; } log_debug("Failed to forward syslog message: %m"); @@ -1733,7 +1780,7 @@ static int system_journal_open(Server *s) { s->system_journal->metrics = s->system_metrics; s->system_journal->compress = s->compress; - fix_perms(s->system_journal, 0); + server_fix_perms(s, s->system_journal, 0); } else if (r < 0) { if (r != -ENOENT && r != -EROFS) @@ -1786,7 +1833,7 @@ static int system_journal_open(Server *s) { s->runtime_journal->metrics = s->runtime_metrics; s->runtime_journal->compress = s->compress; - fix_perms(s->runtime_journal, 0); + server_fix_perms(s, s->runtime_journal, 0); } }