From 26efe39404ddda88ae4a77d335773b19a1b46e5a Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Mon, 10 Jun 2013 16:47:14 +0200 Subject: [PATCH 5/8] idmap: add calls to check if ID mapping conforms to ranges When ID are mapped externally it must be checked if the extern ID falls into the right configured range to avoid ID conflicts. Fixes https://fedorahosted.org/sssd/ticket/1960 --- src/lib/idmap/sss_idmap.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ src/lib/idmap/sss_idmap.h | 75 ++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 0 deletions(-) diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c index ca7c5a0..86af3d3 100644 --- a/src/lib/idmap/sss_idmap.c +++ b/src/lib/idmap/sss_idmap.c @@ -541,6 +541,50 @@ enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx, return no_range ? IDMAP_NO_RANGE : IDMAP_NO_DOMAIN; } +enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx, + const char *sid, + uint32_t id) +{ + struct idmap_domain_info *idmap_domain_info; + size_t dom_len; + bool no_range = false; + + if (sid == NULL) { + return IDMAP_ERROR; + } + + CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); + + if (ctx->idmap_domain_info == NULL) { + return IDMAP_NO_DOMAIN; + } + + idmap_domain_info = ctx->idmap_domain_info; + + if (sss_idmap_sid_is_builtin(sid)) { + return IDMAP_BUILTIN_SID; + } + + 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 (id >= idmap_domain_info->range->min + && id <= idmap_domain_info->range->max) { + return IDMAP_SUCCESS; + } + + no_range = true; + } + } + + idmap_domain_info = idmap_domain_info->next; + } + + return no_range ? IDMAP_NO_RANGE : IDMAP_SID_UNKNOWN; +} enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx, uint32_t id, char **_sid) @@ -656,6 +700,72 @@ done: return err; } +enum idmap_error_code sss_idmap_check_dom_sid_to_unix(struct sss_idmap_ctx *ctx, + struct sss_dom_sid *dom_sid, + uint32_t id) +{ + enum idmap_error_code err; + char *sid; + + CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); + + err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + err = sss_idmap_check_sid_unix(ctx, sid, id); + +done: + ctx->free_func(sid, ctx->alloc_pvt); + + return err; +} + +enum idmap_error_code sss_idmap_check_bin_sid_unix(struct sss_idmap_ctx *ctx, + uint8_t *bin_sid, + size_t length, + uint32_t id) +{ + enum idmap_error_code err; + char *sid; + + CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); + + err = sss_idmap_bin_sid_to_sid(ctx, bin_sid, length, &sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + err = sss_idmap_check_sid_unix(ctx, sid, id); + +done: + ctx->free_func(sid, ctx->alloc_pvt); + + return err; +} + +enum idmap_error_code sss_idmap_check_smb_sid_unix(struct sss_idmap_ctx *ctx, + struct dom_sid *smb_sid, + uint32_t id) +{ + enum idmap_error_code err; + char *sid; + + CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); + + err = sss_idmap_smb_sid_to_sid(ctx, smb_sid, &sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + err = sss_idmap_check_sid_unix(ctx, sid, id); + +done: + ctx->free_func(sid, ctx->alloc_pvt); + + return err; +} enum idmap_error_code sss_idmap_unix_to_dom_sid(struct sss_idmap_ctx *ctx, uint32_t id, struct sss_dom_sid **_dom_sid) diff --git a/src/lib/idmap/sss_idmap.h b/src/lib/idmap/sss_idmap.h index b56e62a..3b3e6a4 100644 --- a/src/lib/idmap/sss_idmap.h +++ b/src/lib/idmap/sss_idmap.h @@ -358,6 +358,81 @@ enum idmap_error_code sss_idmap_smb_sid_to_unix(struct sss_idmap_ctx *ctx, uint32_t *id); /** + * @brief Check if a SID and a unix UID or GID belong to the same range + * + * @param[in] ctx Idmap context + * @param[in] sid Zero-terminated string representation of the SID + * @param[in] id Unix UID or GID + * + * @return + * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context + * - #IDMAP_SID_INVALID: Invalid SID provided + * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the + * idmap context + * - #IDMAP_NO_RANGE No matching ID range found + */ +enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx, + const char *sid, + uint32_t id); + +/** + * @brief Check if a SID structure and a unix UID or GID belong to the same range + * + * @param[in] ctx Idmap context + * @param[in] dom_sid SID structure + * @param[in] id Unix UID or GID + * + * @return + * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context + * - #IDMAP_SID_INVALID: Invalid SID provided + * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the + * idmap context + * - #IDMAP_NO_RANGE No matching ID range found + */ +enum idmap_error_code sss_idmap_check_dom_sid_unix(struct sss_idmap_ctx *ctx, + struct sss_dom_sid *dom_sid, + uint32_t id); + +/** + * @brief Check if a binary SID and a unix UID or GID belong to the same range + * + * @param[in] ctx Idmap context + * @param[in] bin_sid Array with the binary SID + * @param[in] length Size of the array containing the binary SID + * @param[in] id Unix UID or GID + * + * @return + * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context + * - #IDMAP_SID_INVALID: Invalid SID provided + * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the + * idmap context + * - #IDMAP_NO_RANGE No matching ID range found + */ +enum idmap_error_code sss_idmap_check_bin_sid_unix(struct sss_idmap_ctx *ctx, + uint8_t *bin_sid, + size_t length, + uint32_t id); + +/** + * @brief Check if a Samba dom_sid structure and a unix UID or GID belong to + * the same range + * + * @param[in] ctx Idmap context + * @param[in] smb_sid Samba dom_sid structure + * @param[in] id Unix UID or GID + * + * @return + * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context + * - #IDMAP_SID_INVALID: Invalid SID provided + * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the + * idmap context + * - #IDMAP_NO_RANGE No matching ID range found + */ +enum idmap_error_code sss_idmap_check_smb_sid_unix(struct sss_idmap_ctx *ctx, + struct dom_sid *smb_sid, + uint32_t id); + +/** * @brief Translate unix UID or GID to a SID * * @param[in] ctx Idmap context -- 1.7.7.6