[SSSD] [PATCH] sss_idmap: add support for samba struct dom_sid

Sumit Bose sbose at redhat.com
Tue Jun 5 16:34:20 UTC 2012


On Mon, Jun 04, 2012 at 02:49:48PM +0200, Sumit Bose wrote:
> On Mon, Jun 04, 2012 at 02:15:37PM +0200, Jakub Hrozek wrote:
> > On Fri, Jun 01, 2012 at 01:06:11PM +0200, Sumit Bose wrote:
> > > On Thu, May 31, 2012 at 09:09:53AM +0200, Jakub Hrozek wrote:
> > > > On Thu, May 24, 2012 at 03:04:36PM +0200, Sumit Bose wrote:
> > > > > Hi,
> > > > > 
> > > > > this patch allows us besides other conversions to convert the dom_sid
> > > > > structure used by samba to strings and back. This structure is used by
> > > > > various samba libraries, but there are no public inferfaces for the
> > > > > conversion. I've seen Simo adding code to the IPA kdb plugin doing these
> > > > > conversions and I need them for the PAC responder as well. So I thought
> > > > > it might be useful to put it in a library.
> > > > > 
> > > > > bye,
> > > > > Sumit
> > > > 
> > > > Hi, the patch no longer applies to configure.ac, can you rebase?
> > > 
> > > sure, new version attached.
> > > 
> > > bye,
> > > Sumit
> > 
> > The code looks good to me and the unit tests pass. 
> > 
> > But the patch adds a new build-time dependency that should be added into
> > contrib/sssd.spec.in. I also wonder if there should be a configure-time
> 
> ah, I have this in the PAC responder patch. I will extract it there and
> add it here.
> 
> > switch to compile this feature in or out, mainly because nothing is
> > using the feature at the moment?
> 
> When starting the patch I was thinking the same, but then I realized
> that this would change the API/ABI of the library. So the samba header
> files are now required at compile time, but not at run time.
> 

After some discussion on irc it became clear that we what to avoid any
kind of dependencies here, because the needed header files are often not
packaged. The new version of the patch copies the definition of the
struct to reach this.

bye,
Sumit
-------------- next part --------------
From ac926b76874cd52bdb1c06ebc69e43bf9f1998e5 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 24 May 2012 12:39:56 +0200
Subject: [PATCH] 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 ++++
 src/tests/sss_idmap-tests.c       |  102 +++++++++++++++++++++-
 4 files changed, 405 insertions(+), 2 deletions(-)

diff --git a/src/lib/idmap/sss_idmap.h b/src/lib/idmap/sss_idmap.h
index a3ec919..6b7cbe5 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 df96fcc..37629f6 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:
+    talloc_free(dom_sid);
+    if (err != IDMAP_SUCCESS) {
+        talloc_free(smb_sid);
+    }
+
+    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:
+    talloc_free(dom_sid);
+    if (err != IDMAP_SUCCESS) {
+        talloc_free(sid);
+    }
+
+    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:
+    talloc_free(dom_sid);
+    if (err != IDMAP_SUCCESS) {
+        talloc_free(smb_sid);
+    }
+
+    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:
+    talloc_free(dom_sid);
+    if (err != IDMAP_SUCCESS) {
+        talloc_free(bin_sid);
+    }
+
+    return err;
+}
diff --git a/src/lib/idmap/sss_idmap_private.h b/src/lib/idmap/sss_idmap_private.h
index 776c56a..bdb5289 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 b821dfc..73c2d21 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);
 
-- 
1.7.7.6



More information about the sssd-devel mailing list