summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2024-04-19 13:43:15 -0400
committerRay Strode <rstrode@redhat.com>2024-04-19 13:45:12 -0400
commit2aaac4b3ce14aecc042d865b956160b43d8dec4d (patch)
treeec0d55b12b4f1de1bf45a89c621715abc33064d1
parent546445d4310f9feb85e89926bbd925cdb375b554 (diff)
wip! user: Use D-Bus Object Managerobject-manager
AccountsService is really the posterboy for the type of service that should use D-Bus Object Manager, but for weird historical reasons it doesn't. This commit begins to sketch out how a minimally bolted on object manager implementation might look.
-rw-r--r--src/daemon.c10
-rw-r--r--src/user.c105
-rw-r--r--src/user.h3
3 files changed, 76 insertions, 42 deletions
diff --git a/src/daemon.c b/src/daemon.c
index 188ddcb..3243955 100644
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -83,6 +83,7 @@ typedef enum
typedef struct
{
GDBusConnection *bus_connection;
+ GDBusObjectManagerServer *object_manager;
GHashTable *users;
gsize number_of_normal_users;
@@ -642,7 +643,7 @@ reload_users (Daemon *daemon)
stale_user = g_hash_table_lookup (old_users, name);
if (!stale_user || (!user_get_cached (stale_user) && user_get_cached (user))) {
- user_register (user);
+ user_register (user, priv->object_manager);
accounts_accounts_emit_user_added (ACCOUNTS_ACCOUNTS (daemon),
user_get_object_path (user));
}
@@ -919,6 +920,8 @@ daemon_finalize (GObject *object)
if (priv->bus_connection != NULL)
g_object_unref (priv->bus_connection);
+ g_clear_object (&priv->object_manager);
+
g_queue_free_full (priv->pending_list_cached_users,
(GDestroyNotify) list_user_data_free);
@@ -961,6 +964,9 @@ register_accounts_daemon (Daemon *daemon)
return FALSE;
}
+ priv->object_manager = g_dbus_object_manager_server_new ("/org/freedesktop/Accounts/UserManager");
+ g_dbus_object_manager_server_set_connection (priv->object_manager, priv->bus_connection);
+
return TRUE;
}
@@ -1009,7 +1015,7 @@ add_new_user_for_pwent (Daemon *daemon,
user = user_new (daemon, pwent->pw_uid);
user_update_from_pwent (user, pwent, spent);
- user_register (user);
+ user_register (user, priv->object_manager);
g_hash_table_insert (priv->users,
g_strdup (user_get_user_name (user)),
diff --git a/src/user.c b/src/user.c
index 1477392..8123d55 100644
--- a/src/user.c
+++ b/src/user.c
@@ -77,8 +77,7 @@ struct User
gboolean template_loaded;
gboolean local_account_overridden;
- guint *extension_ids;
- guint n_extension_ids;
+ GDBusObjectManager *object_manager;
guint changed_timeout_id;
};
@@ -88,11 +87,24 @@ typedef struct UserClass
AccountsUserSkeletonClass parent_class;
} UserClass;
+typedef struct
+{
+ GDBusInterfaceSkeleton parent;
+} UserExtensionSkeleton;
+
+typedef struct
+{
+ GDBusInterfaceSkeletonClass parent_class;
+} UserExtensionSkeletonClass;
+
+GType user_extension_skeleton_get_type (void);
+
static void user_accounts_user_iface_init (AccountsUserIface *iface);
static void user_update_from_keyfile (User *user,
GKeyFile *keyfile);
G_DEFINE_TYPE_WITH_CODE (User, user, ACCOUNTS_TYPE_USER_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_USER, user_accounts_user_iface_init));
+G_DEFINE_TYPE (UserExtensionSkeleton, user_extension_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON);
static gint
account_type_from_pwent (struct passwd *pwent)
@@ -936,35 +948,50 @@ user_extension_method_call (GDBusConnection *connection,
}
}
-static void
-user_register_extensions (User *user)
+static GDBusInterfaceVTable *
+user_extension_get_vtable (GDBusInterfaceSkeleton *skeleton)
{
static const GDBusInterfaceVTable vtable = {
user_extension_method_call,
NULL /* get_property */,
NULL /* set_property */
};
+
+ return (GDBusInterfaceVTable *) &vtable;
+}
+
+static void
+user_extension_skeleton_init (UserExtensionSkeleton *object)
+{
+}
+
+static void
+user_extension_skeleton_class_init (UserExtensionSkeletonClass *klass)
+{
+ GDBusInterfaceSkeletonClass *skeleton_class;
+
+ skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
+ skeleton_class->get_vtable = user_extension_get_vtable;
+}
+static void
+user_register_extensions (User *user,
+ GDBusObjectSkeleton *object)
+{
GHashTable *extensions;
GHashTableIter iter;
- gpointer iface;
- gint i = 0;
-
- g_assert (user->extension_ids == NULL);
- g_assert (user->n_extension_ids == 0);
+ char *interface_name;
+ GDBusInterfaceInfo *iface;
extensions = daemon_get_extension_ifaces (user->daemon);
- user->n_extension_ids = g_hash_table_size (extensions);
- user->extension_ids = g_new (guint, user->n_extension_ids);
g_hash_table_iter_init (&iter, extensions);
/* Ignore errors when registering more interfaces because (a)
* they won't happen and (b) even if they do, we still want to
* publish the main user interface.
*/
- while (g_hash_table_iter_next (&iter, NULL, &iface)) {
- user->extension_ids[i++] = g_dbus_connection_register_object (user->system_bus_connection,
- g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (user)), iface,
- &vtable, user, NULL, NULL);
+ while (g_hash_table_iter_next (&iter, (gpointer) &interface_name, (gpointer) &iface)) {
+ GDBusInterfaceSkeleton *interface_skeleton = g_object_new (user_extension_skeleton_get_type (), NULL);
+ g_dbus_object_skeleton_add_interface (object, interface_skeleton);
}
}
@@ -998,10 +1025,12 @@ on_user_property_notify (User *user)
}
void
-user_register (User *user)
+user_register (User *user,
+ GDBusObjectManagerServer *object_manager)
{
g_autoptr (GError) error = NULL;
g_autofree gchar *object_path = NULL;
+ g_autoptr (GDBusObjectSkeleton) object = NULL;
user->system_bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (user->system_bus_connection == NULL) {
@@ -1011,17 +1040,13 @@ user_register (User *user)
}
object_path = compute_object_path (user);
+ object = g_dbus_object_skeleton_new (object_path);
- if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (user),
- user->system_bus_connection,
- object_path,
- &error)) {
- if (error != NULL)
- g_critical ("error exporting user object: %s", error->message);
- return;
- }
+ g_dbus_object_skeleton_add_interface (object, G_DBUS_INTERFACE_SKELETON (user));
+ g_dbus_object_manager_server_export (object_manager, object);
+ user->object_manager = g_object_ref (G_DBUS_OBJECT_MANAGER (object_manager));
- user_register_extensions (user);
+ user_register_extensions (user, object);
g_signal_connect (G_OBJECT (user), "notify", G_CALLBACK (on_user_property_notify), NULL);
}
@@ -1035,24 +1060,26 @@ user_save (User *user)
void
user_unregister (User *user)
{
- g_signal_handlers_disconnect_by_func (G_OBJECT (user), G_CALLBACK (on_user_property_notify), NULL);
-
- g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (user));
-
- if (user->extension_ids) {
- guint i;
+ GHashTable *extensions;
+ GHashTableIter iter;
+ g_autofree gchar *object_path = NULL;
+ g_autoptr (GDBusObjectSkeleton) object = NULL;
- for (i = 0; i < user->n_extension_ids; i++) {
- /* In theory, if an error happened during registration, we could have 0 here. */
- if (user->extension_ids[i] == 0)
- continue;
+ g_signal_handlers_disconnect_by_func (G_OBJECT (user), G_CALLBACK (on_user_property_notify), NULL);
+ extensions = daemon_get_extension_ifaces (user->daemon);
- g_dbus_connection_unregister_object (user->system_bus_connection, user->extension_ids[i]);
- }
+ object_path = compute_object_path (user);
+ object = G_DBUS_OBJECT_SKELETON (g_dbus_object_manager_get_object (user->object_manager, object_path));
+ if (object) {
+ const char *interface_name;
+ g_hash_table_iter_init (&iter, extensions);
+ while (g_hash_table_iter_next (&iter, (gpointer) &interface_name, NULL))
+ g_dbus_object_skeleton_remove_interface_by_name (object, interface_name);
- g_clear_pointer (&user->extension_ids, g_free);
- user->n_extension_ids = 0;
+ g_dbus_object_manager_server_unexport (G_DBUS_OBJECT_MANAGER_SERVER (user->object_manager), object_path);
}
+
+ g_clear_object (&user->object_manager);
}
void
diff --git a/src/user.h b/src/user.h
index 4ba64c1..0c3eb56 100644
--- a/src/user.h
+++ b/src/user.h
@@ -71,7 +71,8 @@ void user_set_cached (User *user,
void user_set_saved (User *user,
gboolean saved);
-void user_register (User *user);
+void user_register (User *user,
+ GDBusObjectManagerServer *manager);
void user_unregister (User *user);
void user_changed (User *user);