Codebase list realmd / upstream/0.6 service / realm-sssd-ad-provider.c
upstream/0.6

Tree @upstream/0.6 (Download .tar.gz)

realm-sssd-ad-provider.c @upstream/0.6raw · history · blame

/* realmd -- Realm configuration service
 *
 * Copyright 2012 Red Hat Inc
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2 of the licence or (at
 * your option) any later version.
 *
 * See the included COPYING file for more information.
 *
 * Author: Stef Walter <stefw@gnome.org>
 */

#include "config.h"

#include "realm-ad-discover.h"
#include "realm-command.h"
#include "realm-daemon.h"
#include "realm-dbus-constants.h"
#include "realm-diagnostics.h"
#include "realm-discovery.h"
#include "realm-errors.h"
#include "realm-kerberos.h"
#include "realm-packages.h"
#include "realm-sssd-ad.h"
#include "realm-sssd-ad-provider.h"
#include "realm-sssd-config.h"

#include <glib/gstdio.h>

#include <errno.h>

struct _RealmSssdAdProvider {
	RealmProvider parent;
	RealmIniConfig *config;
};

typedef struct {
	RealmProviderClass parent_class;
} RealmSssdAdProviderClass;

enum {
	PROP_0,
	PROP_SSSD_CONFIG,
};

#define   REALM_DBUS_SSSD_AD_PATH                    "/org/freedesktop/realmd/SssdAd"

G_DEFINE_TYPE (RealmSssdAdProvider, realm_sssd_ad_provider, REALM_TYPE_PROVIDER);

static void
realm_sssd_ad_provider_init (RealmSssdAdProvider *self)
{
	self->config = realm_sssd_config_new (NULL);

	/* The dbus Name property of the provider */
	g_object_set (self, "name", "SssdAd", NULL);
}

static void
realm_sssd_ad_provider_constructed (GObject *obj)
{
	RealmSssdAdProvider *self;
	gchar **domains;
	gchar *section;
	gchar *realm;
	gchar *type;
	gint i;

	G_OBJECT_CLASS (realm_sssd_ad_provider_parent_class)->constructed (obj);

	self = REALM_SSSD_AD_PROVIDER (obj);

	domains = realm_sssd_config_get_domains (self->config);
	for (i = 0; domains && domains[i] != 0; i++) {
		section = realm_sssd_config_domain_to_section (domains[i]);
		type = realm_ini_config_get (self->config, section, "id_provider");
		realm = realm_ini_config_get (self->config, section, "krb5_realm");
		g_free (section);

		if (g_strcmp0 (type, "ad") == 0) {
			realm_provider_lookup_or_register_realm (REALM_PROVIDER (self),
			                                         REALM_TYPE_SSSD_AD,
			                                         realm ? realm : domains[i]);
		}

		g_free (realm);
		g_free (type);
	}
	g_strfreev (domains);
}

static void
on_ad_discover (GObject *source,
                GAsyncResult *result,
                gpointer user_data)
{
	GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
	g_simple_async_result_set_op_res_gpointer (async, g_object_ref (result), g_object_unref);
	g_simple_async_result_complete (async);
	g_object_unref (async);
}

static void
realm_sssd_ad_provider_discover_async (RealmProvider *provider,
                                     const gchar *string,
                                     GDBusMethodInvocation *invocation,
                                     GAsyncReadyCallback callback,
                                     gpointer user_data)
{
	GSimpleAsyncResult *async;

	async = g_simple_async_result_new (G_OBJECT (provider), callback, user_data,
	                                   realm_sssd_ad_provider_discover_async);

	realm_ad_discover_async (string, invocation, on_ad_discover, g_object_ref (async));

	g_object_unref (async);
}

static gint
realm_sssd_ad_provider_discover_finish (RealmProvider *provider,
                                        GAsyncResult *result,
                                        GVariant **realms,
                                        GError **error)
{
	GSimpleAsyncResult *async;
	GAsyncResult *ad_result;
	GDBusInterfaceSkeleton *realm;
	GHashTable *discovery;
	const gchar *object_path;
	GVariant *realm_info;
	gchar *name;

	async = G_SIMPLE_ASYNC_RESULT (result);
	ad_result = g_simple_async_result_get_op_res_gpointer (async);

	name = realm_ad_discover_finish (ad_result, &discovery, error);
	if (name == NULL)
		return 0;

	realm = realm_provider_lookup_or_register_realm (provider,
	                                                 REALM_TYPE_SSSD_AD,
	                                                 name);
	g_free (name);

	if (realm == NULL) {
		g_hash_table_unref (discovery);
		return 0;
	}

	realm_kerberos_set_discovery (REALM_KERBEROS (realm), discovery);

	object_path = g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (realm));
	realm_info = realm_provider_new_realm_info (object_path, REALM_DBUS_KERBEROS_REALM_INTERFACE);
	*realms = g_variant_new_array (G_VARIANT_TYPE ("(os)"), &realm_info, 1);
	g_variant_ref_sink (*realms);

	g_hash_table_unref (discovery);

	/* Return a higher priority if we're the default */
	return realm_provider_is_default ("active-directory", "sssd") ? 100 : 50;
}

static void
realm_sssd_ad_provider_get_property (GObject *obj,
                                   guint prop_id,
                                   GValue *value,
                                   GParamSpec *pspec)
{
	RealmSssdAdProvider *self = REALM_SSSD_AD_PROVIDER (obj);

	switch (prop_id) {
	case PROP_SSSD_CONFIG:
		g_value_set_object (value, self->config);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
		break;
	}
}

static void
realm_sssd_ad_provider_finalize (GObject *obj)
{
	RealmSssdAdProvider *self = REALM_SSSD_AD_PROVIDER (obj);

	g_object_unref (self->config);

	G_OBJECT_CLASS (realm_sssd_ad_provider_parent_class)->finalize (obj);
}

void
realm_sssd_ad_provider_class_init (RealmSssdAdProviderClass *klass)
{
	RealmProviderClass *provider_class = REALM_PROVIDER_CLASS (klass);
	GObjectClass *object_class = G_OBJECT_CLASS (klass);

	provider_class->dbus_path = REALM_DBUS_SSSD_AD_PATH;
	provider_class->discover_async = realm_sssd_ad_provider_discover_async;
	provider_class->discover_finish = realm_sssd_ad_provider_discover_finish;

	object_class->constructed = realm_sssd_ad_provider_constructed;
	object_class->get_property = realm_sssd_ad_provider_get_property;
	object_class->finalize = realm_sssd_ad_provider_finalize;

	g_object_class_install_property (object_class, PROP_SSSD_CONFIG,
	            g_param_spec_object ("sssd-config", "Sssd Config", "Sssd Config",
	                                 REALM_TYPE_INI_CONFIG, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

}