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