summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/idmap/sss_idmap.h107
-rw-r--r--src/lib/idmap/sss_idmap_conv.c179
-rw-r--r--src/lib/idmap/sss_idmap_private.h19
-rw-r--r--src/tests/sss_idmap-tests.c102
4 files changed, 405 insertions, 2 deletions
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
@@ -98,6 +98,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
*
* @param[in] alloc_func Function to allocate memory for the context, if
@@ -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_ */
diff --git a/src/tests/sss_idmap-tests.c b/src/tests/sss_idmap-tests.c
index b821dfc9..73c2d21d 100644
--- a/src/tests/sss_idmap-tests.c
+++ b/src/tests/sss_idmap-tests.c
@@ -23,6 +23,7 @@
#include <check.h>
#include "lib/idmap/sss_idmap.h"
+#include "lib/idmap/sss_idmap_private.h"
#include "tests/common.h"
#define IDMAP_RANGE_MIN 1234
@@ -35,6 +36,8 @@ uint8_t test_bin_sid[] = {0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15,
0x00};
size_t test_bin_sid_length = sizeof(test_bin_sid);
+struct dom_sid test_smb_sid = {1, 5, {0, 0, 0, 0, 0, 5}, {21, 2127521184, 1604012920, 1887927527, 72713, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+
struct sss_idmap_ctx *idmap_ctx;
static void *idmap_talloc(size_t size, void *pvt)
@@ -267,7 +270,7 @@ START_TEST(idmap_test_uid2bin_sid)
}
END_TEST
-START_TEST(idmap_test_sid_bin2dom_sid)
+START_TEST(idmap_test_bin_sid2dom_sid)
{
struct sss_dom_sid *dom_sid = NULL;
enum idmap_error_code err;
@@ -357,6 +360,96 @@ START_TEST(idmap_test_bin_sid2sid)
}
END_TEST
+START_TEST(idmap_test_smb_sid2dom_sid)
+{
+ struct sss_dom_sid *dom_sid = NULL;
+ enum idmap_error_code err;
+ struct dom_sid *new_smb_sid = NULL;
+
+ err = sss_idmap_smb_sid_to_dom_sid(idmap_ctx, &test_smb_sid, &dom_sid);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert samba dom_sid to struct sss_dom_sid.");
+
+ err = sss_idmap_dom_sid_to_smb_sid(idmap_ctx, dom_sid, &new_smb_sid);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert struct sss_dom_sid to samba dom_sid.");
+
+ fail_unless(memcmp(&test_smb_sid, new_smb_sid, sizeof(struct dom_sid)) == 0,
+ "Samba dom_sid-s do not match.");
+
+ talloc_free(dom_sid);
+ talloc_free(new_smb_sid);
+}
+END_TEST
+
+START_TEST(idmap_test_smb_sid2bin_sid)
+{
+ enum idmap_error_code err;
+ size_t length;
+ uint8_t *bin_sid = NULL;
+
+ err = sss_idmap_smb_sid_to_bin_sid(idmap_ctx, &test_smb_sid,
+ &bin_sid, &length);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert samba dom_sid to binary sid.");
+ fail_unless(length == test_bin_sid_length,
+ "Size of binary SIDs do not match, got [%d], expected [%d]",
+ length, test_bin_sid_length);
+ fail_unless(memcmp(bin_sid, test_bin_sid, test_bin_sid_length) == 0,
+ "Binary SIDs do not match.");
+
+ talloc_free(bin_sid);
+}
+END_TEST
+
+START_TEST(idmap_test_bin_sid2smb_sid)
+{
+ enum idmap_error_code err;
+ struct dom_sid *smb_sid = NULL;
+
+ err = sss_idmap_bin_sid_to_smb_sid(idmap_ctx, test_bin_sid,
+ test_bin_sid_length, &smb_sid);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert binary sid to samba dom_sid.");
+ fail_unless(memcmp(&test_smb_sid, smb_sid, sizeof(struct dom_sid)) == 0,
+ "Samba dom_sid structs do not match.");
+
+ talloc_free(smb_sid);
+}
+END_TEST
+
+START_TEST(idmap_test_smb_sid2sid)
+{
+ enum idmap_error_code err;
+ char *sid = NULL;
+
+ err = sss_idmap_smb_sid_to_sid(idmap_ctx, &test_smb_sid, &sid);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert samba dom_sid to sid string.");
+ fail_unless(strcmp(sid, test_sid) == 0, "SID strings do not match, "
+ "expected [%s], get [%s]",
+ test_sid, sid);
+
+ talloc_free(sid);
+}
+END_TEST
+
+START_TEST(idmap_test_sid2smb_sid)
+{
+ enum idmap_error_code err;
+ struct dom_sid *smb_sid = NULL;
+
+ err = sss_idmap_sid_to_smb_sid(idmap_ctx, test_sid, &smb_sid);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert binary sid to samba dom_sid.");
+ fail_unless(memcmp(&test_smb_sid, smb_sid, sizeof(struct dom_sid)) == 0,
+ "Samba dom_sid structs do not match.");
+
+ talloc_free(smb_sid);
+}
+END_TEST
+
+
Suite *idmap_test_suite (void)
{
Suite *s = suite_create ("IDMAP");
@@ -392,10 +485,15 @@ Suite *idmap_test_suite (void)
idmap_ctx_setup,
idmap_ctx_teardown);
- tcase_add_test(tc_conv, idmap_test_sid_bin2dom_sid);
+ tcase_add_test(tc_conv, idmap_test_bin_sid2dom_sid);
tcase_add_test(tc_conv, idmap_test_sid2dom_sid);
tcase_add_test(tc_conv, idmap_test_sid2bin_sid);
tcase_add_test(tc_conv, idmap_test_bin_sid2sid);
+ tcase_add_test(tc_conv, idmap_test_smb_sid2dom_sid);
+ tcase_add_test(tc_conv, idmap_test_smb_sid2bin_sid);
+ tcase_add_test(tc_conv, idmap_test_bin_sid2smb_sid);
+ tcase_add_test(tc_conv, idmap_test_smb_sid2sid);
+ tcase_add_test(tc_conv, idmap_test_sid2smb_sid);
suite_add_tcase(s, tc_conv);