From adb98a993104ac3e5922d5fad99bd00867233944 Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Thu, 8 May 2014 12:58:06 +0200 Subject: Implement the schema --- src/sssd/LMI_SSSDDomainSubdomainProvider.c | 152 +++++++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 9 deletions(-) (limited to 'src/sssd/LMI_SSSDDomainSubdomainProvider.c') diff --git a/src/sssd/LMI_SSSDDomainSubdomainProvider.c b/src/sssd/LMI_SSSDDomainSubdomainProvider.c index fb53dc4..1094b9b 100644 --- a/src/sssd/LMI_SSSDDomainSubdomainProvider.c +++ b/src/sssd/LMI_SSSDDomainSubdomainProvider.c @@ -1,10 +1,15 @@ +#include #include +#include +#include #include "LMI_SSSDDomainSubdomain.h" +#include "utils.h" static const CMPIBroker* _cb; -static void LMI_SSSDDomainSubdomainInitialize() +static void LMI_SSSDDomainSubdomainInitialize(const CMPIContext *ctx) { + lmi_init(PROVIDER_NAME, _cb, ctx, NULL); } static CMPIStatus LMI_SSSDDomainSubdomainCleanup( @@ -25,14 +30,143 @@ static CMPIStatus LMI_SSSDDomainSubdomainEnumInstanceNames( _cb, mi, cc, cr, cop); } -static CMPIStatus LMI_SSSDDomainSubdomainEnumInstances( +static CMPIStatus LMI_SSSDDomainSubdomainEnumInstances( CMPIInstanceMI* mi, - const CMPIContext* cc, - const CMPIResult* cr, - const CMPIObjectPath* cop, - const char** properties) + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop, + const char** properties) { - CMReturn(CMPI_RC_OK); + const char *namespace = KNameSpace(cop); + LMI_SSSDDomainSubdomain association; + LMI_SSSDDomainRef ref_parent; + LMI_SSSDDomainRef ref_sub; + sss_dbus_ctx *dbus_ctx = NULL; + sss_dbus_attr **subdomain = NULL; + sss_dbus_attr **parent = NULL; + sss_dbus_error error; + char **paths = NULL; + const char *parent_path = NULL; + const char *parent_name = NULL; + const char *sub_name = NULL; + sss_dbus_bool is_subdomain; + hash_table_t *table = NULL; + hash_key_t key; + hash_value_t value; + int hret; + CMPIrc ret; + int i; + + error = sss_dbus_init(&dbus_ctx); + check_sss_dbus_error(error, ret, CMPI_RC_ERR_FAILED, done); + + error = sss_dbus_invoke_list(dbus_ctx, SSSD_DBUS_LIST_DOMAINS, &paths, + DBUS_TYPE_INVALID); + check_sss_dbus_error(error, ret, CMPI_RC_ERR_FAILED, done); + + hret = hash_create(10, &table, hash_delete_cb, NULL); + if (hret != HASH_SUCCESS) { + ret = CMPI_RC_ERR_FAILED; + goto done; + } + + for (i = 0; paths[i] != NULL; i++) { + /* fetch information about potential subdomain */ + error = sss_dbus_fetch_all_attrs(dbus_ctx, paths[i], + SSS_DBUS_IFACE_DOMAINS, &subdomain); + check_sss_dbus_error(error, ret, CMPI_RC_ERR_FAILED, done); + + error = sss_dbus_find_attr_as_bool(subdomain, "subdomain", + &is_subdomain); + check_sss_dbus_error(error, ret, CMPI_RC_ERR_FAILED, done); + + /* if it is not subdomain just continue with the next one */ + if (!is_subdomain) { + sss_dbus_free_attrs(dbus_ctx, &subdomain); + continue; + } + + /* get subdomain name and parent */ + error = sss_dbus_find_attr_as_string(subdomain, "name", + &sub_name); + check_sss_dbus_error(error, ret, CMPI_RC_ERR_FAILED, done); + + error = sss_dbus_find_attr_as_string(subdomain, "parent_domain", + &parent_path); + check_sss_dbus_error(error, ret, CMPI_RC_ERR_FAILED, done); + + /* first try to lookup the parent in the hash table */ + key.type = HASH_KEY_STRING; + key.str = strdup(parent_path); + if (key.str == NULL) { + ret = CMPI_RC_ERR_FAILED; + goto done; + } + + hret = hash_lookup(table, &key, &value); + if (hret == HASH_SUCCESS) { + parent_name = (const char*)value.ptr; + free(key.str); + } else { + /* fetch the parent and store it in the hash table */ + error = sss_dbus_fetch_attr(dbus_ctx, parent_path, + SSS_DBUS_IFACE_DOMAINS, "name", + &parent); + + error = sss_dbus_find_attr_as_string(parent, "name", + &parent_name); + check_sss_dbus_error(error, ret, CMPI_RC_ERR_FAILED, done); + + value.type = HASH_VALUE_PTR; + value.ptr = strdup(parent_name); + if (value.ptr == NULL) { + free(key.str); + ret = CMPI_RC_ERR_FAILED; + goto done; + } + + hret = hash_enter(table, &key, &value); + if (hret != HASH_SUCCESS) { + free(key.str); + free(value.ptr); + } + } + + /* create association */ + LMI_SSSDDomainRef_Init(&ref_parent, _cb, namespace); + LMI_SSSDDomainRef_Set_Name(&ref_parent, parent_name); + + LMI_SSSDDomainRef_Init(&ref_sub, _cb, namespace); + LMI_SSSDDomainRef_Set_Name(&ref_sub, sub_name); + + LMI_SSSDDomainSubdomain_Init(&association, _cb, namespace); + LMI_SSSDDomainSubdomain_Set_ParentDomain(&association, &ref_parent); + LMI_SSSDDomainSubdomain_Set_Subdomain(&association, &ref_sub); + + KReturnInstance(cr, association); + + sss_dbus_free_attrs(dbus_ctx, &subdomain); + sss_dbus_free_attrs(dbus_ctx, &parent); + } + + ret = CMPI_RC_OK; + +done: + if (table != NULL) { + hash_destroy(table); + } + + if (subdomain != NULL) { + sss_dbus_free_attrs(dbus_ctx, &subdomain); + } + + if (parent != NULL) { + sss_dbus_free_attrs(dbus_ctx, &parent); + } + + sss_dbus_free_string_array(dbus_ctx, &paths); + sss_dbus_free(&dbus_ctx); + CMReturn(ret); } static CMPIStatus LMI_SSSDDomainSubdomainGetInstance( @@ -187,13 +321,13 @@ CMInstanceMIStub( LMI_SSSDDomainSubdomain, LMI_SSSDDomainSubdomain, _cb, - LMI_SSSDDomainSubdomainInitialize()) + LMI_SSSDDomainSubdomainInitialize(ctx)) CMAssociationMIStub( LMI_SSSDDomainSubdomain, LMI_SSSDDomainSubdomain, _cb, - LMI_SSSDDomainSubdomainInitialize()) + LMI_SSSDDomainSubdomainInitialize(ctx)) KONKRET_REGISTRATION( "root/cimv2", -- cgit