summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/confdb/confdb.c10
-rw-r--r--src/confdb/confdb.h4
-rw-r--r--src/db/sysdb.h7
-rw-r--r--src/db/sysdb_subdomains.c167
-rw-r--r--src/providers/ipa/ipa_subdomains.c152
-rw-r--r--src/responder/common/responder_common.c31
-rw-r--r--src/responder/common/responder_get_domains.c68
-rw-r--r--src/responder/pac/pacsrv_utils.c11
-rw-r--r--src/tests/pac_responder-tests.c43
-rw-r--r--src/tests/sysdb-tests.c87
-rw-r--r--src/util/domain_info_utils.c33
-rw-r--r--src/util/usertools.c20
-rw-r--r--src/util/util.h6
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,