summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2012-04-23 08:55:58 -0400
committerStephen Gallagher <sgallagh@redhat.com>2012-05-03 14:09:14 -0400
commit58d02e0d3d6d48c97fccdb2ad7212e065671ad6d (patch)
tree6dc162349f366cfb2a20429f98141b258a739369
parent532eb49e129bedf57cdbd0a66f39ad228b8f2482 (diff)
downloadsssd-58d02e0d3d6d48c97fccdb2ad7212e065671ad6d.tar.gz
sssd-58d02e0d3d6d48c97fccdb2ad7212e065671ad6d.tar.xz
sssd-58d02e0d3d6d48c97fccdb2ad7212e065671ad6d.zip
LDAP: Add helper routine to convert LDAP blob to SID string
-rw-r--r--src/providers/ldap/ldap_common.c37
-rw-r--r--src/providers/ldap/ldap_common.h6
-rw-r--r--src/providers/ldap/sdap_async_groups.c24
-rw-r--r--src/providers/ldap/sdap_async_initgroups.c172
-rw-r--r--src/providers/ldap/sdap_async_users.c24
5 files changed, 195 insertions, 68 deletions
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 6b03451ad..8e117d267 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -34,6 +34,7 @@
#include "util/crypto/sss_crypto.h"
#include "providers/ldap/ldap_opts.h"
+#include "providers/ldap/sdap_idmap.h"
/* a fd the child process would log into */
int ldap_child_debug_fd = -1;
@@ -1409,3 +1410,39 @@ char *sdap_get_id_specific_filter(TALLOC_CTX *mem_ctx,
}
return filter; /* NULL or not */
}
+
+errno_t
+sdap_attrs_get_sid_str(TALLOC_CTX *mem_ctx,
+ struct sdap_idmap_ctx *idmap_ctx,
+ struct sysdb_attrs *sysdb_attrs,
+ const char *sid_attr,
+ char **_sid_str)
+{
+ errno_t ret;
+ enum idmap_error_code err;
+ struct ldb_message_element *el;
+ char *sid_str;
+
+ ret = sysdb_attrs_get_el(sysdb_attrs, sid_attr, &el);
+ if (ret != EOK || el->num_values != 1) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("No [%s] attribute while id-mapping. [%d][%s]\n",
+ sid_attr, el->num_values, strerror(ret)));
+ return ret;
+ }
+
+ err = sss_idmap_bin_sid_to_sid(idmap_ctx->map,
+ el->values[0].data,
+ el->values[0].length,
+ &sid_str);
+ if (err != IDMAP_SUCCESS) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Could not convert SID: [%s]\n",
+ idmap_error_string(err)));
+ return EIO;
+ }
+
+ *_sid_str = talloc_steal(mem_ctx, sid_str);
+
+ return EOK;
+}
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 44c53ed94..8bd2584e1 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -209,4 +209,10 @@ errno_t common_parse_search_base(TALLOC_CTX *mem_ctx,
const char *old_filter,
struct sdap_search_base ***_search_bases);
+errno_t
+sdap_attrs_get_sid_str(TALLOC_CTX *mem_ctx,
+ struct sdap_idmap_ctx *idmap_ctx,
+ struct sysdb_attrs *sysdb_attrs,
+ const char *sid_attr,
+ char **_sid_str);
#endif /* _LDAP_COMMON_H_ */
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 89882be04..67720025a 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -198,7 +198,6 @@ static int sdap_save_group(TALLOC_CTX *memctx,
TALLOC_CTX *tmpctx = NULL;
bool posix_group;
bool use_id_mapping = dp_opt_get_bool(opts->basic, SDAP_ID_MAPPING);
- struct dom_sid *dom_sid;
char *sid_str;
char *dom_sid_str;
enum idmap_error_code err;
@@ -229,25 +228,10 @@ static int sdap_save_group(TALLOC_CTX *memctx,
DEBUG(SSSDBG_TRACE_LIBS,
("Mapping group [%s] objectSID to unix ID\n", name));
- ret = sysdb_attrs_get_el(attrs,
- opts->group_map[SDAP_AT_GROUP_OBJECTSID].sys_name,
- &el);
- if (ret != EOK || el->num_values != 1) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- ("No [%s] attribute for group [%s] while id-mapping\n",
- opts->group_map[SDAP_AT_GROUP_OBJECTSID].name,
- name));
- goto fail;
- }
-
- ret = binary_to_dom_sid(tmpctx,
- el->values[0].data,
- el->values[0].length,
- &dom_sid);
- if (ret != EOK) goto fail;
-
- ret = dom_sid_to_string(tmpctx, dom_sid, &sid_str);
- talloc_zfree(dom_sid);
+ ret = sdap_attrs_get_sid_str(
+ tmpctx, opts->idmap_ctx, attrs,
+ opts->group_map[SDAP_AT_GROUP_OBJECTSID].sys_name,
+ &sid_str);
if (ret != EOK) goto fail;
/* Add string representation to the cache for easier
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index b0b533242..ff9905f31 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -25,6 +25,7 @@
#include "db/sysdb.h"
#include "providers/ldap/sdap_async_private.h"
#include "providers/ldap/ldap_common.h"
+#include "providers/ldap/sdap_idmap.h"
/* ==Save-fake-group-list=====================================*/
static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
@@ -44,6 +45,9 @@ static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
bool in_transaction = false;
bool posix;
time_t now;
+ char *sid_str;
+ enum idmap_error_code err;
+ bool use_id_mapping = dp_opt_get_bool(opts->basic, SDAP_ID_MAPPING);
/* There are no groups in LDAP but we should add user to groups ?? */
if (ldap_groups_count == 0) return EOK;
@@ -104,18 +108,50 @@ static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
if (strcmp(name, missing[i]) == 0) {
posix = true;
- ret = sysdb_attrs_get_uint32_t(ldap_groups[ai],
- SYSDB_GIDNUM,
- &gid);
- if (ret == ENOENT || (ret == EOK && gid == 0)) {
- DEBUG(9, ("The group %s gid was %s\n",
- name, ret == ENOENT ? "missing" : "zero"));
- DEBUG(8, ("Marking group %s as non-posix and setting GID=0!\n", name));
- gid = 0;
- posix = false;
- } else if (ret) {
- DEBUG(1, ("The GID attribute is malformed\n"));
- goto fail;
+
+ if (use_id_mapping) {
+ DEBUG(SSSDBG_TRACE_LIBS,
+ ("Mapping group [%s] objectSID to unix ID\n", name));
+
+ ret = sdap_attrs_get_sid_str(
+ tmp_ctx, opts->idmap_ctx, ldap_groups[ai],
+ opts->group_map[SDAP_AT_GROUP_OBJECTSID].sys_name,
+ &sid_str);
+ if (ret != EOK) goto fail;
+
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ ("Group [%s] has objectSID [%s]\n",
+ name, sid_str));
+
+ /* Convert the SID into a UNIX group ID */
+ err = sss_idmap_sid_to_unix(opts->idmap_ctx->map,
+ sid_str,
+ (uint32_t *)&gid);
+ if (err != IDMAP_SUCCESS && err != IDMAP_NO_DOMAIN) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Could not convert objectSID [%s] to a UNIX ID\n",
+ sid_str));
+ ret = EIO;
+ goto fail;
+ }
+
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ ("Group [%s] has mapped gid [%lu]\n",
+ name, (unsigned long)gid));
+ } else {
+ ret = sysdb_attrs_get_uint32_t(ldap_groups[ai],
+ SYSDB_GIDNUM,
+ &gid);
+ if (ret == ENOENT || (ret == EOK && gid == 0)) {
+ DEBUG(9, ("The group %s gid was %s\n",
+ name, ret == ENOENT ? "missing" : "zero"));
+ DEBUG(8, ("Marking group %s as non-posix and setting GID=0!\n", name));
+ gid = 0;
+ posix = false;
+ } else if (ret) {
+ DEBUG(1, ("The GID attribute is malformed\n"));
+ goto fail;
+ }
}
ret = sysdb_attrs_get_string(ldap_groups[ai],
@@ -2627,6 +2663,11 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
break;
case SDAP_SCHEMA_RFC2307BIS:
+ case SDAP_SCHEMA_AD:
+ /* TODO: AD uses a different member/memberof schema
+ * We need an AD specific call that is able to unroll
+ * nested groups by doing extensive recursive searches */
+
ret = sysdb_attrs_get_string(state->orig_user,
SYSDB_ORIG_DN,
&orig_dn);
@@ -2647,11 +2688,6 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
tevent_req_set_callback(subreq, sdap_get_initgr_done, req);
break;
case SDAP_SCHEMA_IPA_V1:
- case SDAP_SCHEMA_AD:
- /* TODO: AD uses a different member/memberof schema
- * We need an AD specific call that is able to unroll
- * nested groups by doing extensive recursive searches */
-
subreq = sdap_initgr_nested_send(state, state->ev, state->opts,
state->sysdb, state->dom, state->sh,
state->orig_user, state->grp_attrs);
@@ -2677,11 +2713,24 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
struct sdap_get_initgr_state *state = tevent_req_data(req,
struct sdap_get_initgr_state);
int ret;
+ TALLOC_CTX *tmp_ctx;
gid_t primary_gid;
char *gid;
+ char *sid_str;
+ char *dom_sid_str;
+ char *group_sid_str;
+ enum idmap_error_code err;
+ struct sdap_options *opts = state->opts;
+ bool use_id_mapping = dp_opt_get_bool(opts->basic, SDAP_ID_MAPPING);
DEBUG(9, ("Initgroups done\n"));
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
switch (state->opts->schema_type) {
case SDAP_SCHEMA_RFC2307:
ret = sdap_initgr_rfc2307_recv(subreq);
@@ -2706,35 +2755,102 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
if (ret) {
DEBUG(9, ("Error in initgroups: [%d][%s]\n",
ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
+ goto fail;
}
/* We also need to update the user's primary group, since
* the user may not be an explicit member of that group
*/
- ret = sysdb_attrs_get_uint32_t(state->orig_user, SYSDB_GIDNUM, &primary_gid);
- if (ret != EOK) {
- DEBUG(6, ("Could not find user's primary GID\n"));
- tevent_req_error(req, ret);
- return;
+
+ if (use_id_mapping) {
+ DEBUG(SSSDBG_TRACE_LIBS,
+ ("Mapping primary group to unix ID\n"));
+
+ /* The primary group ID is just the RID part of the objectSID
+ * of the group. Generate the GID by adding this to the domain
+ * SID value.
+ */
+
+ /* Get the user SID so we can extract the domain SID
+ * from it.
+ */
+ ret = sdap_attrs_get_sid_str(
+ tmp_ctx, opts->idmap_ctx, state->orig_user,
+ opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
+ &sid_str);
+ if (ret != EOK) goto fail;
+
+ /* Get the domain SID from the user SID */
+ ret = sdap_idmap_get_dom_sid_from_object(tmp_ctx, sid_str,
+ &dom_sid_str);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Could not parse domain SID from [%s]\n", sid_str));
+ goto fail;
+ }
+
+ ret = sysdb_attrs_get_uint32_t(
+ state->orig_user,
+ opts->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name,
+ &primary_gid);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("no primary group ID provided\n"));
+ ret = EINVAL;
+ goto fail;
+ }
+
+ /* Add the RID to the end */
+ group_sid_str = talloc_asprintf(tmp_ctx, "%s-%lu",
+ dom_sid_str,
+ (unsigned long)primary_gid);
+ if (!group_sid_str) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ /* Convert the SID into a UNIX group ID */
+ err = sss_idmap_sid_to_unix(opts->idmap_ctx->map,
+ sid_str,
+ (uint32_t *)&primary_gid);
+ if (err != IDMAP_SUCCESS) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Could not convert objectSID [%s] to a UNIX ID\n",
+ sid_str));
+ ret = EIO;
+ goto fail;
+ }
+ } else {
+ ret = sysdb_attrs_get_uint32_t(state->orig_user, SYSDB_GIDNUM,
+ &primary_gid);
+ if (ret != EOK) {
+ DEBUG(6, ("Could not find user's primary GID\n"));
+ goto fail;
+ }
}
gid = talloc_asprintf(state, "%lu", (unsigned long)primary_gid);
if (gid == NULL) {
- tevent_req_error(req, ENOMEM);
- return;
+ ret = ENOMEM;
+ goto fail;
}
subreq = groups_get_send(req, state->ev, state->id_ctx, gid,
BE_FILTER_IDNUM, BE_ATTR_ALL);
if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
+ ret = ENOMEM;
+ goto fail;
}
tevent_req_set_callback(subreq, sdap_get_initgr_pgid, req);
+ talloc_free(tmp_ctx);
tevent_req_done(req);
+ return;
+
+fail:
+ talloc_free(tmp_ctx);
+ tevent_req_error(req, ret);
+ return;
}
static void sdap_get_initgr_pgid(struct tevent_req *subreq)
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index c6534993a..c894e874b 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -56,7 +56,6 @@ int sdap_save_user(TALLOC_CTX *memctx,
char **missing = NULL;
TALLOC_CTX *tmpctx = NULL;
bool use_id_mapping = dp_opt_get_bool(opts->basic, SDAP_ID_MAPPING);
- struct dom_sid *dom_sid;
char *sid_str;
char *dom_sid_str = NULL;
char *group_sid_str;
@@ -122,25 +121,10 @@ int sdap_save_user(TALLOC_CTX *memctx,
DEBUG(SSSDBG_TRACE_LIBS,
("Mapping user [%s] objectSID to unix ID\n", name));
- ret = sysdb_attrs_get_el(attrs,
- opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
- &el);
- if (ret != EOK || el->num_values != 1) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- ("No [%s] attribute for user [%s] while id-mapping. [%d][%s]\n",
- opts->user_map[SDAP_AT_USER_OBJECTSID].name,
- name, el->num_values, strerror(ret)));
- goto fail;
- }
-
- ret = binary_to_dom_sid(tmpctx,
- el->values[0].data,
- el->values[0].length,
- &dom_sid);
- if (ret != EOK) goto fail;
-
- ret = dom_sid_to_string(tmpctx, dom_sid, &sid_str);
- talloc_zfree(dom_sid);
+ ret = sdap_attrs_get_sid_str(
+ tmpctx, opts->idmap_ctx, attrs,
+ opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
+ &sid_str);
if (ret != EOK) goto fail;
/* Add string representation to the cache for easier