On Wed, Jan 13, 2016 at 12:11:48PM +0100, Pavel Reichl wrote:
>
>
> On 01/12/2016 04:46 PM, Pavel Reichl wrote:
>> ...
>>>
>>> I would add a test where you set the idmap parameters to some smaller
>>> values than the default, e.g. range size to 10 and the number of initial
>>> slices to 5. Then initialize the id-mapping for some domain and run a
>>> loop with rid values from 0 to 80, call sss_idmap_sid_to_unix() and save
>>> the POSIX IDs in an array. Then run sss_idmap_unix_to_sid() with the
>>> values from the array and check if the expected SID is returned. This
>>> will exercise adding more slices than initialized at startup and make
>>> sure that there are no gaps between the slices or off-by-one errors at
>>> the boundary of the slices.
>>
>> OK, I will work on this now.
>
> Done in attached patch (only change in the patch set).
Thank you. First, the patches work very well in my testing (after adding
the fix for the off-by-one error you found). Nevertheless I have two
comments which hopefully make the patches more consistent with the
current usage and maybe even a bit more robust.
The first was suggested by Simo. For the initial idrange we use the
domain SID as input for murmurhash. For the secondary slices currently
the domain name with a #{rangenumber} suffix is used. Simo suggested to
use "domain-SID"-"first-RID-of-the-new-idrange" as input. Both
formats
are equivalent because the domain-SID maps 1:1 to the domain name and
the first RID is rangenumber*rangesize. Nevertheless I think the scheme
Simo suggested is better, because it continues to use the domain-SID as
we already do for the initial idrange (I'm afraid using the domain name
here was a suggestion by me, I'm sorry I didn't thought about this more
carefully). Additionally using the first RID instead of the rangenumber
make sense because the first RID is a property of the idrange and
independent of the SSSD configuration parameters.
Last patch implements changes described in prev. paragraph. In final patch set I will
merge it with second patch. I just want do make the change obvious.
While the first suggestion one is a minor change the second is a bit
larger. I checked how the idranges are used by the IPA provider a
realized that here SSSD already supports multiple ranges for the same
domain as well. If on the IPA server multiple ranges are configured for
the same domain for each a new struct idmap_domain_info is created and
added to the list. To keep track of the different ranges of the domain
the range_id field is filled with the server side name of the idrange. I
think it would make the usage more consistent, might make the plan to
support manually configured range more easy and might even make the
given patches a bit more easy if this can be adopted here as well. So
instead of using or adding a secondary range if a RID outside of the
existing ranges is found a new suitable struct idmap_domain_info is
created and added to the list. The sec_ranges and use_sec_ranges
elements can still be used but maybe should get different names.
use_sec_ranges should still indicate if automatically adding ranges is
allowed for the domain or not. sec_ranges should only be used as helpers
in the sss_idmap_unix_to_sid() request if no matching range is found for
the given POSIX ID. This is still needed to have a cut-off to not search
the full POSIX ID space and to avoid the recalculation of the murmur
hash in case SSSD is spammed with useless getpwuid() or getgrgid()
requests.
I hope I was able to explain and justify the suggestions properly,
please ping you if you have questions.
bye,
Sumit
>
>>>
>>> Additionally I think it would be more reliable if the secondary slices
>>> can be saved to the cache and can be read at startup as well. I'm
>>> thinking of the case when there is a collision in the secondary slices
>>> of different domains. Currently we try to find a unused slice if a
>>> collision is detected. But if after a restart the slices are initialized
>>> in a different order the colliding slices might get swapped. Maybe
>>> callbacks can be added to sss_idmap_add_auto_domain_ex() which can be
>>> set to a function which can reads and writes the data from the cache?
>>
>> OK, I will work on this after the test is done.
>
> Working on this now.
>
>>
>>
>> Thanks.
>>
>>>
>>> bye,
>>> Sumit
>>> _______________________________________________
>>> sssd-devel mailing list
>>> sssd-devel(a)lists.fedorahosted.org
>>>
https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org
>>>
>>
>>
>> _______________________________________________
>> sssd-devel mailing list
>> sssd-devel(a)lists.fedorahosted.org
>>
https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org
>>
> From ef2ff4c1ee7e1c76fc55eb223f15f396e1af885f Mon Sep 17 00:00:00 2001
> From: Pavel Reichl <preichl(a)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 | 117 ++++++++++++++++++++++++----------------------
> 1 file changed, 60 insertions(+), 57 deletions(-)
>
> diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
> index
4c453120539a549807e9b6bb4db2dc396c1b3152..fce3010d8e840fa86bc8225ef000e6e789072108 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
> */
> @@ -445,10 +435,17 @@ enum idmap_error_code sss_idmap_check_collision(struct
sss_idmap_ctx *ctx,
> {
> struct idmap_domain_info *dom;
> enum idmap_error_code err;
> + struct sss_idmap_range range;
>
> 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,
> +
> + range.min = dom->range_params.min_id;
> + range.max = 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);
> @@ -459,20 +456,29 @@ enum idmap_error_code sss_idmap_check_collision(struct
sss_idmap_ctx *ctx,
> return IDMAP_SUCCESS;
> }
>
> -static enum idmap_error_code dom_check_collision(
> - struct idmap_domain_info *dom_list,
> - struct idmap_domain_info *new_dom)
> +static enum
> +idmap_error_code dom_check_collision(struct idmap_domain_info *dom_list,
> + struct idmap_domain_info *new_dom)
> {
> struct idmap_domain_info *dom;
> enum idmap_error_code err;
> + struct sss_idmap_range range;
> + struct sss_idmap_range new_dom_range = { new_dom->range_params.min_id,
> + new_dom->range_params.max_id };
>
> 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,
> + range.min = dom->range_params.min_id;
> + range.max = 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 +537,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 +624,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 +673,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 +703,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
>
> From 9ccec3ab9f1d118acb307fdbe0ca2954d89f2db9 Mon Sep 17 00:00:00 2001
> From: Pavel Reichl <preichl(a)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 | 470 +++++++++++++++++++++++++++----
> src/lib/idmap/sss_idmap.exports | 5 +-
> src/lib/idmap/sss_idmap.h | 59 ++++
> 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 | 15 +-
> src/tests/cmocka/test_sss_idmap.c | 86 +++++-
> src/tests/sss_idmap-tests.c | 191 +++++++++++++
> 16 files changed, 795 insertions(+), 63 deletions(-)
>
> diff --git a/src/config/SSSDConfig/__init__.py.in
b/src/config/SSSDConfig/__init__.py.in
> index
fe2971d993ccf2975bbddbe6c74572ab9f5d4e51..6506dbd3cab3acfbc18443686d87845389b71a43 100644
> --- a/src/config/SSSDConfig/__init__.py.in
> +++ b/src/config/SSSDConfig/__init__.py.in
> @@ -354,6 +354,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_init' : _('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
5eb546caac913b839112a70bd81dbde2c7ff2d9f..8f828db819e9d33d001bedc13996f52fd89a188d 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_init = 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..35bf6facda7ae363087e64efc465959653a43f90 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_init = 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..54c50c7798498b20d3875c0bbd5db18be6ea2744 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_init = 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
fce3010d8e840fa86bc8225ef000e6e789072108..fd4be746ba338891ae5686e1b9f49d7664d91694 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,12 +199,29 @@ 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_secondary_ranges(struct sss_idmap_ctx *ctx,
> + struct idmap_range_params *sec_ranges)
> +{
> + struct idmap_range_params *it = sec_ranges;
> + struct idmap_range_params *tmp;
> +
> + 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 +230,9 @@ static void sss_idmap_free_domain(struct sss_idmap_ctx *ctx,
> }
>
> ctx->free_func(dom->range_params.range_id, ctx->alloc_pvt);
> +
> + free_secondary_ranges(ctx, dom->sec_ranges);
> +
> 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 +293,36 @@ 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;
> +}
> +
> +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)
> + || check_collision_sec_slices(sec_ranges, 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 +381,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,
dom->sec_ranges,
> + min, max)) {
> /* This range overlaps one already registered
> * We'll try the next available slot
> */
> @@ -487,6 +538,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, 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;
> + 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_name, i + 1);
> + 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 +717,61 @@ 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;
> + }
> +
> + if (external_mapping) {
> + /* There's no point in generating secondary ranges if external_mapping
> + is enabled. */
> + ctx->idmap_domain_info->use_sec_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->use_sec_ranges = false;
> + return IDMAP_SUCCESS;
> + }
> +
> + /* 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,
> @@ -585,16 +790,140 @@ 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_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) {
> + ctx->free_func(secondary_name, ctx->alloc_pvt);
> + return err;
> + }
> +
> + *_slice = slice;
> + return IDMAP_SUCCESS;
> +}
> +
> +static enum idmap_error_code
> +try_secondary_slices(struct sss_idmap_ctx *ctx,
> + struct idmap_domain_info *matched_dom,
> + const char *sid,
> + uint32_t *_id)
> +{
> + struct idmap_range_params *last_slide = NULL;
> + struct idmap_range_params *new_slice;
> + enum idmap_error_code err;
> + size_t dom_len;
> + long long rid;
> +
> + 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_ERROR;
> + }
> + 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;
> @@ -608,39 +937,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->use_sec_ranges) {
> + return try_secondary_slices(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 +1012,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);
>
> @@ -710,24 +1060,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;
> @@ -970,6 +1326,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);
> @@ -1002,6 +1367,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_init;
> + 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..ad1818e10506857b15927d95523b104fcf18f890 100644
> --- a/src/lib/idmap/sss_idmap.exports
> +++ b/src/lib/idmap/sss_idmap.exports
> @@ -1,4 +1,4 @@
> -SSS_IDMAP_0.4 {
> +SSS_IDMAP_0.5 {
>
> # public functions
> global:
> @@ -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_init;
> 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_init;
> 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..c19f6ad7bd4c4628d08bf5d90888d89bf1c79d5d 100644
> --- a/src/lib/idmap/sss_idmap.h
> +++ b/src/lib/idmap/sss_idmap.h
> @@ -175,6 +175,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
> @@ -211,6 +222,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_init 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 +312,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..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..301a7cc9ef62e85f5553d90c0323cc614ec6938c 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_extra_slice_init (integer)</term>
> + <listitem>
> + <para>
> + Number of secondary slices to use for ID mapping
> + that are generated at the startup.
> + </para>
> + <para>
> + Note: Additional secondary slices might be generated
> + when SID is being mapped to UNIX uid and RID part of
> + SID is out of range for secondary slices generated so
> + far. If value of ldap_idmap_extra_slice_init 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
4ea96637ca7264c76109ed8c2f7b5e8a94f73bfe..18a21e205cebd0ac14672ebf97b0ede54c63d8f8 100644
> --- a/src/providers/ad/ad_opts.c
> +++ b/src/providers/ad/ad_opts.c
> @@ -135,6 +135,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_init", 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
bc983ec32d63c37b6fdf06d6009df9084f82d4bf..7ff6589f8cd5342d3f0ef5a8f4210013bbe06bc7 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_extra_slice_init", 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..85bc42fdf8cd198e29fcadaa161f92d76092d5bd 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_extra_slice_init", 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..b82c5475bcb12188fb400c62be6f682e1e2ca541 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
4d9de8a447d46dedc8df49dc5663037248eb6996..2bdb4c290d6d2c2a70ec72e2d5e8bd72f44d0130 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_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");
> @@ -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..a1d1659f7152960f002d84eb16d244fa83618079 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,20 @@ 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);
> +
> + fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_auto_domain_ex
failed.");
> +}
> +
> START_TEST(idmap_test_is_domain_sid)
> {
> size_t c;
> @@ -225,6 +253,100 @@ 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 == 1638210000,
> + "sss_idmap_sid_to_unix returned wrong id, "
> + "got [%d], expected [%d].", id, 1638210000);
> +}
> +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_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 +406,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,
> + 111400000,
> + &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 +772,43 @@ 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 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.4.3
>
> _______________________________________________
> sssd-devel mailing list
> sssd-devel(a)lists.fedorahosted.org
>
https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org
_______________________________________________
sssd-devel mailing list
sssd-devel(a)lists.fedorahosted.org
https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org