>From 3f115bad21ce47bb7dee4541982613c0212ed229 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Sun, 6 Oct 2013 20:23:07 +0200 Subject: [PATCH 1/6] LDAP: Amend sdap_access_check to allow any connection Related: https://fedorahosted.org/sssd/ticket/2082 Also move the check for subdomain to the handler. I think it is the job of the handler to decide which domain the request belongs to, not the request itself. --- src/providers/ad/ad_access.c | 4 +++- src/providers/ipa/ipa_access.c | 13 +++++++++++-- src/providers/ldap/ldap_access.c | 11 ++++++++++- src/providers/ldap/sdap_access.c | 40 ++++++++++++++++++---------------------- src/providers/ldap/sdap_access.h | 2 ++ 5 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/providers/ad/ad_access.c b/src/providers/ad/ad_access.c index 746017dc5f6caa29128cc7404bcaa93359ef5766..cf6412f22c6146b26090646b5b8d060efa43365f 100644 --- a/src/providers/ad/ad_access.c +++ b/src/providers/ad/ad_access.c @@ -56,7 +56,9 @@ ad_access_handler(struct be_req *breq) /* Verify that the account is not locked */ req = sdap_access_send(breq, be_ctx->ev, be_ctx, domain, - access_ctx->sdap_access_ctx, pd); + access_ctx->sdap_access_ctx, + access_ctx->sdap_access_ctx->id_ctx->conn, + pd); if (!req) { be_req_terminate(breq, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL); return; diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c index 7d44788af98350f47358488fc3840e675b2827d8..f067b7021d8afc483385ef9b8176242eca42988a 100644 --- a/src/providers/ipa/ipa_access.c +++ b/src/providers/ipa/ipa_access.c @@ -78,6 +78,7 @@ void ipa_access_handler(struct be_req *be_req) struct pam_data *pd; struct ipa_access_ctx *ipa_access_ctx; struct tevent_req *req; + struct sss_domain_info *dom; struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); @@ -85,13 +86,21 @@ void ipa_access_handler(struct be_req *be_req) ipa_access_ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct ipa_access_ctx); + dom = be_ctx->domain; + if (strcasecmp(pd->domain, be_ctx->domain->name) != 0) { + /* Subdomain request, verify subdomain */ + dom = find_subdomain_by_name(be_ctx->domain, pd->domain, true); + } + /* First, verify that this account isn't locked. * We need to do this in case the auth phase was * skipped (such as during GSSAPI single-sign-on * or SSH public key exchange. */ - req = sdap_access_send(be_req, be_ctx->ev, be_ctx, be_ctx->domain, - ipa_access_ctx->sdap_access_ctx, pd); + req = sdap_access_send(be_req, be_ctx->ev, be_ctx, dom, + ipa_access_ctx->sdap_access_ctx, + ipa_access_ctx->sdap_access_ctx->id_ctx->conn, + pd); if (!req) { be_req_terminate(be_req, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL); return; diff --git a/src/providers/ldap/ldap_access.c b/src/providers/ldap/ldap_access.c index 8d5b5e22865219e13d0a090f0da4bce8ae06a234..c468a1cd53a607dc5b1ebe3635ae24286b7d6604 100644 --- a/src/providers/ldap/ldap_access.c +++ b/src/providers/ldap/ldap_access.c @@ -50,6 +50,7 @@ void sdap_pam_access_handler(struct be_req *breq) struct pam_data *pd; struct tevent_req *req; struct sdap_access_ctx *access_ctx; + struct sss_domain_info *dom; pd = talloc_get_type(be_req_get_data(breq), struct pam_data); @@ -57,8 +58,16 @@ void sdap_pam_access_handler(struct be_req *breq) talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct sdap_access_ctx); + dom = be_ctx->domain; + if (strcasecmp(pd->domain, be_ctx->domain->name) != 0) { + /* Subdomain request, verify subdomain */ + dom = find_subdomain_by_name(be_ctx->domain, pd->domain, true); + } + req = sdap_access_send(breq, be_ctx->ev, be_ctx, - be_ctx->domain, access_ctx, pd); + dom, access_ctx, + access_ctx->id_ctx->conn, + pd); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to start sdap_access request\n")); sdap_access_reply(breq, PAM_SYSTEM_ERR); diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c index 9d1315fab9b838e3f955e82c38ce88a97cb9cd0a..267a2b863cc1e944998ee53ca985d17d2cef715d 100644 --- a/src/providers/ldap/sdap_access.c +++ b/src/providers/ldap/sdap_access.c @@ -45,6 +45,7 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, + struct sdap_id_conn_ctx *conn, const char *username, struct ldb_message *user_entry); static errno_t sdap_access_filter_recv(struct tevent_req *req); @@ -62,6 +63,7 @@ struct sdap_access_req_ctx { struct pam_data *pd; struct tevent_context *ev; struct sdap_access_ctx *access_ctx; + struct sdap_id_conn_ctx *conn; struct be_ctx *be_ctx; struct sss_domain_info *domain; struct ldb_message *user_entry; @@ -78,6 +80,7 @@ sdap_access_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, + struct sdap_id_conn_ctx *conn, struct pam_data *pd) { errno_t ret; @@ -85,7 +88,6 @@ sdap_access_send(TALLOC_CTX *mem_ctx, struct tevent_req *req; struct ldb_result *res; const char *attrs[] = { "*", NULL }; - struct sss_domain_info *user_dom; req = tevent_req_create(mem_ctx, &state, struct sdap_access_req_ctx); if (req == NULL) { @@ -98,6 +100,7 @@ sdap_access_send(TALLOC_CTX *mem_ctx, state->pd = pd; state->ev = ev; state->access_ctx = access_ctx; + state->conn = conn; state->current_rule = 0; DEBUG(6, ("Performing access check for user [%s]\n", pd->user)); @@ -108,20 +111,9 @@ sdap_access_send(TALLOC_CTX *mem_ctx, goto done; } - /* Get original user DN, take care of subdomain users as well */ - if (strcasecmp(pd->domain, be_ctx->domain->name) != 0) { - user_dom = find_subdomain_by_name(be_ctx->domain, pd->domain, true); - if (user_dom == NULL) { - DEBUG(SSSDBG_OP_FAILURE, ("find_subdomain_by_name failed.\n")); - ret = ENOMEM; - goto done; - } - ret = sysdb_get_user_attr(state, user_dom->sysdb, user_dom, - pd->user, attrs, &res); - } else { - ret = sysdb_get_user_attr(state, domain->sysdb, domain, - pd->user, attrs, &res); - } + /* Get original user DN, domain already points to the right (sub)domain */ + ret = sysdb_get_user_attr(state, domain->sysdb, domain, + pd->user, attrs, &res); if (ret != EOK) { if (ret == ENOENT) { /* If we can't find the user, return access denied */ @@ -177,6 +169,7 @@ static errno_t check_next_rule(struct sdap_access_req_ctx *state, subreq = sdap_access_filter_send(state, state->ev, state->be_ctx, state->domain, state->access_ctx, + state->conn, state->pd->user, state->user_entry); if (subreq == NULL) { @@ -624,7 +617,8 @@ struct sdap_access_filter_req_ctx { const char *filter; struct tevent_context *ev; struct sdap_access_ctx *access_ctx; - struct sdap_id_ctx *sdap_ctx; + struct sdap_options *opts; + struct sdap_id_conn_ctx *conn; struct sdap_id_op *sdap_op; struct sysdb_handle *handle; struct sss_domain_info *domain; @@ -641,6 +635,7 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, + struct sdap_id_conn_ctx *conn, const char *username, struct ldb_message *user_entry) { @@ -664,7 +659,8 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, state->filter = NULL; state->username = username; - state->sdap_ctx = access_ctx->id_ctx; + state->opts = access_ctx->id_ctx->opts; + state->conn = conn; state->ev = ev; state->access_ctx = access_ctx; state->domain = domain; @@ -707,9 +703,9 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, state->filter = talloc_asprintf( state, "(&(%s=%s)(objectclass=%s)%s)", - state->sdap_ctx->opts->user_map[SDAP_AT_USER_NAME].name, + state->opts->user_map[SDAP_AT_USER_NAME].name, clean_username, - state->sdap_ctx->opts->user_map[SDAP_OC_USER].name, + state->opts->user_map[SDAP_OC_USER].name, state->access_ctx->filter); if (state->filter == NULL) { DEBUG(0, ("Could not construct access filter\n")); @@ -721,7 +717,7 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, DEBUG(6, ("Checking filter against LDAP\n")); state->sdap_op = sdap_id_op_create(state, - state->sdap_ctx->conn->conn_cache); + state->conn->conn_cache); if (!state->sdap_op) { DEBUG(2, ("sdap_id_op_create failed\n")); ret = ENOMEM; @@ -805,13 +801,13 @@ static void sdap_access_filter_connect_done(struct tevent_req *subreq) */ subreq = sdap_get_generic_send(state, state->ev, - state->sdap_ctx->opts, + state->opts, sdap_id_op_handle(state->sdap_op), state->basedn, LDAP_SCOPE_BASE, state->filter, NULL, NULL, 0, - dp_opt_get_int(state->sdap_ctx->opts->basic, + dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h index cda078688b19182112d27e605008f6406a604daa..30097e21f59abe19fc14d052edb0a6343c67f892 100644 --- a/src/providers/ldap/sdap_access.h +++ b/src/providers/ldap/sdap_access.h @@ -26,6 +26,7 @@ #define SDAP_ACCESS_H_ #include "providers/dp_backend.h" +#include "providers/ldap/ldap_common.h" #define SYSDB_LDAP_ACCESS_FILTER "ldap_access_filter_allow" @@ -62,6 +63,7 @@ sdap_access_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, + struct sdap_id_conn_ctx *conn, struct pam_data *pd); errno_t sdap_access_recv(struct tevent_req *req); -- 1.8.3.1