From 6225e0f20e3bf1fd4f516614ad45dc7c0994d7e9 Mon Sep 17 00:00:00 2001
From: Joshua Lock <joshua.lock@intel.com>
Date: Wed, 29 May 2013 17:16:47 -0700
Subject: [PATCH 4/4] user-accounts: prevent the only Administrator from being
 demoted

If there is only one account of type Adminstrator and it is demoted to type
Standard the user can be left unable to unlock panels and perform other
Administrator tasks - prevent this by only allowing the Account Type to be
changed when the account is a standard user or, in the case that the account
is an Administrator, when there is one or more other Administrators.

https://bugzilla.gnome.org/show_bug.cgi?id=690246
---
 panels/user-accounts/um-user-panel.c | 48 ++++++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/panels/user-accounts/um-user-panel.c b/panels/user-accounts/um-user-panel.c
index 2de2ab8..1d480ef 100644
--- a/panels/user-accounts/um-user-panel.c
+++ b/panels/user-accounts/um-user-panel.c
@@ -999,6 +999,42 @@ remove_unlock_tooltip (GtkWidget *button)
                                               G_CALLBACK (show_tooltip_now), NULL);
 }
 
+static guint
+get_num_admin (ActUserManager *um)
+{
+        GSList *list;
+        GSList *l;
+        guint num_admin = 0;
+
+        list = act_user_manager_list_users (um);
+        for (l = list; l != NULL; l = l->next) {
+                ActUser *u = l->data;
+                if (act_user_get_account_type (u) == ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR) {
+                        num_admin++;
+                }
+        }
+        g_slist_free (list);
+
+        return num_admin;
+}
+
+static gboolean
+would_demote_only_admin (ActUser        *user,
+                         ActUserManager *um)
+{
+        /* Prevent the user from demoting the only admin account.
+         * Returns TRUE when user is an administrator and there is only
+         * one administrator */
+
+        if (act_user_get_account_type (user) == ACT_USER_ACCOUNT_TYPE_STANDARD)
+                return FALSE;
+
+        if (get_num_admin (um) > 1)
+                return FALSE;
+
+        return TRUE;
+}
+
 static void
 on_permission_changed (GPermission *permission,
                        GParamSpec  *pspec,
@@ -1066,14 +1102,22 @@ on_permission_changed (GPermission *permission,
                 remove_unlock_tooltip (get_widget (d, "autologin-switch"));
 
         } else if (is_authorized && act_user_is_local_account (user)) {
-                um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), TRUE);
+                if (would_demote_only_admin (user, d->um)) {
+                        um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), FALSE);
+                } else {
+                        um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), TRUE);
+                }
                 remove_unlock_tooltip (get_widget (d, "account-type-combo"));
                 gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), TRUE);
                 remove_unlock_tooltip (get_widget (d, "autologin-switch"));
         }
         else {
                 um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), FALSE);
-                add_unlock_tooltip (get_widget (d, "account-type-combo"));
+                if (would_demote_only_admin (user, d->um)) {
+                        remove_unlock_tooltip (get_widget (d, "account-type-combo"));
+                } else {
+                        add_unlock_tooltip (get_widget (d, "account-type-combo"));
+                }
                 gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), FALSE);
                 add_unlock_tooltip (get_widget (d, "autologin-switch"));
         }
-- 
1.8.1.4

