Blame SOURCES/0247-loginctl-print-nontrivial-properties-in-logictl-show.patch

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