1538 lines
56 KiB
Diff
1538 lines
56 KiB
Diff
|
From bb102c5afac8fef00487d5db4dc148927ab8e29d Mon Sep 17 00:00:00 2001
|
||
|
From: Pavel Reichl <preichl@redhat.com>
|
||
|
Date: Fri, 27 Nov 2015 04:15:00 -0500
|
||
|
Subject: [PATCH 50/55] IDMAP: Add support for automatic adding of ranges
|
||
|
|
||
|
Resolves:
|
||
|
https://fedorahosted.org/sssd/ticket/2188
|
||
|
|
||
|
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||
|
(cherry picked from commit 8babbeee01e67893af4828ddfc922ecac0be4197)
|
||
|
---
|
||
|
Makefile.am | 2 +-
|
||
|
src/config/SSSDConfig/__init__.py.in | 1 +
|
||
|
src/config/etc/sssd.api.d/sssd-ad.conf | 1 +
|
||
|
src/config/etc/sssd.api.d/sssd-ipa.conf | 1 +
|
||
|
src/config/etc/sssd.api.d/sssd-ldap.conf | 1 +
|
||
|
src/lib/idmap/sss_idmap.c | 526 ++++++++++++++++++++++++++++---
|
||
|
src/lib/idmap/sss_idmap.exports | 10 +
|
||
|
src/lib/idmap/sss_idmap.h | 65 ++++
|
||
|
src/lib/idmap/sss_idmap_private.h | 4 +
|
||
|
src/man/include/ldap_id_mapping.xml | 20 ++
|
||
|
src/providers/ad/ad_opts.c | 1 +
|
||
|
src/providers/ipa/ipa_opts.c | 1 +
|
||
|
src/providers/ldap/ldap_opts.c | 1 +
|
||
|
src/providers/ldap/sdap.h | 1 +
|
||
|
src/providers/ldap/sdap_idmap.c | 16 +-
|
||
|
src/tests/cmocka/test_sss_idmap.c | 87 ++++-
|
||
|
src/tests/sss_idmap-tests.c | 332 +++++++++++++++++++
|
||
|
17 files changed, 1007 insertions(+), 63 deletions(-)
|
||
|
|
||
|
diff --git a/Makefile.am b/Makefile.am
|
||
|
index a9099c07fcfe54a88bd56129364dde5262e901ed..22653cfe08ca1fa42f551bdd585868a7e56046ba 100644
|
||
|
--- a/Makefile.am
|
||
|
+++ b/Makefile.am
|
||
|
@@ -960,7 +960,7 @@ libsss_idmap_la_SOURCES = \
|
||
|
src/util/murmurhash3.c
|
||
|
libsss_idmap_la_LDFLAGS = \
|
||
|
-Wl,--version-script,$(srcdir)/src/lib/idmap/sss_idmap.exports \
|
||
|
- -version-info 4:0:4
|
||
|
+ -version-info 5:0:5
|
||
|
|
||
|
dist_noinst_DATA += src/lib/idmap/sss_idmap.exports
|
||
|
|
||
|
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
|
||
|
index b4a6fcb0d37469e1dda85eda95fd80825697902c..6abdbc3a43cd4dbd74208efa8602b889f6e84d2b 100644
|
||
|
--- a/src/config/SSSDConfig/__init__.py.in
|
||
|
+++ b/src/config/SSSDConfig/__init__.py.in
|
||
|
@@ -355,6 +355,7 @@ option_strings = {
|
||
|
'ldap_idmap_autorid_compat' : _('Use autorid-compatible algorithm for ID-mapping'),
|
||
|
'ldap_idmap_default_domain' : _('Name of the default domain for ID-mapping'),
|
||
|
'ldap_idmap_default_domain_sid' : _('SID of the default domain for ID-mapping'),
|
||
|
+ 'ldap_idmap_helper_table_size' : _('Number of secondary slices'),
|
||
|
|
||
|
'ldap_groups_use_matching_rule_in_chain' : _('Use LDAP_MATCHING_RULE_IN_CHAIN for group lookups'),
|
||
|
'ldap_initgroups_use_matching_rule_in_chain' : _('Use LDAP_MATCHING_RULE_IN_CHAIN for initgroup lookups'),
|
||
|
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
|
||
|
index 0ea73d14112d1c7cf7a6d4cbda0d2b2e53a3a7be..149590f4f30de3438f2fc5534ae65c98ee0f10ad 100644
|
||
|
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
|
||
|
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
|
||
|
@@ -125,6 +125,7 @@ ldap_idmap_range_size = int, None, false
|
||
|
ldap_idmap_autorid_compat = bool, None, false
|
||
|
ldap_idmap_default_domain = str, None, false
|
||
|
ldap_idmap_default_domain_sid = str, None, false
|
||
|
+ldap_idmap_helper_table_size = int, None, false
|
||
|
ldap_groups_use_matching_rule_in_chain = bool, None, false
|
||
|
ldap_initgroups_use_matching_rule_in_chain = bool, None, false
|
||
|
ldap_use_tokengroups = bool, None, false
|
||
|
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
|
||
|
index 13715ec34666f2dbc66df037565b495b9df42511..822599db6390ad2244a71db770c0b162345a3321 100644
|
||
|
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
|
||
|
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
|
||
|
@@ -131,6 +131,7 @@ ldap_idmap_range_size = int, None, false
|
||
|
ldap_idmap_autorid_compat = bool, None, false
|
||
|
ldap_idmap_default_domain = str, None, false
|
||
|
ldap_idmap_default_domain_sid = str, None, false
|
||
|
+ldap_idmap_helper_table_size = int, None, false
|
||
|
ldap_groups_use_matching_rule_in_chain = bool, None, false
|
||
|
ldap_initgroups_use_matching_rule_in_chain = bool, None, false
|
||
|
ldap_use_tokengroups = bool, None, false
|
||
|
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
|
||
|
index 8fd45fd4093714f458161eb352157c845d926f06..fc9fcefce94891760a3f3ada4c044dbcaf156945 100644
|
||
|
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
|
||
|
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
|
||
|
@@ -118,6 +118,7 @@ ldap_idmap_range_size = int, None, false
|
||
|
ldap_idmap_autorid_compat = bool, None, false
|
||
|
ldap_idmap_default_domain = str, None, false
|
||
|
ldap_idmap_default_domain_sid = str, None, false
|
||
|
+ldap_idmap_helper_table_size = int, None, false
|
||
|
ldap_groups_use_matching_rule_in_chain = bool, None, false
|
||
|
ldap_initgroups_use_matching_rule_in_chain = bool, None, false
|
||
|
ldap_use_tokengroups = bool, None, false
|
||
|
diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
|
||
|
index 23ed46a583547a3f2f0bca5ab62824bd045e56b9..269ef0132ff3b9ffbfbe65006361fac6d4f88cf9 100644
|
||
|
--- a/src/lib/idmap/sss_idmap.c
|
||
|
+++ b/src/lib/idmap/sss_idmap.c
|
||
|
@@ -25,6 +25,7 @@
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
#include <errno.h>
|
||
|
+#include <inttypes.h>
|
||
|
|
||
|
#include "lib/idmap/sss_idmap.h"
|
||
|
#include "lib/idmap/sss_idmap_private.h"
|
||
|
@@ -41,6 +42,7 @@ struct idmap_range_params {
|
||
|
char *range_id;
|
||
|
|
||
|
uint32_t first_rid;
|
||
|
+ struct idmap_range_params *next;
|
||
|
};
|
||
|
|
||
|
struct idmap_domain_info {
|
||
|
@@ -49,6 +51,13 @@ struct idmap_domain_info {
|
||
|
struct idmap_range_params range_params;
|
||
|
struct idmap_domain_info *next;
|
||
|
bool external_mapping;
|
||
|
+
|
||
|
+ struct idmap_range_params *helpers;
|
||
|
+ bool auto_add_ranges;
|
||
|
+ bool helpers_owner;
|
||
|
+
|
||
|
+ idmap_store_cb cb;
|
||
|
+ void *pvt;
|
||
|
};
|
||
|
|
||
|
static void *default_alloc(size_t size, void *pvt)
|
||
|
@@ -195,12 +204,34 @@ enum idmap_error_code sss_idmap_init(idmap_alloc_func *alloc_func,
|
||
|
ctx->idmap_opts.idmap_lower = SSS_IDMAP_DEFAULT_LOWER;
|
||
|
ctx->idmap_opts.idmap_upper = SSS_IDMAP_DEFAULT_UPPER;
|
||
|
ctx->idmap_opts.rangesize = SSS_IDMAP_DEFAULT_RANGESIZE;
|
||
|
+ ctx->idmap_opts.extra_slice_init = SSS_IDMAP_DEFAULT_EXTRA_SLICE_INIT;
|
||
|
|
||
|
*_ctx = ctx;
|
||
|
|
||
|
return IDMAP_SUCCESS;
|
||
|
}
|
||
|
|
||
|
+static void free_helpers(struct sss_idmap_ctx *ctx,
|
||
|
+ struct idmap_range_params *helpers,
|
||
|
+ bool helpers_owner)
|
||
|
+{
|
||
|
+ struct idmap_range_params *it = helpers;
|
||
|
+ struct idmap_range_params *tmp;
|
||
|
+
|
||
|
+ if (helpers_owner == false) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ while (it != NULL) {
|
||
|
+ tmp = it->next;
|
||
|
+
|
||
|
+ ctx->free_func(it->range_id, ctx->alloc_pvt);
|
||
|
+ ctx->free_func(it, ctx->alloc_pvt);
|
||
|
+
|
||
|
+ it = tmp;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
static void sss_idmap_free_domain(struct sss_idmap_ctx *ctx,
|
||
|
struct idmap_domain_info *dom)
|
||
|
{
|
||
|
@@ -209,6 +240,9 @@ static void sss_idmap_free_domain(struct sss_idmap_ctx *ctx,
|
||
|
}
|
||
|
|
||
|
ctx->free_func(dom->range_params.range_id, ctx->alloc_pvt);
|
||
|
+
|
||
|
+ free_helpers(ctx, dom->helpers, dom->helpers_owner);
|
||
|
+
|
||
|
ctx->free_func(dom->name, ctx->alloc_pvt);
|
||
|
ctx->free_func(dom->sid, ctx->alloc_pvt);
|
||
|
ctx->free_func(dom, ctx->alloc_pvt);
|
||
|
@@ -269,6 +303,22 @@ enum idmap_error_code sss_idmap_free_bin_sid(struct sss_idmap_ctx *ctx,
|
||
|
return sss_idmap_free_ptr(ctx, bin_sid);
|
||
|
}
|
||
|
|
||
|
+static bool check_overlap(struct idmap_range_params *range,
|
||
|
+ id_t min, id_t max)
|
||
|
+{
|
||
|
+ return ((range->min_id <= min && range->max_id >= max)
|
||
|
+ || (range->min_id >= min && range->min_id <= max)
|
||
|
+ || (range->max_id >= min && range->max_id <= max));
|
||
|
+}
|
||
|
+
|
||
|
+static bool check_dom_overlap(struct idmap_range_params *prim_range,
|
||
|
+ /* struct idmap_range_params *sec_ranges, */
|
||
|
+ id_t min,
|
||
|
+ id_t max)
|
||
|
+{
|
||
|
+ return check_overlap(prim_range, min, max);
|
||
|
+}
|
||
|
+
|
||
|
enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
|
||
|
const char *dom_sid,
|
||
|
id_t *slice_num,
|
||
|
@@ -327,12 +377,9 @@ enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
|
||
|
/* Verify that this slice is not already in use */
|
||
|
do {
|
||
|
for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) {
|
||
|
- uint32_t dmin = dom->range_params.min_id;
|
||
|
- uint32_t dmax = dom->range_params.max_id;
|
||
|
|
||
|
- if ((dmin <= min && dmax >= max) ||
|
||
|
- (dmin >= min && dmin <= max) ||
|
||
|
- (dmax >= min && dmax <= max)) {
|
||
|
+ if (check_dom_overlap(&dom->range_params,
|
||
|
+ min, max)) {
|
||
|
/* This range overlaps one already registered
|
||
|
* We'll try the next available slot
|
||
|
*/
|
||
|
@@ -487,6 +534,105 @@ idmap_error_code dom_check_collision(struct idmap_domain_info *dom_list,
|
||
|
return IDMAP_SUCCESS;
|
||
|
}
|
||
|
|
||
|
+static char*
|
||
|
+generate_sec_slice_name(struct sss_idmap_ctx *ctx,
|
||
|
+ const char *domain_name, uint32_t rid)
|
||
|
+{
|
||
|
+ const char *SEC_SLICE_NAME_FMT = "%s-%"PRIu32;
|
||
|
+ char *slice_name;
|
||
|
+ int len, len2;
|
||
|
+
|
||
|
+ len = snprintf(NULL, 0, SEC_SLICE_NAME_FMT, domain_name, rid);
|
||
|
+ if (len <= 0) {
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ slice_name = ctx->alloc_func(len + 1, ctx->alloc_pvt);
|
||
|
+ if (slice_name == NULL) {
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ len2 = snprintf(slice_name, len + 1, SEC_SLICE_NAME_FMT, domain_name,
|
||
|
+ rid);
|
||
|
+ if (len != len2) {
|
||
|
+ ctx->free_func(slice_name, ctx->alloc_pvt);
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ return slice_name;
|
||
|
+}
|
||
|
+
|
||
|
+static enum idmap_error_code
|
||
|
+generate_slice(struct sss_idmap_ctx *ctx, char *slice_name, uint32_t first_rid,
|
||
|
+ struct idmap_range_params **_slice)
|
||
|
+{
|
||
|
+ struct idmap_range_params *slice;
|
||
|
+ struct sss_idmap_range tmp_range;
|
||
|
+ enum idmap_error_code err;
|
||
|
+
|
||
|
+ slice = ctx->alloc_func(sizeof(struct idmap_range_params), ctx->alloc_pvt);
|
||
|
+ if (slice == NULL) {
|
||
|
+ return IDMAP_OUT_OF_MEMORY;
|
||
|
+ }
|
||
|
+
|
||
|
+ slice->next = NULL;
|
||
|
+
|
||
|
+ err = sss_idmap_calculate_range(ctx, slice_name, NULL, &tmp_range);
|
||
|
+ if (err != IDMAP_SUCCESS) {
|
||
|
+ ctx->free_func(slice, ctx->alloc_pvt);
|
||
|
+ return err;
|
||
|
+ }
|
||
|
+
|
||
|
+ slice->min_id = tmp_range.min;
|
||
|
+ slice->max_id = tmp_range.max;
|
||
|
+ slice->range_id = slice_name;
|
||
|
+ slice->first_rid = first_rid;
|
||
|
+
|
||
|
+ *_slice = slice;
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
+}
|
||
|
+
|
||
|
+static enum idmap_error_code
|
||
|
+get_helpers(struct sss_idmap_ctx *ctx,
|
||
|
+ const char *domain_sid,
|
||
|
+ uint32_t first_rid,
|
||
|
+ struct idmap_range_params **_sec_slices)
|
||
|
+{
|
||
|
+ struct idmap_range_params *prev = NULL;
|
||
|
+ struct idmap_range_params *sec_slices = NULL;
|
||
|
+ static enum idmap_error_code err;
|
||
|
+ struct idmap_range_params *slice;
|
||
|
+ char *secondary_name;
|
||
|
+
|
||
|
+ for (int i = 0; i < ctx->idmap_opts.extra_slice_init; i++) {
|
||
|
+ secondary_name = generate_sec_slice_name(ctx, domain_sid, first_rid);
|
||
|
+ if (secondary_name == NULL) {
|
||
|
+ return IDMAP_OUT_OF_MEMORY;
|
||
|
+ }
|
||
|
+
|
||
|
+ err = generate_slice(ctx, secondary_name, first_rid, &slice);
|
||
|
+ if (err != IDMAP_SUCCESS) {
|
||
|
+ ctx->free_func(secondary_name, ctx->alloc_pvt);
|
||
|
+ return err;
|
||
|
+ }
|
||
|
+
|
||
|
+ first_rid += ctx->idmap_opts.rangesize;
|
||
|
+
|
||
|
+ if (prev != NULL) {
|
||
|
+ prev->next = slice;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (sec_slices == NULL) {
|
||
|
+ sec_slices = slice;
|
||
|
+ }
|
||
|
+
|
||
|
+ prev = slice;
|
||
|
+ }
|
||
|
+
|
||
|
+ *_sec_slices = sec_slices;
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
+}
|
||
|
+
|
||
|
enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx,
|
||
|
const char *domain_name,
|
||
|
const char *domain_sid,
|
||
|
@@ -567,6 +713,67 @@ fail:
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
+enum idmap_error_code
|
||
|
+sss_idmap_add_auto_domain_ex(struct sss_idmap_ctx *ctx,
|
||
|
+ const char *domain_name,
|
||
|
+ const char *domain_sid,
|
||
|
+ struct sss_idmap_range *range,
|
||
|
+ const char *range_id,
|
||
|
+ uint32_t rid,
|
||
|
+ bool external_mapping,
|
||
|
+ idmap_store_cb cb,
|
||
|
+ void *pvt)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+
|
||
|
+ err = sss_idmap_add_domain_ex(ctx, domain_name, domain_sid, range,
|
||
|
+ range_id, rid, external_mapping);
|
||
|
+ if (err != IDMAP_SUCCESS) {
|
||
|
+ return err;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (external_mapping) {
|
||
|
+ /* There's no point in generating secondary ranges if external_mapping
|
||
|
+ is enabled. */
|
||
|
+ ctx->idmap_domain_info->auto_add_ranges = false;
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((range->max - range->min + 1) != ctx->idmap_opts.rangesize) {
|
||
|
+ /* Range of primary slice is not equal to the value of
|
||
|
+ ldap_idmap_range_size option. */
|
||
|
+ return IDMAP_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* No additional secondary ranges should be added if no sec ranges are
|
||
|
+ predeclared. */
|
||
|
+ if (ctx->idmap_opts.extra_slice_init == 0) {
|
||
|
+ ctx->idmap_domain_info->auto_add_ranges = false;
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Add size of primary slice for first_rid of secondary slices. */
|
||
|
+ rid += ctx->idmap_opts.rangesize;
|
||
|
+ err = get_helpers(ctx, domain_sid, rid,
|
||
|
+ &ctx->idmap_domain_info->helpers);
|
||
|
+ if (err == IDMAP_SUCCESS) {
|
||
|
+ ctx->idmap_domain_info->auto_add_ranges = true;
|
||
|
+ ctx->idmap_domain_info->helpers_owner = true;
|
||
|
+ } else {
|
||
|
+ /* Running out of slices for secondary mapping is a non-fatal
|
||
|
+ * problem. */
|
||
|
+ if (err == IDMAP_OUT_OF_SLICES) {
|
||
|
+ err = IDMAP_SUCCESS;
|
||
|
+ }
|
||
|
+ ctx->idmap_domain_info->auto_add_ranges = false;
|
||
|
+ }
|
||
|
+
|
||
|
+ ctx->idmap_domain_info->cb = cb;
|
||
|
+ ctx->idmap_domain_info->pvt = pvt;
|
||
|
+
|
||
|
+ return err;
|
||
|
+}
|
||
|
+
|
||
|
enum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx,
|
||
|
const char *domain_name,
|
||
|
const char *domain_sid,
|
||
|
@@ -585,16 +792,198 @@ static bool sss_idmap_sid_is_builtin(const char *sid)
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
+static bool parse_rid(const char *sid, size_t dom_prefix_len, long long *_rid)
|
||
|
+{
|
||
|
+ long long rid;
|
||
|
+ char *endptr;
|
||
|
+
|
||
|
+ errno = 0;
|
||
|
+ /* Use suffix of sid - part after domain and following '-' */
|
||
|
+ rid = strtoull(sid + dom_prefix_len + 1, &endptr, 10);
|
||
|
+ if (errno != 0 || rid > UINT32_MAX || *endptr != '\0') {
|
||
|
+ return false;
|
||
|
+ }
|
||
|
+
|
||
|
+ *_rid = rid;
|
||
|
+ return true;
|
||
|
+}
|
||
|
+
|
||
|
+static bool is_sid_from_dom(const char *dom_sid, const char *sid,
|
||
|
+ size_t *_dom_sid_len)
|
||
|
+{
|
||
|
+ size_t dom_sid_len;
|
||
|
+
|
||
|
+ if (dom_sid == NULL) {
|
||
|
+ return false;
|
||
|
+ }
|
||
|
+
|
||
|
+ dom_sid_len = strlen(dom_sid);
|
||
|
+ *_dom_sid_len = dom_sid_len;
|
||
|
+
|
||
|
+ if (strlen(sid) < dom_sid_len || sid[dom_sid_len] != '-') {
|
||
|
+ return false;
|
||
|
+ }
|
||
|
+
|
||
|
+ return strncmp(sid, dom_sid, dom_sid_len) == 0;
|
||
|
+}
|
||
|
+
|
||
|
+static bool comp_id(struct idmap_range_params *range_params, long long rid,
|
||
|
+ uint32_t *_id)
|
||
|
+{
|
||
|
+ uint32_t id;
|
||
|
+
|
||
|
+ if (rid >= range_params->first_rid
|
||
|
+ && ((UINT32_MAX - range_params->min_id) >
|
||
|
+ (rid - range_params->first_rid))) {
|
||
|
+ id = range_params->min_id + (rid - range_params->first_rid);
|
||
|
+ if (id <= range_params->max_id) {
|
||
|
+ *_id = id;
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ return false;
|
||
|
+}
|
||
|
+
|
||
|
+static enum idmap_error_code
|
||
|
+get_range(struct sss_idmap_ctx *ctx,
|
||
|
+ const char *dom_sid,
|
||
|
+ long long rid,
|
||
|
+ struct idmap_range_params **_range)
|
||
|
+{
|
||
|
+ char *secondary_name;
|
||
|
+ enum idmap_error_code err;
|
||
|
+ int first_rid;
|
||
|
+ struct idmap_range_params *range;
|
||
|
+
|
||
|
+ first_rid = (rid / ctx->idmap_opts.rangesize) * ctx->idmap_opts.rangesize;
|
||
|
+
|
||
|
+ secondary_name = generate_sec_slice_name(ctx, dom_sid, first_rid);
|
||
|
+ if (secondary_name == NULL) {
|
||
|
+ return IDMAP_OUT_OF_MEMORY;
|
||
|
+ }
|
||
|
+
|
||
|
+ err = generate_slice(ctx, secondary_name, first_rid, &range);
|
||
|
+ if (err == IDMAP_OUT_OF_SLICES) {
|
||
|
+ ctx->free_func(secondary_name, ctx->alloc_pvt);
|
||
|
+ return err;
|
||
|
+ }
|
||
|
+
|
||
|
+ *_range = range;
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
+}
|
||
|
+
|
||
|
+static enum idmap_error_code
|
||
|
+spawn_dom(struct sss_idmap_ctx *ctx,
|
||
|
+ struct idmap_domain_info *parent,
|
||
|
+ struct idmap_range_params *range)
|
||
|
+{
|
||
|
+ struct sss_idmap_range tmp;
|
||
|
+ static enum idmap_error_code err;
|
||
|
+ struct idmap_domain_info *it;
|
||
|
+
|
||
|
+ tmp.min = range->min_id;
|
||
|
+ tmp.max = range->max_id;
|
||
|
+
|
||
|
+ err = sss_idmap_add_domain_ex(ctx,
|
||
|
+ parent->name,
|
||
|
+ parent->sid,
|
||
|
+ &tmp, range->range_id,
|
||
|
+ range->first_rid, false);
|
||
|
+ if (err != IDMAP_SUCCESS) {
|
||
|
+ return err;
|
||
|
+ }
|
||
|
+
|
||
|
+ it = ctx->idmap_domain_info;
|
||
|
+ while (it != NULL) {
|
||
|
+ /* Find the newly added domain. */
|
||
|
+ if (it->range_params.first_rid == range->first_rid
|
||
|
+ && it->range_params.min_id == range->min_id
|
||
|
+ && it->range_params.max_id == range->max_id) {
|
||
|
+
|
||
|
+ /* Share helpers. */
|
||
|
+ it->helpers = parent->helpers;
|
||
|
+ it->auto_add_ranges = parent->auto_add_ranges;
|
||
|
+
|
||
|
+ /* Share call back for storing domains */
|
||
|
+ it->cb = parent->cb;
|
||
|
+ it->pvt = parent->pvt;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ it = it->next;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (it == NULL) {
|
||
|
+ /* Failed to find just added domain. */
|
||
|
+ return IDMAP_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Store mapping for newly created domain. */
|
||
|
+ if (it->cb != NULL) {
|
||
|
+ err = it->cb(it->name,
|
||
|
+ it->sid,
|
||
|
+ it->range_params.range_id,
|
||
|
+ it->range_params.min_id,
|
||
|
+ it->range_params.max_id,
|
||
|
+ it->range_params.first_rid,
|
||
|
+ it->pvt);
|
||
|
+ if (err != IDMAP_SUCCESS) {
|
||
|
+ return err;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
+}
|
||
|
+
|
||
|
+static enum idmap_error_code
|
||
|
+add_dom_for_sid(struct sss_idmap_ctx *ctx,
|
||
|
+ struct idmap_domain_info *matched_dom,
|
||
|
+ const char *sid,
|
||
|
+ uint32_t *_id)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ long long rid;
|
||
|
+ struct idmap_range_params *range = NULL;
|
||
|
+
|
||
|
+ if (parse_rid(sid, strlen(matched_dom->sid), &rid) == false) {
|
||
|
+ err = IDMAP_SID_INVALID;
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* todo optimize */
|
||
|
+ err = get_range(ctx, matched_dom->sid, rid, &range);
|
||
|
+ if (err != IDMAP_SUCCESS) {
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
+ err = spawn_dom(ctx, matched_dom, range);
|
||
|
+ if (err != IDMAP_SUCCESS) {
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!comp_id(range, rid, _id)) {
|
||
|
+ err = IDMAP_ERROR;
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
+ err = IDMAP_SUCCESS;
|
||
|
+
|
||
|
+done:
|
||
|
+ if (range != NULL) {
|
||
|
+ ctx->free_func(range->range_id, ctx->alloc_pvt);
|
||
|
+ }
|
||
|
+ ctx->free_func(range, ctx->alloc_pvt);
|
||
|
+ return err;
|
||
|
+}
|
||
|
+
|
||
|
enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx,
|
||
|
const char *sid,
|
||
|
uint32_t *_id)
|
||
|
{
|
||
|
struct idmap_domain_info *idmap_domain_info;
|
||
|
+ struct idmap_domain_info *matched_dom = NULL;
|
||
|
size_t dom_len;
|
||
|
long long rid;
|
||
|
- char *endptr;
|
||
|
- uint32_t id;
|
||
|
- bool no_range = false;
|
||
|
|
||
|
if (sid == NULL || _id == NULL) {
|
||
|
return IDMAP_ERROR;
|
||
|
@@ -608,39 +997,34 @@ enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx,
|
||
|
return IDMAP_BUILTIN_SID;
|
||
|
}
|
||
|
|
||
|
+ /* Try primary slices */
|
||
|
while (idmap_domain_info != NULL) {
|
||
|
- if (idmap_domain_info->sid != NULL) {
|
||
|
- dom_len = strlen(idmap_domain_info->sid);
|
||
|
- if (strlen(sid) > dom_len && sid[dom_len] == '-'
|
||
|
- && strncmp(sid, idmap_domain_info->sid, dom_len) == 0) {
|
||
|
|
||
|
- if (idmap_domain_info->external_mapping == true) {
|
||
|
- return IDMAP_EXTERNAL;
|
||
|
- }
|
||
|
+ if (is_sid_from_dom(idmap_domain_info->sid, sid, &dom_len)) {
|
||
|
|
||
|
- errno = 0;
|
||
|
- rid = strtoull(sid + dom_len + 1, &endptr, 10);
|
||
|
- if (errno != 0 || rid > UINT32_MAX || *endptr != '\0') {
|
||
|
- return IDMAP_SID_INVALID;
|
||
|
- }
|
||
|
+ if (idmap_domain_info->external_mapping == true) {
|
||
|
+ return IDMAP_EXTERNAL;
|
||
|
+ }
|
||
|
|
||
|
- if (rid >= idmap_domain_info->range_params.first_rid) {
|
||
|
- id = idmap_domain_info->range_params.min_id
|
||
|
- + (rid - idmap_domain_info->range_params.first_rid);
|
||
|
- if (id <= idmap_domain_info->range_params.max_id) {
|
||
|
- *_id = id;
|
||
|
- return IDMAP_SUCCESS;
|
||
|
- }
|
||
|
- }
|
||
|
+ if (parse_rid(sid, dom_len, &rid) == false) {
|
||
|
+ return IDMAP_SID_INVALID;
|
||
|
+ }
|
||
|
|
||
|
- no_range = true;
|
||
|
+ if (comp_id(&idmap_domain_info->range_params, rid, _id)) {
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
}
|
||
|
+
|
||
|
+ matched_dom = idmap_domain_info;
|
||
|
}
|
||
|
|
||
|
idmap_domain_info = idmap_domain_info->next;
|
||
|
}
|
||
|
|
||
|
- return no_range ? IDMAP_NO_RANGE : IDMAP_NO_DOMAIN;
|
||
|
+ if (matched_dom != NULL && matched_dom->auto_add_ranges) {
|
||
|
+ return add_dom_for_sid(ctx, matched_dom, sid, _id);
|
||
|
+ }
|
||
|
+
|
||
|
+ return matched_dom ? IDMAP_NO_RANGE : IDMAP_NO_DOMAIN;
|
||
|
}
|
||
|
|
||
|
enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx,
|
||
|
@@ -688,15 +1072,42 @@ enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx,
|
||
|
return no_range ? IDMAP_NO_RANGE : IDMAP_SID_UNKNOWN;
|
||
|
}
|
||
|
|
||
|
+static enum idmap_error_code generate_sid(struct sss_idmap_ctx *ctx,
|
||
|
+ const char *dom_sid,
|
||
|
+ uint32_t rid,
|
||
|
+ char **_sid)
|
||
|
+{
|
||
|
+ char *sid;
|
||
|
+ int len;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ len = snprintf(NULL, 0, SID_FMT, dom_sid, rid);
|
||
|
+ if (len <= 0 || len > SID_STR_MAX_LEN) {
|
||
|
+ return IDMAP_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ sid = ctx->alloc_func(len + 1, ctx->alloc_pvt);
|
||
|
+ if (sid == NULL) {
|
||
|
+ return IDMAP_OUT_OF_MEMORY;
|
||
|
+ }
|
||
|
+
|
||
|
+ ret = snprintf(sid, len + 1, SID_FMT, dom_sid, rid);
|
||
|
+ if (ret != len) {
|
||
|
+ ctx->free_func(sid, ctx->alloc_pvt);
|
||
|
+ return IDMAP_ERROR;
|
||
|
+ }
|
||
|
+
|
||
|
+ *_sid = sid;
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
+}
|
||
|
+
|
||
|
enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx,
|
||
|
uint32_t id,
|
||
|
char **_sid)
|
||
|
{
|
||
|
struct idmap_domain_info *idmap_domain_info;
|
||
|
- int len;
|
||
|
- int ret;
|
||
|
uint32_t rid;
|
||
|
- char *sid = NULL;
|
||
|
+ enum idmap_error_code err;
|
||
|
|
||
|
CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
|
||
|
|
||
|
@@ -710,24 +1121,34 @@ enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx,
|
||
|
return IDMAP_EXTERNAL;
|
||
|
}
|
||
|
|
||
|
- len = snprintf(NULL, 0, SID_FMT, idmap_domain_info->sid, rid);
|
||
|
- if (len <= 0 || len > SID_STR_MAX_LEN) {
|
||
|
- return IDMAP_ERROR;
|
||
|
- }
|
||
|
+ return generate_sid(ctx, idmap_domain_info->sid, rid, _sid);
|
||
|
+ }
|
||
|
|
||
|
- sid = ctx->alloc_func(len + 1, ctx->alloc_pvt);
|
||
|
- if (sid == NULL) {
|
||
|
- return IDMAP_OUT_OF_MEMORY;
|
||
|
- }
|
||
|
+ idmap_domain_info = idmap_domain_info->next;
|
||
|
+ }
|
||
|
|
||
|
- ret = snprintf(sid, len + 1, SID_FMT, idmap_domain_info->sid, rid);
|
||
|
- if (ret != len) {
|
||
|
- ctx->free_func(sid, ctx->alloc_pvt);
|
||
|
- return IDMAP_ERROR;
|
||
|
- }
|
||
|
+ /* Check secondary ranges. */
|
||
|
+ idmap_domain_info = ctx->idmap_domain_info;
|
||
|
+ while (idmap_domain_info != NULL) {
|
||
|
+
|
||
|
+ for (struct idmap_range_params *it = idmap_domain_info->helpers;
|
||
|
+ it != NULL;
|
||
|
+ it = it->next) {
|
||
|
|
||
|
- *_sid = sid;
|
||
|
- return IDMAP_SUCCESS;
|
||
|
+ if (id_is_in_range(id, it, &rid)) {
|
||
|
+
|
||
|
+ if (idmap_domain_info->external_mapping == true
|
||
|
+ || idmap_domain_info->sid == NULL) {
|
||
|
+ return IDMAP_EXTERNAL;
|
||
|
+ }
|
||
|
+
|
||
|
+ err = spawn_dom(ctx, idmap_domain_info, it);
|
||
|
+ if (err != IDMAP_SUCCESS) {
|
||
|
+ return err;
|
||
|
+ }
|
||
|
+
|
||
|
+ return generate_sid(ctx, idmap_domain_info->sid, rid, _sid);
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
idmap_domain_info = idmap_domain_info->next;
|
||
|
@@ -970,6 +1391,15 @@ sss_idmap_ctx_set_rangesize(struct sss_idmap_ctx *ctx, id_t rangesize)
|
||
|
}
|
||
|
|
||
|
enum idmap_error_code
|
||
|
+sss_idmap_ctx_set_extra_slice_init(struct sss_idmap_ctx *ctx,
|
||
|
+ int extra_slice_init)
|
||
|
+{
|
||
|
+ CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
|
||
|
+ ctx->idmap_opts.extra_slice_init = extra_slice_init;
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
+}
|
||
|
+
|
||
|
+enum idmap_error_code
|
||
|
sss_idmap_ctx_get_autorid(struct sss_idmap_ctx *ctx, bool *_autorid)
|
||
|
{
|
||
|
CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
|
||
|
diff --git a/src/lib/idmap/sss_idmap.exports b/src/lib/idmap/sss_idmap.exports
|
||
|
index 52115636d5a6b936f18b4392e9d12adc26c85f53..f10feea6f880a6e02fdc354dce2044bcfae9b05c 100644
|
||
|
--- a/src/lib/idmap/sss_idmap.exports
|
||
|
+++ b/src/lib/idmap/sss_idmap.exports
|
||
|
@@ -54,3 +54,13 @@ SSS_IDMAP_0.4 {
|
||
|
local:
|
||
|
*;
|
||
|
};
|
||
|
+
|
||
|
+SSS_IDMAP_0.5 {
|
||
|
+
|
||
|
+ # public functions
|
||
|
+ global:
|
||
|
+
|
||
|
+ sss_idmap_ctx_set_extra_slice_init;
|
||
|
+ sss_idmap_add_auto_domain_ex;
|
||
|
+
|
||
|
+} SSS_IDMAP_0.4;
|
||
|
\ No newline at end of file
|
||
|
diff --git a/src/lib/idmap/sss_idmap.h b/src/lib/idmap/sss_idmap.h
|
||
|
index 0797083293f7e010962828ddcd72709b290859b9..483241eeafda7ac5952bbae41c442ba676a09483 100644
|
||
|
--- a/src/lib/idmap/sss_idmap.h
|
||
|
+++ b/src/lib/idmap/sss_idmap.h
|
||
|
@@ -94,6 +94,17 @@ typedef void *(idmap_alloc_func)(size_t size, void *pvt);
|
||
|
typedef void (idmap_free_func)(void *ptr, void *pvt);
|
||
|
|
||
|
/**
|
||
|
+ * Typedef for storing mappings of dynamically created domains
|
||
|
+ */
|
||
|
+typedef enum idmap_error_code (*idmap_store_cb)(const char *dom_name,
|
||
|
+ const char *dom_sid,
|
||
|
+ const char *range_id,
|
||
|
+ uint32_t min_id,
|
||
|
+ uint32_t max_id,
|
||
|
+ uint32_t first_rid,
|
||
|
+ void *pvt);
|
||
|
+
|
||
|
+/**
|
||
|
* Structure for id ranges
|
||
|
* FIXME: this struct might change when it is clear how ranges are handled on
|
||
|
* the server side
|
||
|
@@ -175,6 +186,17 @@ enum idmap_error_code
|
||
|
sss_idmap_ctx_set_rangesize(struct sss_idmap_ctx *ctx, id_t rangesize);
|
||
|
|
||
|
/**
|
||
|
+ * @brief Set the number of secondary slices available for domain
|
||
|
+ *
|
||
|
+ * @param[in] ctx idmap context
|
||
|
+ * @param[in] extra_slice_init number of secondary slices to be generated
|
||
|
+ * at startup
|
||
|
+ */
|
||
|
+enum idmap_error_code
|
||
|
+sss_idmap_ctx_set_extra_slice_init(struct sss_idmap_ctx *ctx,
|
||
|
+ int extra_slice_init);
|
||
|
+
|
||
|
+/**
|
||
|
* @brief Check if autorid compatibility mode is set
|
||
|
*
|
||
|
* @param[in] ctx idmap context
|
||
|
@@ -291,6 +313,49 @@ enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx,
|
||
|
bool external_mapping);
|
||
|
|
||
|
/**
|
||
|
+ * @brief Add a domain with the first mappable RID to the idmap context and
|
||
|
+ * generate automatically secondary slices
|
||
|
+ *
|
||
|
+ * @param[in] ctx Idmap context
|
||
|
+ * @param[in] domain_name Zero-terminated string with the domain name
|
||
|
+ * @param[in] domain_sid Zero-terminated string representation of the domain
|
||
|
+ * SID (S-1-15-.....)
|
||
|
+ * @param[in] range TBD Some information about the id ranges of this
|
||
|
+ * domain
|
||
|
+ * @param[in] range_id optional unique identifier of a range, it is needed
|
||
|
+ * to allow updates at runtime
|
||
|
+ * @param[in] rid The RID that should be mapped to the first ID of the
|
||
|
+ * given range.
|
||
|
+ * @param[in] external_mapping If set to true the ID will not be mapped
|
||
|
+ * algorithmically, but the *_to_unix and *_unix_to_*
|
||
|
+ * calls will return IDMAP_EXTERNAL to instruct the
|
||
|
+ * caller to check external sources. For a single
|
||
|
+ * domain all ranges must be of the same type. It is
|
||
|
+ * not possible to mix algorithmic and external
|
||
|
+ * mapping.
|
||
|
+ * @param[in] s_cv The callback for storing mapping of dynamically
|
||
|
+ * created domains.
|
||
|
+ * @param[in] pvt Private data for callback cb.
|
||
|
+ *
|
||
|
+ * @return
|
||
|
+ * - #IDMAP_OUT_OF_MEMORY: Insufficient memory to store the data in the idmap
|
||
|
+ * context
|
||
|
+ * - #IDMAP_SID_INVALID: Invalid SID provided
|
||
|
+ * - #IDMAP_NO_DOMAIN: No domain domain name given
|
||
|
+ * - #IDMAP_COLLISION: New domain collides with existing one
|
||
|
+ */
|
||
|
+enum idmap_error_code
|
||
|
+sss_idmap_add_auto_domain_ex(struct sss_idmap_ctx *ctx,
|
||
|
+ const char *domain_name,
|
||
|
+ const char *domain_sid,
|
||
|
+ struct sss_idmap_range *range,
|
||
|
+ const char *range_id,
|
||
|
+ uint32_t rid,
|
||
|
+ bool external_mapping,
|
||
|
+ idmap_store_cb cb,
|
||
|
+ void *pvt);
|
||
|
+
|
||
|
+/**
|
||
|
* @brief Check if a new range would collide with any existing one
|
||
|
*
|
||
|
* @param[in] ctx Idmap context
|
||
|
diff --git a/src/lib/idmap/sss_idmap_private.h b/src/lib/idmap/sss_idmap_private.h
|
||
|
index 1d3a36901781ae51ab79015d0b789559325c8de5..15300d11fc50a47c6d37149fdb79477069d931f4 100644
|
||
|
--- a/src/lib/idmap/sss_idmap_private.h
|
||
|
+++ b/src/lib/idmap/sss_idmap_private.h
|
||
|
@@ -29,6 +29,7 @@
|
||
|
#define SSS_IDMAP_DEFAULT_UPPER 2000200000
|
||
|
#define SSS_IDMAP_DEFAULT_RANGESIZE 200000
|
||
|
#define SSS_IDMAP_DEFAULT_AUTORID false
|
||
|
+#define SSS_IDMAP_DEFAULT_EXTRA_SLICE_INIT 10
|
||
|
|
||
|
#define CHECK_IDMAP_CTX(ctx, ret) do { \
|
||
|
if (ctx == NULL || ctx->alloc_func == NULL || ctx->free_func == NULL) { \
|
||
|
@@ -48,6 +49,9 @@ struct sss_idmap_opts {
|
||
|
|
||
|
/* number of available UIDs (for single domain) */
|
||
|
id_t rangesize;
|
||
|
+
|
||
|
+ /* maximal number of secondary slices */
|
||
|
+ int extra_slice_init;
|
||
|
};
|
||
|
|
||
|
struct sss_idmap_ctx {
|
||
|
diff --git a/src/man/include/ldap_id_mapping.xml b/src/man/include/ldap_id_mapping.xml
|
||
|
index 17ef803289d14fa52b725c90062ee4ba0379acd0..a088c4e81d81c5670edea8ae8081abe80927446a 100644
|
||
|
--- a/src/man/include/ldap_id_mapping.xml
|
||
|
+++ b/src/man/include/ldap_id_mapping.xml
|
||
|
@@ -243,6 +243,26 @@ ldap_schema = ad
|
||
|
</para>
|
||
|
</listitem>
|
||
|
</varlistentry>
|
||
|
+ <varlistentry>
|
||
|
+ <term>ldap_idmap_helper_table_size (integer)</term>
|
||
|
+ <listitem>
|
||
|
+ <para>
|
||
|
+ Maximal number of secondary slices that is tried when
|
||
|
+ performing mapping from UNIX id to SID.
|
||
|
+ </para>
|
||
|
+ <para>
|
||
|
+ Note: Additional secondary slices might be generated
|
||
|
+ when SID is being mapped to UNIX id and RID part of
|
||
|
+ SID is out of range for secondary slices generated so
|
||
|
+ far. If value of ldap_idmap_helper_table_size is equal
|
||
|
+ to 0 then no additional secondary slices are
|
||
|
+ generated.
|
||
|
+ </para>
|
||
|
+ <para>
|
||
|
+ Default: 10
|
||
|
+ </para>
|
||
|
+ </listitem>
|
||
|
+ </varlistentry>
|
||
|
</variablelist>
|
||
|
</refsect3>
|
||
|
</refsect2>
|
||
|
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
|
||
|
index 8b2841eadc0236b51f8c9c2c02b7c98837fbe416..28d4768b20bd035f7c1971c95f9b6b690844816e 100644
|
||
|
--- a/src/providers/ad/ad_opts.c
|
||
|
+++ b/src/providers/ad/ad_opts.c
|
||
|
@@ -137,6 +137,7 @@ struct dp_option ad_def_ldap_opts[] = {
|
||
|
{ "ldap_idmap_autorid_compat", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
|
||
|
{ "ldap_idmap_default_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING },
|
||
|
{ "ldap_idmap_default_domain_sid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
|
||
|
+ { "ldap_idmap_helper_table_size", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER },
|
||
|
{ "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
|
||
|
{ "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
|
||
|
{ "ldap_use_tokengroups", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE},
|
||
|
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
|
||
|
index cda10f89a60264ffd998da73ebadd09dff35ed79..cd87852e5891fd43d7ec728f76860f3050a54d2f 100644
|
||
|
--- a/src/providers/ipa/ipa_opts.c
|
||
|
+++ b/src/providers/ipa/ipa_opts.c
|
||
|
@@ -147,6 +147,7 @@ struct dp_option ipa_def_ldap_opts[] = {
|
||
|
{ "ldap_idmap_autorid_compat", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
|
||
|
{ "ldap_idmap_default_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING },
|
||
|
{ "ldap_idmap_default_domain_sid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
|
||
|
+ { "ldap_idmap_helper_table_size", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER },
|
||
|
{ "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
|
||
|
{ "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
|
||
|
{ "ldap_use_tokengroups", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE},
|
||
|
diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c
|
||
|
index 54926c6c31b1b6edfc1f07b22e79225c5fdddf5b..84ba2b54271bcb6650e0336131ace8bfc1a40fc8 100644
|
||
|
--- a/src/providers/ldap/ldap_opts.c
|
||
|
+++ b/src/providers/ldap/ldap_opts.c
|
||
|
@@ -111,6 +111,7 @@ struct dp_option default_basic_opts[] = {
|
||
|
{ "ldap_idmap_autorid_compat", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
|
||
|
{ "ldap_idmap_default_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING },
|
||
|
{ "ldap_idmap_default_domain_sid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
|
||
|
+ { "ldap_idmap_helper_table_size", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER },
|
||
|
{ "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
|
||
|
{ "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
|
||
|
{ "ldap_use_tokengroups", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE},
|
||
|
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
|
||
|
index d7a299220414f2cf9d80de9921b6a5ec49e5793b..e06f2b6ac47990f21985fb86f8ad3f3ae5a74df3 100644
|
||
|
--- a/src/providers/ldap/sdap.h
|
||
|
+++ b/src/providers/ldap/sdap.h
|
||
|
@@ -223,6 +223,7 @@ enum sdap_basic_opt {
|
||
|
SDAP_IDMAP_AUTORID_COMPAT,
|
||
|
SDAP_IDMAP_DEFAULT_DOMAIN,
|
||
|
SDAP_IDMAP_DEFAULT_DOMAIN_SID,
|
||
|
+ SDAP_IDMAP_EXTRA_SLICE_INIT,
|
||
|
SDAP_AD_MATCHING_RULE_GROUPS,
|
||
|
SDAP_AD_MATCHING_RULE_INITGROUPS,
|
||
|
SDAP_AD_USE_TOKENGROUPS,
|
||
|
diff --git a/src/providers/ldap/sdap_idmap.c b/src/providers/ldap/sdap_idmap.c
|
||
|
index fa79e66226e572c29cf371fffe3c149a2eda8895..53a98730954f6ba4321fb2a219c3bc85140c65cc 100644
|
||
|
--- a/src/providers/ldap/sdap_idmap.c
|
||
|
+++ b/src/providers/ldap/sdap_idmap.c
|
||
|
@@ -94,9 +94,10 @@ sdap_idmap_add_configured_external_range(struct sdap_idmap_ctx *idmap_ctx)
|
||
|
|
||
|
id_ctx = idmap_ctx->id_ctx;
|
||
|
|
||
|
- err = sss_idmap_add_domain_ex(idmap_ctx->map, id_ctx->be->domain->name,
|
||
|
- id_ctx->be->domain->domain_id, &range,
|
||
|
- NULL, 0, true);
|
||
|
+ err = sss_idmap_add_auto_domain_ex(idmap_ctx->map,
|
||
|
+ id_ctx->be->domain->name,
|
||
|
+ id_ctx->be->domain->domain_id, &range,
|
||
|
+ NULL, 0, true, NULL, NULL);
|
||
|
if (err != IDMAP_SUCCESS) {
|
||
|
DEBUG(SSSDBG_CRIT_FAILURE,
|
||
|
"Could not add domain [%s] to the map: [%d]\n",
|
||
|
@@ -142,6 +143,7 @@ sdap_idmap_init(TALLOC_CTX *mem_ctx,
|
||
|
id_t idmap_upper;
|
||
|
id_t rangesize;
|
||
|
bool autorid_mode;
|
||
|
+ int extra_slice_init;
|
||
|
struct sdap_idmap_ctx *idmap_ctx = NULL;
|
||
|
|
||
|
tmp_ctx = talloc_new(NULL);
|
||
|
@@ -163,6 +165,8 @@ sdap_idmap_init(TALLOC_CTX *mem_ctx,
|
||
|
SDAP_IDMAP_RANGESIZE);
|
||
|
autorid_mode = dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic,
|
||
|
SDAP_IDMAP_AUTORID_COMPAT);
|
||
|
+ extra_slice_init = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
|
||
|
+ SDAP_IDMAP_EXTRA_SLICE_INIT);
|
||
|
|
||
|
/* Validate that the values make sense */
|
||
|
if (rangesize <= 0
|
||
|
@@ -203,6 +207,7 @@ sdap_idmap_init(TALLOC_CTX *mem_ctx,
|
||
|
err |= sss_idmap_ctx_set_lower(idmap_ctx->map, idmap_lower);
|
||
|
err |= sss_idmap_ctx_set_upper(idmap_ctx->map, idmap_upper);
|
||
|
err |= sss_idmap_ctx_set_rangesize(idmap_ctx->map, rangesize);
|
||
|
+ err |= sss_idmap_ctx_set_extra_slice_init(idmap_ctx->map, extra_slice_init);
|
||
|
if (err != IDMAP_SUCCESS) {
|
||
|
/* This should never happen */
|
||
|
DEBUG(SSSDBG_CRIT_FAILURE, "sss_idmap_ctx corrupted\n");
|
||
|
@@ -376,8 +381,9 @@ sdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx,
|
||
|
}
|
||
|
|
||
|
/* Add this domain to the map */
|
||
|
- err = sss_idmap_add_domain_ex(idmap_ctx->map, dom_name, dom_sid, &range,
|
||
|
- NULL, 0, external_mapping);
|
||
|
+ err = sss_idmap_add_auto_domain_ex(idmap_ctx->map, dom_name, dom_sid,
|
||
|
+ &range, NULL, 0, external_mapping,
|
||
|
+ NULL, NULL);
|
||
|
if (err != IDMAP_SUCCESS) {
|
||
|
DEBUG(SSSDBG_CRIT_FAILURE,
|
||
|
"Could not add domain [%s] to the map: [%d]\n",
|
||
|
diff --git a/src/tests/cmocka/test_sss_idmap.c b/src/tests/cmocka/test_sss_idmap.c
|
||
|
index 1e52c8507461ab3caa04eb2c0e63410c363ba723..00e03ffd9ab1532fb55795b9935b254c8a89ec16 100644
|
||
|
--- a/src/tests/cmocka/test_sss_idmap.c
|
||
|
+++ b/src/tests/cmocka/test_sss_idmap.c
|
||
|
@@ -82,7 +82,7 @@ static int test_sss_idmap_setup(void **state)
|
||
|
}
|
||
|
|
||
|
static int setup_ranges(struct test_ctx *test_ctx, bool external_mapping,
|
||
|
- bool second_domain)
|
||
|
+ bool second_domain, bool sec_slices)
|
||
|
{
|
||
|
struct sss_idmap_range range;
|
||
|
enum idmap_error_code err;
|
||
|
@@ -103,15 +103,27 @@ static int setup_ranges(struct test_ctx *test_ctx, bool external_mapping,
|
||
|
sid = TEST_DOM_SID;
|
||
|
}
|
||
|
|
||
|
- err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL,
|
||
|
- 0, external_mapping);
|
||
|
+ if (sec_slices) {
|
||
|
+ err = sss_idmap_add_auto_domain_ex(test_ctx->idmap_ctx, name, sid,
|
||
|
+ &range, NULL, 0, external_mapping,
|
||
|
+ NULL, NULL);
|
||
|
+ } else {
|
||
|
+ err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range,
|
||
|
+ NULL, 0, external_mapping);
|
||
|
+ }
|
||
|
assert_int_equal(err, IDMAP_SUCCESS);
|
||
|
|
||
|
range.min += TEST_OFFSET;
|
||
|
range.max += TEST_OFFSET;
|
||
|
|
||
|
- err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL,
|
||
|
- TEST_OFFSET, external_mapping);
|
||
|
+ if (sec_slices) {
|
||
|
+ err = sss_idmap_add_auto_domain_ex(test_ctx->idmap_ctx, name, sid,
|
||
|
+ &range, NULL, TEST_OFFSET,
|
||
|
+ external_mapping, NULL, NULL);
|
||
|
+ } else {
|
||
|
+ err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range,
|
||
|
+ NULL, TEST_OFFSET, external_mapping);
|
||
|
+ }
|
||
|
assert_int_equal(err, IDMAP_SUCCESS);
|
||
|
return 0;
|
||
|
}
|
||
|
@@ -124,7 +136,19 @@ static int test_sss_idmap_setup_with_domains(void **state) {
|
||
|
test_ctx = talloc_get_type(*state, struct test_ctx);
|
||
|
assert_non_null(test_ctx);
|
||
|
|
||
|
- setup_ranges(test_ctx, false, false);
|
||
|
+ setup_ranges(test_ctx, false, false, false);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int test_sss_idmap_setup_with_domains_sec_slices(void **state) {
|
||
|
+ struct test_ctx *test_ctx;
|
||
|
+
|
||
|
+ test_sss_idmap_setup(state);
|
||
|
+
|
||
|
+ test_ctx = talloc_get_type(*state, struct test_ctx);
|
||
|
+ assert_non_null(test_ctx);
|
||
|
+
|
||
|
+ setup_ranges(test_ctx, false, false, true);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -136,7 +160,7 @@ static int test_sss_idmap_setup_with_external_mappings(void **state) {
|
||
|
test_ctx = talloc_get_type(*state, struct test_ctx);
|
||
|
assert_non_null(test_ctx);
|
||
|
|
||
|
- setup_ranges(test_ctx, true, false);
|
||
|
+ setup_ranges(test_ctx, true, false, false);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -148,8 +172,8 @@ static int test_sss_idmap_setup_with_both(void **state) {
|
||
|
test_ctx = talloc_get_type(*state, struct test_ctx);
|
||
|
assert_non_null(test_ctx);
|
||
|
|
||
|
- setup_ranges(test_ctx, false, false);
|
||
|
- setup_ranges(test_ctx, true, true);
|
||
|
+ setup_ranges(test_ctx, false, false, false);
|
||
|
+ setup_ranges(test_ctx, true, true, false);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -274,6 +298,48 @@ void test_map_id(void **state)
|
||
|
sss_idmap_free_sid(test_ctx->idmap_ctx, sid);
|
||
|
}
|
||
|
|
||
|
+void test_map_id_sec_slices(void **state)
|
||
|
+{
|
||
|
+ struct test_ctx *test_ctx;
|
||
|
+ enum idmap_error_code err;
|
||
|
+ uint32_t id;
|
||
|
+ char *sid = NULL;
|
||
|
+
|
||
|
+ test_ctx = talloc_get_type(*state, struct test_ctx);
|
||
|
+
|
||
|
+ assert_non_null(test_ctx);
|
||
|
+
|
||
|
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"1-1", &id);
|
||
|
+ assert_int_equal(err, IDMAP_NO_DOMAIN);
|
||
|
+
|
||
|
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-4000000",
|
||
|
+ &id);
|
||
|
+ assert_int_equal(err, IDMAP_SUCCESS);
|
||
|
+ assert_int_equal(id, 575600000);
|
||
|
+
|
||
|
+ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_OFFSET - 1, &sid);
|
||
|
+ assert_int_equal(err, IDMAP_NO_DOMAIN);
|
||
|
+
|
||
|
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-0", &id);
|
||
|
+ assert_int_equal(err, IDMAP_SUCCESS);
|
||
|
+ assert_int_equal(id, TEST_RANGE_MIN);
|
||
|
+
|
||
|
+ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, id, &sid);
|
||
|
+ assert_int_equal(err, IDMAP_SUCCESS);
|
||
|
+ assert_string_equal(sid, TEST_DOM_SID"-0");
|
||
|
+ sss_idmap_free_sid(test_ctx->idmap_ctx, sid);
|
||
|
+
|
||
|
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx,
|
||
|
+ TEST_DOM_SID"-"TEST_OFFSET_STR, &id);
|
||
|
+ assert_int_equal(err, IDMAP_SUCCESS);
|
||
|
+ assert_int_equal(id, TEST_RANGE_MIN+TEST_OFFSET);
|
||
|
+
|
||
|
+ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, id, &sid);
|
||
|
+ assert_int_equal(err, IDMAP_SUCCESS);
|
||
|
+ assert_string_equal(sid, TEST_DOM_SID"-"TEST_OFFSET_STR);
|
||
|
+ sss_idmap_free_sid(test_ctx->idmap_ctx, sid);
|
||
|
+}
|
||
|
+
|
||
|
void test_map_id_external(void **state)
|
||
|
{
|
||
|
struct test_ctx *test_ctx;
|
||
|
@@ -523,6 +589,9 @@ int main(int argc, const char *argv[])
|
||
|
cmocka_unit_test_setup_teardown(test_map_id,
|
||
|
test_sss_idmap_setup_with_domains,
|
||
|
test_sss_idmap_teardown),
|
||
|
+ cmocka_unit_test_setup_teardown(test_map_id_sec_slices,
|
||
|
+ test_sss_idmap_setup_with_domains_sec_slices,
|
||
|
+ test_sss_idmap_teardown),
|
||
|
cmocka_unit_test_setup_teardown(test_map_id_external,
|
||
|
test_sss_idmap_setup_with_external_mappings,
|
||
|
test_sss_idmap_teardown),
|
||
|
diff --git a/src/tests/sss_idmap-tests.c b/src/tests/sss_idmap-tests.c
|
||
|
index f5ec68383679bfc685467bd625c86b8d6f474d48..900b7bff1cd4f3c6f9cdffc4b012864d05e72913 100644
|
||
|
--- a/src/tests/sss_idmap-tests.c
|
||
|
+++ b/src/tests/sss_idmap-tests.c
|
||
|
@@ -68,6 +68,20 @@ void idmap_ctx_setup(void)
|
||
|
fail_unless(idmap_ctx != NULL, "sss_idmap_init returned NULL.");
|
||
|
}
|
||
|
|
||
|
+void idmap_ctx_setup_additional_seconary_slices(void)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+
|
||
|
+ err = sss_idmap_init(idmap_talloc, global_talloc_context, idmap_talloc_free,
|
||
|
+ &idmap_ctx);
|
||
|
+
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_init failed.");
|
||
|
+ fail_unless(idmap_ctx != NULL, "sss_idmap_init returned NULL.");
|
||
|
+
|
||
|
+ idmap_ctx->idmap_opts.rangesize = 10;
|
||
|
+ idmap_ctx->idmap_opts.extra_slice_init = 5;
|
||
|
+}
|
||
|
+
|
||
|
void idmap_ctx_teardown(void)
|
||
|
{
|
||
|
enum idmap_error_code err;
|
||
|
@@ -85,6 +99,86 @@ void idmap_add_domain_setup(void)
|
||
|
fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_domain failed.");
|
||
|
}
|
||
|
|
||
|
+void idmap_add_domain_with_sec_slices_setup(void)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ struct sss_idmap_range range = {
|
||
|
+ IDMAP_RANGE_MIN,
|
||
|
+ IDMAP_RANGE_MIN + idmap_ctx->idmap_opts.rangesize - 1,
|
||
|
+ };
|
||
|
+
|
||
|
+ err = sss_idmap_add_auto_domain_ex(idmap_ctx, "test.dom", "S-1-5-21-1-2-3",
|
||
|
+ &range, NULL, 0, false, NULL, NULL);
|
||
|
+
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_auto_domain_ex failed.");
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+enum idmap_error_code cb(const char *dom_name,
|
||
|
+ const char *dom_sid,
|
||
|
+ const char *range_id,
|
||
|
+ uint32_t min_id,
|
||
|
+ uint32_t max_id,
|
||
|
+ uint32_t first_rid,
|
||
|
+ void *pvt)
|
||
|
+{
|
||
|
+ return IDMAP_ERROR;
|
||
|
+}
|
||
|
+
|
||
|
+void idmap_add_domain_with_sec_slices_setup_cb_fail(void)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ struct sss_idmap_range range = {
|
||
|
+ IDMAP_RANGE_MIN,
|
||
|
+ IDMAP_RANGE_MIN + idmap_ctx->idmap_opts.rangesize - 1,
|
||
|
+ };
|
||
|
+
|
||
|
+ err = sss_idmap_add_auto_domain_ex(idmap_ctx, "test.dom", "S-1-5-21-1-2-3",
|
||
|
+ &range, NULL, 0, false, cb, NULL);
|
||
|
+
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_auto_domain_ex failed.");
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+#define MAX 1000
|
||
|
+char data[MAX];
|
||
|
+
|
||
|
+enum idmap_error_code cb2(const char *dom_name,
|
||
|
+ const char *dom_sid,
|
||
|
+ const char *range_id,
|
||
|
+ uint32_t min_id,
|
||
|
+ uint32_t max_id,
|
||
|
+ uint32_t first_rid,
|
||
|
+ void *pvt)
|
||
|
+{
|
||
|
+ char *p = (char*)pvt;
|
||
|
+ size_t len;
|
||
|
+
|
||
|
+ len = snprintf(p, MAX, "%s, %s %s, %"PRIu32", %"PRIu32", %" PRIu32,
|
||
|
+ dom_name, dom_sid, range_id, min_id, max_id, first_rid);
|
||
|
+
|
||
|
+ if (len >= MAX) {
|
||
|
+ return IDMAP_OUT_OF_MEMORY;
|
||
|
+ }
|
||
|
+ return IDMAP_SUCCESS;
|
||
|
+}
|
||
|
+
|
||
|
+void idmap_add_domain_with_sec_slices_setup_cb_ok(void)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ struct sss_idmap_range range = {
|
||
|
+ IDMAP_RANGE_MIN,
|
||
|
+ IDMAP_RANGE_MIN + idmap_ctx->idmap_opts.rangesize - 1,
|
||
|
+ };
|
||
|
+
|
||
|
+ void *pvt = (void*) data;
|
||
|
+
|
||
|
+ err = sss_idmap_add_auto_domain_ex(idmap_ctx, "test.dom", "S-1-5-21-1-2-3",
|
||
|
+ &range, NULL, 0, false, cb2, pvt);
|
||
|
+
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_auto_domain_ex failed.");
|
||
|
+}
|
||
|
+
|
||
|
START_TEST(idmap_test_is_domain_sid)
|
||
|
{
|
||
|
size_t c;
|
||
|
@@ -225,6 +319,145 @@ START_TEST(idmap_test_sid2uid)
|
||
|
}
|
||
|
END_TEST
|
||
|
|
||
|
+START_TEST(idmap_test_sid2uid_ss)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ uint32_t id;
|
||
|
+ const uint32_t exp_id = 351800000;
|
||
|
+ const uint32_t exp_id2 = 832610000;
|
||
|
+
|
||
|
+ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3333-1000", &id);
|
||
|
+ fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_sid_to_unix did not detect "
|
||
|
+ "unknown domain");
|
||
|
+
|
||
|
+ /* RID out of primary and secondary range */
|
||
|
+ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
|
||
|
+ fail_unless(id == exp_id,
|
||
|
+ "sss_idmap_sid_to_unix returned wrong id, "
|
||
|
+ "got [%d], expected [%d].", id, exp_id);
|
||
|
+
|
||
|
+ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-1000", &id);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
|
||
|
+ fail_unless(id == (1000 + IDMAP_RANGE_MIN),
|
||
|
+ "sss_idmap_sid_to_unix returned wrong id, "
|
||
|
+ "got [%d], expected [%d].", id, 1000 + IDMAP_RANGE_MIN);
|
||
|
+
|
||
|
+ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-210000", &id);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
|
||
|
+ fail_unless(id == exp_id2,
|
||
|
+ "sss_idmap_sid_to_unix returned wrong id, "
|
||
|
+ "got [%d], expected [%d].", id, exp_id2);
|
||
|
+}
|
||
|
+END_TEST
|
||
|
+
|
||
|
+START_TEST(idmap_test_sid2uid_ext_sec_slices)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ uint32_t id;
|
||
|
+ char *sid;
|
||
|
+ const uint32_t exp_id = 351800000;
|
||
|
+
|
||
|
+ err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid);
|
||
|
+ fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect "
|
||
|
+ "id out of range");
|
||
|
+
|
||
|
+ /* RID out of primary and secondary range */
|
||
|
+ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
|
||
|
+ fail_unless(id == exp_id,
|
||
|
+ "sss_idmap_sid_to_unix returned wrong id, "
|
||
|
+ "got [%d], expected [%d].", id, exp_id);
|
||
|
+
|
||
|
+ /* Secondary ranges were expanded by sid_to_unix call */
|
||
|
+ err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed.");
|
||
|
+ fail_unless(strcmp(sid, "S-1-5-21-1-2-3-4000000") == 0,
|
||
|
+ "sss_idmap_unix_to_sid returned wrong SID, "
|
||
|
+ "expected [%s], got [%s].", "S-1-5-21-1-2-3-4000000", sid);
|
||
|
+ sss_idmap_free_sid(idmap_ctx, sid);
|
||
|
+}
|
||
|
+END_TEST
|
||
|
+
|
||
|
+
|
||
|
+START_TEST(idmap_test_dyn_dom_store_cb_fail)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ uint32_t id;
|
||
|
+ char *sid;
|
||
|
+ const uint32_t exp_id = 351800000;
|
||
|
+
|
||
|
+ err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid);
|
||
|
+ fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect "
|
||
|
+ "id out of range");
|
||
|
+
|
||
|
+ /* RID out of primary and secondary range */
|
||
|
+ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id);
|
||
|
+ fail_unless(err == IDMAP_ERROR, "sss_idmap_sid_to_unix failed.");
|
||
|
+}
|
||
|
+END_TEST
|
||
|
+
|
||
|
+START_TEST(idmap_test_dyn_dom_store_cb_ok)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ uint32_t id;
|
||
|
+ char *sid;
|
||
|
+ const uint32_t exp_id = 351800000;
|
||
|
+ const char *exp_stored_data = "test.dom, S-1-5-21-1-2-3 S-1-5-21-1-2-3-4000000, 351800000, 351999999, 4000000";
|
||
|
+
|
||
|
+ err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid);
|
||
|
+ fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect "
|
||
|
+ "id out of range");
|
||
|
+
|
||
|
+ /* RID out of primary and secondary range */
|
||
|
+ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
|
||
|
+
|
||
|
+ fail_unless(strcmp(data,
|
||
|
+ exp_stored_data) == 0,
|
||
|
+ "Storing dynamic domains idmapping failed: "
|
||
|
+ "expected [%s] but got [%s].", exp_stored_data, data);
|
||
|
+}
|
||
|
+END_TEST
|
||
|
+
|
||
|
+
|
||
|
+START_TEST(idmap_test_sid2uid_additional_secondary_slices)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ struct TALLOC_CTX *tmp_ctx;
|
||
|
+ const char *dom_prefix = "S-1-5-21-1-2-3";
|
||
|
+ const int max_rid = 80;
|
||
|
+ const char *sids[max_rid];
|
||
|
+ unsigned int ids[max_rid];
|
||
|
+
|
||
|
+ tmp_ctx = talloc_new(NULL);
|
||
|
+ fail_unless(tmp_ctx != NULL, "Out of memory.");
|
||
|
+
|
||
|
+ for (unsigned int i = 0; i < max_rid + 1; i++) {
|
||
|
+ sids[i] = talloc_asprintf(tmp_ctx, "%s-%u", dom_prefix, i);
|
||
|
+
|
||
|
+ fail_unless(sids[i] != NULL, "Out of memory");
|
||
|
+
|
||
|
+ err = sss_idmap_sid_to_unix(idmap_ctx, sids[i], &ids[i]);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
|
||
|
+ }
|
||
|
+
|
||
|
+ for (unsigned int i = 0; i < max_rid + 1; i++) {
|
||
|
+ char *sid;
|
||
|
+
|
||
|
+ err = sss_idmap_unix_to_sid(idmap_ctx, ids[i], &sid);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
|
||
|
+
|
||
|
+ fail_unless(strcmp(sid, sids[i]) == 0,
|
||
|
+ "sss_idmap_unix_to_sid returned wrong sid, "
|
||
|
+ "got [%s], expected [%s].", sid, sids[i]);
|
||
|
+ talloc_free(sid);
|
||
|
+ }
|
||
|
+
|
||
|
+ talloc_free(tmp_ctx);
|
||
|
+}
|
||
|
+END_TEST
|
||
|
+
|
||
|
START_TEST(idmap_test_bin_sid2uid)
|
||
|
{
|
||
|
enum idmap_error_code err;
|
||
|
@@ -284,6 +517,38 @@ START_TEST(idmap_test_uid2sid)
|
||
|
}
|
||
|
END_TEST
|
||
|
|
||
|
+START_TEST(idmap_test_uid2sid_ss)
|
||
|
+{
|
||
|
+ enum idmap_error_code err;
|
||
|
+ char *sid;
|
||
|
+
|
||
|
+ err = sss_idmap_unix_to_sid(idmap_ctx,
|
||
|
+ IDMAP_RANGE_MIN + idmap_ctx->idmap_opts.rangesize + 1,
|
||
|
+ &sid);
|
||
|
+ fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect "
|
||
|
+ "id out of range");
|
||
|
+
|
||
|
+ err = sss_idmap_unix_to_sid(idmap_ctx, 2234, &sid);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed.");
|
||
|
+ fail_unless(strcmp(sid, "S-1-5-21-1-2-3-1000") == 0,
|
||
|
+ "sss_idmap_unix_to_sid returned wrong SID, "
|
||
|
+ "expected [%s], got [%s].", "S-1-5-21-1-2-3-1000", sid);
|
||
|
+
|
||
|
+ sss_idmap_free_sid(idmap_ctx, sid);
|
||
|
+
|
||
|
+ /* Secondary ranges */
|
||
|
+ err = sss_idmap_unix_to_sid(idmap_ctx,
|
||
|
+ 313800000,
|
||
|
+ &sid);
|
||
|
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed.");
|
||
|
+ fail_unless(strcmp(sid, "S-1-5-21-1-2-3-400000") == 0,
|
||
|
+ "sss_idmap_unix_to_sid returned wrong SID, "
|
||
|
+ "expected [%s], got [%s].", "S-1-5-21-1-2-3-400000", sid);
|
||
|
+
|
||
|
+ sss_idmap_free_sid(idmap_ctx, sid);
|
||
|
+}
|
||
|
+END_TEST
|
||
|
+
|
||
|
START_TEST(idmap_test_uid2dom_sid)
|
||
|
{
|
||
|
enum idmap_error_code err;
|
||
|
@@ -618,6 +883,73 @@ Suite *idmap_test_suite (void)
|
||
|
|
||
|
suite_add_tcase(s, tc_map);
|
||
|
|
||
|
+ /* Test secondary slices */
|
||
|
+ TCase *tc_map_ss = tcase_create("IDMAP mapping tests");
|
||
|
+ tcase_add_checked_fixture(tc_map_ss,
|
||
|
+ ck_leak_check_setup,
|
||
|
+ ck_leak_check_teardown);
|
||
|
+ tcase_add_checked_fixture(tc_map_ss,
|
||
|
+ idmap_ctx_setup,
|
||
|
+ idmap_ctx_teardown);
|
||
|
+ tcase_add_checked_fixture(tc_map_ss,
|
||
|
+ idmap_add_domain_with_sec_slices_setup,
|
||
|
+ NULL);
|
||
|
+
|
||
|
+ tcase_add_test(tc_map_ss, idmap_test_sid2uid_ss);
|
||
|
+ tcase_add_test(tc_map_ss, idmap_test_uid2sid_ss);
|
||
|
+ tcase_add_test(tc_map_ss, idmap_test_sid2uid_ext_sec_slices);
|
||
|
+
|
||
|
+ suite_add_tcase(s, tc_map_ss);
|
||
|
+
|
||
|
+ /* Test secondary slices - callback to store failed. */
|
||
|
+ TCase *tc_map_cb_fail = tcase_create("IDMAP mapping tests - store fail");
|
||
|
+ tcase_add_checked_fixture(tc_map_cb_fail,
|
||
|
+ ck_leak_check_setup,
|
||
|
+ ck_leak_check_teardown);
|
||
|
+ tcase_add_checked_fixture(tc_map_cb_fail,
|
||
|
+ idmap_ctx_setup,
|
||
|
+ idmap_ctx_teardown);
|
||
|
+ tcase_add_checked_fixture(tc_map_cb_fail,
|
||
|
+ idmap_add_domain_with_sec_slices_setup_cb_fail,
|
||
|
+ NULL);
|
||
|
+
|
||
|
+ tcase_add_test(tc_map_cb_fail, idmap_test_dyn_dom_store_cb_fail);
|
||
|
+ suite_add_tcase(s, tc_map_cb_fail);
|
||
|
+
|
||
|
+ /* Test secondary slices - callback to store passed. */
|
||
|
+ TCase *tc_map_cb_ok = tcase_create("IDMAP mapping tests");
|
||
|
+ tcase_add_checked_fixture(tc_map_cb_ok,
|
||
|
+ ck_leak_check_setup,
|
||
|
+ ck_leak_check_teardown);
|
||
|
+ tcase_add_checked_fixture(tc_map_cb_ok,
|
||
|
+ idmap_ctx_setup,
|
||
|
+ idmap_ctx_teardown);
|
||
|
+ tcase_add_checked_fixture(tc_map_cb_ok,
|
||
|
+ idmap_add_domain_with_sec_slices_setup_cb_ok,
|
||
|
+ NULL);
|
||
|
+
|
||
|
+ tcase_add_test(tc_map_cb_ok, idmap_test_dyn_dom_store_cb_ok);
|
||
|
+ suite_add_tcase(s, tc_map_cb_ok);
|
||
|
+
|
||
|
+ /* Test additional secondary slices */
|
||
|
+ TCase *tc_map_additional_secondary_slices = \
|
||
|
+ tcase_create("IDMAP additional secondary slices");
|
||
|
+
|
||
|
+ tcase_add_checked_fixture(tc_map_additional_secondary_slices,
|
||
|
+ ck_leak_check_setup,
|
||
|
+ ck_leak_check_teardown);
|
||
|
+ tcase_add_checked_fixture(tc_map_additional_secondary_slices,
|
||
|
+ idmap_ctx_setup_additional_seconary_slices,
|
||
|
+ idmap_ctx_teardown);
|
||
|
+ tcase_add_checked_fixture(tc_map_additional_secondary_slices,
|
||
|
+ idmap_add_domain_with_sec_slices_setup,
|
||
|
+ NULL);
|
||
|
+
|
||
|
+ tcase_add_test(tc_map_additional_secondary_slices,
|
||
|
+ idmap_test_sid2uid_additional_secondary_slices);
|
||
|
+
|
||
|
+ suite_add_tcase(s, tc_map_additional_secondary_slices);
|
||
|
+
|
||
|
return s;
|
||
|
}
|
||
|
int main(int argc, const char *argv[])
|
||
|
--
|
||
|
2.5.0
|
||
|
|