From f9bfa6962d3689acf50b3e51d5d4af3642d849d8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 21 Mar 2018 13:11:01 +0900 Subject: [PATCH] core: add new dbus method GetDynamicUsers This intruduces a new dbus method GetDynamicUsers for systemd1.Manager, which enumerates all dynamic users realized in the system. --- src/core/dbus-manager.c | 45 ++++++++++++++++++++++++++ src/core/dynamic-user.c | 2 +- src/core/dynamic-user.h | 1 + src/core/org.freedesktop.systemd1.conf | 4 +++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 889779d548..90e7f86389 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1798,6 +1798,50 @@ static int method_lookup_dynamic_user_by_uid(sd_bus_message *message, void *user return sd_bus_reply_method_return(message, "s", name); } +static int method_get_dynamic_users(sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + Manager *m = userdata; + DynamicUser *d; + Iterator i; + int r; + + assert(message); + assert(m); + + assert_cc(sizeof(uid_t) == sizeof(uint32_t)); + + if (!MANAGER_IS_SYSTEM(m)) + return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance."); + + r = sd_bus_message_new_method_return(message, &reply); + if (r < 0) + return r; + + r = sd_bus_message_open_container(reply, 'a', "(us)"); + if (r < 0) + return r; + + HASHMAP_FOREACH(d, m->dynamic_users, i) { + uid_t uid; + + r = dynamic_user_current(d, &uid); + if (r == -EAGAIN) /* not realized yet? */ + continue; + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Failed to lookup a dynamic user."); + + r = sd_bus_message_append(reply, "(us)", uid, d->name); + if (r < 0) + return r; + } + + r = sd_bus_message_close_container(reply); + if (r < 0) + return r; + + return sd_bus_send(NULL, reply, NULL); +} + static int list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; Manager *m = userdata; @@ -2572,6 +2616,7 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_METHOD("SetExitCode", "y", NULL, method_set_exit_code, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("LookupDynamicUserByName", "s", "u", method_lookup_dynamic_user_by_name, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("LookupDynamicUserByUID", "u", "s", method_lookup_dynamic_user_by_uid, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetDynamicUsers", NULL, "a(us)", method_get_dynamic_users, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_SIGNAL("UnitNew", "so", 0), SD_BUS_SIGNAL("UnitRemoved", "so", 0), diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index 3da31bf870..de6aadd597 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -563,7 +563,7 @@ static int dynamic_user_realize( return 0; } -static int dynamic_user_current(DynamicUser *d, uid_t *ret) { +int dynamic_user_current(DynamicUser *d, uid_t *ret) { _cleanup_(unlockfp) int storage_socket0_lock = -1; _cleanup_close_ int lock_fd = -1; uid_t uid; diff --git a/src/core/dynamic-user.h b/src/core/dynamic-user.h index b073c65837..34befa3445 100644 --- a/src/core/dynamic-user.h +++ b/src/core/dynamic-user.h @@ -48,6 +48,7 @@ int dynamic_user_serialize(Manager *m, FILE *f, FDSet *fds); void dynamic_user_deserialize_one(Manager *m, const char *value, FDSet *fds); void dynamic_user_vacuum(Manager *m, bool close_user); +int dynamic_user_current(DynamicUser *d, uid_t *ret); int dynamic_user_lookup_uid(Manager *m, uid_t uid, char **ret); int dynamic_user_lookup_name(Manager *m, const char *name, uid_t *ret); diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf index 645c8f1659..5e72fe7e8e 100644 --- a/src/core/org.freedesktop.systemd1.conf +++ b/src/core/org.freedesktop.systemd1.conf @@ -140,6 +140,10 @@ send_interface="org.freedesktop.systemd1.Manager" send_member="LookupDynamicUserByUID"/> + +