summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2012-04-25 09:16:41 +0200
committerStephen Gallagher <sgallagh@redhat.com>2012-05-01 14:22:51 -0400
commitb6dfbf81c61d4431aaa81687ec53e892f8b71edb (patch)
tree783f2e567335b2a57f8a21ee99847bfb05add78d /src
parentc8a124ac1b03d83016bda02cad5a369ce6fb1cd7 (diff)
downloadsssd-b6dfbf81c61d4431aaa81687ec53e892f8b71edb.tar.gz
sssd-b6dfbf81c61d4431aaa81687ec53e892f8b71edb.tar.xz
sssd-b6dfbf81c61d4431aaa81687ec53e892f8b71edb.zip
Allow different SID representations in libidmap
Besides as strings it is now possible to use binary SIDs or a struct containing all SID information. Functions to convert between these formats are added as well.
Diffstat (limited to 'src')
-rw-r--r--src/lib/idmap/sss_idmap.c127
-rw-r--r--src/lib/idmap/sss_idmap.h179
-rw-r--r--src/lib/idmap/sss_idmap_conv.c385
-rw-r--r--src/lib/idmap/sss_idmap_private.h41
-rw-r--r--src/tests/sss_idmap-tests.c206
5 files changed, 925 insertions, 13 deletions
diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
index 11f934bf5..b00d61501 100644
--- a/src/lib/idmap/sss_idmap.c
+++ b/src/lib/idmap/sss_idmap.c
@@ -27,18 +27,13 @@
#include <errno.h>
#include "lib/idmap/sss_idmap.h"
+#include "lib/idmap/sss_idmap_private.h"
#define DOM_SID_PREFIX "S-1-5-21-"
#define DOM_SID_PREFIX_LEN (sizeof(DOM_SID_PREFIX) - 1)
#define SID_FMT "%s-%d"
#define SID_STR_MAX_LEN 1024
-#define CHECK_IDMAP_CTX(ctx, ret) do { \
- if (ctx == NULL || ctx->alloc_func == NULL || ctx->free_func == NULL) { \
- return ret; \
- } \
-} while(0)
-
struct idmap_domain_info {
char *name;
char *sid;
@@ -46,13 +41,6 @@ struct idmap_domain_info {
struct idmap_domain_info *next;
};
-struct sss_idmap_ctx {
- idmap_alloc_func *alloc_func;
- void *alloc_pvt;
- idmap_free_func *free_func;
- struct idmap_domain_info *idmap_domain_info;
-};
-
static void *default_alloc(size_t size, void *pvt)
{
return malloc(size);
@@ -373,3 +361,116 @@ enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx,
return IDMAP_NO_DOMAIN;
}
+
+enum idmap_error_code sss_idmap_dom_sid_to_unix(struct sss_idmap_ctx *ctx,
+ struct 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_sid_to_unix(ctx, sid, id);
+
+done:
+ ctx->free_func(sid, ctx->alloc_pvt);
+
+ return err;
+}
+
+enum idmap_error_code sss_idmap_bin_sid_to_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_sid_to_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 dom_sid **_dom_sid)
+{
+ enum idmap_error_code err;
+ char *sid = NULL;
+ struct dom_sid *dom_sid = NULL;
+
+ CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
+
+ err = sss_idmap_unix_to_sid(ctx, id, &sid);
+ if (err != IDMAP_SUCCESS) {
+ goto done;
+ }
+
+ err = sss_idmap_sid_to_dom_sid(ctx, sid, &dom_sid);
+ if (err != IDMAP_SUCCESS) {
+ goto done;
+ }
+
+ *_dom_sid = dom_sid;
+ err = IDMAP_SUCCESS;
+
+done:
+ ctx->free_func(sid, ctx->alloc_pvt);
+ if (err != IDMAP_SUCCESS) {
+ ctx->free_func(dom_sid, ctx->alloc_pvt);
+ }
+
+ return err;
+}
+
+enum idmap_error_code sss_idmap_unix_to_bin_sid(struct sss_idmap_ctx *ctx,
+ uint32_t id,
+ uint8_t **_bin_sid,
+ size_t *_length)
+{
+ enum idmap_error_code err;
+ char *sid = NULL;
+ uint8_t *bin_sid = NULL;
+ size_t length;
+
+ CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
+
+ err = sss_idmap_unix_to_sid(ctx, id, &sid);
+ if (err != IDMAP_SUCCESS) {
+ goto done;
+ }
+
+ err = sss_idmap_sid_to_bin_sid(ctx, sid, &bin_sid, &length);
+ if (err != IDMAP_SUCCESS) {
+ goto done;
+ }
+
+ *_bin_sid = bin_sid;
+ *_length = length;
+ err = IDMAP_SUCCESS;
+
+done:
+ ctx->free_func(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.h b/src/lib/idmap/sss_idmap.h
index dbb2700a0..146f831e9 100644
--- a/src/lib/idmap/sss_idmap.h
+++ b/src/lib/idmap/sss_idmap.h
@@ -85,6 +85,11 @@ struct sss_idmap_range {
};
/**
+ * Opaque type for SIDs
+ */
+struct dom_sid;
+
+/**
* Opaque type for the idmap context
*/
struct sss_idmap_ctx;
@@ -146,6 +151,42 @@ enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx,
uint32_t *id);
/**
+ * @brief Translate a SID stucture to a unix UID or GID
+ *
+ * @param[in] ctx Idmap context
+ * @param[in] dom_sid SID structure
+ * @param[out] id Returned 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
+ */
+enum idmap_error_code sss_idmap_dom_sid_to_unix(struct sss_idmap_ctx *ctx,
+ struct dom_sid *dom_sid,
+ uint32_t *id);
+
+/**
+ * @brief Translate a binary SID to a unix UID or GID
+ *
+ * @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] id Returned 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
+ */
+enum idmap_error_code sss_idmap_bin_sid_to_unix(struct sss_idmap_ctx *ctx,
+ uint8_t *bin_sid,
+ size_t length,
+ uint32_t *id);
+
+/**
* @brief Translate unix UID or GID to a SID
*
* @param[in] ctx Idmap context
@@ -163,6 +204,41 @@ enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx,
char **sid);
/**
+ * @brief Translate unix UID or GID to a SID structure
+ *
+ * @param[in] ctx Idmap context
+ * @param[in] id unix UID or GID
+ * @param[out] dom_sid SID structure, must be freed if not needed anymore
+ *
+ * @return
+ * - #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
+ */
+enum idmap_error_code sss_idmap_unix_to_dom_sid(struct sss_idmap_ctx *ctx,
+ uint32_t id,
+ struct dom_sid **dom_sid);
+
+/**
+ * @brief Translate unix UID or GID to a binary SID
+ *
+ * @param[in] ctx Idmap context
+ * @param[in] id unix UID or GID
+ * @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_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
+ */
+enum idmap_error_code sss_idmap_unix_to_bin_sid(struct sss_idmap_ctx *ctx,
+ uint32_t id,
+ uint8_t **bin_sid,
+ size_t *length);
+
+/**
* @brief Free all the allocated memory of the idmap context
*
* @param[in] ctx Idmap context
@@ -194,6 +270,109 @@ const char *idmap_error_string(enum idmap_error_code err);
bool is_domain_sid(const char *str);
/**
+ * @brief Convert binary SID to 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] 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_bin_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
+ const uint8_t *bin_sid,
+ size_t length,
+ struct dom_sid **dom_sid);
+
+/**
+ * @brief Convert binary SID to SID string
+ *
+ * @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] 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_bin_sid_to_sid(struct sss_idmap_ctx *ctx,
+ const uint8_t *bin_sid,
+ size_t length,
+ char **sid);
+
+/**
+ * @brief Convert SID structure to binary SID
+ *
+ * @param[in] ctx Idmap context
+ * @param[in] dom_sid 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_dom_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
+ struct dom_sid *dom_sid,
+ uint8_t **bin_sid,
+ size_t *length);
+
+/**
+ * @brief Convert SID string to binary SID
+ *
+ * @param[in] ctx Idmap context
+ * @param[in] sid Zero-terminated string representation of the SID
+ * @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_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
+ const char *sid,
+ uint8_t **bin_sid,
+ size_t *length);
+
+/**
+ * @brief Convert SID structure to SID string
+ *
+ * @param[in] ctx Idmap context
+ * @param[in] dom_sid 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_dom_sid_to_sid(struct sss_idmap_ctx *ctx,
+ struct dom_sid *dom_sid,
+ char **sid);
+
+/**
+ * @brief Convert SID string to SID structure
+ *
+ * @param[in] ctx Idmap context
+ * @param[in] sid Zero-terminated string representation of the SID
+ * @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_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
+ const char *sid,
+ struct dom_sid **dom_sid);
+/**
* @}
*/
#endif /* SSS_IDMAP_H_ */
diff --git a/src/lib/idmap/sss_idmap_conv.c b/src/lib/idmap/sss_idmap_conv.c
new file mode 100644
index 000000000..83041efee
--- /dev/null
+++ b/src/lib/idmap/sss_idmap_conv.c
@@ -0,0 +1,385 @@
+/*
+ SSSD
+
+ ID-mapping library - conversion utilities
+
+ Authors:
+ Sumit Bose <sbose@redhat.com>
+
+ Copyright (C) 2012 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "lib/idmap/sss_idmap.h"
+#include "lib/idmap/sss_idmap_private.h"
+#include "util/util.h"
+
+#define SID_ID_AUTHS 6
+#define SID_SUB_AUTHS 15
+struct dom_sid {
+ uint8_t sid_rev_num;
+ int8_t num_auths;/* [range(0,15)] */
+ uint8_t id_auth[SID_ID_AUTHS];
+ uint32_t sub_auths[SID_SUB_AUTHS];
+};
+
+enum idmap_error_code sss_idmap_bin_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
+ const uint8_t *bin_sid,
+ size_t length,
+ struct dom_sid **_dom_sid)
+{
+ enum idmap_error_code err;
+ struct dom_sid *dom_sid;
+ size_t i = 0;
+ size_t p = 0;
+
+ CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
+
+ if (length > sizeof(struct dom_sid)) return IDMAP_SID_INVALID;
+
+ dom_sid = ctx->alloc_func(sizeof(struct dom_sid), ctx->alloc_pvt);
+ if (dom_sid == NULL) {
+ return IDMAP_OUT_OF_MEMORY;
+ }
+
+ /* Safely copy in the SID revision number */
+ dom_sid->sid_rev_num = (uint8_t) *(bin_sid + p);
+ p++;
+
+ /* Safely copy in the number of sub auth values */
+ dom_sid->num_auths = (uint8_t) *(bin_sid + p);
+ p++;
+
+ /* Make sure we aren't being told to read more bin_sid
+ * than can fit in the structure
+ */
+ if (dom_sid->num_auths > SID_SUB_AUTHS) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+
+ /* Safely copy in the id_auth values */
+ for (i = 0; i < SID_ID_AUTHS; i++) {
+ dom_sid->id_auth[i] = (uint8_t) *(bin_sid + p);
+ p++;
+ }
+
+ /* Safely copy in the sub_auths values */
+ for (i = 0; i < dom_sid->num_auths; i++) {
+ SAFEALIGN_COPY_UINT32(&dom_sid->sub_auths[i], bin_sid + p, &p);
+ }
+
+ *_dom_sid = dom_sid;
+ err = IDMAP_SUCCESS;
+
+done:
+ if (err != IDMAP_SUCCESS) {
+ ctx->free_func(dom_sid, ctx->alloc_pvt);
+ }
+ return err;
+}
+
+enum idmap_error_code sss_idmap_dom_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
+ struct dom_sid *dom_sid,
+ uint8_t **_bin_sid,
+ size_t *_length)
+{
+ enum idmap_error_code err;
+ uint8_t *bin_sid;
+ size_t length;
+ size_t i = 0;
+ size_t p = 0;
+
+ CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
+
+ if (dom_sid->num_auths > SID_SUB_AUTHS) {
+ return IDMAP_SID_INVALID;
+ }
+
+ length = 2 + SID_ID_AUTHS + dom_sid->num_auths * 4;
+
+ bin_sid = ctx->alloc_func(length, ctx->alloc_pvt);
+ if (bin_sid == NULL) {
+ return IDMAP_OUT_OF_MEMORY;
+ }
+
+ bin_sid[p] = dom_sid->sid_rev_num;
+ p++;
+
+ bin_sid[p] = dom_sid->num_auths;
+ p++;
+
+ for (i = 0; i < SID_ID_AUTHS; i++) {
+ bin_sid[p] = dom_sid->id_auth[i];
+ p++;
+ }
+
+ for (i = 0; i < dom_sid->num_auths; i++) {
+ if (p + sizeof(uint32_t) > length) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+ SAFEALIGN_COPY_UINT32(bin_sid + p, &dom_sid->sub_auths[i], &p);
+ }
+
+ *_bin_sid = bin_sid;
+ *_length = length;
+
+ err = IDMAP_SUCCESS;
+done:
+ if (err != IDMAP_SUCCESS) {
+ ctx->free_func(bin_sid, ctx->alloc_pvt);
+ }
+ return err;
+}
+
+enum idmap_error_code sss_idmap_dom_sid_to_sid(struct sss_idmap_ctx *ctx,
+ struct dom_sid *dom_sid,
+ char **_sid)
+{
+ enum idmap_error_code err;
+ char *sid_buf;
+ size_t sid_buf_len;
+ char *p;
+ int nc;
+ int8_t i;
+ uint32_t id_auth_val = 0;
+ uint32_t sub_auth_val;
+
+ if (dom_sid->num_auths > SID_SUB_AUTHS) {
+ return IDMAP_SID_INVALID;
+ }
+
+ sid_buf_len = 25 + dom_sid->num_auths * 11;
+ sid_buf = ctx->alloc_func(sid_buf_len, ctx->alloc_pvt);
+ if (sid_buf == NULL) {
+ return IDMAP_OUT_OF_MEMORY;
+ }
+ memset(sid_buf, 0, sid_buf_len);
+
+ /* Only 32bits are used for the string representation */
+ id_auth_val = (dom_sid->id_auth[2] << 24) +
+ (dom_sid->id_auth[3] << 16) +
+ (dom_sid->id_auth[4] << 8) +
+ (dom_sid->id_auth[5]);
+
+ nc = snprintf(sid_buf, sid_buf_len, "S-%u-%lu", dom_sid->sid_rev_num,
+ (unsigned long) id_auth_val);
+ if (nc < 0 || nc >= sid_buf_len) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+
+
+ /* Loop through the sub-auths, if any, prepending a hyphen
+ * for each one.
+ */
+ p = sid_buf;
+ for (i = 0; i < dom_sid->num_auths ; i++) {
+ p += nc;
+ sid_buf_len -= nc;
+ /* SID values in Active Directory are stored little-endian */
+ sub_auth_val = le32toh(dom_sid->sub_auths[i]);
+
+ nc = snprintf(p, sid_buf_len, "-%lu", (unsigned long) sub_auth_val);
+ if (nc < 0 || nc >= sid_buf_len) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+ }
+
+ *_sid = sid_buf;
+ err = IDMAP_SUCCESS;
+
+done:
+ if (err != IDMAP_SUCCESS) {
+ ctx->free_func(sid_buf, ctx->alloc_pvt);
+ }
+
+ return err;
+}
+
+enum idmap_error_code sss_idmap_sid_to_dom_sid(struct sss_idmap_ctx *ctx,
+ const char *sid,
+ struct dom_sid **_dom_sid)
+{
+ enum idmap_error_code err;
+ unsigned long ul;
+ char *r;
+ char *end;
+ struct dom_sid *dom_sid;
+
+ CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID);
+
+ if (sid == NULL || (sid[0] != 'S' && sid[0] != 's') || sid[1] != '-') {
+ return IDMAP_SID_INVALID;
+ }
+
+ dom_sid = ctx->alloc_func(sizeof(struct dom_sid), ctx->alloc_pvt);
+ if (dom_sid == NULL) {
+ return IDMAP_OUT_OF_MEMORY;
+ }
+ memset(dom_sid, 0, sizeof(struct dom_sid));
+
+
+ if (!isdigit(sid[2])) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+ errno = 0;
+ ul = strtoul(sid + 2, &r, 10);
+ if (errno != 0 || r == NULL || *r != '-' || ul > UINT8_MAX) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+ dom_sid->sid_rev_num = (uint8_t) ul;
+ r++;
+
+ if (!isdigit(*r)) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+ errno = 0;
+ ul = strtoul(r, &r, 10);
+ if (errno != 0 || r == NULL) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+
+ /* id_auth in the string should always be <2^32 in decimal */
+ /* store values in the same order as the binary representation */
+ dom_sid->id_auth[0] = 0;
+ dom_sid->id_auth[1] = 0;
+ dom_sid->id_auth[2] = (ul & 0xff000000) >> 24;
+ dom_sid->id_auth[3] = (ul & 0x00ff0000) >> 16;
+ dom_sid->id_auth[4] = (ul & 0x0000ff00) >> 8;
+ dom_sid->id_auth[5] = (ul & 0x000000ff);
+
+ if (*r == '\0') {
+ /* no sub auths given */
+ err = IDMAP_SUCCESS;
+ goto done;
+ }
+
+ if (*r != '-') {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+
+ do {
+ if (dom_sid->num_auths > SID_SUB_AUTHS) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+
+ r++;
+ if (!isdigit(*r)) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+
+ errno = 0;
+ ul = strtol(r, &end, 10);
+ if (errno != 0 || end == NULL ||
+ (*end != '\0' && *end != '-')) {
+ err = IDMAP_SID_INVALID;
+ goto done;
+ }
+
+ dom_sid->sub_auths[dom_sid->num_auths++] = ul;
+
+ r = end;
+ } while (*r != '\0');
+
+ err = IDMAP_SUCCESS;
+
+done:
+ if (err != IDMAP_SUCCESS) {
+ ctx->free_func(dom_sid, ctx->alloc_pvt);
+ } else {
+ *_dom_sid = dom_sid;
+ }
+
+ return err;
+}
+
+enum idmap_error_code sss_idmap_sid_to_bin_sid(struct sss_idmap_ctx *ctx,
+ const char *sid,
+ uint8_t **_bin_sid,
+ size_t *_length)
+{
+ enum idmap_error_code err;
+ struct dom_sid *dom_sid = NULL;
+ size_t length;
+ uint8_t *bin_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_bin_sid(ctx, dom_sid, &bin_sid, &length);
+ if (err != IDMAP_SUCCESS) {
+ goto done;
+ }
+
+ *_length = length;
+ *_bin_sid = bin_sid;
+ 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;
+}
+
+enum idmap_error_code sss_idmap_bin_sid_to_sid(struct sss_idmap_ctx *ctx,
+ const uint8_t *bin_sid,
+ size_t length,
+ char **_sid)
+{
+ enum idmap_error_code err;
+ struct dom_sid *dom_sid = NULL;
+ char *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_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;
+}
diff --git a/src/lib/idmap/sss_idmap_private.h b/src/lib/idmap/sss_idmap_private.h
new file mode 100644
index 000000000..776c56ab5
--- /dev/null
+++ b/src/lib/idmap/sss_idmap_private.h
@@ -0,0 +1,41 @@
+/*
+ SSSD
+
+ ID-mapping library - private headers
+
+ Authors:
+ Sumit Bose <sbose@redhat.com>
+
+ Copyright (C) 2012 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SSS_IDMAP_PRIVATE_H_
+#define SSS_IDMAP_PRIVATE_H_
+
+#define CHECK_IDMAP_CTX(ctx, ret) do { \
+ if (ctx == NULL || ctx->alloc_func == NULL || ctx->free_func == NULL) { \
+ return ret; \
+ } \
+} while(0)
+
+struct sss_idmap_ctx {
+ idmap_alloc_func *alloc_func;
+ void *alloc_pvt;
+ idmap_free_func *free_func;
+ struct idmap_domain_info *idmap_domain_info;
+};
+
+#endif /* SSS_IDMAP_PRIVATE_H_ */
diff --git a/src/tests/sss_idmap-tests.c b/src/tests/sss_idmap-tests.c
index 101970e01..5be7a5fdb 100644
--- a/src/tests/sss_idmap-tests.c
+++ b/src/tests/sss_idmap-tests.c
@@ -28,6 +28,13 @@
#define IDMAP_RANGE_MIN 1234
#define IDMAP_RANGE_MAX 9876
+const char test_sid[] = "S-1-5-21-2127521184-1604012920-1887927527-72713";
+uint8_t test_bin_sid[] = {0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15,
+ 0x00, 0x00, 0x00, 0xA0, 0x65, 0xCF, 0x7E, 0x78, 0x4B,
+ 0x9B, 0x5F, 0xE7, 0x7C, 0x87, 0x70, 0x09, 0x1C, 0x01,
+ 0x00};
+size_t test_bin_sid_length = sizeof(test_bin_sid);
+
struct sss_idmap_ctx *idmap_ctx;
static void *idmap_talloc(size_t size, void *pvt)
@@ -150,6 +157,46 @@ START_TEST(idmap_test_sid2uid)
}
END_TEST
+START_TEST(idmap_test_bin_sid2uid)
+{
+ enum idmap_error_code err;
+ uint32_t id;
+ uint8_t *bin_sid = NULL;
+ size_t length;
+
+ err = sss_idmap_sid_to_bin_sid(idmap_ctx, "S-1-5-21-1-2-3-1000",
+ &bin_sid, &length);
+ fail_unless(err == IDMAP_SUCCESS, "Failed to convert SID to binary SID");
+
+ err = sss_idmap_bin_sid_to_unix(idmap_ctx, bin_sid, length , &id);
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_bin_sid_to_unix failed.");
+ fail_unless(id == (1000 + IDMAP_RANGE_MIN),
+ "sss_idmap_bin_sid_to_unix returned wrong id, "
+ "got [%d], expected [%d].", id, 1000 + IDMAP_RANGE_MIN);
+
+ talloc_free(bin_sid);
+}
+END_TEST
+
+START_TEST(idmap_test_dom_sid2uid)
+{
+ enum idmap_error_code err;
+ uint32_t id;
+ struct dom_sid *dom_sid = NULL;
+
+ err = sss_idmap_sid_to_dom_sid(idmap_ctx, "S-1-5-21-1-2-3-1000", &dom_sid);
+ fail_unless(err == IDMAP_SUCCESS, "Failed to convert SID to SID structure");
+
+ err = sss_idmap_dom_sid_to_unix(idmap_ctx, dom_sid, &id);
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_dom_sid_to_unix failed.");
+ fail_unless(id == (1000 + IDMAP_RANGE_MIN),
+ "sss_idmap_dom_sid_to_unix returned wrong id, "
+ "got [%d], expected [%d].", id, 1000 + IDMAP_RANGE_MIN);
+
+ talloc_free(dom_sid);
+}
+END_TEST
+
START_TEST(idmap_test_uid2sid)
{
enum idmap_error_code err;
@@ -169,6 +216,145 @@ START_TEST(idmap_test_uid2sid)
}
END_TEST
+START_TEST(idmap_test_uid2dom_sid)
+{
+ enum idmap_error_code err;
+ struct dom_sid *dom_sid = NULL;
+ char *sid = NULL;
+
+ err = sss_idmap_unix_to_dom_sid(idmap_ctx, 10000, &dom_sid);
+ fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_dom_sid did not detect "
+ "id out of range");
+
+ err = sss_idmap_unix_to_dom_sid(idmap_ctx, 2234, &dom_sid);
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_dom_sid failed.");
+
+ err = sss_idmap_dom_sid_to_sid(idmap_ctx, dom_sid, &sid);
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_dom_sid_to_sid failed.");
+
+ fail_unless(strcmp(sid, "S-1-5-21-1-2-3-1000") == 0,
+ "sss_idmap_unix_to_dom_sid returned wrong SID, "
+ "expected [%s], got [%s].", "S-1-5-21-1-2-3-1000", sid);
+
+ talloc_free(sid);
+ talloc_free(dom_sid);
+}
+END_TEST
+
+START_TEST(idmap_test_uid2bin_sid)
+{
+ enum idmap_error_code err;
+ uint8_t *bin_sid = NULL;
+ size_t length;
+ char *sid = NULL;
+
+ err = sss_idmap_unix_to_bin_sid(idmap_ctx, 10000, &bin_sid, &length);
+ fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_bin_sid did not detect "
+ "id out of range");
+
+ err = sss_idmap_unix_to_bin_sid(idmap_ctx, 2234, &bin_sid, &length);
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_bin_sid failed.");
+
+ err = sss_idmap_bin_sid_to_sid(idmap_ctx, bin_sid, length, &sid);
+ fail_unless(err == IDMAP_SUCCESS, "sss_idmap_bin_sid_to_sid failed.");
+
+ fail_unless(strcmp(sid, "S-1-5-21-1-2-3-1000") == 0,
+ "sss_idmap_unix_to_bin_sid returned wrong SID, "
+ "expected [%s], got [%s].", "S-1-5-21-1-2-3-1000", sid);
+
+ talloc_free(sid);
+ talloc_free(bin_sid);
+}
+END_TEST
+
+START_TEST(idmap_test_sid_bin2dom_sid)
+{
+ struct dom_sid *dom_sid = NULL;
+ enum idmap_error_code err;
+ uint8_t *new_bin_sid = NULL;
+ size_t new_bin_sid_length;
+
+ err = sss_idmap_bin_sid_to_dom_sid(idmap_ctx, test_bin_sid,
+ test_bin_sid_length, &dom_sid);
+
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert binary SID to struct dom_sid.");
+
+ err = sss_idmap_dom_sid_to_bin_sid(idmap_ctx, dom_sid, &new_bin_sid,
+ &new_bin_sid_length);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert struct dom_sid to binary SID.");
+
+ fail_unless(new_bin_sid_length == test_bin_sid_length,
+ "Length of binary SIDs do not match.");
+ fail_unless(memcmp(test_bin_sid, new_bin_sid, test_bin_sid_length) == 0,
+ "Binary SIDs do not match.");
+
+ talloc_free(dom_sid);
+ talloc_free(new_bin_sid);
+}
+END_TEST
+
+START_TEST(idmap_test_sid2dom_sid)
+{
+ struct dom_sid *dom_sid = NULL;
+ enum idmap_error_code err;
+ char *new_sid = NULL;
+
+ err = sss_idmap_sid_to_dom_sid(idmap_ctx, "S-1-5-21-1-2-3-1000", &dom_sid);
+
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert SID string to struct dom_sid.");
+
+ err = sss_idmap_dom_sid_to_sid(idmap_ctx, dom_sid, &new_sid);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert struct dom_sid to SID string.");
+
+ fail_unless(new_sid != NULL, "SID string not set");
+ fail_unless(strlen("S-1-5-21-1-2-3-1000") == strlen(new_sid),
+ "Length of SID strings do not match.");
+ fail_unless(strcmp("S-1-5-21-1-2-3-1000", new_sid) == 0,
+ "SID strings do not match.");
+
+ talloc_free(dom_sid);
+ talloc_free(new_sid);
+}
+END_TEST
+
+START_TEST(idmap_test_sid2bin_sid)
+{
+ enum idmap_error_code err;
+ size_t length;
+ uint8_t *bin_sid = NULL;
+
+ err = sss_idmap_sid_to_bin_sid(idmap_ctx, test_sid, &bin_sid, &length);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert SID string 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_sid2sid)
+{
+ enum idmap_error_code err;
+ char *sid = NULL;
+
+ err = sss_idmap_bin_sid_to_sid(idmap_ctx, test_bin_sid, test_bin_sid_length,
+ &sid);
+ fail_unless(err == IDMAP_SUCCESS,
+ "Failed to convert binary SID to SID string.");
+ fail_unless(strcmp(sid, test_sid) == 0, "SID strings do not match");
+
+ talloc_free(sid);
+}
+END_TEST
+
Suite *idmap_test_suite (void)
{
Suite *s = suite_create ("IDMAP");
@@ -196,6 +382,21 @@ Suite *idmap_test_suite (void)
suite_add_tcase(s, tc_dom);
+ TCase *tc_conv = tcase_create("IDMAP SID conversion tests");
+ tcase_add_checked_fixture(tc_conv,
+ leak_check_setup,
+ leak_check_teardown);
+ tcase_add_checked_fixture(tc_conv,
+ idmap_ctx_setup,
+ idmap_ctx_teardown);
+
+ tcase_add_test(tc_conv, idmap_test_sid_bin2dom_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);
+
+ suite_add_tcase(s, tc_conv);
+
TCase *tc_map = tcase_create("IDMAP mapping tests");
tcase_add_checked_fixture(tc_map,
leak_check_setup,
@@ -208,9 +409,14 @@ Suite *idmap_test_suite (void)
NULL);
tcase_add_test(tc_map, idmap_test_sid2uid);
+ tcase_add_test(tc_map, idmap_test_bin_sid2uid);
+ tcase_add_test(tc_map, idmap_test_dom_sid2uid);
tcase_add_test(tc_map, idmap_test_uid2sid);
+ tcase_add_test(tc_map, idmap_test_uid2dom_sid);
+ tcase_add_test(tc_map, idmap_test_uid2bin_sid);
suite_add_tcase(s, tc_map);
+
return s;
}
int main(int argc, const char *argv[])