|
|
1ff636 |
From d3706690bf2953cb8e0362253dc68d77989de3be Mon Sep 17 00:00:00 2001
|
|
|
1ff636 |
From: Lukas Nykryn <lnykryn@redhat.com>
|
|
|
1ff636 |
Date: Fri, 11 Sep 2015 13:37:59 +0200
|
|
|
1ff636 |
Subject: [PATCH] loginctl: print nontrivial properties in logictl show-*
|
|
|
1ff636 |
|
|
|
1ff636 |
Cherry-picked from: 2a998c74028a109d6bd8888951abfa8e25a15fb1
|
|
|
1ff636 |
Resolves: #1260465
|
|
|
1ff636 |
---
|
|
|
1ff636 |
src/login/loginctl.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
1ff636 |
src/shared/macro.h | 13 +++++
|
|
|
1ff636 |
2 files changed, 162 insertions(+), 3 deletions(-)
|
|
|
1ff636 |
|
|
|
1ff636 |
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
|
|
|
1ff636 |
index b0eede9..6c8a59e 100644
|
|
|
1ff636 |
--- a/src/login/loginctl.c
|
|
|
1ff636 |
+++ b/src/login/loginctl.c
|
|
|
1ff636 |
@@ -657,19 +657,165 @@ finish:
|
|
|
1ff636 |
return r;
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
+static int print_property(const char *name, sd_bus_message *m, const char *contents) {
|
|
|
1ff636 |
+ int r;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ assert(name);
|
|
|
1ff636 |
+ assert(m);
|
|
|
1ff636 |
+ assert(contents);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (arg_property && !strv_find(arg_property, name))
|
|
|
1ff636 |
+ /* skip what we didn't read */
|
|
|
1ff636 |
+ return sd_bus_message_skip(m, contents);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ switch (contents[0]) {
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ case SD_BUS_TYPE_STRUCT_BEGIN:
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (contents[1] == SD_BUS_TYPE_STRING && STR_IN_SET(name, "Display", "Seat", "ActiveSession")) {
|
|
|
1ff636 |
+ const char *s;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_read(m, "(so)", &s, NULL);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (arg_all || !isempty(s))
|
|
|
1ff636 |
+ printf("%s=%s\n", name, s);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ return 0;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ } else if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "User")) {
|
|
|
1ff636 |
+ uint32_t uid;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_read(m, "(uo)", &uid, NULL);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (UID_IS_INVALID(uid)) {
|
|
|
1ff636 |
+ log_error("Invalid user ID: " UID_FMT, uid);
|
|
|
1ff636 |
+ return -EINVAL;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ printf("%s=" UID_FMT "\n", name, uid);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ return 0;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ break;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ case SD_BUS_TYPE_ARRAY:
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Sessions")) {
|
|
|
1ff636 |
+ const char *s;
|
|
|
1ff636 |
+ bool space = false;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(so)");
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ printf("%s=", name);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ while ((r = sd_bus_message_read(m, "(so)", &s, NULL)) > 0) {
|
|
|
1ff636 |
+ printf("%s%s", space ? " " : "", s);
|
|
|
1ff636 |
+ space = true;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ printf("\n");
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_exit_container(m);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ return 0;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ break;
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = bus_print_property(name, m, arg_all);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (r == 0) {
|
|
|
1ff636 |
+ r = sd_bus_message_skip(m, contents);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ if (arg_all)
|
|
|
1ff636 |
+ printf("%s=[unprintable]\n", name);
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ return 0;
|
|
|
1ff636 |
+}
|
|
|
1ff636 |
+
|
|
|
1ff636 |
static int show_properties(sd_bus *bus, const char *path, bool *new_line) {
|
|
|
1ff636 |
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
|
|
1ff636 |
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
|
1ff636 |
int r;
|
|
|
1ff636 |
|
|
|
1ff636 |
+ assert(bus);
|
|
|
1ff636 |
+ assert(path);
|
|
|
1ff636 |
+ assert(new_line);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_call_method(
|
|
|
1ff636 |
+ bus,
|
|
|
1ff636 |
+ "org.freedesktop.login1",
|
|
|
1ff636 |
+ path,
|
|
|
1ff636 |
+ "org.freedesktop.DBus.Properties",
|
|
|
1ff636 |
+ "GetAll",
|
|
|
1ff636 |
+ &error,
|
|
|
1ff636 |
+ &reply,
|
|
|
1ff636 |
+ "s", "");
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
if (*new_line)
|
|
|
1ff636 |
printf("\n");
|
|
|
1ff636 |
|
|
|
1ff636 |
*new_line = true;
|
|
|
1ff636 |
|
|
|
1ff636 |
- r = bus_print_all_properties(bus, "org.freedesktop.login1", path, arg_property, arg_all);
|
|
|
1ff636 |
+ while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
|
|
|
1ff636 |
+ const char *name, *contents;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_read(reply, "s", &name);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_peek_type(reply, NULL, &contents);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = print_property(name, reply, contents);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return r;
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_exit_container(reply);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ r = sd_bus_message_exit_container(reply);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+ }
|
|
|
1ff636 |
if (r < 0)
|
|
|
1ff636 |
- log_error_errno(r, "Could not get properties: %m");
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
|
|
|
1ff636 |
- return r;
|
|
|
1ff636 |
+ r = sd_bus_message_exit_container(reply);
|
|
|
1ff636 |
+ if (r < 0)
|
|
|
1ff636 |
+ return bus_log_parse_error(r);
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ return 0;
|
|
|
1ff636 |
}
|
|
|
1ff636 |
|
|
|
1ff636 |
static int show_session(int argc, char *argv[], void *userdata) {
|
|
|
1ff636 |
diff --git a/src/shared/macro.h b/src/shared/macro.h
|
|
|
1ff636 |
index 7f89951..9d857dc 100644
|
|
|
1ff636 |
--- a/src/shared/macro.h
|
|
|
1ff636 |
+++ b/src/shared/macro.h
|
|
|
1ff636 |
@@ -26,6 +26,7 @@
|
|
|
1ff636 |
#include <sys/types.h>
|
|
|
1ff636 |
#include <sys/uio.h>
|
|
|
1ff636 |
#include <inttypes.h>
|
|
|
1ff636 |
+#include <stdbool.h>
|
|
|
1ff636 |
|
|
|
1ff636 |
#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
|
|
|
1ff636 |
#define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
|
|
|
1ff636 |
@@ -451,6 +452,18 @@ do { \
|
|
|
1ff636 |
#define GID_INVALID ((gid_t) -1)
|
|
|
1ff636 |
#define MODE_INVALID ((mode_t) -1)
|
|
|
1ff636 |
|
|
|
1ff636 |
+static inline bool UID_IS_INVALID(uid_t uid) {
|
|
|
1ff636 |
+ /* We consider both the old 16bit -1 user and the newer 32bit
|
|
|
1ff636 |
+ * -1 user invalid, since they are or used to be incompatible
|
|
|
1ff636 |
+ * with syscalls such as setresuid() or chown(). */
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+ return uid == (uid_t) ((uint32_t) -1) || uid == (uid_t) ((uint16_t) -1);
|
|
|
1ff636 |
+}
|
|
|
1ff636 |
+
|
|
|
1ff636 |
+static inline bool GID_IS_INVALID(gid_t gid) {
|
|
|
1ff636 |
+ return gid == (gid_t) ((uint32_t) -1) || gid == (gid_t) ((uint16_t) -1);
|
|
|
1ff636 |
+}
|
|
|
1ff636 |
+
|
|
|
1ff636 |
#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \
|
|
|
1ff636 |
static inline void func##p(type *p) { \
|
|
|
1ff636 |
if (*p) \
|