From 2aae75b167f1d9d5cf65d5529c585cfb18c6207b Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Sun, 22 Apr 2012 15:14:22 -0400 Subject: LDAP: Allow looking up ID-mapped groups by name --- src/providers/ldap/ldap_id.c | 31 ++++++--- src/providers/ldap/sdap_async_groups.c | 123 ++++++++++++++++++++++++++++----- 2 files changed, 125 insertions(+), 29 deletions(-) (limited to 'src/providers') diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index a210a472..98f99019 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -335,6 +335,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, const char *attr_name; char *clean_name; int ret; + bool use_id_mapping = dp_opt_get_bool(ctx->opts->basic, SDAP_ID_MAPPING); req = tevent_req_create(memctx, &state, struct groups_get_state); if (!req) return NULL; @@ -367,18 +368,26 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, goto fail; } - ret = sss_filter_sanitize(state, name, &clean_name); - if (ret != EOK) { - goto fail; - } - state->filter = talloc_asprintf(state, - "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))", - attr_name, clean_name, - ctx->opts->group_map[SDAP_OC_GROUP].name, - ctx->opts->group_map[SDAP_AT_GROUP_NAME].name, - ctx->opts->group_map[SDAP_AT_GROUP_GID].name, - ctx->opts->group_map[SDAP_AT_GROUP_GID].name); + if (use_id_mapping) { + /* When mapping IDs, we don't want to limit ourselves + * to groups with a GID value + */ + + state->filter = talloc_asprintf(state, + "(&(%s=%s)(objectclass=%s)(%s=*))", + attr_name, clean_name, + ctx->opts->group_map[SDAP_OC_GROUP].name, + ctx->opts->group_map[SDAP_AT_GROUP_NAME].name); + } else { + state->filter = talloc_asprintf(state, + "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))", + attr_name, clean_name, + ctx->opts->group_map[SDAP_OC_GROUP].name, + ctx->opts->group_map[SDAP_AT_GROUP_NAME].name, + ctx->opts->group_map[SDAP_AT_GROUP_GID].name, + ctx->opts->group_map[SDAP_AT_GROUP_GID].name); + } talloc_zfree(clean_name); if (!state->filter) { DEBUG(2, ("Failed to build filter\n")); diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c index d6877a37..89882be0 100644 --- a/src/providers/ldap/sdap_async_groups.c +++ b/src/providers/ldap/sdap_async_groups.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" /* ==Group-Parsing Routines=============================================== */ @@ -196,6 +197,11 @@ static int sdap_save_group(TALLOC_CTX *memctx, char *usn_value = NULL; 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; tmpctx = talloc_new(memctx); if (!tmpctx) { @@ -217,27 +223,108 @@ static int sdap_save_group(TALLOC_CTX *memctx, goto fail; } - ret = sysdb_attrs_get_bool(attrs, SYSDB_POSIX, &posix_group); - if (ret == ENOENT) { + if (use_id_mapping) { posix_group = true; - } else if (ret != EOK) { - goto fail; - } - DEBUG(8, ("This is%s a posix group\n", (posix_group)?"":" not")); - ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, posix_group); - if (ret != EOK) { - goto fail; - } + 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 = sysdb_attrs_get_uint32_t(attrs, - opts->group_map[SDAP_AT_GROUP_GID].sys_name, - &gid); - if (ret != EOK) { - DEBUG(1, ("no gid provided for [%s] in domain [%s].\n", - name, dom->name)); - ret = EINVAL; - 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); + if (ret != EOK) goto fail; + + /* Add string representation to the cache for easier + * debugging + */ + ret = sysdb_attrs_add_string(group_attrs, SYSDB_SID_STR, sid_str); + if (ret != EOK) goto fail; + + /* 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; + } else if (err == IDMAP_NO_DOMAIN) { + /* This is the first time we've seen this domain + * Create a new domain for it. We'll use the dom-sid + * as the domain name for now, since we don't have + * any way to get the real name. + */ + ret = sdap_idmap_get_dom_sid_from_object(tmpctx, 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 = sdap_idmap_add_domain(opts->idmap_ctx, + dom_sid_str, dom_sid_str, + -1); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Could not add new domain for sid [%s]\n", sid_str)); + goto fail; + } + + /* Now try converting to a UNIX ID again */ + err = sss_idmap_sid_to_unix(opts->idmap_ctx->map, + sid_str, + (uint32_t *)&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_bool(attrs, SYSDB_POSIX, &posix_group); + if (ret == ENOENT) { + posix_group = true; + } else if (ret != EOK) { + goto fail; + } + + DEBUG(8, ("This is%s a posix group\n", (posix_group)?"":" not")); + ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, posix_group); + if (ret != EOK) { + goto fail; + } + + ret = sysdb_attrs_get_uint32_t(attrs, + opts->group_map[SDAP_AT_GROUP_GID].sys_name, + &gid); + if (ret != EOK) { + DEBUG(1, ("no gid provided for [%s] in domain [%s].\n", + name, dom->name)); + ret = EINVAL; + goto fail; + } } /* check that the gid is valid for this domain */ -- cgit