diff options
-rw-r--r-- | src/confdb/confdb.c | 10 | ||||
-rw-r--r-- | src/confdb/confdb.h | 4 | ||||
-rw-r--r-- | src/db/sysdb.h | 7 | ||||
-rw-r--r-- | src/db/sysdb_subdomains.c | 167 | ||||
-rw-r--r-- | src/providers/ipa/ipa_subdomains.c | 152 | ||||
-rw-r--r-- | src/responder/common/responder_common.c | 31 | ||||
-rw-r--r-- | src/responder/common/responder_get_domains.c | 68 | ||||
-rw-r--r-- | src/responder/pac/pacsrv_utils.c | 11 | ||||
-rw-r--r-- | src/tests/pac_responder-tests.c | 43 | ||||
-rw-r--r-- | src/tests/sysdb-tests.c | 87 | ||||
-rw-r--r-- | src/util/domain_info_utils.c | 33 | ||||
-rw-r--r-- | src/util/usertools.c | 20 | ||||
-rw-r--r-- | src/util/util.h | 6 |
13 files changed, 225 insertions, 414 deletions
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c index 14e9f057c..31efd9443 100644 --- a/src/confdb/confdb.c +++ b/src/confdb/confdb.c @@ -1122,7 +1122,7 @@ int confdb_get_domains(struct confdb_ctx *cdb, struct sss_domain_info **domains) { TALLOC_CTX *tmp_ctx; - struct sss_domain_info *domain, *prevdom = NULL; + struct sss_domain_info *domain = NULL; char **domlist; int ret, i; @@ -1155,13 +1155,7 @@ int confdb_get_domains(struct confdb_ctx *cdb, continue; } - if (cdb->doms == NULL) { - cdb->doms = domain; - prevdom = cdb->doms; - } else { - prevdom->next = domain; - prevdom = domain; - } + DLIST_ADD_END(cdb->doms, domain, struct sss_domain_info *); } if (cdb->doms == NULL) { diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 71c30367f..c1b925349 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -229,14 +229,14 @@ struct sss_domain_info { struct sysdb_ctx *sysdb; struct sss_names_ctx *names; - struct sss_domain_info **subdomains; - uint32_t subdomain_count; struct sss_domain_info *parent; + struct sss_domain_info *subdomains; char *realm; char *flat_name; char *domain_id; struct timeval subdomains_last_checked; + struct sss_domain_info *prev; struct sss_domain_info *next; bool disabled; diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 2bc858edb..fff97a8aa 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -355,11 +355,6 @@ int sysdb_transaction_commit(struct sysdb_ctx *sysdb); int sysdb_transaction_cancel(struct sysdb_ctx *sysdb); /* functions related to subdomains */ -errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - size_t *subdomain_count, - struct sss_domain_info ***subdomain_list); - errno_t sysdb_domain_create(struct sysdb_ctx *sysdb, const char *domain_name); errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, @@ -374,6 +369,8 @@ errno_t sysdb_master_domain_add_info(struct sss_domain_info *domain, const char *realm, const char *flat, const char *id); +errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name); + errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, size_t *range_count, struct range_info ***range_list); diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c index c27190757..3e0d7b40a 100644 --- a/src/db/sysdb_subdomains.c +++ b/src/db/sysdb_subdomains.c @@ -23,10 +23,7 @@ #include "util/util.h" #include "db/sysdb_private.h" -errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - size_t *subdomain_count, - struct sss_domain_info ***subdomain_list) +errno_t sysdb_update_subdomains(struct sss_domain_info *domain) { int i; errno_t ret; @@ -37,7 +34,7 @@ errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, SYSDB_SUBDOMAIN_FLAT, SYSDB_SUBDOMAIN_ID, NULL}; - struct sss_domain_info **list; + struct sss_domain_info *dom; struct ldb_dn *basedn; tmp_ctx = talloc_new(NULL); @@ -59,10 +56,14 @@ errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, goto done; } - list = talloc_zero_array(tmp_ctx, struct sss_domain_info *, - res->count + 1); - if (list == NULL) { - ret = ENOMEM; + /* disable all domains, + * let the search result refresh any that are still valid */ + for (dom = domain->subdomains; dom; dom = get_next_domain(dom, false)) { + dom->disabled = true; + } + + if (res->count == 0) { + ret = EOK; goto done; } @@ -90,17 +91,58 @@ errno_t sysdb_get_subdomains(TALLOC_CTX *mem_ctx, id = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_SUBDOMAIN_ID, NULL); - list[i] = new_subdomain(list, domain, name, realm, flat, id); - if (list[i] == NULL) { - ret = ENOMEM; - goto done; + /* explicitly use dom->next as we need to check 'disabled' domains */ + for (dom = domain->subdomains; dom; dom = dom->next) { + if (strcasecmp(dom->name, name) == 0) { + dom->disabled = false; + /* in theory these may change, but it should never happen */ + if (strcasecmp(dom->realm, realm) != 0) { + DEBUG(SSSDBG_TRACE_INTERNAL, + ("Realm name changed from [%s] to [%s]!\n", + dom->realm, realm)); + talloc_zfree(dom->realm); + dom->realm = talloc_strdup(dom, realm); + if (dom->realm == NULL) { + ret = ENOMEM; + goto done; + } + } + if (strcasecmp(dom->flat_name, flat) != 0) { + DEBUG(SSSDBG_TRACE_INTERNAL, + ("Flat name changed from [%s] to [%s]!\n", + dom->flat_name, flat)); + talloc_zfree(dom->flat_name); + dom->flat_name = talloc_strdup(dom, flat); + if (dom->flat_name == NULL) { + ret = ENOMEM; + goto done; + } + } + if (strcasecmp(dom->domain_id, id) != 0) { + DEBUG(SSSDBG_TRACE_INTERNAL, + ("Domain changed from [%s] to [%s]!\n", + dom->domain_id, id)); + talloc_zfree(dom->domain_id); + dom->domain_id = talloc_strdup(dom, id); + if (dom->domain_id == NULL) { + ret = ENOMEM; + goto done; + } + } + break; + } + } + /* If not found in loop it is a new subdomain */ + if (dom == NULL) { + dom = new_subdomain(domain, domain, name, realm, flat, id); + if (dom == NULL) { + ret = ENOMEM; + goto done; + } + DLIST_ADD_END(domain->subdomains, dom, struct sss_domain_info *); } } - list[res->count] = NULL; - - *subdomain_count = res->count; - *subdomain_list = talloc_steal(mem_ctx, list); ret = EOK; done: @@ -460,18 +502,11 @@ done: return ret; } -errno_t sysdb_update_subdomains(struct sss_domain_info *domain) +errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name) { - int ret; - int sret; - size_t c; - size_t d; TALLOC_CTX *tmp_ctx = NULL; - size_t cur_subdomains_count; - struct sss_domain_info **cur_subdomains; struct ldb_dn *dn; - bool in_transaction = false; - bool *keep_subdomain; + int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { @@ -479,90 +514,20 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain) goto done; } - /* Retrieve all subdomains that are currently in sysdb */ - ret = sysdb_get_subdomains(tmp_ctx, domain, &cur_subdomains_count, - &cur_subdomains); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, ("sysdb_get_subdomains failed.\n")); - goto done; - } - - keep_subdomain = talloc_zero_array(tmp_ctx, bool, cur_subdomains_count); - if (keep_subdomain == NULL) { + DEBUG(SSSDBG_TRACE_FUNC, ("Removing sub-domain [%s] from db.\n", name)); + dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, name); + if (dn == NULL) { ret = ENOMEM; - DEBUG(SSSDBG_OP_FAILURE, ("talloc_zero_array failed.\n")); goto done; } - ret = sysdb_transaction_start(domain->sysdb); + ret = sysdb_delete_recursive(sysdb, dn, true); if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, ("sysdb_transaction_start failed.\n")); + DEBUG(SSSDBG_OP_FAILURE, ("sysdb_delete_recursive failed.\n")); goto done; } - in_transaction = true; - - /* Go through a list of retrieved subdomains and: - * - if a subdomain already exists in sysdb, mark it for preservation - * - if the subdomain doesn't exist in sysdb, create its bare structure - */ - for (c = 0; c < domain->subdomain_count; c++) { - for (d = 0; d < cur_subdomains_count; d++) { - if (strcasecmp(domain->subdomains[c]->name, - cur_subdomains[d]->name) == 0) { - keep_subdomain[d] = true; - /* sub-domain already in cache, nothing to do */ - break; - } - } - - if (d == cur_subdomains_count) { - DEBUG(SSSDBG_TRACE_FUNC, ("Adding sub-domain [%s].\n", - domain->subdomains[c]->name)); - ret = sysdb_subdomain_create(domain->subdomains[c]); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, ("sysdb_subdomain_create failed.\n")); - goto done; - } - } - } - - /* Now delete all subdomains that have been in sysdb prior to - * refreshing the list and are not marked for preservation - * (i.e. they are not in the new list of subdomains) - */ - for (d = 0; d < cur_subdomains_count; d++) { - if (!keep_subdomain[d]) { - DEBUG(SSSDBG_TRACE_FUNC, ("Removing sub-domain [%s].\n", - cur_subdomains[d]->name)); - dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, - cur_subdomains[d]->name); - if (dn == NULL) { - ret = ENOMEM; - goto done; - } - - ret = sysdb_delete_recursive(domain->sysdb, dn, true); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, ("sysdb_delete_recursive failed.\n")); - goto done; - } - } - } - - ret = sysdb_transaction_commit(domain->sysdb); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, ("Could not commit transaction\n")); - goto done; - } - in_transaction = false; done: - if (in_transaction) { - sret = sysdb_transaction_cancel(domain->sysdb); - if (sret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction\n")); - } - } talloc_free(tmp_ctx); return ret; } diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index 312813c00..deee153b8 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -82,9 +82,8 @@ struct ipa_subdomains_ctx { const char *get_flat_name_from_subdomain_name(struct be_ctx *be_ctx, const char *name) { - size_t c; struct ipa_subdomains_ctx *ctx; - struct sss_domain_info *domain; + struct sss_domain_info *dom; ctx = talloc_get_type(be_ctx->bet_info[BET_SUBDOMAINS].pvt_bet_data, struct ipa_subdomains_ctx); @@ -93,14 +92,9 @@ const char *get_flat_name_from_subdomain_name(struct be_ctx *be_ctx, return NULL; } - domain = ctx->be_ctx->domain; - - for (c = 0; c < domain->subdomain_count; c++) { - if (strcasecmp(domain->subdomains[c]->name, name) == 0 || - (domain->subdomains[c]->flat_name != NULL && - strcasecmp(domain->subdomains[c]->flat_name, name) == 0)) { - return domain->subdomains[c]->flat_name; - } + dom = find_subdomain_by_name(ctx->be_ctx->domain, name, true); + if (dom) { + return dom->flat_name; } return NULL; @@ -197,91 +191,56 @@ done: return ret; } -static errno_t ipa_subdom_parse(TALLOC_CTX *memctx, - struct sss_domain_info *parent, - struct sysdb_attrs *attrs, - struct sss_domain_info **_subdom) +static errno_t ipa_subdom_store(struct sss_domain_info *domain, + struct sysdb_attrs *attrs) { - struct sss_domain_info *subdom = *_subdom; - const char *value; + TALLOC_CTX *tmp_ctx; + const char *name; + char *realm; + const char *flat; + const char *id; int ret; - ret = sysdb_attrs_get_string(attrs, IPA_CN, &value); + tmp_ctx = talloc_new(domain); + + ret = sysdb_attrs_get_string(attrs, IPA_CN, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n")); - return ret; - } - - if (subdom == NULL) { - subdom = new_subdomain(memctx, parent, value, NULL, NULL, NULL); - if (subdom == NULL) { - return ENOMEM; - } - } else if (strcmp(subdom->name, value) != 0) { - DEBUG(SSSDBG_OP_FAILURE, ("subdomain name mismatch!\n")); - return EINVAL; + goto done; } - if (subdom->realm == NULL) { - /* Add Realm as upper(domain name), this is generally always correct - * with AD domains */ - subdom->realm = get_uppercase_realm(subdom, subdom->name); - if (!subdom->realm) { - return ENOMEM; - } + realm = get_uppercase_realm(tmp_ctx, name); + if (!realm) { + ret = ENOMEM; + goto done; } - ret = sysdb_attrs_get_string(attrs, IPA_FLATNAME, &value); + ret = sysdb_attrs_get_string(attrs, IPA_FLATNAME, &flat); if (ret) { DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n")); - return ret; - } - - /* in theory this may change, it should never happen, so we will log a - * warning if it does, but we will allow it for now */ - if (subdom->flat_name != NULL) { - if (strcmp(subdom->flat_name, value) != 0) { - DEBUG(SSSDBG_TRACE_INTERNAL, - ("Flat name for subdomain changed!\n")); - talloc_zfree(subdom->flat_name); - } - } - if (subdom->flat_name == NULL) { - subdom->flat_name = talloc_strdup(subdom, value); - if (subdom->flat_name == NULL) { - return ENOMEM; - } + goto done; } - ret = sysdb_attrs_get_string(attrs, IPA_TRUSTED_DOMAIN_SID, &value); + ret = sysdb_attrs_get_string(attrs, IPA_TRUSTED_DOMAIN_SID, &id); if (ret) { DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n")); - return ret; + goto done; } - /* in theory this may change, it should never happen, so we will log a - * warning if it does, but we will allow it for now */ - if (subdom->domain_id != NULL) { - if (strcmp(subdom->domain_id, value) != 0) { - DEBUG(SSSDBG_TRACE_INTERNAL, - ("ID for subdomain changed!\n")); - talloc_zfree(subdom->domain_id); - } - } - if (subdom->domain_id == NULL) { - subdom->domain_id = talloc_strdup(subdom, value); - if (subdom->domain_id == NULL) { - return ENOMEM; - } + ret = sysdb_subdomain_store(domain->sysdb, name, realm, flat, id); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, ("sysdb_subdomain_store failed.\n")); } - *_subdom = subdom; +done: + talloc_free(tmp_ctx); return EOK; } static errno_t ipa_subdomains_write_mappings(struct sss_domain_info *domain) { + struct sss_domain_info *dom; errno_t ret; errno_t err; TALLOC_CTX *tmp_ctx; @@ -290,7 +249,6 @@ ipa_subdomains_write_mappings(struct sss_domain_info *domain) int fd = -1; mode_t old_mode; FILE *fstream = NULL; - size_t i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; @@ -342,12 +300,11 @@ ipa_subdomains_write_mappings(struct sss_domain_info *domain) goto done; } - for (i = 0; i < domain->subdomain_count; i++) { + for (dom = get_next_domain(domain, true); + dom && dom->parent; /* if we get back to a parent, stop */ + dom = get_next_domain(dom, false)) { ret = fprintf(fstream, ".%s = %s\n%s = %s\n", - domain->subdomains[i]->name, - domain->subdomains[i]->realm, - domain->subdomains[i]->name, - domain->subdomains[i]->realm); + dom->name, dom->realm, dom->name, dom->realm); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, ("fprintf failed\n")); goto done; @@ -410,18 +367,20 @@ static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, int count, struct sysdb_attrs **reply, bool *changes) { - struct sss_domain_info *domain; + struct sss_domain_info *domain, *dom; bool handled[count]; const char *value; int c, h; int ret; - int i, j; domain = ctx->be_ctx->domain; memset(handled, 0, sizeof(bool) * count); + h = 0; /* check existing subdomains */ - for (i = 0, h = 0; i < domain->subdomain_count; i++) { + for (dom = get_next_domain(domain, true); + dom && dom->parent; + dom = get_next_domain(dom, false)) { for (c = 0; c < count; c++) { if (handled[c]) { continue; @@ -431,26 +390,21 @@ static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n")); goto done; } - if (strcmp(value, domain->subdomains[i]->name) == 0) { + if (strcmp(value, dom->name) == 0) { break; } } if (c >= count) { /* ok this subdomain does not exist anymore, let's clean up */ - for (j = i; j < domain->subdomain_count - 1; j++) { - talloc_zfree(domain->subdomains[j]); - domain->subdomains[j] = domain->subdomains[j + 1]; - } - if (i != 0) { - domain->subdomains[i - 1]->next = domain->subdomains[i]; + dom->disabled = true; + ret = sysdb_subdomain_delete(dom->sysdb, dom->name); + if (ret != EOK) { + goto done; } - domain->subdomain_count--; - i--; } else { /* ok let's try to update it */ - ret = ipa_subdom_parse(domain->subdomains, domain, - reply[c], &domain->subdomains[i]); + ret = ipa_subdom_store(domain, reply[c]); if (ret) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to parse subdom data\n")); goto done; @@ -469,29 +423,15 @@ static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, /* if we get here it means we have changes to the subdomains list */ *changes = true; - /* add space for unhandled domains */ - c = count - h; - domain->subdomains = talloc_realloc(domain, domain->subdomains, - struct sss_domain_info *, - domain->subdomain_count + c); - if (domain->subdomains == NULL) { - ret = ENOMEM; - goto done; - } - for (c = 0; c < count; c++) { if (handled[c]) { continue; } - i = domain->subdomain_count; - domain->subdomains[i] = NULL; - ret = ipa_subdom_parse(domain->subdomains, domain, - reply[c], &domain->subdomains[i]); + ret = ipa_subdom_store(domain, reply[c]); if (ret) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to parse subdom data\n")); goto done; } - domain->subdomain_count++; } ret = EOK; @@ -499,8 +439,6 @@ static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, done: if (ret != EOK) { ctx->last_refreshed = 0; - domain->subdomain_count = 0; - talloc_zfree(domain->subdomains); } else { ctx->last_refreshed = time(NULL); } diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c index 3a634e03b..877181f8d 100644 --- a/src/responder/common/responder_common.c +++ b/src/responder/common/responder_common.c @@ -886,41 +886,32 @@ int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain, struct sss_domain_info * responder_get_domain(TALLOC_CTX *sd_mem_ctx, struct resp_ctx *rctx, - const char *domain) + const char *name) { time_t now = time(NULL); time_t time_diff; struct sss_domain_info *dom; struct sss_domain_info *ret_dom = NULL; - int i; - for (dom = rctx->domains; dom; dom = get_next_domain(dom, false)) { - if (strcasecmp(dom->name, domain) == 0 || + for (dom = rctx->domains; dom; dom = get_next_domain(dom, true)) { + if (!dom->parent) { + time_diff = now - dom->subdomains_last_checked.tv_sec; + } + if (strcasecmp(dom->name, name) == 0 || (dom->flat_name != NULL && - strcasecmp(dom->flat_name, domain) == 0)) { + strcasecmp(dom->flat_name, name) == 0)) { ret_dom = dom; - break; - } - - for (i = 0; i < dom->subdomain_count; i++) { - if (strcasecmp(dom->subdomains[i]->name, domain) == 0 || - (dom->subdomains[i]->flat_name != NULL && - strcasecmp(dom->subdomains[i]->flat_name, domain) == 0)) { - /* Sub-domains may come and go, so we better copy the struct - * for each request. */ - ret_dom = copy_subdomain(sd_mem_ctx, dom->subdomains[i]); + if (!dom->parent || + (dom->parent && time_diff < rctx->domains_timeout)) { break; } } - time_diff = now - dom->subdomains_last_checked.tv_sec; - if (i < dom->subdomain_count && time_diff < rctx->domains_timeout) break; } - /* FIXME: we might want to return a real error, e.g. if copy_subdomain - * fails. */ + if (!ret_dom) { DEBUG(SSSDBG_OP_FAILURE, ("Unknown domain [%s], checking for" - "possible subdomains!\n", domain)); + "possible subdomains!\n", name)); } return ret_dom; diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c index 77e2b146d..b69875e1c 100644 --- a/src/responder/common/responder_get_domains.c +++ b/src/responder/common/responder_get_domains.c @@ -280,32 +280,6 @@ static errno_t process_subdomains(struct sss_domain_info *domain) { int ret; - size_t c; - size_t subdomain_count; - struct sss_domain_info **subdomains; - - /* Retrieve all subdomains of this domain from sysdb - * and create their struct sss_domain_info representations - */ - ret = sysdb_get_subdomains(domain, domain, - &subdomain_count, &subdomains); - if (ret != EOK) { - DEBUG(SSSDBG_FUNC_DATA, ("sysdb_get_subdomains failed.\n")); - goto done; - } - - if (subdomain_count == 0) { - talloc_zfree(domain->subdomains); - domain->subdomain_count = 0; - goto done; - } - - /* Link all subdomains into single-linked list - * (the list is used when processing all domains) - */ - for (c = 0; c < subdomain_count - 1; c++) { - subdomains[c]->next = subdomains[c + 1]; - } if (domain->realm == NULL || domain->flat_name == NULL || @@ -318,6 +292,15 @@ process_subdomains(struct sss_domain_info *domain) } } + /* Retrieve all subdomains of this domain from sysdb + * and create their struct sss_domain_info representations + */ + ret = sysdb_update_subdomains(domain); + if (ret != EOK) { + DEBUG(SSSDBG_FUNC_DATA, ("sysdb_update_subdomains failed.\n")); + goto done; + } + errno = 0; ret = gettimeofday(&domain->subdomains_last_checked, NULL); if (ret == -1) { @@ -325,17 +308,12 @@ process_subdomains(struct sss_domain_info *domain) goto done; } - talloc_zfree(domain->subdomains); - domain->subdomain_count = subdomain_count; - domain->subdomains = subdomains; - ret = EOK; done: if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to update sub-domains " "of domain [%s].\n", domain->name)); - talloc_free(subdomains); } return ret; @@ -366,32 +344,26 @@ static errno_t check_last_request(struct resp_ctx *rctx, const char *hint) struct sss_domain_info *dom; time_t now = time(NULL); time_t diff; - int i; - diff = now-rctx->get_domains_last_call.tv_sec; + diff = now - rctx->get_domains_last_call.tv_sec; if (diff >= rctx->domains_timeout) { /* Timeout, expired, fetch domains again */ return EAGAIN; } if (hint != NULL) { - dom = rctx->domains; - while (dom) { - for (i = 0; i< dom->subdomain_count; i++) { - if (strcasecmp(dom->subdomains[i]->name, hint) == 0) { - diff = now-dom->subdomains_last_checked.tv_sec; - if (diff >= rctx->domains_timeout) { - /* Timeout, expired, fetch domains again */ - return EAGAIN; - } - /* Skip the rest of this domain, but check other domains - * perhaps this subdomain will be also a part of another - * domain where it will need refreshing - */ - break; + for (dom = rctx->domains; dom; dom = get_next_domain(dom, true)) { + if (dom->parent == NULL) { + diff = now - dom->subdomains_last_checked.tv_sec; + /* not a subdomain */ + continue; + } + if (strcasecmp(dom->name, hint) == 0) { + if (diff >= rctx->domains_timeout) { + /* Timeout, expired, fetch domains again */ + return EAGAIN; } } - dom = get_next_domain(dom, false); } } diff --git a/src/responder/pac/pacsrv_utils.c b/src/responder/pac/pacsrv_utils.c index cab582644..2708e5a2e 100644 --- a/src/responder/pac/pacsrv_utils.c +++ b/src/responder/pac/pacsrv_utils.c @@ -76,14 +76,13 @@ struct sss_domain_info *find_domain_by_id(struct sss_domain_info *domains, { struct sss_domain_info *dom; struct sss_domain_info *ret_dom = NULL; - size_t c; if (id_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, ("Missing domain id.\n")); return NULL; } - for (dom = domains; dom; dom = get_next_domain(dom, false)) { + for (dom = domains; dom; dom = get_next_domain(dom, true)) { if (dom->domain_id == NULL) { continue; } @@ -92,14 +91,6 @@ struct sss_domain_info *find_domain_by_id(struct sss_domain_info *domains, ret_dom = dom; break; } - - for (c = 0; c < dom->subdomain_count; c++) { - if (strcasecmp(dom->subdomains[c]->domain_id, id_str) == 0) { - ret_dom = dom->subdomains[c]; - break; - } - } - } if (!ret_dom) { diff --git a/src/tests/pac_responder-tests.c b/src/tests/pac_responder-tests.c index 7d352a0e8..847dbe009 100644 --- a/src/tests/pac_responder-tests.c +++ b/src/tests/pac_responder-tests.c @@ -98,15 +98,7 @@ void pac_setup(void) { fail_unless(pac_ctx->rctx->domains->domain_id != NULL, "talloc_strdup failed."); - pac_ctx->rctx->domains->subdomain_count = 1; - pac_ctx->rctx->domains->subdomains = talloc_zero_array(pac_ctx->rctx->domains, - struct sss_domain_info *, - pac_ctx->rctx->domains->subdomain_count); - fail_unless(pac_ctx->rctx->domains->subdomains != NULL, - "talloc_array_zero failed"); - - sd = talloc_zero(pac_ctx->rctx->domains->subdomains, - struct sss_domain_info); + sd = talloc_zero(pac_ctx->rctx->domains, struct sss_domain_info); fail_unless(sd != NULL, "talloc_zero failed."); sd->name = talloc_strdup(sd, "remote.dom"); @@ -118,7 +110,7 @@ void pac_setup(void) { sd->domain_id = talloc_strdup(sd, test_remote_dom_sid_str); fail_unless(sd->domain_id != NULL, "talloc_strdup failed"); - pac_ctx->rctx->domains->subdomains[0] = sd; + pac_ctx->rctx->domains->subdomains = sd; err = sss_idmap_init(idmap_talloc, pac_ctx, idmap_talloc_free, &pac_ctx->idmap_ctx); @@ -285,8 +277,8 @@ END_TEST #define NUM_DOMAINS 10 START_TEST(pac_test_find_domain_by_id) { + struct sss_domain_info *domains; struct sss_domain_info *dom; - struct sss_domain_info **domains; size_t c; char *id; @@ -296,33 +288,30 @@ START_TEST(pac_test_find_domain_by_id) dom = find_domain_by_id(NULL, "id"); fail_unless(dom == NULL, "Domain returned without domain list."); - domains = talloc_zero_array(global_talloc_context, struct sss_domain_info *, - NUM_DOMAINS); + domains = NULL; for (c = 0; c < NUM_DOMAINS; c++) { - domains[c] = talloc_zero(domains, struct sss_domain_info); - fail_unless(domains[c] != NULL, "talloc_zero failed."); - - domains[c]->domain_id = talloc_asprintf(domains[c], - "ID-of-domains-%zu", c); - fail_unless(domains[c]->domain_id != NULL, "talloc_asprintf failed."); - if (c > 0) { - domains[c-1]->next = domains[c]; - } + dom = talloc_zero(domains, struct sss_domain_info); + fail_unless(dom != NULL, "talloc_zero failed."); + + dom->domain_id = talloc_asprintf(dom, "ID-of-domains-%zu", c); + fail_unless(dom->domain_id != NULL, "talloc_aprintf failed."); + + DLIST_ADD(domains, dom); } - dom = find_domain_by_id(domains[0], NULL); + dom = find_domain_by_id(domains, NULL); fail_unless(dom == NULL, "Domain returned without search domain."); - dom = find_domain_by_id(domains[0], "DOES-NOT_EXISTS"); + dom = find_domain_by_id(domains, "DOES-NOT_EXISTS"); fail_unless(dom == NULL, "Domain returned with non existing id."); for (c = 0; c < NUM_DOMAINS; c++) { id = talloc_asprintf(global_talloc_context, "ID-of-domains-%zu", c); fail_unless(id != NULL, "talloc_asprintf failed.\n"); - dom = find_domain_by_id(domains[0], id); - fail_unless(dom == domains[c], "Wrong domain returned for id [%s].", - id); + dom = find_domain_by_id(domains, id); + fail_unless((strcmp(dom->domain_id, id) == 0), + "Wrong domain returned for id [%s].", id); talloc_free(id); } diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 58198d508..081df6cf6 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -4471,90 +4471,54 @@ START_TEST(test_sysdb_subdomain_create) { struct sysdb_test_ctx *test_ctx; errno_t ret; - struct sss_domain_info **cur_subdomains = NULL; - size_t cur_subdomains_count; - struct sss_domain_info *new_subdom1; - struct sss_domain_info *new_subdom2; + const char const *dom1[4] = { "dom1.sub", "DOM1.SUB", "dom1", "S-1" }; + const char const *dom2[4] = { "dom2.sub", "DOM2.SUB", "dom2", "S-2" }; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); - ret = sysdb_get_subdomains(test_ctx, test_ctx->domain, - &cur_subdomains_count, &cur_subdomains); - fail_unless(ret == EOK, "sysdb_get_subdomains failed with [%d][%s]", - ret, strerror(ret)); - fail_unless(cur_subdomains != NULL, "Non zero sub-domains returned."); - fail_unless(cur_subdomains[0] == NULL, "No empty sub-domain list returned."); - - test_ctx->domain->subdomains = talloc_array(test_ctx->domain, - struct sss_domain_info *, 2); - fail_unless(test_ctx->domain->subdomains != NULL, - "talloc_array_zero failed"); - - new_subdom1 = new_subdomain(test_ctx, test_ctx->domain, - "dom1.sub", "DOM1.SUB", "dom1", "S-1"); - fail_unless(new_subdom1 != NULL, "Failed to create new subdomin."); - test_ctx->domain->subdomains[0] = new_subdom1; - test_ctx->domain->subdomain_count = 1; - ret = sysdb_subdomain_store(test_ctx->sysdb, - "dom1.sub", "DOM1.SUB", "dom1", "S-1"); + dom1[0], dom1[1], dom1[2], dom1[3]); fail_if(ret != EOK, "Could not set up the test (dom1)"); ret = sysdb_update_subdomains(test_ctx->domain); fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]", ret, strerror(ret)); - ret = sysdb_get_subdomains(test_ctx, test_ctx->domain, - &cur_subdomains_count, &cur_subdomains); - fail_unless(ret == EOK, "sysdb_get_subdomains failed with [%d][%s]", - ret, strerror(ret)); - fail_if(cur_subdomains_count != 1, "Wrong number of sub-domains returned."); - fail_if(cur_subdomains[0] == NULL, "Empyt sub-domain list returned."); - fail_if(strcmp(cur_subdomains[0]->name, new_subdom1->name) != 0, + fail_if(test_ctx->domain->subdomains == NULL, "Empyt sub-domain list."); + fail_if(strcmp(test_ctx->domain->subdomains->name, dom1[0]) != 0, "Unexpected sub-domain found, expected [%s], got [%s]", - new_subdom1->name, cur_subdomains[0]->name); - - new_subdom2 = new_subdomain(test_ctx, test_ctx->domain, - "dom2.sub", "DOM2.SUB", "dom2", "S-2"); - fail_unless(new_subdom2 != NULL, "Failed to create new subdomin."); - test_ctx->domain->subdomains[1] = new_subdom2; - test_ctx->domain->subdomain_count = 2; + dom1[0], test_ctx->domain->subdomains->name); ret = sysdb_subdomain_store(test_ctx->sysdb, - "dom2.sub", "DOM2.SUB", "dom2", "S-2"); + dom2[0], dom2[1], dom2[2], dom2[3]); fail_if(ret != EOK, "Could not set up the test (dom2)"); ret = sysdb_update_subdomains(test_ctx->domain); fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]", ret, strerror(ret)); - ret = sysdb_get_subdomains(test_ctx, test_ctx->domain, - &cur_subdomains_count, &cur_subdomains); - fail_unless(ret == EOK, "sysdb_get_subdomains failed with [%d][%s]", - ret, strerror(ret)); - fail_if(cur_subdomains_count != 2, "Wrong number of sub-domains returned."); - fail_if(cur_subdomains[1] == NULL, "Empyt sub-domain list returned."); - fail_if(strcmp(cur_subdomains[1]->name, new_subdom2->name) != 0, + fail_if(test_ctx->domain->subdomains->next == NULL, "Missing sub-domain"); + fail_if(strcmp(test_ctx->domain->subdomains->next->name, dom2[0]) != 0, "Unexpected sub-domain found, expected [%s], got [%s]", - new_subdom2->name, cur_subdomains[1]->name); + dom2[0], test_ctx->domain->subdomains->next->name); - test_ctx->domain->subdomain_count = 0; - talloc_zfree(test_ctx->domain->subdomains); + ret = sysdb_subdomain_delete(test_ctx->sysdb, dom2[0]); + fail_if(ret != EOK, "Could not delete subdomain"); + + ret = sysdb_subdomain_delete(test_ctx->sysdb, dom1[0]); + fail_if(ret != EOK, "Could not delete subdomain"); ret = sysdb_update_subdomains(test_ctx->domain); fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]", ret, strerror(ret)); - ret = sysdb_get_subdomains(test_ctx, test_ctx->domain, - &cur_subdomains_count, &cur_subdomains); - fail_unless(ret == EOK, "sysdb_get_subdomains failed with [%d][%s]", - ret, strerror(ret)); - fail_unless(cur_subdomains != NULL, "No sub-domains returned."); - fail_if(cur_subdomains[0] != NULL, "No empty sub-domain list returned."); + fail_unless(test_ctx->domain->subdomains->disabled, "Subdomain not disabled."); } END_TEST +const char const *testdom[4] = { "test.sub", "TEST.SUB", "test", "S-3" }; + START_TEST(test_sysdb_subdomain_store_user) { struct sysdb_test_ctx *test_ctx; @@ -4568,9 +4532,10 @@ START_TEST(test_sysdb_subdomain_store_user) fail_if(ret != EOK, "Could not set up the test"); subdomain = new_subdomain(test_ctx, test_ctx->domain, - "test.sub", "TEST.SUB", "test", "S-3"); + testdom[0], testdom[1], testdom[2], testdom[3]); fail_unless(subdomain != NULL, "Failed to create new subdomin."); - ret = sysdb_subdomain_create(subdomain); + ret = sysdb_subdomain_store(test_ctx->sysdb, + testdom[0], testdom[1], testdom[2], testdom[3]); fail_if(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain); @@ -4624,9 +4589,10 @@ START_TEST(test_sysdb_subdomain_user_ops) fail_if(ret != EOK, "Could not set up the test"); subdomain = new_subdomain(test_ctx, test_ctx->domain, - "test.sub", "TEST.SUB", "test", "S-3"); + testdom[0], testdom[1], testdom[2], testdom[3]); fail_unless(subdomain != NULL, "Failed to create new subdomin."); - ret = sysdb_subdomain_create(subdomain); + ret = sysdb_subdomain_store(test_ctx->sysdb, + testdom[0], testdom[1], testdom[2], testdom[3]); fail_if(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain); @@ -4676,9 +4642,10 @@ START_TEST(test_sysdb_subdomain_group_ops) fail_if(ret != EOK, "Could not set up the test"); subdomain = new_subdomain(test_ctx, test_ctx->domain, - "test.sub", "TEST.SUB", "test", "S-3"); + testdom[0], testdom[1], testdom[2], testdom[3]); fail_unless(subdomain != NULL, "Failed to create new subdomin."); - ret = sysdb_subdomain_create(subdomain); + ret = sysdb_subdomain_store(test_ctx->sysdb, + testdom[0], testdom[1], testdom[2], testdom[3]); fail_if(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain); diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c index 59d5c534b..6db7e157a 100644 --- a/src/util/domain_info_utils.c +++ b/src/util/domain_info_utils.c @@ -29,8 +29,8 @@ struct sss_domain_info *get_next_domain(struct sss_domain_info *domain, dom = domain; while (dom) { - if (descend && dom->subdomain_count > 0) { - dom = dom->subdomains[0]; + if (descend && dom->subdomains) { + dom = dom->subdomains; } else if (dom->next) { dom = dom->next; } else if (descend && dom->parent) { @@ -44,6 +44,27 @@ struct sss_domain_info *get_next_domain(struct sss_domain_info *domain, return dom; } +struct sss_domain_info *find_subdomain_by_name(struct sss_domain_info *domain, + const char *name, + bool match_any) +{ + struct sss_domain_info *dom = domain; + + while (dom && dom->disabled) { + dom = get_next_domain(dom, true); + } + while (dom) { + if (strcasecmp(dom->name, name) == 0 || + ((match_any == true) && (dom->flat_name != NULL) && + (strcasecmp(dom->flat_name, name) == 0))) { + return dom; + } + dom = get_next_domain(dom, true); + } + + return NULL; +} + struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, struct sss_domain_info *parent, const char *name, @@ -136,14 +157,6 @@ fail: return NULL; } -struct sss_domain_info *copy_subdomain(TALLOC_CTX *mem_ctx, - struct sss_domain_info *subdomain) -{ - return new_subdomain(mem_ctx, subdomain->parent, - subdomain->name, subdomain->realm, - subdomain->flat_name, subdomain->domain_id); -} - errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *domain_name, diff --git a/src/util/usertools.c b/src/util/usertools.c index 33a2a7bd5..587fd9cbf 100644 --- a/src/util/usertools.c +++ b/src/util/usertools.c @@ -298,24 +298,16 @@ int sss_parse_name(TALLOC_CTX *memctx, return EOK; } -static struct sss_domain_info * match_any_domain_or_subdomain_name ( - struct sss_domain_info *dom, const char *dmatch) +static struct sss_domain_info * match_any_domain_or_subdomain_name( + struct sss_domain_info *dom, + const char *dmatch) { - uint32_t i; - - if (strcasecmp (dom->name, dmatch) == 0 || - (dom->flat_name != NULL && strcasecmp(dom->flat_name, dmatch) == 0)) + if (strcasecmp(dom->name, dmatch) == 0 || + (dom->flat_name != NULL && strcasecmp(dom->flat_name, dmatch) == 0)) { return dom; - - for (i = 0; i < dom->subdomain_count; i++) { - if (strcasecmp(dom->subdomains[i]->name, dmatch) == 0 || - (dom->subdomains[i]->flat_name != NULL && - strcasecmp(dom->subdomains[i]->flat_name, dmatch) == 0)) { - return dom->subdomains[i]; - } } - return NULL; + return find_subdomain_by_name(dom, dmatch, true); } int sss_parse_name_for_domains(TALLOC_CTX *memctx, diff --git a/src/util/util.h b/src/util/util.h index de212811f..7697dbb51 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -568,14 +568,16 @@ void to_sized_string(struct sized_string *out, const char *in); /* form domain_info.c */ struct sss_domain_info *get_next_domain(struct sss_domain_info *domain, bool descend); +struct sss_domain_info *find_subdomain_by_name(struct sss_domain_info *domain, + const char *name, + bool match_any); + struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, struct sss_domain_info *parent, const char *name, const char *realm, const char *flat_name, const char *id); -struct sss_domain_info *copy_subdomain(TALLOC_CTX *mem_ctx, - struct sss_domain_info *subdomain); errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, |