ipa_subdomains.c revision 65393a294e635822c1d7a15fe5853dc457ad8a2a
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose/*
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose SSSD
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose IPA Subdomains Module
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose Authors:
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose Sumit Bose <sbose@redhat.com>
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose Copyright (C) 2011 Red Hat
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose This program is free software; you can redistribute it and/or modify
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose it under the terms of the GNU General Public License as published by
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose the Free Software Foundation; either version 3 of the License, or
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose (at your option) any later version.
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose This program is distributed in the hope that it will be useful,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose GNU General Public License for more details.
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose You should have received a copy of the GNU General Public License
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose*/
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose#include "providers/ldap/sdap_async.h"
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose#include "providers/ipa/ipa_subdomains.h"
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose#include "providers/ipa/ipa_common.h"
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose#include <ctype.h>
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny#define SUBDOMAINS_FILTER "objectclass=ipaNTTrustedDomain"
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose#define MASTER_DOMAIN_FILTER "objectclass=ipaNTDomainAttrs"
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny#define RANGE_FILTER "objectclass=ipaIDRange"
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose#define IPA_CN "cn"
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose#define IPA_FLATNAME "ipaNTFlatName"
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose#define IPA_SID "ipaNTSecurityIdentifier"
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose#define IPA_TRUSTED_DOMAIN_SID "ipaNTTrustedDomainSID"
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose#define IPA_BASE_ID "ipaBaseID"
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose#define IPA_ID_RANGE_SIZE "ipaIDRangeSize"
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose#define IPA_BASE_RID "ipaBaseRID"
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose#define IPA_SECONDARY_BASE_RID "ipaSecondaryBaseRID"
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose#define OBJECTCLASS "objectClass"
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny/* do not refresh more often than every 5 seconds for now */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny#define IPA_SUBDOMAIN_REFRESH_LIMIT 5
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny/* refresh automatically every 4 hours */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny#define IPA_SUBDOMAIN_REFRESH_PERIOD (3600 * 4)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny#define IPA_SUBDOMAIN_DISABLED_PERIOD 3600
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny/* the directory domain - realm mappings are written to */
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny#define IPA_SUBDOMAIN_MAPPING_DIR PUBCONF_PATH"/krb5.include.d"
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Boseenum ipa_subdomains_req_type {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny IPA_SUBDOMAINS_MASTER,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny IPA_SUBDOMAINS_SLAVE,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose IPA_SUBDOMAINS_RANGES,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose IPA_SUBDOMAINS_MAX /* Counter */
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose};
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bosestruct ipa_subdomains_req_params {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose const char *filter;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose tevent_req_fn cb;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose const char *attrs[8];
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose};
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bosestruct ipa_subdomains_ctx {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct be_ctx *be_ctx;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct sdap_id_ctx *sdap_id_ctx;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct sdap_search_base **search_bases;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct sdap_search_base **master_search_bases;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct sdap_search_base **ranges_search_bases;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose time_t last_refreshed;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct tevent_timer *timer_event;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose bool configured_explicit;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose time_t disabled_until;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose /* subdomain map cache */
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose int num_subdoms;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct sysdb_subdom *subdoms;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose};
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Boseconst char *get_flat_name_from_subdomain_name(struct be_ctx *be_ctx,
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose const char *name)
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose{
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose size_t c;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct ipa_subdomains_ctx *ctx;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ctx = talloc_get_type(be_ctx->bet_info[BET_SUBDOMAINS].pvt_bet_data,
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct ipa_subdomains_ctx);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (ctx == NULL) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose DEBUG(SSSDBG_TRACE_ALL, ("Subdomains are not configured.\n"));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose return NULL;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose for (c = 0; c < ctx->num_subdoms; c++) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (strcasecmp(ctx->subdoms[c].name, name) == 0 ||
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose (ctx->subdoms[c].flat_name != NULL &&
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose strcasecmp(ctx->subdoms[c].flat_name, name) == 0)) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose return ctx->subdoms[c].flat_name;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose return NULL;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose}
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bosestatic errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose size_t count,
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct sysdb_attrs **reply,
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct range_info ***_range_list)
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose{
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct range_info **range_list = NULL;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose const char *value;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose size_t c;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose int ret;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose range_list = talloc_array(mem_ctx, struct range_info *, count + 1);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (range_list == NULL) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_array failed.\n"));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose return ENOMEM;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose for (c = 0; c < count; c++) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose range_list[c] = talloc_zero(range_list, struct range_info);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (range_list[c] == NULL) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_zero failed.\n"));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ret = ENOMEM;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose goto done;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ret = sysdb_attrs_get_string(reply[c], IPA_CN, &value);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (ret != EOK) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose goto done;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose range_list[c]->name = talloc_strdup(range_list[c], value);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (range_list[c]->name == NULL) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ret = ENOMEM;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose goto done;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ret = sysdb_attrs_get_string(reply[c], IPA_TRUSTED_DOMAIN_SID, &value);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (ret == EOK) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose range_list[c]->trusted_dom_sid = talloc_strdup(range_list[c],
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose value);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (range_list[c]->trusted_dom_sid == NULL) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ret = ENOMEM;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose } else if (ret != ENOENT) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_ID,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose &range_list[c]->base_id);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret != EOK && ret != ENOENT) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = sysdb_attrs_get_uint32_t(reply[c], IPA_ID_RANGE_SIZE,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose &range_list[c]->id_range_size);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret != EOK && ret != ENOENT) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_RID,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose &range_list[c]->base_rid);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret != EOK && ret != ENOENT) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = sysdb_attrs_get_uint32_t(reply[c], IPA_SECONDARY_BASE_RID,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose &range_list[c]->secondary_base_rid);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret != EOK && ret != ENOENT) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose range_list[c] = NULL;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose *_range_list = range_list;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = EOK;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bosedone:
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret != EOK) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose talloc_free(range_list);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose return ret;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose}
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bosestatic errno_t ipa_subdom_parse(TALLOC_CTX *memctx,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose struct sysdb_attrs *attrs,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose struct sysdb_subdom *subdom)
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose{
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose const char *value;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose int ret;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = sysdb_attrs_get_string(attrs, IPA_CN, &value);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret != EOK) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose return ret;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (subdom->name == NULL) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose subdom->name = talloc_strdup(memctx, value);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (subdom->name == NULL) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose return ENOMEM;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose } else if (strcmp(subdom->name, value) != 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("subdomain name mismatch!\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose return EINVAL;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (subdom->realm == NULL) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose /* Add Realm as upper(domain name), this is generally always correct
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose * with AD domains */
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose subdom->realm = get_uppercase_realm(memctx, subdom->name);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (!subdom->realm) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose return ENOMEM;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = sysdb_attrs_get_string(attrs, IPA_FLATNAME, &value);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose return ret;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose /* in theory this may change, it should never happen, so we will log a
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose * warning if it does, but we will allow it for now */
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (subdom->flat_name != NULL) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (strcmp(subdom->flat_name, value) != 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_TRACE_INTERNAL,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ("Flat name for subdomain changed!\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose talloc_free(discard_const(subdom->flat_name));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose subdom->flat_name = (const char *)NULL;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (subdom->flat_name == NULL) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny subdom->flat_name = talloc_strdup(memctx, value);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (subdom->flat_name == NULL) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return ENOMEM;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ret = sysdb_attrs_get_string(attrs, IPA_TRUSTED_DOMAIN_SID, &value);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (ret) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose return ret;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose /* in theory this may change, it should never happen, so we will log a
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose * warning if it does, but we will allow it for now */
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (subdom->id != NULL) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (strcmp(subdom->id, value) != 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_TRACE_INTERNAL,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ("ID for subdomain changed!\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose talloc_free(discard_const(subdom->id));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose subdom->flat_name = (const char *)NULL;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (subdom->id == NULL) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose subdom->id = talloc_strdup(memctx, value);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (subdom->id == NULL) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose return ENOMEM;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose return EOK;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose}
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bosestatic errno_t
81165faf5d951aca69f410713730c26ff048ec44Sumit Boseipa_subdomains_write_mappings(struct sss_domain_info *domain,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose size_t num_subdoms,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose struct sysdb_subdom *subdoms)
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose{
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose errno_t ret;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose errno_t err;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose TALLOC_CTX *tmp_ctx;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose const char *mapping_file;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose char *tmp_file = NULL;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose int fd = -1;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose mode_t old_mode;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose FILE *fstream = NULL;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose size_t i;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose tmp_ctx = talloc_new(NULL);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (!tmp_ctx) return ENOMEM;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose mapping_file = talloc_asprintf(tmp_ctx, "%s/domain_realm_%s",
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose IPA_SUBDOMAIN_MAPPING_DIR, domain->name);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (!mapping_file) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = ENOMEM;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", mapping_file);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (tmp_file == NULL) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = ENOMEM;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose old_mode = umask(077);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose fd = mkstemp(tmp_file);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose umask(old_mode);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (fd < 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("creating the temp file [%s] for domain-realm "
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose "mappings failed.", tmp_file));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = EIO;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose talloc_zfree(tmp_ctx);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose fstream = fdopen(fd, "a");
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (!fstream) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = errno;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("fdopen failed [%d]: %s\n",
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret, strerror(ret)));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = close(fd);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret != 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = errno;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ("fclose failed [%d][%s].\n", ret, strerror(ret)));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose /* Nothing to do here, just report the failure */
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = EIO;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = fprintf(fstream, "[domain_realm]\n");
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (ret < 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("fprintf failed\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = EIO;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose for (i = 0; i < num_subdoms; i++) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = fprintf(fstream, ".%s = %s\n%s = %s\n",
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose subdoms[i].name, subdoms[i].realm,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose subdoms[i].name, subdoms[i].realm);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret < 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, ("fprintf failed\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = fclose(fstream);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose fstream = NULL;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret != 0) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ret = errno;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ("fclose failed [%d][%s].\n", ret, strerror(ret)));
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny goto done;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ret = rename(tmp_file, mapping_file);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (ret == -1) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = errno;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ("rename failed [%d][%s].\n", ret, strerror(ret)));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny talloc_zfree(tmp_file);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = chmod(mapping_file, 0644);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret == -1) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = errno;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ("fchmod failed [%d][%s].\n", ret, strerror(ret)));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = EOK;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bosedone:
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (fstream) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose err = fclose(fstream);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (err != 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose err = errno;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ("fclose failed [%d][%s].\n", err, strerror(err)));
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny /* Nothing to do here, just report the failure */
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (tmp_file) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose err = unlink(tmp_file);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (err < 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose err = errno;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose DEBUG(SSSDBG_MINOR_FAILURE,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ("Could not remove file [%s]: [%d]: %s",
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose tmp_file, err, strerror(err)));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny talloc_free(tmp_ctx);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose return ret;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny}
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bosestatic errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose int count, struct sysdb_attrs **reply,
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose bool *changes)
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose{
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose bool handled[count];
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose const char *value;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose int c, h;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose int ret;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose int i, j;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose memset(handled, 0, sizeof(bool) * count);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose /* check existing subdoms in cache */
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose for (i = 0, h = 0; i < ctx->num_subdoms; i++) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose for (c = 0; c < count; c++) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (handled[c]) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose continue;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = sysdb_attrs_get_string(reply[c], IPA_CN, &value);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret != EOK) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose goto done;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (strcmp(value, ctx->subdoms[i].name) == 0) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose break;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (c >= count) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose /* ok this subdomain does not exist anymore, let's clean up */
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose for (j = i; j < ctx->num_subdoms - 1; j++) {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ctx->subdoms[j] = ctx->subdoms[j + 1];
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ctx->num_subdoms--;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose i--;
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose } else {
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose /* ok let's try to update it */
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose ret = ipa_subdom_parse(ctx->subdoms, reply[c], &ctx->subdoms[i]);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose if (ret) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("Failed to parse subdom data\n"));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose goto done;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose handled[c] = true;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose h++;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (count == h) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose /* all domains were already accounted for and have been updated */
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ret = EOK;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose goto done;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose /* if we get here it means we have changes to the subdomains list */
a56156c13c71a96166b0a8f3921e67f36470f8d7Sumit Bose *changes = true;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose /* add space for unhandled domains */
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose c = count - h;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ctx->subdoms = talloc_realloc(ctx, ctx->subdoms,
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose struct sysdb_subdom,
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ctx->num_subdoms + c);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (ctx->subdoms == NULL) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ret = ENOMEM;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose goto done;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose for (c = 0; c < count; c++) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (handled[c]) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose continue;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose i = ctx->num_subdoms;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose memset(&ctx->subdoms[i], 0, sizeof(struct sysdb_subdom));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ret = ipa_subdom_parse(ctx->subdoms, reply[c], &ctx->subdoms[i]);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (ret) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose DEBUG(SSSDBG_OP_FAILURE, ("Failed to parse subdom data\n"));
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose goto done;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ctx->num_subdoms++;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ret = EOK;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bosedone:
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose if (ret != EOK) {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ctx->last_refreshed = 0;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ctx->num_subdoms = 0;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose talloc_zfree(ctx->subdoms);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose } else {
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose ctx->last_refreshed = time(NULL);
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose }
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose return ret;
386a66b1aa18a176e6a06fa126556c9590c373b6Sumit Bose}
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenystruct ipa_subdomains_req_ctx {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny struct be_req *be_req;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny struct ipa_subdomains_ctx *sd_ctx;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny struct sdap_id_op *sdap_op;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny char *current_filter;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny struct sdap_search_base **search_bases;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny int search_base_iter;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny size_t reply_count;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny struct sysdb_attrs **reply;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny};
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenystatic void ipa_subdomains_get_conn_done(struct tevent_req *req);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenystatic errno_t
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenyipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny enum ipa_subdomains_req_type type);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenystatic void ipa_subdomains_handler_done(struct tevent_req *req);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenystatic void ipa_subdomains_handler_master_done(struct tevent_req *req);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenystatic void ipa_subdomains_handler_ranges_done(struct tevent_req *req);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenystatic struct ipa_subdomains_req_params subdomain_requests[] = {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny { MASTER_DOMAIN_FILTER,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ipa_subdomains_handler_master_done,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny { IPA_CN, IPA_FLATNAME, IPA_SID, NULL }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny },
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny { SUBDOMAINS_FILTER,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ipa_subdomains_handler_done,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny { IPA_CN, IPA_FLATNAME, IPA_TRUSTED_DOMAIN_SID, NULL }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny },
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny { RANGE_FILTER,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ipa_subdomains_handler_ranges_done,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny { OBJECTCLASS, IPA_CN,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny IPA_BASE_ID, IPA_BASE_RID, IPA_SECONDARY_BASE_RID,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny IPA_ID_RANGE_SIZE, IPA_TRUSTED_DOMAIN_SID, NULL
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny};
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenystatic void ipa_subdomains_retrieve(struct ipa_subdomains_ctx *ctx, struct be_req *be_req)
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny{
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny struct ipa_subdomains_req_ctx *req_ctx = NULL;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny struct tevent_req *req;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny int dp_error = DP_ERR_FATAL;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny int ret;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req_ctx = talloc(be_req, struct ipa_subdomains_req_ctx);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (req_ctx == NULL) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ret = ENOMEM;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny goto done;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req_ctx->be_req = be_req;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req_ctx->sd_ctx = ctx;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req_ctx->search_base_iter = 0;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req_ctx->search_bases = ctx->search_bases;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req_ctx->current_filter = NULL;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req_ctx->reply_count = 0;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req_ctx->reply = NULL;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req_ctx->sdap_op = sdap_id_op_create(req_ctx,
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ctx->sdap_id_ctx->conn_cache);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (req_ctx->sdap_op == NULL) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_create failed.\n"));
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ret = ENOMEM;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny goto done;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny req = sdap_id_op_connect_send(req_ctx->sdap_op, req_ctx, &ret);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (req == NULL) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_connect_send failed: %d(%s).\n",
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny ret, strerror(ret)));
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny goto done;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny tevent_req_set_callback(req, ipa_subdomains_get_conn_done, req_ctx);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny return;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zelenydone:
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny talloc_free(req_ctx);
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny if (ret == EOK) {
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny dp_error = DP_ERR_OK;
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny }
84c611c1b7c04cc7735ab54d4e5f48284b79e6fbJan Zeleny be_req_terminate(be_req, dp_error, ret, NULL);
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose}
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose
81165faf5d951aca69f410713730c26ff048ec44Sumit Bosestatic void ipa_subdomains_get_conn_done(struct tevent_req *req)
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose{
81165faf5d951aca69f410713730c26ff048ec44Sumit Bose int ret;
int dp_error = DP_ERR_FATAL;
struct ipa_subdomains_req_ctx *ctx;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
ret = sdap_id_op_connect_recv(req, &dp_error);
talloc_zfree(req);
if (ret) {
if (dp_error == DP_ERR_OFFLINE) {
DEBUG(SSSDBG_MINOR_FAILURE,
("No IPA server is available, cannot get the "
"subdomain list while offline\n"));
/* FIXME: return saved results ?? */
} else {
DEBUG(SSSDBG_OP_FAILURE,
("Failed to connect to IPA server: [%d](%s)\n",
ret, strerror(ret)));
}
goto fail;
}
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_SLAVE);
if (ret != EOK && ret != EAGAIN) {
goto fail;
}
return;
fail:
be_req_terminate(ctx->be_req, dp_error, ret, NULL);
}
static errno_t
ipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx,
enum ipa_subdomains_req_type type)
{
struct tevent_req *req;
struct sdap_search_base *base;
struct ipa_subdomains_req_params *params;
if (type >= IPA_SUBDOMAINS_MAX) {
return EINVAL;
}
params = &subdomain_requests[type];
base = ctx->search_bases[ctx->search_base_iter];
if (base == NULL) {
return EOK;
}
talloc_free(ctx->current_filter);
ctx->current_filter = sdap_get_id_specific_filter(ctx, params->filter,
base->filter);
if (ctx->current_filter == NULL) {
return ENOMEM;
}
req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev,
ctx->sd_ctx->sdap_id_ctx->opts,
sdap_id_op_handle(ctx->sdap_op),
base->basedn, base->scope,
ctx->current_filter, params->attrs, NULL, 0,
dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic,
SDAP_SEARCH_TIMEOUT), false);
if (req == NULL) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n"));
return ENOMEM;
}
tevent_req_set_callback(req, params->cb, ctx);
return EAGAIN;
}
static void ipa_subdomains_handler_done(struct tevent_req *req)
{
int ret;
size_t reply_count;
struct sysdb_attrs **reply = NULL;
struct ipa_subdomains_req_ctx *ctx;
struct sss_domain_info *domain;
bool refresh_has_changes = false;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
domain = ctx->sd_ctx->be_ctx->domain;
ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
talloc_zfree(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
goto done;
}
if (reply_count) {
ctx->reply = talloc_realloc(ctx, ctx->reply, struct sysdb_attrs *,
ctx->reply_count + reply_count);
if (ctx->reply == NULL) {
ret = ENOMEM;
goto done;
}
memcpy(ctx->reply+ctx->reply_count, reply,
reply_count * sizeof(struct sysdb_attrs *));
ctx->reply_count += reply_count;
}
ctx->search_base_iter++;
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_SLAVE);
if (ret == EAGAIN) {
return;
} else if (ret != EOK) {
goto done;
}
ret = ipa_subdomains_refresh(ctx->sd_ctx, ctx->reply_count, ctx->reply,
&refresh_has_changes);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Failed to refresh subdomains.\n"));
goto done;
}
if (refresh_has_changes) {
ret = sysdb_update_subdomains(domain, ctx->sd_ctx->num_subdoms,
ctx->sd_ctx->subdoms);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sysdb_update_subdomains failed.\n"));
goto done;
}
ret = ipa_subdomains_write_mappings(domain,
ctx->sd_ctx->num_subdoms,
ctx->sd_ctx->subdoms);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
("ipa_subdomains_write_mappings failed.\n"));
}
}
ctx->search_base_iter = 0;
ctx->search_bases = ctx->sd_ctx->ranges_search_bases;
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_RANGES);
if (ret == EAGAIN) {
return;
} else if (ret != EOK) {
goto done;
}
DEBUG(SSSDBG_OP_FAILURE, ("No search base for ranges available.\n"));
ret = EINVAL;
done:
be_req_terminate(ctx->be_req, DP_ERR_FATAL, ret, NULL);
}
static void ipa_subdomains_handler_ranges_done(struct tevent_req *req)
{
errno_t ret;
int dp_error = DP_ERR_FATAL;
size_t reply_count;
struct sysdb_attrs **reply = NULL;
struct ipa_subdomains_req_ctx *ctx;
struct range_info **range_list = NULL;
struct sysdb_ctx *sysdb;
struct sss_domain_info *domain;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
domain = ctx->sd_ctx->be_ctx->domain;
sysdb = domain->sysdb;
ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
talloc_zfree(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
goto done;
}
ret = ipa_ranges_parse_results(ctx, reply_count, reply, &range_list);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("ipa_ranges_parse_results request failed.\n"));
goto done;
}
ret = sysdb_update_ranges(sysdb, range_list);
talloc_free(range_list);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sysdb_update_ranges failed.\n"));
goto done;
}
ret = sysdb_master_domain_update(domain);
if (ret != EOK) {
goto done;
}
if (domain->flat_name == NULL ||
domain->domain_id == NULL ||
domain->realm == NULL) {
ctx->search_base_iter = 0;
ctx->search_bases = ctx->sd_ctx->master_search_bases;
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER);
if (ret == EAGAIN) {
return;
} else if (ret != EOK) {
goto done;
}
} else {
ret = EOK;
}
done:
if (ret == EOK) {
dp_error = DP_ERR_OK;
}
be_req_terminate(ctx->be_req, dp_error, ret, NULL);
}
static void ipa_subdomains_handler_master_done(struct tevent_req *req)
{
errno_t ret;
int dp_error = DP_ERR_FATAL;
size_t reply_count;
struct sysdb_attrs **reply = NULL;
struct ipa_subdomains_req_ctx *ctx;
struct sysdb_subdom *domain_info;
const char *tmp_str;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
talloc_zfree(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
goto done;
}
if (reply_count) {
domain_info = talloc_zero(ctx, struct sysdb_subdom);
if (domain_info == NULL) {
ret = ENOMEM;
goto done;
}
ret = sysdb_attrs_get_string(reply[0], IPA_FLATNAME, &tmp_str);
if (ret != EOK) {
goto done;
}
domain_info->flat_name = talloc_strdup(domain_info, tmp_str);
if (domain_info->flat_name == NULL) {
ret = ENOMEM;
goto done;
}
ret = sysdb_attrs_get_string(reply[0], IPA_SID, &tmp_str);
if (ret != EOK) {
goto done;
}
domain_info->id = talloc_strdup(domain_info, tmp_str);
if (domain_info->id == NULL) {
ret = ENOMEM;
goto done;
}
ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain->sysdb,
ctx->sd_ctx->be_ctx->domain,
domain_info);
goto done;
} else {
ctx->search_base_iter++;
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER);
if (ret == EAGAIN) {
return;
} else if (ret != EOK) {
goto done;
}
/* Right now we know there has been an error
* and we don't have the master domain record
*/
DEBUG(SSSDBG_CRIT_FAILURE, ("Master domain record not found!\n"));
if (!ctx->sd_ctx->configured_explicit) {
ctx->sd_ctx->disabled_until = time(NULL) +
IPA_SUBDOMAIN_DISABLED_PERIOD;
}
ret = EIO;
goto done;
}
done:
if (ret == EOK) {
dp_error = DP_ERR_OK;
}
be_req_terminate(ctx->be_req, dp_error, ret, NULL);
}
static void ipa_subdom_online_cb(void *pvt);
static void ipa_subdom_timer_refresh(struct tevent_context *ev,
struct tevent_timer *te,
struct timeval current_time,
void *pvt)
{
ipa_subdom_online_cb(pvt);
}
static void ipa_subdom_be_req_callback(struct be_req *be_req,
int dp_err, int dp_ret,
const char *errstr)
{
talloc_free(be_req);
}
static void ipa_subdom_online_cb(void *pvt)
{
struct ipa_subdomains_ctx *ctx;
struct be_req *be_req;
struct timeval tv;
ctx = talloc_get_type(pvt, struct ipa_subdomains_ctx);
if (!ctx) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Bad private pointer\n"));
return;
}
ctx->disabled_until = 0;
be_req = be_req_create(ctx, NULL, ctx->be_ctx,
ipa_subdom_be_req_callback, NULL);
if (be_req == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("be_req_create() failed.\n"));
return;
}
ipa_subdomains_retrieve(ctx, be_req);
tv = tevent_timeval_current_ofs(IPA_SUBDOMAIN_REFRESH_PERIOD, 0);
ctx->timer_event = tevent_add_timer(ctx->be_ctx->ev, ctx, tv,
ipa_subdom_timer_refresh, ctx);
if (!ctx->timer_event) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom timer event\n"));
}
}
static void ipa_subdom_offline_cb(void *pvt)
{
struct ipa_subdomains_ctx *ctx;
ctx = talloc_get_type(pvt, struct ipa_subdomains_ctx);
if (ctx) {
talloc_zfree(ctx->timer_event);
}
}
static errno_t get_config_status(struct be_ctx *be_ctx,
bool *configured_explicit)
{
int ret;
TALLOC_CTX *tmp_ctx = NULL;
char *tmp_str;
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n"));
return ENOMEM;
}
ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path,
CONFDB_DOMAIN_SUBDOMAINS_PROVIDER, NULL,
&tmp_str);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("confdb_get_string failed.\n"));
goto done;
}
if (tmp_str == NULL) {
*configured_explicit = false;
} else {
*configured_explicit = true;
}
DEBUG(SSSDBG_TRACE_ALL, ("IPA subdomain provider is configured %s.\n",
*configured_explicit ? "explicit" : "implicit"));
ret = EOK;
done:
talloc_free(tmp_ctx);
return ret;
}
void ipa_subdomains_handler(struct be_req *be_req)
{
struct be_ctx *be_ctx = be_req_get_be_ctx(be_req);
struct ipa_subdomains_ctx *ctx;
time_t now;
ctx = talloc_get_type(be_ctx->bet_info[BET_SUBDOMAINS].pvt_bet_data,
struct ipa_subdomains_ctx);
if (!ctx) {
be_req_terminate(be_req, DP_ERR_FATAL, EINVAL, NULL);
return;
}
now = time(NULL);
if (ctx->disabled_until > now) {
DEBUG(SSSDBG_TRACE_ALL, ("Subdomain provider disabled.\n"));
be_req_terminate(be_req, DP_ERR_OK, EOK, NULL);
return;
}
if (ctx->last_refreshed > now - IPA_SUBDOMAIN_REFRESH_LIMIT) {
be_req_terminate(be_req, DP_ERR_OK, EOK, NULL);
return;
}
ipa_subdomains_retrieve(ctx, be_req);
}
struct bet_ops ipa_subdomains_ops = {
.handler = ipa_subdomains_handler,
.finalize = NULL
};
int ipa_subdom_init(struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
struct bet_ops **ops,
void **pvt_data)
{
struct ipa_subdomains_ctx *ctx;
int ret;
bool configured_explicit = false;
ret = get_config_status(be_ctx, &configured_explicit);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("get_config_status failed.\n"));
return ret;
}
ctx = talloc_zero(id_ctx, struct ipa_subdomains_ctx);
if (ctx == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n"));
return ENOMEM;
}
ctx->be_ctx = be_ctx;
ctx->sdap_id_ctx = id_ctx->sdap_id_ctx;
ctx->search_bases = id_ctx->ipa_options->subdomains_search_bases;
ctx->master_search_bases = id_ctx->ipa_options->master_domain_search_bases;
ctx->ranges_search_bases = id_ctx->ipa_options->ranges_search_bases;
ctx->configured_explicit = configured_explicit;
ctx->disabled_until = 0;
*ops = &ipa_subdomains_ops;
*pvt_data = ctx;
ret = be_add_online_cb(ctx, be_ctx, ipa_subdom_online_cb, ctx, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom online callback"));
}
ret = be_add_offline_cb(ctx, be_ctx, ipa_subdom_offline_cb, ctx, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom offline callback"));
}
return EOK;
}