From c63c8a63ab062a9c4397278a29b12bd32c4f3895 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Mon, 10 Jun 2013 13:24:46 +0200 Subject: idmap: add option to indicate external_mapping The idea is that ranges for IDs from AD can be used in libsss_idmap as well, but whenever a mapping is requested for this range a specific error code IDMAP_EXTERNAL is returned to tell SSSD to do an AD lookup. This way SSSD does not need to inspect the ranges itself but all is done inside if libsss_idmap. Fixes https://fedorahosted.org/sssd/ticket/1960 --- src/lib/idmap/sss_idmap.c | 25 +++++++++++++++++++++++-- src/lib/idmap/sss_idmap.h | 22 ++++++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c index b04d849a..0a145c47 100644 --- a/src/lib/idmap/sss_idmap.c +++ b/src/lib/idmap/sss_idmap.c @@ -40,6 +40,7 @@ struct idmap_domain_info { struct idmap_domain_info *next; uint32_t first_rid; char *range_id; + bool external_mapping; }; static void *default_alloc(size_t size, void *pvt) @@ -359,9 +360,17 @@ static enum idmap_error_code dom_check_collision( return IDMAP_COLLISION; } + /* check if external_mapping is consistent */ + if (strcasecmp(new_dom->name, dom->name) == 0 + && strcasecmp(new_dom->sid, dom->sid) == 0 + && new_dom->external_mapping != dom->external_mapping) { + return IDMAP_COLLISION; + } + /* check if RID ranges overlap */ if (strcasecmp(new_dom->name, dom->name) == 0 && strcasecmp(new_dom->sid, dom->sid) == 0 + && new_dom->external_mapping == false && new_dom->first_rid >= dom->first_rid && new_dom->first_rid <= dom->first_rid + (dom->range->max - dom->range->min)) { @@ -377,7 +386,8 @@ enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx, const char *domain_sid, struct sss_idmap_range *range, const char *range_id, - uint32_t rid) + uint32_t rid, + bool external_mapping) { struct idmap_domain_info *dom = NULL; enum idmap_error_code err; @@ -425,6 +435,7 @@ enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx, } dom->first_rid = rid; + dom->external_mapping = external_mapping; err = dom_check_collision(ctx->idmap_domain_info, dom); if (err != IDMAP_SUCCESS) { @@ -451,7 +462,7 @@ enum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx, struct sss_idmap_range *range) { return sss_idmap_add_domain_ex(ctx, domain_name, domain_sid, range, NULL, - 0); + 0, false); } static bool sss_idmap_sid_is_builtin(const char *sid) @@ -490,6 +501,11 @@ enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx, 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; + } + errno = 0; rid = strtoull(sid + dom_len + 1, &endptr, 10); if (errno != 0 || rid > UINT32_MAX || *endptr != '\0') { @@ -530,6 +546,11 @@ enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx, while (idmap_domain_info != NULL) { if (id_is_in_range(id, idmap_domain_info, &rid)) { + + if (idmap_domain_info->external_mapping == true) { + 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; diff --git a/src/lib/idmap/sss_idmap.h b/src/lib/idmap/sss_idmap.h index 5536aeb7..824a7c62 100644 --- a/src/lib/idmap/sss_idmap.h +++ b/src/lib/idmap/sss_idmap.h @@ -77,7 +77,10 @@ enum idmap_error_code { IDMAP_OUT_OF_SLICES, /** New domain collides with existing one */ - IDMAP_COLLISION + IDMAP_COLLISION, + + /** External source should be consulted for idmapping */ + IDMAP_EXTERNAL }; /** @@ -260,6 +263,13 @@ enum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx, * 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 @@ -273,7 +283,8 @@ enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx, const char *domain_sid, struct sss_idmap_range *range, const char *range_id, - uint32_t rid); + uint32_t rid, + bool external_mapping); /** * @brief Translate SID to a unix UID or GID * @@ -286,6 +297,7 @@ enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx, * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context + * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx, const char *sid, @@ -303,6 +315,7 @@ enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx, * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context + * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_dom_sid_to_unix(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, @@ -321,6 +334,7 @@ enum idmap_error_code sss_idmap_dom_sid_to_unix(struct sss_idmap_ctx *ctx, * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context + * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_bin_sid_to_unix(struct sss_idmap_ctx *ctx, uint8_t *bin_sid, @@ -339,6 +353,7 @@ enum idmap_error_code sss_idmap_bin_sid_to_unix(struct sss_idmap_ctx *ctx, * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context + * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_smb_sid_to_unix(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, @@ -356,6 +371,7 @@ enum idmap_error_code sss_idmap_smb_sid_to_unix(struct sss_idmap_ctx *ctx, * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_NO_RANGE: The provided ID cannot be found in the domains added * to the idmap context + * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx, uint32_t id, @@ -372,6 +388,7 @@ enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx, * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_NO_RANGE: The provided ID cannot be found in the domains added * to the idmap context + * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_unix_to_dom_sid(struct sss_idmap_ctx *ctx, uint32_t id, @@ -390,6 +407,7 @@ enum idmap_error_code sss_idmap_unix_to_dom_sid(struct sss_idmap_ctx *ctx, * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_NO_RANGE: The provided ID cannot be found in the domains added * to the idmap context + * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_unix_to_bin_sid(struct sss_idmap_ctx *ctx, uint32_t id, -- cgit