[gnome-initial-setup] account: Prompt for admin credentials if necessary when joining realm
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-initial-setup] account: Prompt for admin credentials if necessary when joining realm
- Date: Mon, 27 May 2013 16:29:58 +0000 (UTC)
commit 33141a1ad14fcb4920846283125aec317f577d74
Author: Stef Walter <stefw redhat com>
Date: Sun May 26 14:24:54 2013 +0200
account: Prompt for admin credentials if necessary when joining realm
This is often the case, so we need to have this prompt
https://bugzilla.gnome.org/show_bug.cgi?id=701045
.../pages/account/gis-account-page.c | 146 +++++++++++-
.../pages/account/gis-account-page.ui | 265 ++++++++++++++++++++
2 files changed, 405 insertions(+), 6 deletions(-)
---
diff --git a/gnome-initial-setup/pages/account/gis-account-page.c
b/gnome-initial-setup/pages/account/gis-account-page.c
index a8b40d5..8d58d31 100644
--- a/gnome-initial-setup/pages/account/gis-account-page.c
+++ b/gnome-initial-setup/pages/account/gis-account-page.c
@@ -42,6 +42,14 @@
#include <cheese-gtk.h>
#endif
+static void on_join_login (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data);
+
+static void on_realm_joined (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data);
+
G_DEFINE_TYPE (GisAccountPage, gis_account_page, GIS_TYPE_PAGE);
#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GIS_TYPE_ACCOUNT_PAGE, GisAccountPagePrivate))
@@ -73,6 +81,7 @@ struct _GisAccountPagePrivate
UmRealmManager *realm_manager;
gboolean domain_chosen;
GCancellable *cancellable;
+ gboolean join_prompted;
GtkWidget *action;
};
@@ -603,6 +612,131 @@ enterprise_permit_user_login (GisAccountPage *page, UmRealmObject *realm)
}
static void
+on_join_response (GtkDialog *dialog,
+ gint response,
+ gpointer user_data)
+{
+ GisAccountPage *page = user_data;
+ const gchar *name;
+
+ gtk_widget_hide (GTK_WIDGET (dialog));
+ if (response != GTK_RESPONSE_OK) {
+ gis_page_apply_complete (GIS_PAGE (page), FALSE);
+ return;
+ }
+
+ name = gtk_entry_get_text (OBJ (GtkEntry *, "join-name"));
+ g_debug ("Logging in as admin user: %s", name);
+
+ /* Prompted for some admin credentials, try to use them to log in */
+ um_realm_login (g_object_get_data (G_OBJECT (dialog), "join-realm"),
+ name, gtk_entry_get_text (OBJ (GtkEntry *, "join-password")),
+ NULL, on_join_login, page);
+}
+
+static void
+join_show_prompt (GisAccountPage *page,
+ UmRealmObject *realm,
+ GError *error)
+{
+ UmRealmKerberosMembership *membership;
+ UmRealmKerberos *kerberos;
+ gchar hostname[128];
+ const gchar *name;
+ GtkDialog *join_dialog;
+ GtkEntry *join_name;
+ GtkEntry *join_password;
+ GtkLabel *join_domain;
+ GtkLabel *join_computer;
+
+ join_dialog = OBJ (GtkDialog *, "join-dialog");
+ join_domain = OBJ (GtkLabel *, "join-domain");
+ join_name = OBJ (GtkEntry *, "join-name");
+ join_password = OBJ (GtkEntry *, "join-password");
+ join_computer = OBJ (GtkLabel *, "join-computer");
+
+ gtk_entry_set_text (join_password, "");
+ gtk_widget_grab_focus (GTK_WIDGET (join_password));
+
+ kerberos = um_realm_object_get_kerberos (realm);
+ membership = um_realm_object_get_kerberos_membership (realm);
+
+ gtk_label_set_text (join_domain,
+ um_realm_kerberos_get_domain_name (kerberos));
+
+ if (gethostname (hostname, sizeof (hostname)) == 0)
+ gtk_label_set_text (join_computer, hostname);
+
+ clear_entry_validation_error (join_name);
+ clear_entry_validation_error (join_password);
+
+ if (!page->priv->join_prompted) {
+ name = um_realm_kerberos_membership_get_suggested_administrator (membership);
+ if (name && !g_str_equal (name, "")) {
+ g_debug ("Suggesting admin user: %s", name);
+ gtk_entry_set_text (join_name, name);
+ } else {
+ gtk_widget_grab_focus (GTK_WIDGET (join_name));
+ }
+
+ } else if (g_error_matches (error, UM_REALM_ERROR, UM_REALM_ERROR_BAD_PASSWORD)) {
+ g_debug ("Bad admin password: %s", error->message);
+ set_entry_validation_error (join_password, error->message);
+
+ } else {
+ g_debug ("Admin login failure: %s", error->message);
+ g_dbus_error_strip_remote_error (error);
+ set_entry_validation_error (join_name, error->message);
+ }
+
+ g_debug ("Showing admin password dialog");
+ g_object_set_data_full (G_OBJECT (join_dialog), "join-realm",
+ g_object_ref (realm), g_object_unref);
+ gtk_window_set_transient_for (GTK_WINDOW (join_dialog),
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))));
+ gtk_window_set_modal (GTK_WINDOW (join_dialog), TRUE);
+ gtk_window_present (GTK_WINDOW (join_dialog));
+
+ page->priv->join_prompted = TRUE;
+ g_object_unref (kerberos);
+ g_object_unref (membership);
+
+ /* And now we wait for on_join_response() */
+}
+
+static void
+on_join_login (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GisAccountPage *page = user_data;
+ UmRealmObject *realm = UM_REALM_OBJECT (source);
+ GError *error = NULL;
+ GBytes *creds;
+
+ um_realm_login_finish (realm, result, &creds, &error);
+
+ /* Logged in as admin successfully, use creds to join domain */
+ if (error == NULL) {
+ if (!um_realm_join_as_admin (realm,
+ gtk_entry_get_text (OBJ (GtkEntry *, "join-name")),
+ gtk_entry_get_text (OBJ (GtkEntry *, "join-password")),
+ creds, NULL, on_realm_joined, page)) {
+ show_error_dialog (page, _("No supported way to authenticate with this domain"), NULL);
+ g_message ("Authenticating as admin is not supported by the realm");
+ }
+
+ g_bytes_unref (creds);
+
+ /* Couldn't login as admin, show prompt again */
+ } else {
+ join_show_prompt (page, realm, error);
+ g_message ("Couldn't log in as admin to join domain: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
on_realm_joined (GObject *source,
GAsyncResult *result,
gpointer user_data)
@@ -623,9 +757,7 @@ on_realm_joined (GObject *source,
g_error_matches (error, UM_REALM_ERROR, UM_REALM_ERROR_BAD_PASSWORD)) {
g_debug ("Joining realm failed due to credentials");
- /* XXX */
- /* join_show_prompt (self, error); */
- gis_page_apply_complete (GIS_PAGE (page), FALSE);
+ join_show_prompt (page, realm, error);
/* Other failure */
} else {
@@ -677,9 +809,7 @@ on_realm_login (GObject *source,
/* If we can't do user auth, try to authenticate as admin */
g_debug ("Cannot join with user credentials");
- /* XXX: creds */
- /* join_show_prompt (self, NULL); */
- gis_page_apply_complete (GIS_PAGE (page), FALSE);
+ join_show_prompt (page, realm, error);
}
g_bytes_unref (creds);
@@ -760,6 +890,8 @@ enterprise_add_user (GisAccountPage *page)
GtkTreeIter iter;
GtkComboBox *domain = OBJ(GtkComboBox*, "enterprise-domain");
+ priv->join_prompted = FALSE;
+
/* Already know about this realm, try to login as user */
if (gtk_combo_box_get_active_iter (domain, &iter)) {
gtk_tree_model_get (gtk_combo_box_get_model (domain),
@@ -1015,6 +1147,8 @@ gis_account_page_constructed (GObject *object)
g_signal_connect_after (confirm_entry, "focus-out-event",
G_CALLBACK (confirm_entry_focus_out), page);
+ g_signal_connect (WID("join-dialog"), "response",
+ G_CALLBACK (on_join_response), page);
g_signal_connect (WID("enterprise-domain"), "changed",
G_CALLBACK (on_domain_changed), page);
g_signal_connect (WID("enterprise-login"), "changed",
diff --git a/gnome-initial-setup/pages/account/gis-account-page.ui
b/gnome-initial-setup/pages/account/gis-account-page.ui
index 0ebf4b6..9602dec 100644
--- a/gnome-initial-setup/pages/account/gis-account-page.ui
+++ b/gnome-initial-setup/pages/account/gis-account-page.ui
@@ -495,6 +495,271 @@
</packing>
</child>
</object>
+ <object class="GtkDialog" id="join-dialog">
+ <property name="can_focus">False</property>
+ <property name="border_width">10</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="label">gtk-cancel</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button2">
+ <property name="label" translatable="yes">C_ontinue</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkLabel" id="label71">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Domain Administrator Login</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="scale" value="1.2"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">In order to use enterprise logins, this computer
needs to be
+enrolled in the domain. Please have your network administrator
+type their domain password here.</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="hexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label13">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Domain</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">join-domain</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="join-domain">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">5</property>
+ <property name="margin_bottom">5</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Computer</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">join-computer</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="join-computer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">5</property>
+ <property name="margin_bottom">5</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Administrator _Name</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">join-name</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="join-name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="invisible_char">●</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Administrator Password</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">join-password</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="join-password">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="visibility">False</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ <property name="invisible_char_set">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">button1</action-widget>
+ <action-widget response="-5">button2</action-widget>
+ </action-widgets>
+ </object>
<object class="GtkListStore" id="account-username-model">
<columns>
<!-- column-name gchararray -->
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]