summaryrefslogtreecommitdiff
path: root/src/journal
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-03-22 17:44:15 +0100
committerLennart Poettering <lennart@poettering.net>2013-03-22 17:44:19 +0100
commit4468addca6d01a0d2d154371dd72f54307a9c786 (patch)
tree01d5a809da50ccdf1621a5e5cb7813b262519ae4 /src/journal
parent8e70580bb07ae46dc0b0bf377de6333540668acc (diff)
journalctl: give a nice hint about group membership based on ACLs of /var/log/journal
If we notice that we unprivileged and not in any of the groups which have access to /var/log/journal, print a nice message about which groups do. This checks and prints all groups that are in the default ACL for /var/log/journal, which is not necessarily correct for all journal files, but pretty close.
Diffstat (limited to 'src/journal')
-rw-r--r--src/journal/journalctl.c91
1 files changed, 89 insertions, 2 deletions
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index ddadc21338..4c288f3334 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -35,6 +35,10 @@
#include <sys/ioctl.h>
#include <linux/fs.h>
+#ifdef HAVE_ACL
+#include <sys/acl.h>
+#endif
+
#include <systemd/sd-journal.h>
#include "log.h"
@@ -881,13 +885,96 @@ static int verify(sd_journal *j) {
static int access_check(void) {
#ifdef HAVE_ACL
+ /* If /var/log/journal doesn't even exist, unprivileged users have no access at all */
if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("systemd-journal") <= 0) {
log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'systemd-journal' can always see messages.");
return -EACCES;
}
- if (!arg_quiet && geteuid() != 0 && in_group("systemd-journal") <= 0)
- log_warning("Showing user generated messages only. Users in the group 'systemd-journal' can see all messages. Pass -q to turn this notice off.");
+ /* If /var/log/journal exists, try to pring a nice notice if the user lacks access to it */
+ if (!arg_quiet && geteuid() != 0) {
+ _cleanup_strv_free_ char **g = NULL;
+ bool have_access;
+ acl_t acl;
+ int r;
+
+ have_access = in_group("systemd-journal") > 0;
+ if (!have_access) {
+
+ /* Let's enumerate all groups from the default
+ * ACL of the directory, which generally
+ * should allow access to most journal
+ * files too */
+
+ acl = acl_get_file("/var/log/journal/", ACL_TYPE_DEFAULT);
+ if (acl) {
+ acl_entry_t entry;
+
+ r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
+ while (r > 0) {
+ acl_tag_t tag;
+ gid_t *gid;
+ char *name;
+
+ r = acl_get_tag_type(entry, &tag);
+ if (r < 0)
+ break;
+
+ if (tag != ACL_GROUP)
+ goto next;
+
+ gid = acl_get_qualifier(entry);
+ if (!gid)
+ break;
+
+ if (in_gid(*gid) > 0) {
+ have_access = true;
+ break;
+ }
+
+ name = gid_to_name(*gid);
+ if (!name) {
+ acl_free(acl);
+ return log_oom();
+ }
+
+ r = strv_push(&g, name);
+ if (r < 0) {
+ free(name);
+ acl_free(acl);
+ return log_oom();
+ }
+
+ next:
+ r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
+ }
+
+ acl_free(acl);
+ }
+ }
+
+ if (!have_access) {
+
+ if (strv_isempty(g))
+ log_notice("Hint: You are currently not seeing messages from other users and the system. Users in the group 'systemd-journal' can see all messages. Pass -q to turn this notice off.");
+ else {
+ _cleanup_free_ char *s = NULL;
+
+ r = strv_extend(&g, "systemd-journal");
+ if (r < 0)
+ return log_oom();
+
+ strv_sort(g);
+ strv_uniq(g);
+
+ s = strv_join(g, "', '");
+ if (!s)
+ return log_oom();
+
+ log_notice("Hint: You are currently not seeing messages from other users and the system. Users in the groups '%s' can see all messages. Pass -q to turn this notice off.", s);
+ }
+ }
+ }
#else
if (geteuid() != 0 && in_group("systemd-journal") <= 0) {
log_error("No access to messages. Only users in the group 'systemd-journal' can see messages.");