diff options
author | Sumit Bose <sbose@redhat.com> | 2013-12-18 13:47:31 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-12-19 20:14:25 +0100 |
commit | 402af69c0bb7ea8b84e36f3567de6086042cb152 (patch) | |
tree | 17fe1acf01cb29403028935941d9caca66e2105a /src/providers/ldap/sdap_async_groups.c | |
parent | 8d55e0fffd29184d44cb49eaab2ca3a4226e0123 (diff) | |
download | sssd-402af69c0bb7ea8b84e36f3567de6086042cb152.tar.gz sssd-402af69c0bb7ea8b84e36f3567de6086042cb152.tar.xz sssd-402af69c0bb7ea8b84e36f3567de6086042cb152.zip |
AD: cross-domain membership fix
A recent patch directed all call related to group membership lookups to
the AD LDAP port to fix an issue related to missing group memberships in
the Global Catalog. As a side-effect it broke cross-domain
group-memberships because those cannot be resolved by the connection to
the LDAP port.
The patch tires to fix this by restoring the original behaviour in the
top-level lookup calls in the AD provider and switching to the LDAP port
only for the LDAP request which is expected to return the full group
membership.
Additionally this patch contains a related fix for the tokenGroups with
Posix attributes patch. The original connection, typically a Global
Catalog connection in the AD case is passed down the stack so that the
group lookup after the tokenGroups request can run over the same
connection.
Diffstat (limited to 'src/providers/ldap/sdap_async_groups.c')
-rw-r--r-- | src/providers/ldap/sdap_async_groups.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c index 33648c5da..9eece9a6e 100644 --- a/src/providers/ldap/sdap_async_groups.c +++ b/src/providers/ldap/sdap_async_groups.c @@ -26,6 +26,7 @@ #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_idmap.h" +#include "providers/ad/ad_common.h" /* ==Group-Parsing Routines=============================================== */ @@ -1540,9 +1541,13 @@ struct sdap_get_groups_state { size_t base_iter; struct sdap_search_base **search_bases; + + struct sdap_handle *ldap_sh; + struct sdap_id_op *op; }; static errno_t sdap_get_groups_next_base(struct tevent_req *req); +static void sdap_get_groups_ldap_connect_done(struct tevent_req *subreq); static void sdap_get_groups_process(struct tevent_req *subreq); static void sdap_get_groups_done(struct tevent_req *subreq); @@ -1558,7 +1563,9 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, { errno_t ret; struct tevent_req *req; + struct tevent_req *subreq; struct sdap_get_groups_state *state; + struct ad_id_ctx *subdom_id_ctx; req = tevent_req_create(memctx, &state, struct sdap_get_groups_state); if (!req) return NULL; @@ -1586,6 +1593,30 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, goto done; } + /* With AD by default the Global Catalog is used for lookup. But the GC + * group object might not have full group membership data. To make sure we + * connect to an LDAP server of the group's domain. */ + if (state->opts->schema_type == SDAP_SCHEMA_AD && sdom->pvt != NULL) { + subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx); + state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache); + if (!state->op) { + DEBUG(2, ("sdap_id_op_create failed\n")); + ret = ENOMEM; + goto done; + } + + subreq = sdap_id_op_connect_send(state->op, state, &ret); + if (subreq == NULL) { + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, + sdap_get_groups_ldap_connect_done, + req); + return req; + } + ret = sdap_get_groups_next_base(req); done: @@ -1597,6 +1628,34 @@ done: return req; } +static void sdap_get_groups_ldap_connect_done(struct tevent_req *subreq) +{ + struct tevent_req *req; + struct sdap_get_groups_state *state; + int ret; + int dp_error; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct sdap_get_groups_state); + + ret = sdap_id_op_connect_recv(subreq, &dp_error); + talloc_zfree(subreq); + + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + state->ldap_sh = sdap_id_op_handle(state->op); + + ret = sdap_get_groups_next_base(req); + if (ret != EOK) { + tevent_req_error(req, ret); + } + + return; +} + static errno_t sdap_get_groups_next_base(struct tevent_req *req) { struct tevent_req *subreq; @@ -1617,7 +1676,8 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req) state->search_bases[state->base_iter]->basedn)); subreq = sdap_get_generic_send( - state, state->ev, state->opts, state->sh, + state, state->ev, state->opts, + state->ldap_sh != NULL ? state->ldap_sh : state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, |