From 6205c27f618ab549fd2cc1d8880bad218b5ab74f Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 13 Jun 2012 12:22:53 +0200 Subject: [PATCH 2/2] Add CacheUser() method * Caches a user so that it becomes visible via ListCachedUsers() * The user account must be accessible via getpwnam() https://bugs.freedesktop.org/show_bug.cgi?id=50770 --- data/org.freedesktop.Accounts.xml | 27 +++++++++++ src/daemon.c | 70 +++++++++++++++++++++++++++++ src/libaccountsservice/act-user-manager.c | 43 ++++++++++++++++++ src/libaccountsservice/act-user-manager.h | 4 ++ 4 files changed, 144 insertions(+) diff --git a/data/org.freedesktop.Accounts.xml b/data/org.freedesktop.Accounts.xml index ab3a15c..c5ac523 100644 --- a/data/org.freedesktop.Accounts.xml +++ b/data/org.freedesktop.Accounts.xml @@ -112,6 +112,33 @@ + + + + The username for the user + + + Object path of user + + + + + + Caches a user account, so that it shows up in ListCachedUsers() output. + The user name may be a remote user, but the system must be able to lookup + the user name and resolve the user information. + + + + The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. + + + if the caller lacks the appropriate PolicyKit authorization + if the user name cannot be resolved + + + + diff --git a/src/daemon.c b/src/daemon.c index 7754e80..cdc10dd 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -1091,6 +1091,75 @@ daemon_create_user (AccountsAccounts *accounts, return TRUE; } +static void +daemon_cache_user_authorized_cb (Daemon *daemon, + User *dummy, + GDBusMethodInvocation *context, + gpointer data) +{ + const gchar *user_name = data; + GError *error = NULL; + gchar *filename; + gchar *comment; + User *user; + + sys_log (context, "cache user '%s'", user_name); + + user = daemon_local_find_user_by_name (daemon, user_name); + if (user == NULL) { + throw_error (context, ERROR_USER_DOES_NOT_EXIST, + "No user with the name %s found", user_name); + return; + } + + /* Always use the canonical user name looked up */ + user_name = user_local_get_user_name (user); + + filename = g_build_filename (USERDIR, user_name, NULL); + if (!g_file_test (filename, G_FILE_TEST_EXISTS)) { + comment = g_strdup_printf ("# Cached file for %s\n\n", user_name); + g_file_set_contents (filename, comment, -1, &error); + g_free (comment); + + if (error != NULL) { + g_warning ("Couldn't write user cache file: %s: %s", + filename, error->message); + g_error_free (error); + } + } + + g_free (filename); + + accounts_accounts_complete_cache_user (NULL, context, user_local_get_object_path (user)); +} + +static gboolean +daemon_cache_user (AccountsAccounts *accounts, + GDBusMethodInvocation *context, + const gchar *user_name) +{ + Daemon *daemon = (Daemon*)accounts; + + /* Can't have a slash in the user name */ + if (strchr (user_name, '/') != NULL) { + g_dbus_method_invocation_return_error (context, G_DBUS_ERROR, + G_DBUS_ERROR_INVALID_ARGS, + "Invalid user name: %s", user_name); + return TRUE; + } + + daemon_local_check_auth (daemon, + NULL, + "org.freedesktop.accounts.user-administration", + TRUE, + daemon_cache_user_authorized_cb, + context, + g_strdup (user_name), + g_free); + + return TRUE; +} + typedef struct { gint64 uid; gboolean remove_files; @@ -1454,4 +1523,5 @@ daemon_accounts_accounts_iface_init (AccountsAccountsIface *iface) iface->handle_find_user_by_name = daemon_find_user_by_name; iface->handle_list_cached_users = daemon_list_cached_users; iface->get_daemon_version = daemon_get_daemon_version; + iface->handle_cache_user = daemon_cache_user; } diff --git a/src/libaccountsservice/act-user-manager.c b/src/libaccountsservice/act-user-manager.c index 0d7e433..72cdb96 100644 --- a/src/libaccountsservice/act-user-manager.c +++ b/src/libaccountsservice/act-user-manager.c @@ -2612,6 +2612,49 @@ act_user_manager_create_user (ActUserManager *manager, return user; } +/** + * act_user_manager_cache_user: + * @manager: a #ActUserManager + * @username: a user name + * @error: a #GError + * + * Caches a user account so it shows up via act_user_manager_list_users(). + * + * Returns: (transfer full): user object + */ +ActUser * +act_user_manager_cache_user (ActUserManager *manager, + const char *username, + GError **error) +{ + GError *local_error = NULL; + gboolean res; + gchar *path; + ActUser *user; + + g_debug ("ActUserManager: Caching user '%s'", + username); + + g_assert (manager->priv->accounts_proxy != NULL); + + local_error = NULL; + res = accounts_accounts_call_cache_user_sync (manager->priv->accounts_proxy, + username, + &path, + NULL, + &local_error); + if (! res) { + g_propagate_error (error, local_error); + return NULL; + } + + user = add_new_user_for_object_path (path, manager); + + g_free (path); + + return user; +} + gboolean act_user_manager_delete_user (ActUserManager *manager, ActUser *user, diff --git a/src/libaccountsservice/act-user-manager.h b/src/libaccountsservice/act-user-manager.h index 4e79ce9..d2b083a 100644 --- a/src/libaccountsservice/act-user-manager.h +++ b/src/libaccountsservice/act-user-manager.h @@ -88,6 +88,10 @@ ActUser * act_user_manager_create_user (ActUserManager * ActUserAccountType accounttype, GError **error); +ActUser * act_user_manager_cache_user (ActUserManager *manager, + const char *username, + GError **error); + gboolean act_user_manager_delete_user (ActUserManager *manager, ActUser *user, gboolean remove_files, -- 1.7.10.2