summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/responder/pac/pacsrv.h7
-rw-r--r--src/responder/pac/pacsrv_cmd.c6
-rw-r--r--src/responder/pac/pacsrv_utils.c172
3 files changed, 140 insertions, 45 deletions
diff --git a/src/responder/pac/pacsrv.h b/src/responder/pac/pacsrv.h
index f0ffea29..08b4461f 100644
--- a/src/responder/pac/pacsrv.h
+++ b/src/responder/pac/pacsrv.h
@@ -85,9 +85,10 @@ errno_t domsid_rid_to_uid(struct pac_ctx *pac_ctx,
struct dom_sid2 *domsid, uint32_t rid,
uid_t *uid);
-errno_t get_my_domain_sid(struct pac_ctx *pac_ctx,
- struct sss_domain_info *dom,
- struct dom_sid **_sid);
+errno_t get_my_domain_data(struct pac_ctx *pac_ctx,
+ struct sss_domain_info *dom,
+ struct dom_sid **_sid,
+ struct local_mapping_ranges **_range_map);
errno_t get_gids_from_pac(TALLOC_CTX *mem_ctx,
struct local_mapping_ranges *range_map,
diff --git a/src/responder/pac/pacsrv_cmd.c b/src/responder/pac/pacsrv_cmd.c
index 1d67657d..0696caca 100644
--- a/src/responder/pac/pacsrv_cmd.c
+++ b/src/responder/pac/pacsrv_cmd.c
@@ -178,6 +178,7 @@ static errno_t pac_add_user_next(struct pac_req_ctx *pr_ctx)
int ret;
struct tevent_req *req;
struct dom_sid *my_dom_sid;
+ struct local_mapping_ranges *my_range_map;
ret = save_pac_user(pr_ctx);
if (ret != EOK) {
@@ -185,13 +186,14 @@ static errno_t pac_add_user_next(struct pac_req_ctx *pr_ctx)
goto done;
}
- ret = get_my_domain_sid(pr_ctx->pac_ctx, pr_ctx->dom, &my_dom_sid);
+ ret = get_my_domain_data(pr_ctx->pac_ctx, pr_ctx->dom,
+ &my_dom_sid, &my_range_map);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("get_my_domain_sid failed.\n"));
goto done;
}
- ret = get_gids_from_pac(pr_ctx, pr_ctx->pac_ctx->range_map, my_dom_sid,
+ ret = get_gids_from_pac(pr_ctx, my_range_map, my_dom_sid,
pr_ctx->logon_info, &pr_ctx->gid_count,
&pr_ctx->gids);
if (ret != EOK) {
diff --git a/src/responder/pac/pacsrv_utils.c b/src/responder/pac/pacsrv_utils.c
index 43d84121..d4df5b16 100644
--- a/src/responder/pac/pacsrv_utils.c
+++ b/src/responder/pac/pacsrv_utils.c
@@ -81,13 +81,48 @@ errno_t add_idmap_domain(struct sss_idmap_ctx *idmap_ctx,
const char *domain_name,
const char *dom_sid_str)
{
- struct sss_idmap_range range;
+ struct sss_idmap_range range = {0, 0};
enum idmap_error_code err;
+ TALLOC_CTX *tmp_ctx = NULL;
+ size_t range_count;
+ struct range_info **range_list;
+ size_t c;
+ int ret;
+
+ if (domain_name == NULL || dom_sid_str == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Missing domain name or SID.\n"));
+ return EINVAL;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n"));
+ return ENOMEM;
+ }
+
+ ret = sysdb_get_ranges(tmp_ctx, sysdb, &range_count, &range_list);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_get_ranges failed.\n"));
+ goto done;
+ }
- /* TODO: read range form sysdb if
- * https://fedorahosted.org/freeipa/ticket/2185 is fixed */
- range.min = 200000;
- range.max = 400000;
+ for (c = 0; c < range_count; c++) {
+ if (range_list[c]->trusted_dom_sid != NULL &&
+ strcmp(range_list[c]->trusted_dom_sid, dom_sid_str) == 0) {
+ range.min = range_list[c]->base_id;
+ range.max = range_list[c]->base_id +
+ range_list[c]->id_range_size - 1;
+ /* TODO: add support for multiple ranges. */
+ break;
+ }
+ }
+
+ if (range.min == 0 && range.max == 0) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Failed to find mapping range for domain "
+ "[%s][%s].\n", domain_name, dom_sid_str));
+ ret = ENOENT;
+ goto done;
+ }
err = sss_idmap_add_domain(idmap_ctx, domain_name, dom_sid_str, &range);
if (err != IDMAP_SUCCESS) {
@@ -95,7 +130,11 @@ errno_t add_idmap_domain(struct sss_idmap_ctx *idmap_ctx,
return EFAULT;
}
- return EOK;
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
}
/**
@@ -171,9 +210,10 @@ done:
* Return information about the local domain from the main PAC responder
* context or try to read it from cache and store it in the context.
*/
-errno_t get_my_domain_sid(struct pac_ctx *pac_ctx,
- struct sss_domain_info *dom,
- struct dom_sid **_sid)
+errno_t get_my_domain_data(struct pac_ctx *pac_ctx,
+ struct sss_domain_info *dom,
+ struct dom_sid **_sid,
+ struct local_mapping_ranges **_range_map)
{
struct sysdb_ctx *sysdb;
int ret;
@@ -187,8 +227,12 @@ errno_t get_my_domain_sid(struct pac_ctx *pac_ctx,
struct dom_sid *sid = NULL;
char *dom_name;
enum idmap_error_code err;
+ size_t range_count;
+ struct range_info **range_list;
+ struct local_mapping_ranges *r_map = NULL;
+ size_t c;
- if (pac_ctx->my_dom_sid == NULL) {
+ if (pac_ctx->my_dom_sid == NULL || pac_ctx->range_map == NULL) {
if (dom->parent != NULL) {
sysdb = dom->parent->sysdb;
dom_name = dom->parent->name;
@@ -216,44 +260,92 @@ errno_t get_my_domain_sid(struct pac_ctx *pac_ctx,
goto done;
}
- ret = sysdb_search_entry(tmp_ctx, sysdb, basedn, LDB_SCOPE_BASE, NULL,
- attrs, &msgs_count, &msgs);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto done;
- }
+ if (pac_ctx->my_dom_sid == NULL) {
+ ret = sysdb_search_entry(tmp_ctx, sysdb, basedn, LDB_SCOPE_BASE, NULL,
+ attrs, &msgs_count, &msgs);
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
- if (msgs_count != 1) {
- DEBUG(SSSDBG_OP_FAILURE, ("Base search returned [%d] results, "
- "expected 1.\n", msgs_count));
- ret = EINVAL;
- goto done;
- }
+ if (msgs_count != 1) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Base search returned [%d] results, "
+ "expected 1.\n", msgs_count));
+ ret = EINVAL;
+ goto done;
+ }
- sid_str = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUBDOMAIN_ID, NULL);
- if (sid_str == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, ("SID of my domain is not available.\n"));
- ret = EINVAL;
- goto done;
- }
+ sid_str = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUBDOMAIN_ID, NULL);
+ if (sid_str == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("SID of my domain is not available.\n"));
+ ret = EINVAL;
+ goto done;
+ }
- err = sss_idmap_sid_to_smb_sid(pac_ctx->idmap_ctx, sid_str, &sid);
- if (err != IDMAP_SUCCESS) {
- DEBUG(SSSDBG_OP_FAILURE, ("sss_idmap_sid_to_smb_sid failed.\n"));
- ret = EFAULT;
- goto done;
- }
+ err = sss_idmap_sid_to_smb_sid(pac_ctx->idmap_ctx, sid_str, &sid);
+ if (err != IDMAP_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sss_idmap_sid_to_smb_sid failed.\n"));
+ ret = EFAULT;
+ goto done;
+ }
- pac_ctx->my_dom_sid = talloc_memdup(pac_ctx, sid,
- sizeof(struct dom_sid));
- if (pac_ctx->my_dom_sid == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, ("talloc_memdup failed.\n"));
- ret = ENOMEM;
- goto done;
+ pac_ctx->my_dom_sid = talloc_memdup(pac_ctx, sid,
+ sizeof(struct dom_sid));
+ if (pac_ctx->my_dom_sid == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_memdup failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
}
+
+ if (pac_ctx->range_map == NULL) {
+ ret = sysdb_get_ranges(tmp_ctx, sysdb, &range_count, &range_list);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_get_ranges failed.\n"));
+ goto done;
+ }
+
+ for (c = 0; c < range_count; c++) {
+ if (range_list[c]->trusted_dom_sid == NULL &&
+ range_list[c]->secondary_base_rid != 0) {
+ r_map = talloc_zero(pac_ctx,
+ struct local_mapping_ranges);
+ if (r_map == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_zero failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ r_map->local_ids.min = range_list[c]->base_id;
+ r_map->local_ids.max = range_list[c]->base_id +
+ range_list[c]->id_range_size - 1;
+
+ r_map->primary_rids.min = range_list[c]->base_rid;
+ r_map->primary_rids.max = range_list[c]->base_rid +
+ range_list[c]->id_range_size - 1;
+
+ r_map->secondary_rids.min = range_list[c]->secondary_base_rid;
+ r_map->secondary_rids.max = range_list[c]->secondary_base_rid +
+ range_list[c]->id_range_size - 1;
+
+ /* TODO: add support for multiple ranges. */
+ break;
+ }
+ }
+
+ if (r_map == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Failed to find local id map.\n"));
+ ret = ENOENT;
+ goto done;
+ }
+
+ pac_ctx->range_map = r_map;
+ }
+
}
*_sid = pac_ctx->my_dom_sid;
+ *_range_map = pac_ctx->range_map;
ret = EOK;