[prev in list] [next in list] [prev in thread] [next in thread]
List: sssd-devel
Subject: [SSSD]Re: [DESIGN] ID mapping - Automatically assign new slices for any AD domain
From: Pavel Reichl <preichl () redhat ! com>
Date: 2015-12-09 15:27:29
Message-ID: 56684861.8010904 () redhat ! com
[Download RAW message or body]
On 12/08/2015 05:27 PM, Pavel Reichl wrote:
> On 12/02/2015 02:18 PM, Pavel Reichl wrote:
> > Hello,
> >
> > I decided to share this design document although it still a work in progress. \
> > Attached patches are just prove of concept and are very much work in progress. So \
> > far patches also defers from design in order in which secondary slices are \
> > generated.
> > Thanks for feedback on this early state of effort.
> >
> > Bye.
> >
> > https://fedorahosted.org/sssd/wiki/IdmapAutoAssignNewSlices
> >
> >
> > _______________________________________________
> > sssd-devel mailing list
> > sssd-devel@lists.fedorahosted.org
> > https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org
> >
> Hello, attached patches are still work in progress - I mainly addressed Sumit's \
> comments focused on: 1) Changing secondary slices from arrays to link list (to make \
> adding new slices easy in sid_to_unix()). 2) Added new function \
> sss_idmap_add_auto_domain_ex() which adds secondary slices - it's not a good idea \
> to add secondary slices in sss_idmap_add_domain_ex() because it's called by IPA \
> which won't use them. 3) Changing sss_idmap_sid_to_unix() to always generate new \
> secondary slice if RID is out of scope of currently allocated secondary slices. 4) \
> And other smaller fixes.
> Also, option ldap_idmap_extra_slice_max was added and patch was refactored to \
> remove code duplication.
> I still need to increase code coverage and do more testing.
>
> Bye.
>
>
> _______________________________________________
> sssd-devel mailing list
> sssd-devel@lists.fedorahosted.org
> https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org
>
I did some testing and amended the patch a little.
You can see diff here:
> diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
> index a92066b..c4ae811 100644
> --- a/src/lib/idmap/sss_idmap.c
> +++ b/src/lib/idmap/sss_idmap.c
> @@ -562,6 +562,7 @@ generate_slice(struct sss_idmap_ctx *ctx, char *slice_name, \
> uint32_t first_rid,
> err = sss_idmap_calculate_range(ctx, slice_name, NULL, &tmp_range);
> if (err != IDMAP_SUCCESS) {
> + ctx->free_func(slice, ctx->alloc_pvt);
> return err;
> }
>
> @@ -718,17 +719,18 @@ sss_idmap_add_auto_domain_ex(struct sss_idmap_ctx *ctx,
> rid += ctx->idmap_opts.rangesize;
> err = get_sec_slices(ctx, domain_name, rid,
> &ctx->idmap_domain_info->sec_ranges);
> - if (err != IDMAP_SUCCESS) {
> + if (err == IDMAP_SUCCESS) {
> + ctx->idmap_domain_info->use_sec_ranges = true;
> + } else {
> /* Running out of slices for secondary mapping is a non-fatal
> * problem. */
> - if (err != IDMAP_OUT_OF_SLICES) {
> - return err;
> + if (err == IDMAP_OUT_OF_SLICES) {
> + err = IDMAP_SUCCESS;
> }
> + ctx->idmap_domain_info->use_sec_ranges = false;
> }
>
> - ctx->idmap_domain_info->use_sec_ranges = true;
> -
> - return IDMAP_SUCCESS;
> + return err;
> }
>
> enum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx,
> @@ -874,7 +876,7 @@ enum idmap_error_code sss_idmap_sid_to_unix(struct \
> sss_idmap_ctx *ctx,
> /* Try secondary slices */
> if (matched_dom != NULL && matched_dom->use_sec_ranges) {
> - struct idmap_range_params *last_slide;
> + struct idmap_range_params *last_slide = NULL;
> struct idmap_range_params *new_slice;
> enum idmap_error_code err;
>
> @@ -898,7 +900,11 @@ enum idmap_error_code sss_idmap_sid_to_unix(struct \
> sss_idmap_ctx *ctx, return err;
> }
>
> - last_slide->next = new_slice;
> + if (last_slide == NULL) {
> + matched_dom->sec_ranges = new_slice;
> + } else {
> + last_slide->next = new_slice;
> + }
>
> if (comp_id(new_slice, rid, _id)) {
> return IDMAP_SUCCESS;
["0001-IDMAP-New-structure-for-domain-range-params.patch" (text/x-patch)]
From caf11d143460c14a37a7f112f7e2240789d1b611 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Thu, 26 Nov 2015 10:46:34 -0500
Subject: [PATCH 1/2] IDMAP: New structure for domain range params
Create new internal structure idmap_range_params by merging ID mapping
range relevant fields from idmap_domain_info and remove corrsponding
fields.
Resolves:
https://fedorahosted.org/sssd/ticket/2188
---
src/lib/idmap/sss_idmap.c | 110 +++++++++++++++++++++++-----------------------
1 file changed, 56 insertions(+), 54 deletions(-)
diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
index 4c453120539a549807e9b6bb4db2dc396c1b3152..7a91e419983d59bed6a8ae06f7cfd448e8e18f63 100644
--- a/src/lib/idmap/sss_idmap.c
+++ b/src/lib/idmap/sss_idmap.c
@@ -33,13 +33,21 @@
#define SID_FMT "%s-%d"
#define SID_STR_MAX_LEN 1024
+/* Hold all parameters for unix<->sid mapping relevant for
+ * given slice. */
+struct idmap_range_params {
+ uint32_t min_id;
+ uint32_t max_id;
+ char *range_id;
+
+ uint32_t first_rid;
+};
+
struct idmap_domain_info {
char *name;
char *sid;
- struct sss_idmap_range *range;
+ struct idmap_range_params range_params;
struct idmap_domain_info *next;
- uint32_t first_rid;
- char *range_id;
bool external_mapping;
};
@@ -72,37 +80,17 @@ static char *idmap_strdup(struct sss_idmap_ctx *ctx, const char *str)
return new;
}
-static struct sss_idmap_range *idmap_range_dup(struct sss_idmap_ctx *ctx,
- struct sss_idmap_range *range)
-{
- struct sss_idmap_range *new = NULL;
-
- CHECK_IDMAP_CTX(ctx, NULL);
-
-
- new = ctx->alloc_func(sizeof(struct sss_idmap_range), ctx->alloc_pvt);
- if (new == NULL) {
- return NULL;
- }
-
- memset(new, 0, sizeof(struct sss_idmap_range));
-
- new->min = range->min;
- new->max = range->max;
-
- return new;
-}
-
-static bool id_is_in_range(uint32_t id, struct idmap_domain_info *dom,
+static bool id_is_in_range(uint32_t id,
+ struct idmap_range_params *rp,
uint32_t *rid)
{
- if (id == 0 || dom == NULL || dom->range == NULL) {
+ if (id == 0 || rp == NULL) {
return false;
}
- if (id >= dom->range->min && id <= dom->range->max) {
+ if (id >= rp->min_id && id <= rp->max_id) {
if (rid != NULL) {
- *rid = dom->first_rid + (id - dom->range->min);
+ *rid = rp->first_rid + (id - rp->min_id);
}
return true;
@@ -220,8 +208,7 @@ static void sss_idmap_free_domain(struct sss_idmap_ctx *ctx,
return;
}
- ctx->free_func(dom->range_id, ctx->alloc_pvt);
- ctx->free_func(dom->range, ctx->alloc_pvt);
+ ctx->free_func(dom->range_params.range_id, ctx->alloc_pvt);
ctx->free_func(dom->name, ctx->alloc_pvt);
ctx->free_func(dom->sid, ctx->alloc_pvt);
ctx->free_func(dom, ctx->alloc_pvt);
@@ -340,9 +327,12 @@ 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) {
- if ((dom->range->min <= min && dom->range->max >= max) ||
- (dom->range->min >= min && dom->range->min <= max) ||
- (dom->range->max >= min && dom->range->max <= max)) {
+ 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)) {
/* This range overlaps one already registered
* We'll try the next available slot
*/
@@ -447,8 +437,13 @@ enum idmap_error_code sss_idmap_check_collision(struct sss_idmap_ctx *ctx,
enum idmap_error_code err;
for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) {
- err = sss_idmap_check_collision_ex(dom->name, dom->sid, dom->range,
- dom->first_rid, dom->range_id,
+ struct sss_idmap_range range = { dom->range_params.min_id,
+ dom->range_params.max_id };
+
+ err = sss_idmap_check_collision_ex(dom->name, dom->sid,
+ &range,
+ dom->range_params.first_rid,
+ dom->range_params.range_id,
dom->external_mapping,
n_name, n_sid, n_range, n_first_rid,
n_range_id, n_external_mapping);
@@ -467,12 +462,22 @@ static enum idmap_error_code dom_check_collision(
enum idmap_error_code err;
for (dom = dom_list; dom != NULL; dom = dom->next) {
- err = sss_idmap_check_collision_ex(dom->name, dom->sid, dom->range,
- dom->first_rid, dom->range_id,
+ struct sss_idmap_range range = { dom->range_params.min_id,
+ dom->range_params.max_id };
+ struct sss_idmap_range new_dom_range = {
+ new_dom->range_params.min_id,
+ new_dom->range_params.max_id };
+
+
+ err = sss_idmap_check_collision_ex(dom->name, dom->sid,
+ &range,
+ dom->range_params.first_rid,
+ dom->range_params.range_id,
dom->external_mapping,
new_dom->name, new_dom->sid,
- new_dom->range, new_dom->first_rid,
- new_dom->range_id,
+ &new_dom_range,
+ new_dom->range_params.first_rid,
+ new_dom->range_params.range_id,
new_dom->external_mapping);
if (err != IDMAP_SUCCESS) {
return err;
@@ -531,21 +536,18 @@ enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx,
}
}
- dom->range = idmap_range_dup(ctx, range);
- if (dom->range == NULL) {
- err = IDMAP_OUT_OF_MEMORY;
- goto fail;
- }
+ dom->range_params.min_id = range->min;
+ dom->range_params.max_id = range->max;
if (range_id != NULL) {
- dom->range_id = idmap_strdup(ctx, range_id);
- if (dom->range_id == NULL) {
+ dom->range_params.range_id = idmap_strdup(ctx, range_id);
+ if (dom->range_params.range_id == NULL) {
err = IDMAP_OUT_OF_MEMORY;
goto fail;
}
}
- dom->first_rid = rid;
+ dom->range_params.first_rid = rid;
dom->external_mapping = external_mapping;
err = dom_check_collision(ctx->idmap_domain_info, dom);
@@ -621,10 +623,10 @@ enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx,
return IDMAP_SID_INVALID;
}
- if (rid >= idmap_domain_info->first_rid) {
- id = idmap_domain_info->range->min
- + (rid - idmap_domain_info->first_rid);
- if (id <= idmap_domain_info->range->max) {
+ 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;
}
@@ -670,8 +672,8 @@ enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx,
if (strlen(sid) > dom_len && sid[dom_len] == '-'
&& strncmp(sid, idmap_domain_info->sid, dom_len) == 0) {
- if (id >= idmap_domain_info->range->min
- && id <= idmap_domain_info->range->max) {
+ if (id >= idmap_domain_info->range_params.min_id
+ && id <= idmap_domain_info->range_params.max_id) {
return IDMAP_SUCCESS;
}
@@ -700,7 +702,7 @@ enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx,
idmap_domain_info = ctx->idmap_domain_info;
while (idmap_domain_info != NULL) {
- if (id_is_in_range(id, idmap_domain_info, &rid)) {
+ if (id_is_in_range(id, &idmap_domain_info->range_params, &rid)) {
if (idmap_domain_info->external_mapping == true
|| idmap_domain_info->sid == NULL) {
--
2.4.3
["0002-IDMAP-introduce-secondary-slices.patch" (text/x-patch)]
From 753d3625aa35e32dba1fb99ea27704a36091d95c Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 27 Nov 2015 04:15:00 -0500
Subject: [PATCH 2/2] IDMAP: introduce secondary slices
Resolves:
https://fedorahosted.org/sssd/ticket/2188
---
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 | 419 +++++++++++++++++++++++++++----
src/lib/idmap/sss_idmap.exports | 3 +
src/lib/idmap/sss_idmap.h | 58 +++++
src/lib/idmap/sss_idmap_private.h | 4 +
src/man/include/ldap_id_mapping.xml | 11 +
src/providers/ad/ad_opts.h | 1 +
src/providers/ipa/ipa_opts.h | 1 +
src/providers/ldap/ldap_opts.h | 1 +
src/providers/ldap/sdap.h | 1 +
src/providers/ldap/sdap_idmap.c | 15 +-
src/tests/cmocka/test_sss_idmap.c | 86 ++++++-
src/tests/sss_idmap-tests.c | 114 +++++++++
16 files changed, 656 insertions(+), 62 deletions(-)
diff --git a/src/config/SSSDConfig/__init__.py.in \
b/src/config/SSSDConfig/__init__.py.in index \
60129e6e7fbc96d11c539323346c22a7db6d7f23..0b6c12723a6ae00594b385dcc8adb6131a4849be \
100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -353,6 +353,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_extra_slice_max' : _('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 \
b636d93108ef0a3831970d7827895c14b0f3571c..995cec8b1842da3cf915af9f92c7d2ef88de38f5 \
100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -123,6 +123,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_extra_slice_max = 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 \
ab712fe55cdac6d247a085aeca5cc82d65966623..1a7430db407ef519b60ffb2f35982bb188fb1225 \
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_extra_slice_max = 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..e8d652cd535a5ee32a13510a337b4b6815114555 \
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_extra_slice_max = 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 7a91e419983d59bed6a8ae06f7cfd448e8e18f63..c4ae81172448d2524880ea1ee28f88baad4b2686 \
100644
--- a/src/lib/idmap/sss_idmap.c
+++ b/src/lib/idmap/sss_idmap.c
@@ -41,6 +41,7 @@ struct idmap_range_params {
char *range_id;
uint32_t first_rid;
+ struct idmap_range_params *next;
};
struct idmap_domain_info {
@@ -49,6 +50,9 @@ struct idmap_domain_info {
struct idmap_range_params range_params;
struct idmap_domain_info *next;
bool external_mapping;
+
+ struct idmap_range_params *sec_ranges;
+ bool use_sec_ranges;
};
static void *default_alloc(size_t size, void *pvt)
@@ -195,6 +199,7 @@ 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_max = SSS_IDMAP_DEFAULT_EXTRA_SLICE_MAX;
*_ctx = ctx;
@@ -204,11 +209,19 @@ enum idmap_error_code sss_idmap_init(idmap_alloc_func \
*alloc_func, static void sss_idmap_free_domain(struct sss_idmap_ctx *ctx,
struct idmap_domain_info *dom)
{
+ struct idmap_range_params *it;
+
if (ctx == NULL || dom == NULL) {
return;
}
ctx->free_func(dom->range_params.range_id, ctx->alloc_pvt);
+ /* Free list of secondary ranges */
+ for (it = dom->sec_ranges; it != NULL; it = it->next) {
+ ctx->free_func(it->range_id, ctx->alloc_pvt);
+ ctx->free_func(it, ctx->alloc_pvt);
+ }
+
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 +282,27 @@ 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_collision_sec_slices(struct idmap_range_params *sec_ranges,
+ id_t min, id_t max)
+{
+ struct idmap_range_params *it;
+
+ for (it = sec_ranges; it != NULL; it = it->next) {
+ if (check_overlap(it, min, max)) {
+ return true;
+ }
+ }
+ return false;
+}
+
enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
const char *dom_sid,
id_t *slice_num,
@@ -327,12 +361,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_overlap(&dom->range_params, min, max) ||
+ check_collision_sec_slices(dom->sec_ranges, min, max)) {
/* This range overlaps one already registered
* We'll try the next available slot
*/
@@ -486,6 +517,106 @@ static enum idmap_error_code dom_check_collision(
return IDMAP_SUCCESS;
}
+static char*
+generate_sec_slice_name(struct sss_idmap_ctx *ctx,
+ const char *domain_name, int slice_index)
+{
+ const char * SEC_SLICE_NAME_FMT = "%s#%d";
+ char *slice_name;
+ int len, len2;
+
+ len = snprintf(NULL, 0, SEC_SLICE_NAME_FMT, domain_name, slice_index + 1);
+ 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,
+ slice_index + 1);
+ 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_sec_slices(struct sss_idmap_ctx *ctx,
+ const char *domain_name,
+ uint32_t first_rid,
+ struct idmap_range_params **_sec_slices)
+{
+ struct idmap_range_params *prev = NULL;
+ struct idmap_range_params *sec_slices = NULL;
+
+ for (int i = 0; i < ctx->idmap_opts.extra_slice_max; i++) {
+ static enum idmap_error_code err;
+ struct idmap_range_params *slice;
+ char *secondary_name;
+
+ secondary_name = generate_sec_slice_name(ctx, domain_name, i);
+ 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,
@@ -566,6 +697,42 @@ 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)
+{
+ 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;
+ }
+
+ /* Todo - Add tests */
+ /* Add size of primary slice for first_rid of secondary slices. */
+ rid += ctx->idmap_opts.rangesize;
+ err = get_sec_slices(ctx, domain_name, rid,
+ &ctx->idmap_domain_info->sec_ranges);
+ if (err == IDMAP_SUCCESS) {
+ ctx->idmap_domain_info->use_sec_ranges = 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->use_sec_ranges = false;
+ }
+
+ return err;
+}
+
enum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx,
const char *domain_name,
const char *domain_sid,
@@ -584,16 +751,93 @@ 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) {
+ 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_new_sec_slide(struct sss_idmap_ctx *ctx,
+ const char *dom_name,
+ long long rid,
+ struct idmap_range_params **_slice)
+{
+ char *secondary_name;
+ enum idmap_error_code err;
+ int index;
+ int first_rid;
+ struct idmap_range_params *slice;
+
+ index = rid / ctx->idmap_opts.rangesize;
+ first_rid = index * ctx->idmap_opts.rangesize;
+
+ secondary_name = generate_sec_slice_name(ctx, dom_name, index);
+ if (secondary_name == NULL) {
+ return IDMAP_OUT_OF_MEMORY;
+ }
+
+ err = generate_slice(ctx, secondary_name, first_rid, &slice);
+ if (err == IDMAP_OUT_OF_SLICES) {
+ return err;
+ }
+
+ *_slice = slice;
+ return IDMAP_SUCCESS;
+}
+
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;
@@ -607,39 +851,68 @@ 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;
+ /* Try secondary slices */
+ if (matched_dom != NULL && matched_dom->use_sec_ranges) {
+ struct idmap_range_params *last_slide = NULL;
+ struct idmap_range_params *new_slice;
+ enum idmap_error_code err;
+
+ dom_len = strlen(matched_dom->sid);
+
+ if (parse_rid(sid, dom_len, &rid) == false) {
+ return IDMAP_SID_INVALID;
+ }
+
+ for (struct idmap_range_params *it = matched_dom->sec_ranges;
+ it != NULL; it = it->next) {
+ if (comp_id(it, rid, _id)) {
+ return IDMAP_SUCCESS;
+ }
+ last_slide = it;
+ }
+
+ /* If no secondary slide matched then new slide is added. */
+ err = get_new_sec_slide(ctx, matched_dom->name, rid, &new_slice);
+ if (err != IDMAP_SUCCESS) {
+ return err;
+ }
+
+ if (last_slide == NULL) {
+ matched_dom->sec_ranges = new_slice;
+ } else {
+ last_slide->next = new_slice;
+ }
+
+ if (comp_id(new_slice, rid, _id)) {
+ return IDMAP_SUCCESS;
+ }
+
+ }
+
+ return matched_dom ? IDMAP_NO_RANGE : IDMAP_NO_DOMAIN;
}
enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx,
@@ -687,15 +960,41 @@ 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;
CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
@@ -709,24 +1008,30 @@ 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->sec_ranges;
+ 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;
+ }
+
+ return generate_sid(ctx, idmap_domain_info->sid, rid, _sid);
+ }
}
idmap_domain_info = idmap_domain_info->next;
@@ -969,6 +1274,15 @@ sss_idmap_ctx_set_rangesize(struct sss_idmap_ctx *ctx, id_t \
rangesize) }
enum idmap_error_code
+sss_idmap_ctx_set_extra_slice_max(struct sss_idmap_ctx *ctx,
+ int extra_slice_max)
+{
+ CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
+ ctx->idmap_opts.extra_slice_max = extra_slice_max;
+ 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);
@@ -1001,6 +1315,15 @@ sss_idmap_ctx_get_rangesize(struct sss_idmap_ctx *ctx, id_t \
*_rangesize) }
enum idmap_error_code
+sss_idmap_ctx_get_extra_slide_max(struct sss_idmap_ctx *ctx,
+ int *_extra_slide_max)
+{
+ CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
+ *_extra_slide_max = ctx->idmap_opts.extra_slice_max;
+ return IDMAP_SUCCESS;
+}
+
+enum idmap_error_code
sss_idmap_domain_has_algorithmic_mapping(struct sss_idmap_ctx *ctx,
const char *dom_sid,
bool *has_algorithmic_mapping)
diff --git a/src/lib/idmap/sss_idmap.exports b/src/lib/idmap/sss_idmap.exports
index 52115636d5a6b936f18b4392e9d12adc26c85f53..d4d3d0cb50146ba62b1bbd068420be2e6ea83976 \
100644
--- a/src/lib/idmap/sss_idmap.exports
+++ b/src/lib/idmap/sss_idmap.exports
@@ -8,13 +8,16 @@ SSS_IDMAP_0.4 {
sss_idmap_ctx_set_lower;
sss_idmap_ctx_set_upper;
sss_idmap_ctx_set_rangesize;
+ sss_idmap_ctx_set_extra_slice_max;
sss_idmap_ctx_get_autorid;
sss_idmap_ctx_get_lower;
sss_idmap_ctx_get_upper;
sss_idmap_ctx_get_rangesize;
+ sss_idmap_ctx_get_extra_slice_max;
sss_idmap_calculate_range;
sss_idmap_add_domain;
sss_idmap_add_domain_ex;
+ sss_idmap_add_auto_domain_ex;
sss_idmap_check_collision;
sss_idmap_check_collision_ex;
sss_idmap_sid_to_unix;
diff --git a/src/lib/idmap/sss_idmap.h b/src/lib/idmap/sss_idmap.h
index 0797083293f7e010962828ddcd72709b290859b9..b90f5067afffa931682229a2ebf6db23b1568606 \
100644
--- a/src/lib/idmap/sss_idmap.h
+++ b/src/lib/idmap/sss_idmap.h
@@ -175,6 +175,16 @@ enum idmap_error_code
sss_idmap_ctx_set_rangesize(struct sss_idmap_ctx *ctx, id_t rangesize);
/**
+ * @brief Set the maximal number of secondary slices available for domain
+ *
+ * @param[in] ctx idmap context
+ * @param[in] extra_slice_max maximal number of secondary slices
+ */
+enum idmap_error_code
+sss_idmap_ctx_set_extra_slice_max(struct sss_idmap_ctx *ctx,
+ int extra_slice_max);
+
+/**
* @brief Check if autorid compatibility mode is set
*
* @param[in] ctx idmap context
@@ -211,6 +221,16 @@ enum idmap_error_code
sss_idmap_ctx_get_rangesize(struct sss_idmap_ctx *ctx, id_t *rangesize);
/**
+ * @brief Get the maximal number of secondary slices available for domain
+ *
+ * @param[in] ctx idmap context
+ * @param[out] _extra_slice_max maximal number of secondary slices
+ */
+enum idmap_error_code
+sss_idmap_ctx_get_extra_slide_max(struct sss_idmap_ctx *ctx,
+ int *_extra_slide_max);
+
+/**
* @brief Calculate new range of available POSIX IDs
*
* @param[in] ctx Idmap context
@@ -291,6 +311,44 @@ 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.
+ *
+ * @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);
+
+/**
* @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..f09f60e00450e4e65baced99d1cb77da4165fa2e \
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_MAX 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_max;
};
struct sss_idmap_ctx {
diff --git a/src/man/include/ldap_id_mapping.xml \
b/src/man/include/ldap_id_mapping.xml index \
17ef803289d14fa52b725c90062ee4ba0379acd0..bd72bc01186762a15f94de88e4a3708d3dc0f7ad \
100644
--- a/src/man/include/ldap_id_mapping.xml
+++ b/src/man/include/ldap_id_mapping.xml
@@ -243,6 +243,17 @@ ldap_schema = ad
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>ldap_idmap_extra_slice_max (integer)</term>
+ <listitem>
+ <para>
+ Number of secondary slices to use for ID mapping.
+ </para>
+ <para>
+ Default: 10
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect3>
</refsect2>
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
index 00586a7ada63ad4c89630e9589d3ff75d1726703..b25b4f44273202e3cccc1008d99c989a02ac1efc \
100644
--- a/src/providers/ad/ad_opts.h
+++ b/src/providers/ad/ad_opts.h
@@ -138,6 +138,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_extra_slice_max", 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.h b/src/providers/ipa/ipa_opts.h
index 78949e3ddec95f7f4303eab905bbbf6ec14ed6ae..e83c697e5898ab73a7b84f34e29e5eafed523c8a \
100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -150,6 +150,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_extra_slice_max", 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.h b/src/providers/ldap/ldap_opts.h
index 9f58db5bd9eef1391e97c1890cbff94c2a5406d6..d43c8698f960dfd87ee1590618384790f45edcd5 \
100644
--- a/src/providers/ldap/ldap_opts.h
+++ b/src/providers/ldap/ldap_opts.h
@@ -114,6 +114,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_extra_slice_max", 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 edfbf229b4c4396592020de931eba5f83a8f06ed..4405d3ce554de2fda90073dcaee994a5a484a4d9 \
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_MAX,
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 f4a065b0b251b868344eae856c3655ff30b8a5dc..324838fd5b0f51ae02862f11b7f92f1dcfefed80 \
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);
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_max;
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_max = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
+ SDAP_IDMAP_EXTRA_SLICE_MAX);
/* 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_max(idmap_ctx->map, extra_slice_max);
if (err != IDMAP_SUCCESS) {
/* This should never happen */
DEBUG(SSSDBG_CRIT_FAILURE, "sss_idmap_ctx corrupted\n");
@@ -377,8 +382,8 @@ 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);
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..91e38546436bb3c248e63dcba0bbc3ba425c3483 \
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,26 @@ 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);
+ } 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);
+ } 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 +135,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 +159,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 +171,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 +297,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, 351800000);
+
+ 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 +588,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..3d2fbde196364d2b078ef7090cbf40c69fa6e90c \
100644
--- a/src/tests/sss_idmap-tests.c
+++ b/src/tests/sss_idmap-tests.c
@@ -85,6 +85,17 @@ 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_MAX};
+
+ err = sss_idmap_add_auto_domain_ex(idmap_ctx, "test.dom", "S-1-5-21-1-2-3",
+ &range, NULL, 0, false);
+
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_auto_domain_ex failed.");
+}
+
START_TEST(idmap_test_is_domain_sid)
{
size_t c;
@@ -225,6 +236,63 @@ START_TEST(idmap_test_sid2uid)
}
END_TEST
+START_TEST(idmap_test_sid2uid_ss)
+{
+ enum idmap_error_code err;
+ uint32_t id;
+
+ 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 == 351800000,
+ "sss_idmap_sid_to_unix returned wrong id, "
+ "got [%d], expected [%d].", id, 351800000);
+
+ 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 == 263810000,
+ "sss_idmap_sid_to_unix returned wrong id, "
+ "got [%d], expected [%d].", id, 265210000);
+}
+END_TEST
+
+START_TEST(idmap_test_sid2uid_ext_sec_slices)
+{
+ enum idmap_error_code err;
+ uint32_t id;
+ char *sid;
+
+ err = sss_idmap_unix_to_sid(idmap_ctx, 351800000, &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 == 351800000,
+ "sss_idmap_sid_to_unix returned wrong id, "
+ "got [%d], expected [%d].", id, 351800000);
+
+ /* Secondary ranges were expanded by sid_to_unix call */
+ err = sss_idmap_unix_to_sid(idmap_ctx, 351800000, &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_bin_sid2uid)
{
enum idmap_error_code err;
@@ -284,6 +352,34 @@ 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, 10000, &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, 263810000, &sid);
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed.");
+ fail_unless(strcmp(sid, "S-1-5-21-1-2-3-210000") == 0,
+ "sss_idmap_unix_to_sid returned wrong SID, "
+ "expected [%s], got [%s].", "S-1-5-21-1-2-3-210000", sid);
+
+ sss_idmap_free_sid(idmap_ctx, sid);
+}
+END_TEST
+
START_TEST(idmap_test_uid2dom_sid)
{
enum idmap_error_code err;
@@ -618,6 +714,24 @@ 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);
+
return s;
}
int main(int argc, const char *argv[])
--
2.4.3
_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic