From b7b2610cc839c690b9aa05755d5c69718336c156 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 4 Jun 2013 11:20:39 -0400 Subject: [PATCH] daemon: turn off autologin for deleted users Right now it's possible to delete a user who is configured to automatically log in. Doing so causes the system not to boot. This commit turns off autologin before deleting the user. https://bugs.freedesktop.org/show_bug.cgi?id=54506 --- src/daemon.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/daemon.c b/src/daemon.c index d8abe64..846895e 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -82,60 +82,64 @@ static const char *default_excludes[] = { NULL }; enum { PROP_0, PROP_DAEMON_VERSION }; struct DaemonPrivate { GDBusConnection *bus_connection; GDBusProxy *bus_proxy; GHashTable *users; GHashTable *exclusions; User *autologin; GFileMonitor *passwd_monitor; GFileMonitor *shadow_monitor; GFileMonitor *gdm_monitor; guint reload_id; guint autologin_id; PolkitAuthority *authority; }; typedef struct passwd * (* EntryGeneratorFunc) (GHashTable *, gpointer *); static void daemon_accounts_accounts_iface_init (AccountsAccountsIface *iface); +static gboolean save_autologin (Daemon *daemon, + const gchar *name, + gboolean enabled, + GError **error); G_DEFINE_TYPE_WITH_CODE (Daemon, daemon, ACCOUNTS_TYPE_ACCOUNTS_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_ACCOUNTS, daemon_accounts_accounts_iface_init)); #define DAEMON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DAEMON, DaemonPrivate)) static const GDBusErrorEntry accounts_error_entries[] = { { ERROR_FAILED, "org.freedesktop.Accounts.Error.Failed" }, { ERROR_USER_EXISTS, "org.freedesktop.Accounts.Error.UserExists" }, { ERROR_USER_DOES_NOT_EXIST, "org.freedesktop.Accounts.Error.UserDoesNotExist" }, { ERROR_PERMISSION_DENIED, "org.freedesktop.Accounts.Error.PermissionDenied" }, { ERROR_NOT_SUPPORTED, "org.freedesktop.Accounts.Error.NotSupported" } }; GQuark error_quark (void) { static volatile gsize quark_volatile = 0; g_dbus_error_register_error_domain ("accounts_error", &quark_volatile, accounts_error_entries, G_N_ELEMENTS (accounts_error_entries)); return (GQuark) quark_volatile; } #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } GType error_get_type (void) @@ -1321,60 +1325,73 @@ daemon_uncache_user (AccountsAccounts *accounts, } typedef struct { gint64 uid; gboolean remove_files; } DeleteUserData; static void daemon_delete_user_authorized_cb (Daemon *daemon, User *dummy, GDBusMethodInvocation *context, gpointer data) { DeleteUserData *ud = data; GError *error; gchar *filename; struct passwd *pwent; const gchar *argv[6]; pwent = getpwuid (ud->uid); if (pwent == NULL) { throw_error (context, ERROR_USER_DOES_NOT_EXIST, "No user with uid %d found", ud->uid); return; } sys_log (context, "delete user '%s' (%d)", pwent->pw_name, ud->uid); + if (daemon->priv->autologin != NULL) { + User *user; + + user = daemon_local_find_user_by_id (daemon, ud->uid); + + g_assert (user != NULL); + + if (daemon->priv->autologin == user) { + save_autologin (daemon, pwent->pw_name, FALSE, NULL); + } + + } + filename = g_build_filename (USERDIR, pwent->pw_name, NULL); g_remove (filename); g_free (filename); filename = g_build_filename (ICONDIR, pwent->pw_name, NULL); g_remove (filename); g_free (filename); argv[0] = "/usr/sbin/userdel"; if (ud->remove_files) { argv[1] = "-f"; argv[2] = "-r"; argv[3] = "--"; argv[4] = pwent->pw_name; argv[5] = NULL; } else { argv[1] = "--"; argv[2] = pwent->pw_name; argv[3] = NULL; } error = NULL; if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); return; } accounts_accounts_complete_delete_user (NULL, context); -- 1.8.1.4