From 2998435fcc95857b73049b3955af9889ab595f24 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 24 May 2012 12:39:56 +0200 Subject: sss_idmap: add support for samba struct dom_sid The samba ndr libraries use struct dom_sid to handle SIDs. Since there is no public samba library which offers conversion from other representations, e.g. as string, this is added to libsss_idmap. To avoid compile-time or run-time dependency to any samba library or header file the definition of the struct is copied here. --- src/lib/idmap/sss_idmap.h | 107 +++++++++++++++++++++++ src/lib/idmap/sss_idmap_conv.c | 179 ++++++++++++++++++++++++++++++++++++++ src/lib/idmap/sss_idmap_private.h | 19 ++++ 3 files changed, 305 insertions(+) (limited to 'src/lib') diff --git a/src/lib/idmap/sss_idmap.h b/src/lib/idmap/sss_idmap.h index a3ec919c..6b7cbe50 100644 --- a/src/lib/idmap/sss_idmap.h +++ b/src/lib/idmap/sss_idmap.h @@ -97,6 +97,13 @@ struct sss_dom_sid; */ struct sss_idmap_ctx; +/** + * Placeholder for Samba's struct dom_sid. Consumers of libsss_idmap should + * include an appropriate Samba header file to define struct dom_sid. We use + * it here to avoid a hard dependency on Samba devel packages. + */ +struct dom_sid; + /** * @brief Initialize idmap context * @@ -375,6 +382,106 @@ enum idmap_error_code sss_idmap_dom_sid_to_sid(struct sss_idmap_ctx *ctx, enum idmap_error_code sss_idmap_sid_to_dom_sid(struct sss_idmap_ctx *ctx, const char *sid, struct sss_dom_sid **dom_sid); + +/** + * @brief Convert SID string to Samba dom_sid structure + * + * @param[in] ctx Idmap context + * @param[in] sid Zero-terminated string representation of the SID + * @param[out] smb_sid Samba dom_sid structure, + * must be freed if not needed anymore + * + * @return + * - #IDMAP_SID_INVALID: Given SID is invalid + * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result + */ +enum idmap_error_code sss_idmap_sid_to_smb_sid(struct sss_idmap_ctx *ctx, + const char *sid, + struct dom_sid **smb_sid); + +/** + * @brief Convert Samba dom_sid structure to SID string + * + * @param[in] ctx Idmap context + * @param[in] smb_sid Samba dom_sid structure + * @param[out] sid Zero-terminated string representation of the SID, + * must be freed if not needed anymore + * + * @return + * - #IDMAP_SID_INVALID: Given SID is invalid + * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result + */ +enum idmap_error_code sss_idmap_smb_sid_to_sid(struct sss_idmap_ctx *ctx, + struct dom_sid *smb_sid, + char **sid); + +/** + * @brief Convert SID stucture to Samba dom_sid structure + * + * @param[in] ctx Idmap context + * @param[in] dom_sid SID structure + * @param[out] smb_sid Samba dom_sid structure, + * must be freed if not needed anymore + * + * @return + * - #IDMAP_SID_INVALID: Given SID is invalid + * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result + */ +enum idmap_error_code sss_idmap_dom_sid_to_smb_sid(struct sss_idmap_ctx *ctx, + struct sss_dom_sid *dom_sid, + struct dom_sid **smb_sid); + +/** + * @brief Convert Samba dom_sid structure to SID structure + * + * @param[in] ctx Idmap context + * @param[in] smb_sid Samba dom_sid structure + * @param[out] dom_sid SID structure, + * must be freed if not needed anymore + * + * @return + * - #IDMAP_SID_INVALID: Given SID is invalid + * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result + */ +enum idmap_error_code sss_idmap_smb_sid_to_dom_sid(struct sss_idmap_ctx *ctx, + struct dom_sid *smb_sid, + struct sss_dom_sid **dom_sid); + +/** + * @brief Convert binary SID to Samba dom_sid structure + * + * @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[out] smb_sid Samba dom_sid structure, + * must be freed if not needed anymore + * + * @return + * - #IDMAP_SID_INVALID: Given SID is invalid + * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result + */ +enum idmap_error_code sss_idmap_bin_sid_to_smb_sid(struct sss_idmap_ctx *ctx, + const uint8_t *bin_sid, + size_t length, + struct dom_sid **smb_sid); + +/** + * @brief Convert Samba dom_sid structure to binary SID + * + * @param[in] ctx Idmap context + * @param[in] smb_sid Samba dom_sid structure + * @param[out] bin_sid Array with the binary SID, + * must be freed if not needed anymore + * @param[out] length Size of the array containing the binary SID + * + * @return + * - #IDMAP_SID_INVALID: Given SID is invalid + * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result + */ +enum idmap_error_code sss_idmap_smb_sid_to_bin_sid(struct sss_idmap_ctx *ctx, + struct dom_sid *smb_sid, + uint8_t **bin_sid, + size_t *length); /** * @} */ diff --git a/src/lib/idmap/sss_idmap_conv.c b/src/lib/idmap/sss_idmap_conv.c index df96fcc3..1d3ffb3b 100644 --- a/src/lib/idmap/sss_idmap_conv.c +++ b/src/lib/idmap/sss_idmap_conv.c @@ -59,6 +59,7 @@ enum idmap_error_code sss_idmap_bin_sid_to_dom_sid(struct sss_idmap_ctx *ctx, if (dom_sid == NULL) { return IDMAP_OUT_OF_MEMORY; } + memset(dom_sid, 0, sizeof(struct sss_dom_sid)); /* Safely copy in the SID revision number */ dom_sid->sid_rev_num = (uint8_t) *(bin_sid + p); @@ -387,3 +388,181 @@ done: return err; } + +enum idmap_error_code sss_idmap_sid_to_smb_sid(struct sss_idmap_ctx *ctx, + const char *sid, + struct dom_sid **_smb_sid) +{ + enum idmap_error_code err; + struct sss_dom_sid *dom_sid = NULL; + struct dom_sid *smb_sid = NULL; + + err = sss_idmap_sid_to_dom_sid(ctx, sid, &dom_sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + err = sss_idmap_dom_sid_to_smb_sid(ctx, dom_sid, &smb_sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + *_smb_sid = smb_sid; + err = IDMAP_SUCCESS; + +done: + ctx->free_func(dom_sid, ctx->alloc_pvt); + if (err != IDMAP_SUCCESS) { + ctx->free_func(smb_sid, ctx->alloc_pvt); + } + + return err; +} + +enum idmap_error_code sss_idmap_smb_sid_to_sid(struct sss_idmap_ctx *ctx, + struct dom_sid *smb_sid, + char **_sid) +{ + enum idmap_error_code err; + struct sss_dom_sid *dom_sid = NULL; + char *sid = NULL; + + err = sss_idmap_smb_sid_to_dom_sid(ctx, smb_sid, &dom_sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + *_sid = sid; + err = IDMAP_SUCCESS; + +done: + ctx->free_func(dom_sid, ctx->alloc_pvt); + if (err != IDMAP_SUCCESS) { + ctx->free_func(sid, ctx->alloc_pvt); + } + + return err; +} + +enum idmap_error_code sss_idmap_dom_sid_to_smb_sid(struct sss_idmap_ctx *ctx, + struct sss_dom_sid *dom_sid, + struct dom_sid **_smb_sid) +{ + struct dom_sid *smb_sid; + size_t c; + + smb_sid = ctx->alloc_func(sizeof(struct dom_sid), ctx->alloc_pvt); + if (smb_sid == NULL) { + return IDMAP_OUT_OF_MEMORY; + } + memset(smb_sid, 0, sizeof(struct dom_sid)); + + smb_sid->sid_rev_num = dom_sid->sid_rev_num; + smb_sid->num_auths = dom_sid->num_auths; + for (c = 0; c < SID_ID_AUTHS; c++) { + smb_sid->id_auth[c] = dom_sid->id_auth[c]; + } + for (c = 0; c < SID_SUB_AUTHS; c++) { + smb_sid->sub_auths[c] = dom_sid->sub_auths[c]; + } + + *_smb_sid = smb_sid; + + return IDMAP_SUCCESS; +} + +enum idmap_error_code sss_idmap_smb_sid_to_dom_sid(struct sss_idmap_ctx *ctx, + struct dom_sid *smb_sid, + struct sss_dom_sid **_dom_sid) +{ + struct sss_dom_sid *dom_sid; + size_t c; + + dom_sid = ctx->alloc_func(sizeof(struct sss_dom_sid), ctx->alloc_pvt); + if (dom_sid == NULL) { + return IDMAP_OUT_OF_MEMORY; + } + memset(dom_sid, 0, sizeof(struct sss_dom_sid)); + + dom_sid->sid_rev_num = smb_sid->sid_rev_num; + dom_sid->num_auths = smb_sid->num_auths; + for (c = 0; c < SID_ID_AUTHS; c++) { + dom_sid->id_auth[c] = smb_sid->id_auth[c]; + } + for (c = 0; c < SID_SUB_AUTHS; c++) { + dom_sid->sub_auths[c] = smb_sid->sub_auths[c]; + } + + *_dom_sid = dom_sid; + + return IDMAP_SUCCESS; +} + +enum idmap_error_code sss_idmap_bin_sid_to_smb_sid(struct sss_idmap_ctx *ctx, + const uint8_t *bin_sid, + size_t length, + struct dom_sid **_smb_sid) +{ + enum idmap_error_code err; + struct sss_dom_sid *dom_sid = NULL; + struct dom_sid *smb_sid = NULL; + + err = sss_idmap_bin_sid_to_dom_sid(ctx, bin_sid, length, &dom_sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + err = sss_idmap_dom_sid_to_smb_sid(ctx, dom_sid, &smb_sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + *_smb_sid = smb_sid; + err = IDMAP_SUCCESS; + +done: + ctx->free_func(dom_sid, ctx->alloc_pvt); + if (err != IDMAP_SUCCESS) { + ctx->free_func(smb_sid, ctx->alloc_pvt); + } + + return err; +} + +enum idmap_error_code sss_idmap_smb_sid_to_bin_sid(struct sss_idmap_ctx *ctx, + struct dom_sid *smb_sid, + uint8_t **_bin_sid, + size_t *_length) +{ + enum idmap_error_code err; + struct sss_dom_sid *dom_sid = NULL; + uint8_t *bin_sid = NULL; + size_t length; + + err = sss_idmap_smb_sid_to_dom_sid(ctx, smb_sid, &dom_sid); + if (err != IDMAP_SUCCESS) { + goto done; + } + + err = sss_idmap_dom_sid_to_bin_sid(ctx, dom_sid, &bin_sid, &length); + if (err != IDMAP_SUCCESS) { + goto done; + } + + *_bin_sid = bin_sid; + *_length = length; + err = IDMAP_SUCCESS; + +done: + ctx->free_func(dom_sid, ctx->alloc_pvt); + if (err != IDMAP_SUCCESS) { + ctx->free_func(bin_sid, ctx->alloc_pvt); + } + + return err; +} diff --git a/src/lib/idmap/sss_idmap_private.h b/src/lib/idmap/sss_idmap_private.h index 776c56ab..bdb52895 100644 --- a/src/lib/idmap/sss_idmap_private.h +++ b/src/lib/idmap/sss_idmap_private.h @@ -38,4 +38,23 @@ struct sss_idmap_ctx { struct idmap_domain_info *idmap_domain_info; }; +/* This is a copy of the definition in the samba gen_ndr/security.h header + * file. We use it here to be able to offer conversions form struct dom_sid to + * string or binary representation since those are not made available by + * public samba libraries. + * + * If the definition ever changes on the samba side we have to adopt the + * change. But chances are very low that this will ever happen since e.g. this + * struct is also defined in public documentation from Microsoft. See e.g. + * section 2.4.2.3 of "[MS-DTYP]: Windows Data Types" + * http://msdn.microsoft.com/en-us/library/cc230364(v=prot.10) + */ + +struct dom_sid { + uint8_t sid_rev_num; + int8_t num_auths; + uint8_t id_auth[6]; + uint32_t sub_auths[15]; +}; + #endif /* SSS_IDMAP_PRIVATE_H_ */ -- cgit