Commit 4bb07396 authored by Stef Walter's avatar Stef Walter

user-accounts: Implement enterprise logins in add dialog

 * Use realmd for domain joining and lookup, runtime dependency
 * Validate join domain correctly
 * Add UmRealmManager for handling some stuff above the autogenerated
   realmd dbus code
 * Show a dialog if the user's credentials cannot be used to join
   the domain. Prompt for admin creds.
 * Register the user's login with the AccountsService
 * This depends on the CacheUser() method of AccountsService

https://bugzilla.gnome.org/show_bug.cgi?id=677548
parent 06233ebb
......@@ -225,6 +225,23 @@ PKG_CHECK_MODULES(ISOCODES, iso-codes)
AC_DEFINE_UNQUOTED([ISO_CODES_PREFIX],["`$PKG_CONFIG --variable=prefix iso-codes`"],[ISO codes prefix])
ISO_CODES=iso-codes
# Kerberos kerberos support
AC_PATH_PROG(KRB5_CONFIG, krb5-config, no)
if test "$KRB5_CONFIG" = "no"; then
AC_MSG_ERROR([krb5-config executable not found in your path - should be installed with the kerberos libraries])
fi
AC_MSG_CHECKING(for krb5 libraries and flags)
KRB5_CFLAGS="`$KRB5_CONFIG --cflags`"
KRB5_LIBS="`$KRB5_CONFIG --libs`"
AC_MSG_RESULT($KRB5_CFLAGS $KRB5_LIBS)
AC_SUBST(KRB5_CFLAGS)
AC_SUBST(KRB5_LIBS)
USER_ACCOUNTS_PANEL_CFLAGS="$USER_ACCOUNTS_PANEL_CFLAGS $KRB5_CFLAGS"
USER_ACCOUNTS_PANEL_LIBS="$USER_ACCOUNTS_PANEL_LIBS $KRB5_LIBS"
dnl ==============================================
dnl End: Check that we meet the dependencies
dnl ==============================================
......
......@@ -23,6 +23,10 @@ if BUILD_CHEESE
AM_CPPFLAGS += $(CHEESE_CFLAGS)
endif
BUILT_SOURCES = \
um-realm-generated.c \
um-realm-generated.h
libuser_accounts_la_SOURCES = \
um-account-type.h \
um-account-type.c \
......@@ -53,7 +57,10 @@ libuser_accounts_la_SOURCES = \
um-editable-combo.c \
um-user-panel.h \
um-user-panel.c \
um-user-module.c
um-user-module.c \
um-realm-manager.c \
um-realm-manager.h \
$(BUILT_SOURCES)
libuser_accounts_la_LIBADD = \
$(PANEL_LIBS) \
......@@ -69,18 +76,26 @@ endif
libuser_accounts_la_LDFLAGS = $(PANEL_LDFLAGS)
um-realm-generated.c: $(srcdir)/data/org.freedesktop.realmd.xml
$(AM_V_GEN) gdbus-codegen --interface-prefix org.freedesktop.realmd. \
--generate-c-code um-realm-generated --c-namespace UmRealm $<
um-realm-generated.h: um-realm-generated.c
noinst_PROGRAMS = frob-account-dialog
frob_account_dialog_SOURCES = \
frob-account-dialog.c \
um-account-dialog.h \
um-account-dialog.c \
um-realm-manager.c \
um-realm-manager.h \
um-user.h \
um-user.c \
um-user-manager.c \
um-user-manager.h \
um-utils.h \
um-utils.c
um-utils.c \
$(BUILT_SOURCES)
frob_account_dialog_LDADD = \
$(libuser_accounts_la_LIBADD)
......
......@@ -16,6 +16,7 @@ desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
EXTRA_DIST = \
gnome-user-accounts-panel.desktop.in.in \
org.freedesktop.realmd.xml \
$(ui_DATA)
CLEANFILES = \
......
......@@ -205,29 +205,380 @@
<child>
<object class="GtkGrid" id="enterprise-area">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="column_spacing">10</property>
<property name="row_spacing">10</property>
<property name="column_spacing">10</property>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">5</property>
<property name="xalign">1</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">_Domain</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">enterprise-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="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Login Name</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">enterprise-login</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="label61">
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Enterprise Widgets</property>
<property name="label" translatable="yes">_Password</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">enterprise-password</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="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkComboBox" id="enterprise-domain">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="has_entry">True</property>
<property name="entry_text_column">0</property>
<child internal-child="entry">
<object class="GtkEntry" id="combobox-entry">
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Tip: Enterprise domain or realm name</property>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</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="GtkEntry" id="enterprise-login">
<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">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="enterprise-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">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
</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">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 enterpise 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="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">1</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">1</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">2</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">2</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>
</interface>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/">
<!--
* Global interface implemented by realmd. Allows listing of providers
* and discovering which one is relevant for a given domain.
*
* This is implemented by individual providers, but is aggregated
* globally at the system bus name 'org.freedesktop.realmd' with the
* object path '/org/freedesktop/realmd'
-->
<interface name="org.freedesktop.realmd.Provider">
<!--
* A list of known, enrolled or discovered realms.
* Each realm is a DBus object and is represeted by a:
* s: DBus bus name of the realm
* o: DBus object path of the realm
* s: DBus interface name, like 'ofr.Kerberos' (below)
-->
<property name="Realms" type="a(sos)" access="read"/>
<!--
* Discover whether a string represents a realm that a provider
* can enroll or otherwise use.
-->
<method name="Discover">
<!-- The input string -->
<arg name="string" type="s" direction="in"/>
<!-- Returned match relevance -->
<arg name="relevance" type="i" direction="out"/>
<!-- The realm objects: bus name, object path, interface -->
<arg name="realm" type="a(sos)" direction="out"/>
</method>
</interface>
<!--
* This interface is implemented by Providers and Realms to provide
* additional information when an long running operation is happening
*
* In particular you can connect to the "Diagnostics" signal when
* during an enroll or unenroll to get details.
-->
<interface name="org.freedesktop.realmd.Diagnostics">
<signal name="Diagnostics">
<arg name="data" type="s"/>
</signal>
</interface>
<!--
* This interface is implemented by Kerberos realms.
-->
<interface name="org.freedesktop.realmd.Kerberos">
<!--
* The kerberos realm name. Usually capitalized.
-->
<property name="Name" type="s" access="read"/>
<!--
* The DNS domain name for this realm.
-->
<property name="Domain" type="s" access="read"/>
<!--
* The suggested Administrator login name for this realm
-->
<property name="SuggestedAdministrator" type="s" access="read"/>
<!--
* Whether the machine is enrolled in this realm or not.
-->
<property name="Enrolled" type="b" access="read"/>
<!--
* Enroll the machine in this realm using an administrative
* account and a password.
-->
<method name="EnrollWithPassword">
<arg name="principal" type="s" direction="in"/>
<arg name="password" type="s" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
</method>
<!--
* Enroll the machine in this realm using kerberos cached
* administrative credentials.
-->
<method name="EnrollWithCredentialCache">
<!-- The contents of a kerberos cache file containing administrative credentials -->
<arg name="kerberos_cache" type="ay" direction="in">
<annotation name="org.gtk.GDBus.C.ForceGVariant" value="yup"/>
</arg>
<arg name="options" type="a{sv}" direction="in"/>
</method>
<!--
* Unenroll the machine from this realm using an administrative
* account and a password.
-->
<method name="UnenrollWithPassword">
<arg name="principal" type="s" direction="in"/>
<arg name="password" type="s" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
</method>
<!--
* Unenroll the machine from this realm using a kerberos cached
* administrative credentials.
-->
<method name="UnenrollWithCredentialCache">
<!-- The contents of a kerberos cache file containing administrative credentials -->
<arg name="kerberos_cache" type="ay" direction="in">
<annotation name="org.gtk.GDBus.C.ForceGVariant" value="yup"/>
</arg>
<arg name="options" type="a{sv}" direction="in"/>
</method>
<!--
* The format for user logins when this realm is enrolled.
* This property may not be valid unless machine is enrolled
* in this realm. The format contains a %s where the user name
* goes eg: "DOMAIN\%s"
-->
<property name="LoginFormat" type="s" access="read"/>
<!--
* The list of permitted logins in the LoginFormat style
-->
<property name="PermittedLogins" type="as" access="read"/>
<!--
* Change the PermittedLogins property. Should take effect
* immediately. Some providers may not enforce this :S
-->
<method name="ChangePermittedLogins">
<arg name="add" type="as" direction="in"/>
<arg name="remove" type="as" direction="in"/>
</method>
</interface>
</node>
This diff is collapsed.
This diff is collapsed.
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright 2012 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Written by: Stef Walter <stefw@gnome.org>
*/
#ifndef __UM_REALM_MANAGER_H__
#define __UM_REALM_MANAGER_H__
#include "um-realm-generated.h"
G_BEGIN_DECLS
typedef enum {
UM_REALM_ERROR_BAD_LOGIN,
UM_REALM_ERROR_BAD_PASSWORD,
UM_REALM_ERROR_GENERIC,
} UmRealmErrors;
#define UM_REALM_ERROR (um_realm_error_get_quark ())
GQuark um_realm_error_get_quark (void) G_GNUC_CONST;
#define UM_TYPE_REALM_MANAGER (um_realm_manager_get_type ())
#define UM_REALM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UM_TYPE_REALM_MANAGER, UmRealmManager))
#define UM_IS_REALM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UM_TYPE_REALM_MANAGER))
typedef struct _UmRealmManager UmRealmManager;
GType um_realm_manager_get_type (void) G_GNUC_CONST;
void um_realm_manager_new (GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
UmRealmManager * um_realm_manager_new_finish (GAsyncResult *result,
GError **error);
void um_realm_manager_discover (UmRealmManager *self,
const gchar *input,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GList * um_realm_manager_discover_finish (UmRealmManager *self,
GAsyncResult *result,
GError **error);
GList * um_realm_manager_get_realms (UmRealmManager *self);
void um_realm_login (const gchar *realm_name,
const gchar *domain,
const gchar *login,
const gchar *password,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean um_realm_login_finish (GAsyncResult *result,
GBytes **credentials,
GError **error);
void um_realm_join (UmRealmKerberos *realm,
GBytes *credentials,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean um_realm_join_finish (UmRealmKerberos *self,
GAsyncResult *result,
GError **error);
G_END_DECLS
#endif /* __UM_REALM_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment