[gnome-online-accounts/wip/kerberos: 5/5] start to port to new realmd
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts/wip/kerberos: 5/5] start to port to new realmd
- Date: Mon, 20 Aug 2012 04:22:45 +0000 (UTC)
commit 916c93e6655db8761121b057cd60a5efe755cdcf
Author: Ray Strode <rstrode redhat com>
Date: Mon Aug 20 00:21:28 2012 -0400
start to port to new realmd
it's not working very well yet
src/goabackend/goakerberosprovider.c | 2 +-
src/goaidentity/Makefile.am | 5 +-
src/goaidentity/goaidentityservice.c | 178 ++++++---
src/goaidentity/org.freedesktop.realmd.xml | 645 +++++++++++++++++++++++++---
src/goaidentity/um-realm-manager.c | 501 +++++++++-------------
src/goaidentity/um-realm-manager.h | 13 +-
6 files changed, 923 insertions(+), 421 deletions(-)
---
diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c
index ad17e30..9449e90 100644
--- a/src/goabackend/goakerberosprovider.c
+++ b/src/goabackend/goakerberosprovider.c
@@ -80,7 +80,7 @@ get_provider_type (GoaProvider *provider)
static gchar *
get_provider_name (GoaProvider *provider, GoaObject *object)
{
- return g_strdup(_("Enterprise Identity"));
+ return g_strdup(_("Enterprise Login (Kerberos)"));
}
typedef struct
diff --git a/src/goaidentity/Makefile.am b/src/goaidentity/Makefile.am
index 1be71b4..9e74b26 100644
--- a/src/goaidentity/Makefile.am
+++ b/src/goaidentity/Makefile.am
@@ -82,8 +82,11 @@ realmd_dbus_built_sources = \
$(realmd_dbus_built_sources) : Makefile.am org.freedesktop.realmd.xml
gdbus-codegen \
--interface-prefix org.freedesktop.realmd. \
- --c-namespace UmRealm \
--generate-c-code um-realm-generated \
+ --c-generate-object-manager \
+ --c-namespace UmRealm \
+ --annotate "org.freedesktop.realmd.Realm" \
+ org.gtk.GDBus.C.Name Common \
org.freedesktop.realmd.xml \
$(NULL)
BUILT_SOURCES += $(realmd_dbus_built_sources)
diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c
index f4b7cb3..03f0473 100644
--- a/src/goaidentity/goaidentityservice.c
+++ b/src/goaidentity/goaidentityservice.c
@@ -64,10 +64,14 @@ struct _GoaIdentityServicePrivate
static void identity_service_manager_interface_init (GoaIdentityServiceManagerIface *interface);
-static void on_realm_joined (UmRealmKerberos *realm,
+static void on_realm_joined (UmRealmObject *realm,
GAsyncResult *result,
GSimpleAsyncResult *operation_result);
+static void on_realm_looked_up_for_sign_in (GoaIdentityService *self,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result);
+
static void
look_up_realm (GoaIdentityService *self,
const char *identifier,
@@ -78,7 +82,7 @@ look_up_realm (GoaIdentityService *self,
static void
sign_in (GoaIdentityService *self,
const char *identifier,
- UmRealmKerberos *realm,
+ UmRealmObject *realm,
gconstpointer initial_password,
GoaIdentitySignInFlags flags,
GCancellable *cancellable,
@@ -163,13 +167,13 @@ unexport_identity (GoaIdentityService *self,
static char *
get_object_path_for_realm (GoaIdentityService *self,
- UmRealmKerberos *realm)
+ UmRealmObject *realm)
{
const char *domain;
char *escaped_domain;
char *object_path;
- domain = um_realm_kerberos_get_domain (realm);
+ domain = um_realm_kerberos_get_domain_name (um_realm_object_peek_kerberos (realm));
escaped_domain = goa_identity_utils_escape_object_path (domain,
strlen (domain));
object_path = g_strdup_printf ("/org/gnome/Identity/Realms/%s", escaped_domain);
@@ -191,15 +195,18 @@ on_realm_gone (GoaIdentityService *self,
static char *
export_realm (GoaIdentityService *self,
- UmRealmKerberos *realm)
+ UmRealmObject *realm)
{
char *object_path;
GDBusObjectSkeleton *object;
GDBusInterfaceSkeleton *interface;
+ UmRealmKerberos *kerberos;
GSimpleAsyncResult *operation_result;
+ kerberos = um_realm_object_peek_kerberos (realm);
+
goa_debug ("GoaIdentityService: exporting realm %s",
- um_realm_kerberos_get_domain (realm));
+ um_realm_kerberos_get_domain_name (kerberos));
object_path = get_object_path_for_realm (self, realm);
@@ -207,21 +214,21 @@ export_realm (GoaIdentityService *self,
interface = G_DBUS_INTERFACE_SKELETON (goa_identity_service_realm_skeleton_new ());
g_object_bind_property (G_OBJECT (realm),
- "enrolled",
+ "configured",
G_OBJECT (interface),
"is-enrolled",
G_BINDING_SYNC_CREATE);
- g_object_bind_property (G_OBJECT (realm),
- "name",
+ g_object_bind_property (G_OBJECT (kerberos),
+ "realm-name",
G_OBJECT (interface),
- "name",
+ "realm-name",
G_BINDING_SYNC_CREATE);
- g_object_bind_property (G_OBJECT (realm),
- "domain",
+ g_object_bind_property (G_OBJECT (kerberos),
+ "domain-name",
G_OBJECT (interface),
- "domain",
+ "domain-name",
G_BINDING_SYNC_CREATE);
operation_result = g_simple_async_result_new (G_OBJECT (self),
(GAsyncReadyCallback)
@@ -355,7 +362,7 @@ on_system_enrollment_password_answered (GoaIdentityService *self,
{
GCancellable *cancellable;
GcrPrompt *prompt;
- UmRealmKerberos *realm;
+ UmRealmObject *realm;
GBytes *credentials;
const char *username;
const char *password;
@@ -450,7 +457,7 @@ on_system_enrollment_username_answered (GoaIdentityService *self,
static void
enroll_machine_as_administrator (GoaIdentityService *self,
GoaIdentity *identity,
- UmRealmKerberos *realm,
+ UmRealmObject *realm,
GBytes *credentials,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -493,12 +500,11 @@ on_machine_enrolled (GoaIdentityService *self,
GAsyncResult *result,
GSimpleAsyncResult *operation_result)
{
- g_simple_async_result_complete_in_idle (operation_result);
g_object_unref (operation_result);
}
static void
-on_realm_joined (UmRealmKerberos *realm,
+on_realm_joined (UmRealmObject *realm,
GAsyncResult *result,
GSimpleAsyncResult *operation_result)
{
@@ -547,7 +553,7 @@ on_realm_joined (UmRealmKerberos *realm,
static void
enroll_machine_as_user (GoaIdentityService *self,
GoaIdentity *identity,
- UmRealmKerberos *realm,
+ UmRealmObject *realm,
const char *password,
GBytes *credentials,
GCancellable *cancellable,
@@ -596,16 +602,61 @@ enroll_machine_as_user (GoaIdentityService *self,
}
static void
+on_realm_looked_up_for_enrollment (GoaIdentityService *self,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ UmRealmObject *realm;
+ GoaIdentity *identity;
+ GError *error;
+ GCancellable *cancellable;
+ GBytes *credentials;
+ gconstpointer initial_password;
+
+ realm = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
+ error = NULL;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+ &error))
+ {
+ goa_debug ("GoaIdentityService: Could not discover realm: %s",
+ error->message);
+ g_error_free (error);
+
+ g_object_unref (operation_result);
+ return;
+ }
+
+ cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+ initial_password = g_object_get_data (G_OBJECT (operation_result),
+ "initial-password");
+ identity = g_object_get_data (G_OBJECT (operation_result), "identity");
+ credentials = goa_identity_get_credentials (identity);
+
+ /* Otherwise, try to enroll the machine with the domain controller
+ */
+ enroll_machine_as_user (self,
+ identity,
+ realm,
+ initial_password,
+ credentials,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_machine_enrolled,
+ operation_result);
+ g_bytes_unref (credentials);
+}
+
+static void
on_sign_in_done (GoaIdentityService *self,
GAsyncResult *result,
GSimpleAsyncResult *operation_result)
{
GoaIdentity *identity;
char *object_path;
- char *initial_password;
+ char *domain;
GCancellable *cancellable;
- UmRealmKerberos *realm;
- GBytes *credentials;
+ UmRealmObject *realm;
GError *error;
error = NULL;
@@ -626,33 +677,35 @@ on_sign_in_done (GoaIdentityService *self,
(GDestroyNotify)
g_free);
- /* If realmd isn't around or the machine is already enrolled,
- * then we're done.
+ /* User is signed in, so we're mostly done
*/
- if (realm == NULL || um_realm_kerberos_get_enrolled (realm))
+ g_simple_async_result_complete_in_idle (operation_result);
+
+ if (realm != NULL && um_realm_is_configured (realm))
{
- g_simple_async_result_complete_in_idle (operation_result);
g_object_unref (operation_result);
return;
}
- initial_password = g_object_get_data (G_OBJECT (operation_result),
- "initial-password");
+ /* Try to enroll the machine at the point, too, if necessary.
+ */
+ g_object_set_data_full (G_OBJECT (operation_result),
+ "identity",
+ g_object_ref (identity),
+ (GDestroyNotify)
+ g_object_unref);
+
+ domain = g_object_get_data (G_OBJECT (operation_result),
+ "domain");
cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
- credentials = goa_identity_get_credentials (identity);
- /* Otherwise, try to enroll the machine with the domain controller
- */
- enroll_machine_as_user (self,
- identity,
- realm,
- initial_password,
- credentials,
- cancellable,
- (GAsyncReadyCallback)
- on_machine_enrolled,
- operation_result);
- g_bytes_unref (credentials);
+ look_up_realm (self,
+ goa_identity_get_identifier (identity),
+ domain,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_realm_looked_up_for_enrollment,
+ operation_result);
}
static GoaObject *
@@ -826,7 +879,7 @@ on_realm_looked_up_for_sign_in (GoaIdentityService *self,
GAsyncResult *result,
GSimpleAsyncResult *operation_result)
{
- UmRealmKerberos *realm;
+ UmRealmObject *realm;
GoaIdentitySignInFlags flags;
GError *error;
GCancellable *cancellable;
@@ -851,6 +904,7 @@ on_realm_looked_up_for_sign_in (GoaIdentityService *self,
else
{
char *user;
+ UmRealmKerberos *kerberos;
/* Rebuild the identifier using the updated realm
*/
@@ -861,10 +915,12 @@ on_realm_looked_up_for_sign_in (GoaIdentityService *self,
&user,
NULL);
+ kerberos = um_realm_object_peek_kerberos (realm);
+
if (user != NULL)
new_identifier = g_strdup_printf ("%s %s",
user,
- um_realm_kerberos_get_name (realm));
+ um_realm_kerberos_get_realm_name (kerberos));
identifier = new_identifier;
@@ -922,7 +978,7 @@ on_realm_looked_up (UmRealmManager *manager,
static void
on_manager_realm_added (UmRealmManager *manager,
- UmRealmKerberos *realm,
+ UmRealmObject *realm,
GoaIdentityService *self)
{
export_realm (self, realm);
@@ -1007,7 +1063,6 @@ on_realm_manager_ensured_for_look_up (GoaIdentityService *self,
domain = g_object_get_data (G_OBJECT (operation_result), "domain");
cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
-
um_realm_manager_discover (self->priv->realm_manager,
domain,
cancellable,
@@ -1057,7 +1112,7 @@ look_up_realm (GoaIdentityService *self,
g_free);
ensure_realm_manager (self,
- NULL,
+ cancellable,
(GAsyncReadyCallback)
on_realm_manager_ensured_for_look_up,
operation_result);
@@ -1120,18 +1175,33 @@ goa_identity_service_handle_sign_in (GoaIdentityServiceManager *manager,
"initial-password",
(gpointer)
initial_password);
+ g_object_set_data_full (G_OBJECT (operation_result),
+ "domain",
+ domain,
+ (GDestroyNotify)
+ g_free);
g_object_set_data (G_OBJECT (operation_result),
"flags",
GINT_TO_POINTER ((int) flags));
+ if (domain == NULL)
+ sign_in (self,
+ identifier,
+ NULL,
+ initial_password,
+ flags,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_sign_in_done,
+ operation_result);
+ else
+ look_up_realm (self,
+ identifier,
+ domain,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_realm_looked_up_for_sign_in,
+ operation_result);
- look_up_realm (self,
- identifier,
- domain,
- cancellable,
- (GAsyncReadyCallback)
- on_realm_looked_up_for_sign_in,
- operation_result);
- g_free (domain);
g_object_unref (cancellable);
return TRUE;
@@ -1935,7 +2005,7 @@ cancel_sign_in (GoaIdentityManager *identity_manager,
static void
sign_in (GoaIdentityService *self,
const char *identifier,
- UmRealmKerberos *realm,
+ UmRealmObject *realm,
gconstpointer initial_password,
GoaIdentitySignInFlags flags,
GCancellable *cancellable,
diff --git a/src/goaidentity/org.freedesktop.realmd.xml b/src/goaidentity/org.freedesktop.realmd.xml
index e09eb50..557de5c 100644
--- a/src/goaidentity/org.freedesktop.realmd.xml
+++ b/src/goaidentity/org.freedesktop.realmd.xml
@@ -1,150 +1,435 @@
<!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'
+ org.freedesktop.realmd.Provider:
+ @short_description: a realm provider
+
+ Various realm providers represent different software implementations
+ that provide access to realms or domains.
+
+ This interface is implemented by individual providers, but is
+ aggregated globally at the system bus name
+ <literal>org.freedesktop.realmd</literal>
+ with the object path <literal>/org/freedesktop/realmd</literal>
-->
<interface name="org.freedesktop.realmd.Provider">
<!--
- * The name of the provider
+ Name: the name of the provider
+
+ The name of the provider. This is not normally displayed
+ to the user, but may be useful for diagnostics or debugging.
-->
<property name="Name" type="s" access="read"/>
<!--
- * A version number for the provider
+ Version: the version of the provider
+
+ The version of the provider. This is not normally used in
+ logic, but may be useful for diagnostics or debugging.
-->
<property name="Version" type="s" access="read"/>
<!--
- * A list of known, enrolled or discovered realms.
- * Each realm is a DBus object and is represeted by a:
- * o: DBus object path of the realm
- * s: DBus interface name, like 'ofr.Kerberos' (below)
+ Realms: a list of realms
+
+ A list of known, enrolled or discovered realms. All realms
+ that this provider knows about are listed here. As realms
+ are discovered they are added to this list.
+
+ Each realm is represented by the DBus object path of the
+ realm object.
-->
- <property name="Realms" type="a(os)" access="read"/>
+ <property name="Realms" type="ao" access="read"/>
<!--
- * Discover whether a string represents a realm that a provider
- * can enroll or otherwise use.
+ Discover:
+ @string: an input string to discover realms for
+ @options: options for the discovery operation
+ @relevance: the relevance of the returned results
+ @realm: a list of realms discovered
+
+ Discover realms for the given string. The input @string is
+ usually a domain or realm name, perhaps typed by a user. If
+ an empty string is provided the realm provider should try to
+ discover a default realm if possible (eg: from DHCP).
+
+ @options can contain, but is not limited to, the following values:
+ <itemizedlist>
+ <listitem><para><literal>operation</literal>: a string
+ identifier chosen by the client, which can then later be
+ passed to org.freedesktop.realmd.Service.Cancel() in order
+ to cancel the operation</para></listitem>
+ </itemizedlist>
+
+ The @relevance returned can be used to rank results from
+ different discover calls to different providers. Implementors
+ should return a positive number if the provider highly
+ recommends that the realms be handled by this provider,
+ or a zero if it can possibly handle the realms. Negative
+ should be returned if no realms are found.
+
+ This method does not return an error when no realms are
+ discovered. It simply returns an @realm list.
+
+ To see diagnostic information about the discovery process
+ connect to the org.freedesktop.realmd.Service::Diagnostics
+ signal.
+
+ This method requires authorization for the PolicyKit action
+ called <literal>org.freedesktop.realmd.discover-realm</literal>.
+
+ In addition to common DBus error results, this method may
+ return:
+ <itemizedlist>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+ may be returned if the discovery could not be run for some reason.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+ returned if the operation was cancelled.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+ returned if the calling client is not permitted to perform a discovery
+ operation.</para></listitem>
+ </itemizedlist>
-->
<method name="Discover">
- <!-- The input string -->
<arg name="string" type="s" direction="in"/>
<arg name="options" type="a{sv}" 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(os)" direction="out"/>
+ <arg name="realm" type="ao" direction="out"/>
</method>
+
</interface>
+ <!--
+ org.freedesktop.realmd.Service:
+ @short_description: the realmd service
+
+ Global calls for managing the realmd service. Usually you'll want
+ to use #org.freedesktop.realmd.Provider instead.
+
+ This interface is implemented by the realmd service, and is always
+ available at the object path <literal>/org/freedesktop/realmd</literal>
+
+ The service also implements the
+ <literal>org.freedesktop.DBus.ObjectManager</literal> interface which
+ makes it easy to retrieve all realmd objects and properties in one go.
+ -->
<interface name="org.freedesktop.realmd.Service">
+
+ <!--
+ Cancel:
+ @operation: the operation to cancel
+
+ Cancel a realmd operation. To be able to cancel an operation
+ pass a uniquely chosen <literal>operation</literal> string
+ identifier as an option in the methods <literal>options</literal>
+ argument.
+
+ These operation string identifiers should be unique per client
+ calling the realmd service.
+
+ It is not guaranteed that the service can or will cancel the
+ operation. For example the operation may have already completed
+ by the time this method is handled. The caller of the operation
+ method will receive a
+ <literal>org.freedesktop.realmd.Error.Cancelled</literal>
+ if the operation was cancelled.
+ -->
<method name="Cancel">
- <arg name="operation_id" type="s" direction="in"/>
+ <arg name="operation" type="s" direction="in"/>
</method>
+ <!--
+ SetLocale:
+ @locale: the locale for the client
+
+ Set the language @locale for the client. This locale is used
+ for error messages. The locale is used until the next time
+ this method is called, the client disconnects, or the client
+ calls #org.freedesktop.realmd.Service.Release().
+ -->
<method name="SetLocale">
<arg name="locale" type="s" direction="in"/>
</method>
+ <!--
+ Diagnostics:
+ @data: diagnostic data
+ @operation: the operation this data resulted from
+
+ This signal is fired when diagnostics result from an operation
+ in the provider or one of its realms.
+
+ It is not guaranteed that this signal is emitted once per line.
+ More than one line may be contained in @data, or a partial
+ line. New line characters are embedded in @data.
+
+ This signal is sent explicitly to the client which invoked
+ operation method. In order to tell which operation this
+ diagnostic data results from, pass a unique
+ <literal>operation</literal> string identifier in the
+ <literal>options</literal> argument of the operation method.
+ That same identifier will be passed back via the @operation
+ argument of this signal.
+ -->
<signal name="Diagnostics">
<arg name="data" type="s"/>
- <arg name="operation_id" type="s"/>
+ <arg name="operation" type="s"/>
</signal>
<!--
- * Normally realmd waits until all clients have disconnected
- * before exiting. For long lived clients, they can call
- * Release() allow realmd to quit. This is an optimization.
- * The daemon will not exit immediately. It is safe to call
- * this multiple times.
+ Release:
+
+ Normally realmd waits until all clients have disconnected
+ before exiting itself, sometime later. For long lived clients
+ they can call this method to allow the realmd service to quit.
+ This is an optimization. The daemon will not exit immediately.
+ It is safe to call this multiple times.
-->
<method name="Release">
<!-- no arguments -->
</method>
+
</interface>
<!--
- * This interface is implemented by Kerberos realms.
+ org.freedesktop.realmd.Realm:
+ @short_description: a realm
+
+ Represents one realm.
+
+ Contains generic information about a realm, and useful properties for
+ introspecting what kind of realm this is and how to work with
+ the realm.
+
+ Use #org.freedesktop.realmd.Provider:Realms or
+ #org.freedesktop.realmd.Provider.Discover() to get access to some
+ kerberos realm objects.
+
+ Realms will always implement additional interfaces, such as
+ #org.freedesktop.realmd.Kerberos. Do not assume that all realms
+ implement that kerberos interface. Use the
+ #org.freedesktop.realmd.Realm:SupportedInterfaces property to see
+ which interfaces are set.
+
+ Different realms support various ways to configure them on the
+ system. Use the #org.freedesktop.realmd.Realm:Configured property
+ to determine if a realm is configured. If it is configured the
+ property will be set to the interface of the mechanism that was
+ used to configure it.
+
+ To configure a realm, look in the
+ #org.freedesktop.realmd.Realm:SupportedInterfaces property for a
+ recognized purpose specific interface that can be used for
+ configuration, such as the
+ #org.freedesktop.realmd.KerberosMembership interface and its
+ #org.freedesktop.realmd.KerberosMembership.Join() method.
+
+ To deconfigure a realm from the current system, you can use the
+ #org.freedesktop.realmd.Realm.Deconfigure() method. In additon some
+ of the configuration specific interfaces provide methods to
+ deconfigure a realm in a specific way, such as
+ #org.freedesktop.realmd.KerberosMembership.Leave() method.
+
+ The various properties are guaranteed to have been updated before
+ the operation methods return, if they change state.
-->
- <interface name="org.freedesktop.realmd.Kerberos">
+ <interface name="org.freedesktop.realmd.Realm">
<!--
- * The kerberos realm name. Usually capitalized.
+ Name: the realm name
+
+ This is the name of the realm, appropriate for display to
+ end users where necessary.
-->
<property name="Name" type="s" access="read"/>
<!--
- * The DNS domain name for this realm.
- -->
- <property name="Domain" type="s" access="read"/>
+ Configured: whether this domain is configured and how
- <!--
- * The server software, for information only. eg: active-directory
+ If this property is an empty string, then the realm is not
+ configured. Otherwise the realm is configured, and contains
+ a string which is the interface that represents how it was
+ configured, for example #org.freedesktop.realmd.KerberosMembership.
-->
- <property name="Details" type="a{ss}" access="read"/>
+ <property name="Configured" type="s" access="read"/>
<!--
- * The suggested Administrator login name for this realm
+ Deconfigure: deconfigure this realm
+
+ Deconfigure this realm from the local machine with standard
+ default behavior.
+
+ The behavior of this method depends on the which configuration
+ interface is present in the
+ #org.freedesktop.realmd.Realm.Configured property. It does not
+ always delete membership accounts in the realm, but just
+ reconfigures the local machine so it no longer is configured
+ for the given realm. In some cases the implementation may try
+ to update membership accounts, but this is not guaranteed.
+
+ Various configuration interfaces may support more specific ways
+ to deconfigure a realm in a specific way, such as the
+ #org.freedesktop.realmd.KerberosMembership.Leave() method.
+
+ @options can contain, but is not limited to, the following values:
+ <itemizedlist>
+ <listitem><para><literal>operation</literal>: a string
+ identifier chosen by the client, which can then later be
+ passed to org.freedesktop.realmd.Service.Cancel() in order
+ to cancel the operation</para></listitem>
+ </itemizedlist>
+
+ This method requires authorization for the PolicyKit action
+ called <literal>org.freedesktop.realmd.deconfigure-realm</literal>.
+
+ In addition to common DBus error results, this method may return:
+ <itemizedlist>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+ may be returned if the deconfigure failed for a generic reason.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+ returned if the operation was cancelled.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+ returned if the calling client is not permitted to deconfigure a
+ realm.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.NotConfigured</literal>:
+ returned if this realm is not configured on the machine.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Busy</literal>:
+ returned if the service is currently performing another operation like
+ join or leave.</para></listitem>
+ </itemizedlist>
-->
- <property name="SuggestedAdministrator" type="s" access="read"/>
+ <method name="Deconfigure">
+ <arg name="options" type="a{sv}" direction="in"/>
+ </method>
<!--
- * Whether the machine is enrolled in this realm or not.
+ SupportedInterfaces:
+
+ Additional supported interfaces of this realm. This includes
+ interfaces that contain more information about the realm,
+ such as #org.freedesktop.realmd.Kerberos and interfaces
+ which contain methods for configuring a realm, such as
+ #org.freedesktop.realmd.KerberosMembership.
-->
- <property name="Enrolled" type="b" access="read"/>
+ <property name="SupportedInterfaces" type="as" access="read"/>
<!--
- * Credentials: (ssv)
- * type: 'ccache', 'password', 'automatic'
- * who: 'administrator', 'user', 'computer', 'secret'
- * contents: ay, ss, b
- -->
- <property name="SupportedEnrollCredentials" type="a(ss)" access="read"/>
+ Details: informational details about the realm
- <property name="SupportedUnenrollCredentials" type="a(ss)" access="read"/>
+ Informational details about the realm. The following values
+ should be present:
+ <itemizedlist>
+ <listitem><para><literal>server-software</literal>:
+ identifier of the software running on the server (eg:
+ <literal>active-directory</literal>).</para></listitem>
+ <listitem><para><literal>client-software</literal>:
+ identifier of the software running on the client (eg:
+ <literal>sssd</literal>).</para></listitem>
+ </itemizedlist>
+ -->
+ <property name="Details" type="a(ss)" access="read"/>
- <method name="Enroll">
- <arg name="credentials" type="(ssv)" direction="in"/>
- <arg name="options" type="a{sv}" direction="in"/>
- </method>
+ <!--
+ LoginFormats: supported formats for login names
- <method name="Unenroll">
- <arg name="credentials" type="(ssv)" direction="in"/>
- <arg name="options" type="a{sv}" direction="in"/>
- </method>
+ Supported formats for login to this realm. This is only
+ relevant once the realm has been enrolled. The formats
+ will contain a <literal>%U</literal> in the string, which
+ indicate where the user name should be placed. The formats
+ may contain a <literal>%D</literal> in the string which
+ indicate where a domain name should be placed.
- <!--
- * 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"
+ The first format in the list is the preferred format for
+ login names.
-->
- <property name="LoginFormat" type="s" access="read"/>
+ <property name="LoginFormats" type="as" access="read"/>
<!--
- * The policy for logins using this realm.
- * 'allow-any-login' 'allow-permitted-logins' 'deny-any-login'
+ LoginPolicy: the policy for logins using this realm
+
+ The policy for logging into this computer using this realm.
+
+ The policy can be changed using the
+ #org.freedesktop.realmd.Realm.ChangeLoginPolicy() method.
+
+ The following policies are predefined. Not all providers
+ support all these policies and there may be provider specific
+ policies or multiple policies represented in the string:
+ <itemizedlist>
+ <listitem><para><literal>allow-any-login</literal>: allow
+ login by any authenticated user present in this
+ realm.</para></listitem>
+ <listitem><para><literal>allow-permitted-logins</literal>:
+ only allow the logins permitted in the
+ #org.freedesktop.realmd.Realm:PermittedLogins
+ property.</para></listitem>
+ <listitem><para><literal>deny-any-login</literal>:
+ don't allow any logins via authenticated users of this
+ realm.</para></listitem>
+ </itemizedlist>
-->
<property name="LoginPolicy" type="s" access="read"/>
<!--
- * The list of permitted logins in the LoginFormat style
+ PermittedLogins: the permitted login names
+
+ The list of permitted authenticated users allowed to login
+ into this computer. This is only relevant if the
+ #org.freedesktop.realmd.Realm:LoginPolicy property
+ contains the <literal>allow-permitted-logins</literal>
+ string.
-->
<property name="PermittedLogins" type="as" access="read"/>
<!--
- * Change the PermittedLogins property. Should take effect
- * immediately.
+ ChangeLoginPolicy:
+ @login_policy: the new login policy, or an empty string
+ @permitted_add: a list of logins to permit
+ @permitted_remove: a list of logins to not permit
+ @options: options for this operation
+
+ Change the login policy and/or permitted logins for this realm.
+
+ Not all realms support the all the various login policies. An
+ error will be returned if the new login policy is not supported.
+ You may specify an empty string for the @login_policy argument
+ which will cause no change in the policy itself. If the policy
+ is changed, it will be reflected in the
+ #org.freedesktop.realmd.Realm:LoginPolicy property.
+
+ The @permitted_add and @permitted_remove arguments represent
+ lists of login names that should be added and removed from
+ the #org.freedesktop.realmd.Kerberos:PermittedLogins property.
+
+ @options can contain, but is not limited to, the following values:
+ <itemizedlist>
+ <listitem><para><literal>operation</literal>: a string
+ identifier chosen by the client, which can then later be
+ passed to org.freedesktop.realmd.Service.Cancel() in order
+ to cancel the operation</para></listitem>
+ </itemizedlist>
+
+ This method requires authorization for the PolicyKit action
+ called <literal>org.freedesktop.realmd.login-policy</literal>.
+
+ In addition to common DBus error results, this method may return:
+ <itemizedlist>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+ may be returned if the policy change failed for a generic reason.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+ returned if the operation was cancelled.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+ returned if the calling client is not permitted to change login policy
+ operation.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.NotConfigured</literal>:
+ returned if the realm is not configured.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Busy</literal>:
+ returned if the service is currently performing another operation like
+ join or leave.</para></listitem>
+ </itemizedlist>
-->
<method name="ChangeLoginPolicy">
<arg name="login_policy" type="s" direction="in"/>
@@ -154,4 +439,228 @@
</method>
</interface>
+
+ <!--
+ org.freedesktop.realmd.Kerberos:
+ @short_description: a kerberos realm
+
+ An interface that describes a kerberos realm in more detail. This
+ is always implemented on an DBus object path that also implements
+ the #org.freedesktop.realmd.Realm interface.
+ -->
+ <interface name="org.freedesktop.realmd.Kerberos">
+
+ <!--
+ RealmName: the kerberos realm name
+
+ The kerberos name for this realm. This is usually in upper
+ case.
+ -->
+ <property name="RealmName" type="s" access="read"/>
+
+ <!--
+ DomainName: the DNS domain name
+
+ The DNS domain name for this realm.
+ -->
+ <property name="DomainName" type="s" access="read"/>
+
+ </interface>
+
+ <!--
+ org.freedesktop.realmd.KerberosMembership:
+
+ An interface used to configure this machine by joining a realm.
+
+ It sets up a computer/host account in the realm for this machine
+ and a keytab to track the credentials for that account.
+
+ The various properties are guaranteed to have been updated before
+ the operation methods return, if they change state.
+ -->
+ <interface name="org.freedesktop.realmd.KerberosMembership">
+
+ <!--
+ SuggestedAdministrator: common administrator name
+
+ The common administrator name for this type of realm. This
+ can be used by clients as a hint when prompting the user for
+ administrative authentication.
+ -->
+ <property name="SuggestedAdministrator" type="s" access="read"/>
+
+ <!--
+ SupportedJoinCredentials: credentials supported for joining
+
+ Various kinds of credentials that are supported when calling the
+ #org.freedesktop.realmd.Kerberos.Join() method.
+
+ Each credential is represented by a type, and an owner. The type
+ denotes which kind of credential is passed to the method. The
+ owner indicates to the client how to prompt the user or obtain
+ the credential, and to the service how to use the credential.
+
+ The various types are:
+ <itemizedlist>
+ <listitem><para><literal>ccache</literal>:
+ the credentials should contain an array of bytes as a
+ <literal>ay</literal> containing the data from a kerberos
+ credential cache file.</para></listitem>
+ <listitem><para><literal>password</literal>:
+ the credentials should contain a pair of strings as a
+ <literal>(ss)</literal> representing a name and
+ password. The name may contain a realm in the standard
+ kerberos format. If missing, it will default to this
+ realm. The name may be empty for a computer or one time
+ password.</para></listitem>
+ <listitem><para><literal>automatic</literal>:
+ the credentials should contain an empty string as a
+ <literal>s</literal>. Using <literal>automatic</literal>
+ indicates that default or system credentials are to be
+ used.</para></listitem>
+ </itemizedlist>
+
+ The various owners are:
+ <itemizedlist>
+ <listitem><para><literal>administrator</literal>:
+ the credentials belong to a kerberos user principal.
+ The caller may use this as a hint to prompt the user
+ for administrative credentials.</para></listitem>
+ <listitem><para><literal>user</literal>:
+ the credentials belong to a kerberos user principal.
+ The caller may use this as a hint to prompt the user
+ for his (possibly non-administrative)
+ credentials.</para></listitem>
+ <listitem><para><literal>computer</literal>:
+ the credentials belong to the computer realmd is
+ being run on.</para></listitem>
+ <listitem><para><literal>secret</literal>:
+ the credentials are a one time password or other secret
+ used to join or leave the computer.</para></listitem>
+ </itemizedlist>
+ -->
+ <property name="SupportedJoinCredentials" type="a(ss)" access="read"/>
+
+ <!--
+ SupportedLeaveCredentials: credentials supported for leaving
+
+ Various kinds of credentials that are supported when calling the
+ #org.freedesktop.realmd.Kerberos.Leave() method.
+
+ See #org.freedesktop.realmd.Kerberos:SupportedJoinCredentials for
+ a discussion of what the values represent.
+ -->
+ <property name="SupportedLeaveCredentials" type="a(ss)" access="read"/>
+
+ <!--
+ Join:
+
+ Join this machine to the realm and enroll the machine.
+
+ If this method returns successfully then the machine will be
+ joined to the realm. It is not necessary to restart services or the
+ machine afterward. Relevant properties on the realm will be updated
+ before the method returns.
+
+ The @credentials should be set according to one of the
+ supported credentials returned by
+ #org.freedesktop.realmd.Kerberos:SupportedJoinCredentials.
+ The first string in the tuple is the type, the second string
+ is the owner, and the variant contains the credential contents
+ See the discussion at
+ #org.freedesktop.realmd.Kerberos:SupportedJoinCredentials
+ for more information.
+
+ @options can contain, but is not limited to, the following values:
+ <itemizedlist>
+ <listitem><para><literal>operation</literal>: a string
+ identifier chosen by the client, which can then later be
+ passed to org.freedesktop.realmd.Service.Cancel() in order
+ to cancel the operation</para></listitem>
+ </itemizedlist>
+
+ This method requires authorization for the PolicyKit action
+ called <literal>org.freedesktop.realmd.configure-realm</literal>.
+
+ In addition to common DBus error results, this method may return:
+ <itemizedlist>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+ may be returned if the join failed for a generic reason.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+ returned if the operation was cancelled.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+ returned if the calling client is not permitted to perform an join
+ operation.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.AuthenticationFailed</literal>:
+ returned if the credentials passed did not authenticate against the realm
+ correctly. It is appropriate to prompt the user again.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.AlreadyEnrolled</literal>:
+ returned if already enrolled in this realm, or another realm and enrolling
+ in multiple realms is not supported.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Busy</literal>:
+ returned if the service is currently performing another operation like
+ join or leave.</para></listitem>
+ </itemizedlist>
+ -->
+ <method name="Join">
+ <arg name="credentials" type="(ssv)" direction="in"/>
+ <arg name="options" type="a{sv}" direction="in"/>
+ </method>
+
+ <!--
+ Leave:
+
+ Leave the realm and unenroll the machine.
+
+ If this method returns successfully then the machine will have
+ left the domain and been unenrolled. It is not necessary to restart
+ services or the machine afterward. Relevant properties on the realm
+ will be updated before the method returns.
+
+ The @credentials should be set according to one of the
+ supported credentials returned by
+ #org.freedesktop.realmd.Kerberos:SupportedUnenrollCredentials.
+ The first string in the tuple is the type, the second string
+ is the owner, and the variant contains the credential contents
+ See the discussion at
+ #org.freedesktop.realmd.Kerberos:SupportedEnrollCredentials
+ for more information.
+
+ @options can contain, but is not limited to, the following values:
+ <itemizedlist>
+ <listitem><para><literal>operation</literal>: a string
+ identifier chosen by the client, which can then later be
+ passed to org.freedesktop.realmd.Service.Cancel() in order
+ to cancel the operation</para></listitem>
+ </itemizedlist>
+
+ This method requires authorization for the PolicyKit action
+ called <literal>org.freedesktop.realmd.deconfigure-realm</literal>.
+
+ In addition to common DBus error results, this method may return:
+ <itemizedlist>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Failed</literal>:
+ may be returned if the unenroll failed for a generic reason.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Cancelled</literal>:
+ returned if the operation was cancelled.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.NotAuthorized</literal>:
+ returned if the calling client is not permitted to perform an unenroll
+ operation.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.AuthenticationFailed</literal>:
+ returned if the credentials passed did not authenticate against the realm
+ correctly. It is appropriate to prompt the user again.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.NotEnrolled</literal>:
+ returned if not enrolled in this realm.</para></listitem>
+ <listitem><para><literal>org.freedesktop.realmd.Error.Busy</literal>:
+ returned if the service is currently performing another operation like
+ enroll or unenroll.</para></listitem>
+ </itemizedlist>
+ -->
+ <method name="Leave">
+ <arg name="credentials" type="(ssv)" direction="in"/>
+ <arg name="options" type="a{sv}" direction="in"/>
+ </method>
+
+ </interface>
+
</node>
diff --git a/src/goaidentity/um-realm-manager.c b/src/goaidentity/um-realm-manager.c
index 4ff40d8..f4fec71 100644
--- a/src/goaidentity/um-realm-manager.c
+++ b/src/goaidentity/um-realm-manager.c
@@ -37,9 +37,9 @@
struct _UmRealmManager {
- UmRealmProviderProxy parent;
+ UmRealmObjectManagerClient parent;
+ UmRealmProvider *provider;
guint diagnostics_sig;
- GHashTable *realms;
};
typedef struct {
@@ -53,7 +53,7 @@ enum {
static gint signals[NUM_SIGNALS] = { 0, };
-G_DEFINE_TYPE (UmRealmManager, um_realm_manager, UM_REALM_TYPE_PROVIDER_PROXY);
+G_DEFINE_TYPE (UmRealmManager, um_realm_manager, UM_REALM_TYPE_OBJECT_MANAGER_CLIENT);
GQuark
um_realm_error_get_quark (void)
@@ -64,172 +64,49 @@ um_realm_error_get_quark (void)
return quark;
}
-typedef struct {
- UmRealmManager *manager;
- GList *realms;
- gint outstanding;
-} LoadClosure;
-
-static void
-load_closure_free (gpointer data)
-{
- LoadClosure *load = data;
- g_list_free_full (load->realms, g_object_unref);
- g_object_unref (load->manager);
- g_slice_free (LoadClosure, load);
-}
-
-static void
-on_realm_proxy_created (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
+static gboolean
+is_realm_with_kerberos_and_membership (gpointer object)
{
- GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
- LoadClosure *load = g_simple_async_result_get_op_res_gpointer (async);
- UmRealmManager *self = load->manager;
- UmRealmKerberos *realm;
- UmRealmKerberos *have;
- GError *error = NULL;
- GDBusProxy *proxy;
- GVariant *info;
+ GDBusInterface *interface;
- realm = um_realm_kerberos_proxy_new_finish (result, &error);
- if (error == NULL) {
- proxy = G_DBUS_PROXY (realm);
- info = g_variant_new ("(os)",
- g_dbus_proxy_get_object_path (proxy),
- g_dbus_proxy_get_interface_name (proxy));
-
- /* Add it to the manager, unless race */
- have = g_hash_table_lookup (self->realms, info);
- if (have == NULL) {
- g_dbus_proxy_set_default_timeout (proxy, G_MAXINT);
- g_hash_table_insert (self->realms,
- g_variant_ref_sink (info), realm);
- g_signal_emit (self, signals[REALM_ADDED], 0, realm);
-
- } else {
- g_object_unref (realm);
- g_variant_unref (info);
- realm = have;
- }
-
- load->realms = g_list_prepend (load->realms, g_object_ref (realm));
+ if (!G_IS_DBUS_OBJECT (object))
+ return FALSE;
- } else {
- g_simple_async_result_take_error (async, error);
- }
+ interface = g_dbus_object_get_interface (object, "org.freedesktop.realmd.Kerberos");
+ if (interface == NULL)
+ return FALSE;
+ g_object_unref (interface);
- if (load->outstanding-- == 1)
- g_simple_async_result_complete (async);
+ interface = g_dbus_object_get_interface (object, "org.freedesktop.realmd.KerberosMembership");
+ if (interface == NULL)
+ return FALSE;
+ g_object_unref (interface);
- g_object_unref (async);
+ return TRUE;
}
static void
-um_realm_manager_load (UmRealmManager *self,
- GVariant *realms,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+on_interface_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ GDBusInterface *interface)
{
- GSimpleAsyncResult *async;
- GDBusConnection *connection;
- LoadClosure *load;
- GVariantIter iter;
- GVariant *info;
- UmRealmKerberos *realm;
- const gchar *path;
- const gchar *iface;
-
- g_return_if_fail (realms != NULL);
-
- async = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
- um_realm_manager_load);
- load = g_slice_new0 (LoadClosure);
- load->manager = g_object_ref (self);
- g_simple_async_result_set_op_res_gpointer (async, load, load_closure_free);
-
- connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (self));
-
- g_variant_iter_init (&iter, realms);
- while (1) {
- info = g_variant_iter_next_value (&iter);
- if (info == NULL)
- break;
- realm = g_hash_table_lookup (self->realms, info);
- if (realm == NULL) {
- g_variant_get (info, "(&o&s)", &path, &iface);
- if (g_str_equal (iface, "org.freedesktop.realmd.Kerberos")) {
- um_realm_kerberos_proxy_new (connection,
- G_DBUS_PROXY_FLAGS_NONE,
- "org.freedesktop.realmd",
- path, cancellable,
- on_realm_proxy_created,
- g_object_ref (async));
- load->outstanding++;
- }
- } else {
- load->realms = g_list_prepend (load->realms, g_object_ref (realm));
- }
- g_variant_unref (info);
- }
-
- if (load->outstanding == 0)
- g_simple_async_result_complete_in_idle (async);
-
- g_object_unref (async);
-}
-
-static GList *
-um_realm_manager_load_finish (UmRealmManager *self,
- GAsyncResult *result,
- GError **error)
-{
- GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (result);
- LoadClosure *load;
- GList *realms;
-
- if (g_simple_async_result_propagate_error (async, error))
- return NULL;
-
- load = g_simple_async_result_get_op_res_gpointer (async);
- realms = g_list_reverse (load->realms);
- load->realms = NULL;
- return realms;
-}
-
-static guint
-hash_realm_info (gconstpointer value)
-{
- const gchar *path, *iface;
- g_variant_get ((GVariant *)value, "(&o&s)", &path, &iface);
- return g_str_hash (path) ^ g_str_hash (iface);
+ g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (interface), G_MAXINT);
}
static void
-um_realm_manager_init (UmRealmManager *self)
+on_object_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data)
{
- self->realms = g_hash_table_new_full (hash_realm_info, g_variant_equal,
- (GDestroyNotify)g_variant_unref,
- g_object_unref);
+ if (is_realm_with_kerberos_and_membership (object))
+ g_signal_emit (user_data, signals[REALM_ADDED], 0, object);
}
static void
-um_realm_manager_notify (GObject *obj,
- GParamSpec *spec)
+um_realm_manager_init (UmRealmManager *self)
{
- UmRealmManager *self = UM_REALM_MANAGER (obj);
- GVariant *realms;
-
- if (G_OBJECT_CLASS (um_realm_manager_parent_class)->notify)
- G_OBJECT_CLASS (um_realm_manager_parent_class)->notify (obj, spec);
-
- if (g_str_equal (spec->name, "realms")) {
- realms = um_realm_provider_get_realms (UM_REALM_PROVIDER (self));
- if (realms != NULL)
- um_realm_manager_load (self, realms, NULL, NULL, NULL);
- }
+ g_signal_connect (self, "object-added", G_CALLBACK (on_object_added), self);
+ g_signal_connect (self, "interface-added", G_CALLBACK (on_interface_added), self);
}
static void
@@ -238,8 +115,10 @@ um_realm_manager_dispose (GObject *obj)
UmRealmManager *self = UM_REALM_MANAGER (obj);
GDBusConnection *connection;
+ g_clear_object (&self->provider);
+
if (self->diagnostics_sig) {
- connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (self));
+ connection = g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (self));
if (connection != NULL)
g_dbus_connection_signal_unsubscribe (connection, self->diagnostics_sig);
self->diagnostics_sig = 0;
@@ -249,28 +128,16 @@ um_realm_manager_dispose (GObject *obj)
}
static void
-um_realm_manager_finalize (GObject *obj)
-{
- UmRealmManager *self = UM_REALM_MANAGER (obj);
-
- g_hash_table_destroy (self->realms);
-
- G_OBJECT_CLASS (um_realm_manager_parent_class)->finalize (obj);
-}
-
-static void
um_realm_manager_class_init (UmRealmManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->notify = um_realm_manager_notify;
object_class->dispose = um_realm_manager_dispose;
- object_class->finalize = um_realm_manager_finalize;
signals[REALM_ADDED] = g_signal_new ("realm-added", UM_TYPE_REALM_MANAGER,
G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
g_cclosure_marshal_generic,
- G_TYPE_NONE, 1, UM_REALM_TYPE_KERBEROS);
+ G_TYPE_NONE, 1, UM_REALM_TYPE_OBJECT);
}
static void
@@ -324,80 +191,19 @@ version_compare (const char *version,
return match;
}
-static void
-on_realm_manager_async_init (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
- UmRealmManager *self;
- GError *error = NULL;
- const gchar *version;
- GDBusProxy *proxy;
- GObject *object;
- guint sig;
-
- object = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, &error);
-
- if (error != NULL)
- g_simple_async_result_take_error (async, error);
-
- /* This is temporary until the dbus interface stabilizes */
- if (object) {
- version = um_realm_provider_get_version (UM_REALM_PROVIDER (object));
- if (!version_compare (version, 0, 6)) {
- /* No need to bother translators with this temporary message */
- g_simple_async_result_set_error (async, UM_REALM_ERROR,
- UM_REALM_ERROR_GENERIC,
- "Unsupported version of realmd: %s", version);
- g_object_unref (object);
- object = NULL;
- }
- }
-
- if (object != NULL) {
- proxy = G_DBUS_PROXY (object);
- sig = g_dbus_connection_signal_subscribe (g_dbus_proxy_get_connection (proxy),
- "org.freedesktop.realmd",
- "org.freedesktop.realmd.Service",
- "Diagnostics",
- NULL,
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- on_realm_diagnostics,
- NULL,
- NULL);
-
- self = UM_REALM_MANAGER (object);
- self->diagnostics_sig = sig;
- g_simple_async_result_set_op_res_gpointer (async, self, g_object_unref);
- }
-
- g_simple_async_result_complete (async);
- g_object_unref (async);
-}
-
void
um_realm_manager_new (GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *async;
-
- async = g_simple_async_result_new (NULL, callback, user_data,
- um_realm_manager_new);
-
- g_async_initable_new_async (UM_TYPE_REALM_MANAGER,
- G_PRIORITY_DEFAULT, cancellable,
- on_realm_manager_async_init, g_object_ref (async),
- "g-name", "org.freedesktop.realmd",
- "g-bus-type", G_BUS_TYPE_SYSTEM,
- "g-object-path", "/org/freedesktop/realmd",
- "g-interface-name", "org.freedesktop.realmd.Provider",
- "g-default-timeout", G_MAXINT,
+ g_async_initable_new_async (UM_TYPE_REALM_MANAGER, G_PRIORITY_DEFAULT,
+ cancellable, callback, user_data,
+ "flags", G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+ "name", "org.freedesktop.realmd",
+ "bus-type", G_BUS_TYPE_SYSTEM,
+ "object-path", "/org/freedesktop/realmd",
+ "get-proxy-type-func", um_realm_object_manager_client_get_proxy_type,
NULL);
-
- g_object_unref (async);
}
UmRealmManager *
@@ -405,23 +211,63 @@ um_realm_manager_new_finish (GAsyncResult *result,
GError **error)
{
UmRealmManager *self;
- GSimpleAsyncResult *async;
+ GDBusConnection *connection;
+ GObject *source_object;
+ const gchar *version;
+ GObject *ret;
+ guint sig;
- g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
- um_realm_manager_new), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ source_object = g_async_result_get_source_object (result);
+ ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
+ g_object_unref (source_object);
- async = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (async, error))
+ if (ret == NULL)
+ return NULL;
+
+ self = UM_REALM_MANAGER (ret);
+ connection = g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (self));
+
+ /*
+ * TODO: Remove this version checking. This is temporary code, so
+ * just use sync here. Shortly we'll be stabilizing the realmd
+ * interfaces.
+ */
+
+ self->provider = um_realm_provider_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
+ "org.freedesktop.realmd",
+ "/org/freedesktop/realmd",
+ NULL, error);
+ if (self->provider == NULL) {
+ g_object_unref (self);
+ return NULL;
+ }
+
+ version = um_realm_provider_get_version (self->provider);
+ if (!version_compare (version, 0, 7)) {
+ /* No need to bother translators with this temporary message */
+ g_set_error (error, UM_REALM_ERROR, UM_REALM_ERROR_GENERIC,
+ "Unsupported version of realmd: %s", version);
+ g_object_unref (self);
return NULL;
+ }
+
+ sig = g_dbus_connection_signal_subscribe (connection,
+ "org.freedesktop.realmd",
+ "org.freedesktop.realmd.Service",
+ "Diagnostics",
+ NULL,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ on_realm_diagnostics,
+ NULL,
+ NULL);
+ self->diagnostics_sig = sig;
- self = g_simple_async_result_get_op_res_gpointer (async);
- if (self != NULL)
- g_object_ref (self);
return self;
}
typedef struct {
+ GDBusObjectManager *manager;
GCancellable *cancellable;
GList *realms;
} DiscoverClosure;
@@ -430,46 +276,35 @@ static void
discover_closure_free (gpointer data)
{
DiscoverClosure *discover = data;
+ g_object_unref (discover->manager);
g_clear_object (&discover->cancellable);
g_list_free_full (discover->realms, g_object_unref);
g_slice_free (DiscoverClosure, discover);
}
static void
-on_manager_load (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
- DiscoverClosure *discover = g_simple_async_result_get_op_res_gpointer (async);
- GError *error = NULL;
-
- discover->realms = um_realm_manager_load_finish (UM_REALM_MANAGER (source),
- result, &error);
- if (error != NULL)
- g_simple_async_result_take_error (async, error);
- g_simple_async_result_complete (async);
-
- g_object_unref (async);
-}
-
-static void
on_provider_discover (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
DiscoverClosure *discover = g_simple_async_result_get_op_res_gpointer (async);
- UmRealmManager *self = UM_REALM_MANAGER (source);
+ GDBusObject *object;
GError *error = NULL;
- GVariant *realms;
+ gchar **realms;
gint relevance;
+ gint i;
- um_realm_provider_call_discover_finish (UM_REALM_PROVIDER (self),
- &relevance, &realms, result, &error);
+ um_realm_provider_call_discover_finish (UM_REALM_PROVIDER (source), &relevance,
+ &realms, result, &error);
if (error == NULL) {
- um_realm_manager_load (self, realms, discover->cancellable,
- on_manager_load, g_object_ref (async));
+ for (i = 0; realms[i]; i++) {
+ object = g_dbus_object_manager_get_object (discover->manager, realms[i]);
+ if (object == NULL)
+ g_warning ("Realm is not in object manager: %s", realms[i]);
+ else
+ discover->realms = g_list_prepend (discover->realms, object);
+ }
} else {
g_simple_async_result_take_error (async, error);
@@ -497,12 +332,13 @@ um_realm_manager_discover (UmRealmManager *self,
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
um_realm_manager_discover);
discover = g_slice_new0 (DiscoverClosure);
+ discover->manager = g_object_ref (self);
discover->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
g_simple_async_result_set_op_res_gpointer (res, discover, discover_closure_free);
options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
- um_realm_provider_call_discover (UM_REALM_PROVIDER (self), input, options, cancellable,
+ um_realm_provider_call_discover (self->provider, input, options, cancellable,
on_provider_discover, g_object_ref (res));
g_object_unref (res);
@@ -533,7 +369,7 @@ um_realm_manager_discover_finish (UmRealmManager *self,
return NULL;
}
- realms = discover->realms;
+ realms = g_list_reverse (discover->realms);
discover->realms = NULL;
return realms;
}
@@ -541,12 +377,75 @@ um_realm_manager_discover_finish (UmRealmManager *self,
GList *
um_realm_manager_get_realms (UmRealmManager *self)
{
+ GList *objects;
+ GList *realms = NULL;
+ GList *l;
+
g_return_val_if_fail (UM_IS_REALM_MANAGER (self), NULL);
- return g_hash_table_get_values (self->realms);
+
+ objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self));
+ for (l = objects; l != NULL; l = g_list_next (l)) {
+ if (is_realm_with_kerberos_and_membership (l->data))
+ realms = g_list_prepend (realms, g_object_ref (l->data));
+ }
+
+ g_list_free_full (objects, g_object_unref);
+ return realms;
+}
+
+static void
+string_replace (GString *string,
+ const gchar *find,
+ const gchar *replace)
+{
+ const gchar *at;
+ gssize pos;
+
+ at = strstr (string->str, find);
+ if (at != NULL) {
+ pos = at - string->str;
+ g_string_erase (string, pos, strlen (find));
+ g_string_insert (string, pos, replace);
+ }
+}
+
+gchar *
+um_realm_calculate_login (UmRealmCommon *realm,
+ const gchar *username)
+{
+ GString *string;
+ const gchar *const *formats;
+ gchar *login = NULL;
+
+ formats = um_realm_common_get_login_formats (realm);
+ if (formats[0] != NULL) {
+ string = g_string_new (formats[0]);
+ string_replace (string, "%U", username);
+ string_replace (string, "%D", um_realm_common_get_name (realm));
+ login = g_string_free (string, FALSE);
+ }
+
+ return login;
+
+}
+
+gboolean
+um_realm_is_configured (UmRealmObject *realm)
+{
+ UmRealmCommon *common;
+ const gchar *configured;
+ gboolean is;
+
+ common = um_realm_object_get_common (realm);
+ configured = um_realm_common_get_configured (common);
+ is = configured != NULL && !g_str_equal (configured, "");
+ g_object_unref (common);
+
+ return is;
}
static const gchar *
-find_supported_credentials (UmRealmKerberos *realm,
+find_supported_credentials (UmRealmKerberosMembership *membership,
const gchar *owner)
{
const gchar *cred_owner;
@@ -554,7 +453,7 @@ find_supported_credentials (UmRealmKerberos *realm,
GVariant *supported;
GVariantIter iter;
- supported = um_realm_kerberos_get_supported_enroll_credentials (realm);
+ supported = um_realm_kerberos_membership_get_supported_join_credentials (membership);
g_return_val_if_fail (supported != NULL, NULL);
g_variant_iter_init (&iter, supported);
@@ -582,7 +481,7 @@ on_realm_join_complete (GObject *source,
}
static gboolean
-realm_join_as_owner (UmRealmKerberos *realm,
+realm_join_as_owner (UmRealmObject *realm,
const gchar *owner,
const gchar *login,
const gchar *password,
@@ -591,15 +490,21 @@ realm_join_as_owner (UmRealmKerberos *realm,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ UmRealmKerberosMembership *membership;
GSimpleAsyncResult *async;
GVariant *contents;
GVariant *options;
GVariant *creds;
const gchar *type;
- type = find_supported_credentials (realm, owner);
- if (type == NULL)
+ membership = um_realm_object_get_kerberos_membership (realm);
+ g_return_val_if_fail (membership != NULL, FALSE);
+
+ type = find_supported_credentials (membership, owner);
+ if (type == NULL) {
+ g_object_unref (membership);
return FALSE;
+ }
async = g_simple_async_result_new (G_OBJECT (realm), callback, user_data,
realm_join_as_owner);
@@ -620,16 +525,18 @@ realm_join_as_owner (UmRealmKerberos *realm,
creds = g_variant_new ("(ssv)", type, owner, contents);
options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
- um_realm_kerberos_call_enroll (realm, creds, options,
- cancellable, on_realm_join_complete, g_object_ref (async));
+ um_realm_kerberos_membership_call_join (membership, creds, options,
+ cancellable, on_realm_join_complete,
+ g_object_ref (async));
g_object_unref (async);
+ g_object_unref (membership);
return TRUE;
}
gboolean
-um_realm_join_as_user (UmRealmKerberos *realm,
+um_realm_join_as_user (UmRealmObject *realm,
const gchar *login,
const gchar *password,
GBytes *credentials,
@@ -637,19 +544,19 @@ um_realm_join_as_user (UmRealmKerberos *realm,
GAsyncReadyCallback callback,
gpointer user_data)
{
- g_return_val_if_fail (UM_REALM_IS_KERBEROS (realm), FALSE);
+ g_return_val_if_fail (UM_REALM_IS_OBJECT (realm), FALSE);
g_return_val_if_fail (credentials != NULL, FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (login != NULL, FALSE);
g_return_val_if_fail (password != NULL, FALSE);
g_return_val_if_fail (credentials != NULL, FALSE);
- return realm_join_as_owner (realm, "user", login, password, credentials,
- cancellable, callback, user_data);
+ return realm_join_as_owner (realm, "user", login, password,
+ credentials, cancellable, callback, user_data);
}
gboolean
-um_realm_join_as_admin (UmRealmKerberos *realm,
+um_realm_join_as_admin (UmRealmObject *realm,
const gchar *login,
const gchar *password,
GBytes *credentials,
@@ -657,7 +564,7 @@ um_realm_join_as_admin (UmRealmKerberos *realm,
GAsyncReadyCallback callback,
gpointer user_data)
{
- g_return_val_if_fail (UM_REALM_IS_KERBEROS (realm), FALSE);
+ g_return_val_if_fail (UM_REALM_IS_OBJECT (realm), FALSE);
g_return_val_if_fail (credentials != NULL, FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (login != NULL, FALSE);
@@ -669,19 +576,25 @@ um_realm_join_as_admin (UmRealmKerberos *realm,
}
gboolean
-um_realm_join_finish (UmRealmKerberos *self,
+um_realm_join_finish (UmRealmObject *realm,
GAsyncResult *result,
GError **error)
{
+ UmRealmKerberosMembership *membership;
GError *call_error = NULL;
gchar *dbus_error;
GAsyncResult *async;
- g_return_val_if_fail (UM_REALM_IS_KERBEROS (self), FALSE);
+ g_return_val_if_fail (UM_REALM_IS_OBJECT (realm), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ membership = um_realm_object_get_kerberos_membership (realm);
+ g_return_val_if_fail (membership != NULL, FALSE);
+
async = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
- um_realm_kerberos_call_enroll_finish (self, async, &call_error);
+ um_realm_kerberos_membership_call_join_finish (membership, async, &call_error);
+ g_object_unref (membership);
+
if (call_error == NULL)
return TRUE;
@@ -693,7 +606,7 @@ um_realm_join_finish (UmRealmKerberos *self,
g_dbus_error_strip_remote_error (call_error);
- if (g_str_equal (dbus_error, "org.freedesktop.realmd.Error.AuthFailed")) {
+ if (g_str_equal (dbus_error, "org.freedesktop.realmd.Error.AuthenticationFailed")) {
g_set_error (error, UM_REALM_ERROR, UM_REALM_ERROR_BAD_LOGIN,
"%s", call_error->message);
g_error_free (call_error);
@@ -851,8 +764,7 @@ kinit_thread_func (GSimpleAsyncResult *async,
}
void
-um_realm_login (const gchar *realm,
- const gchar *domain,
+um_realm_login (UmRealmObject *realm,
const gchar *user,
const gchar *password,
GCancellable *cancellable,
@@ -861,17 +773,21 @@ um_realm_login (const gchar *realm,
{
GSimpleAsyncResult *async;
LoginClosure *login;
+ UmRealmKerberos *kerberos;
- g_return_if_fail (realm != NULL);
+ g_return_if_fail (UM_REALM_IS_OBJECT (realm));
g_return_if_fail (user != NULL);
g_return_if_fail (password != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ kerberos = um_realm_object_get_kerberos (realm);
+ g_return_if_fail (kerberos != NULL);
+
async = g_simple_async_result_new (NULL, callback, user_data,
um_realm_login);
login = g_slice_new0 (LoginClosure);
- login->domain = g_strdup (domain ? domain : realm);
- login->realm = g_strdup (realm);
+ login->domain = g_strdup (um_realm_kerberos_get_domain_name (kerberos));
+ login->realm = g_strdup (um_realm_kerberos_get_realm_name (kerberos));
login->user = g_strdup (user);
login->password = g_strdup (password);
g_simple_async_result_set_op_res_gpointer (async, login, login_closure_free);
@@ -881,6 +797,7 @@ um_realm_login (const gchar *realm,
G_PRIORITY_DEFAULT, cancellable);
g_object_unref (async);
+ g_object_unref (kerberos);
}
gboolean
diff --git a/src/goaidentity/um-realm-manager.h b/src/goaidentity/um-realm-manager.h
index c5ffea3..a604fae 100644
--- a/src/goaidentity/um-realm-manager.h
+++ b/src/goaidentity/um-realm-manager.h
@@ -63,8 +63,7 @@ GList * um_realm_manager_discover_finish (UmRealmManager *self,
GList * um_realm_manager_get_realms (UmRealmManager *self);
-void um_realm_login (const gchar *realm_name,
- const gchar *domain,
+void um_realm_login (UmRealmObject *realm,
const gchar *login,
const gchar *password,
GCancellable *cancellable,
@@ -75,7 +74,7 @@ gboolean um_realm_login_finish (GAsyncResult *result,
GBytes **credentials,
GError **error);
-gboolean um_realm_join_as_user (UmRealmKerberos *realm,
+gboolean um_realm_join_as_user (UmRealmObject *realm,
const gchar *login,
const gchar *password,
GBytes *credentials,
@@ -84,7 +83,7 @@ gboolean um_realm_join_as_user (UmRealmKerberos *realm,
gpointer user_data)
G_GNUC_WARN_UNUSED_RESULT;
-gboolean um_realm_join_as_admin (UmRealmKerberos *realm,
+gboolean um_realm_join_as_admin (UmRealmObject *realm,
const gchar *login,
const gchar *password,
GBytes *credentials,
@@ -93,10 +92,14 @@ gboolean um_realm_join_as_admin (UmRealmKerberos *realm,
gpointer user_data)
G_GNUC_WARN_UNUSED_RESULT;
-gboolean um_realm_join_finish (UmRealmKerberos *self,
+gboolean um_realm_join_finish (UmRealmObject *realm,
GAsyncResult *result,
GError **error);
+gboolean um_realm_is_configured (UmRealmObject *realm);
+
+gchar * um_realm_calculate_login (UmRealmCommon *realm,
+ const gchar *username);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]