From 9d8b384d0b258d96ffc1cf8fd16ef883ca05871e Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 19 Oct 2012 18:28:41 +0200 Subject: [PATCH 06/17] krb5_auth_send: check for sub-domains If there is an authentication request for a user from a sub-domain a temporary sysdb context is generated to allow lookups in the corresponding sub-tree in the cache. --- src/providers/ipa/ipa_auth.c | 6 ------ src/providers/krb5/krb5_auth.c | 20 +++++++++++++++----- src/providers/krb5/krb5_utils.c | 19 +++++++++++++++++++ src/providers/krb5/krb5_utils.h | 3 +++ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/providers/ipa/ipa_auth.c b/src/providers/ipa/ipa_auth.c index 2bd313b..eb62f02 100644 --- a/src/providers/ipa/ipa_auth.c +++ b/src/providers/ipa/ipa_auth.c @@ -210,12 +210,6 @@ void ipa_auth(struct be_req *be_req) state->pd = pd; - if (strcasecmp(pd->domain, be_req->be_ctx->domain->name) != 0 && - state->pd->cmd != SSS_PAM_ACCT_MGMT) { - DEBUG(SSSDBG_OP_FAILURE, ("This operation is not allowed for subdomains!\n")); - goto fail; - } - switch (state->pd->cmd) { case SSS_PAM_AUTHENTICATE: state->ipa_auth_ctx = talloc_get_type( diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index e244cea..c98535b 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -281,6 +281,7 @@ struct krb5_auth_state { struct tevent_context *ev; struct be_ctx *be_ctx; struct pam_data *pd; + struct sysdb_ctx *sysdb; struct krb5_ctx *krb5_ctx; struct krb5child_req *kr; @@ -318,6 +319,7 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, struct tevent_req *req; struct tevent_req *subreq; int ret; + struct sss_domain_info *dom; req = tevent_req_create(mem_ctx, &state, struct krb5_auth_state); if (req == NULL) { @@ -333,6 +335,14 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, state->pam_status = PAM_SYSTEM_ERR; state->dp_err = DP_ERR_FATAL; + ret = get_domain_or_subdomain(state, be_ctx, pd->domain, &dom); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("get_domain_or_subdomain failed.\n")); + goto done; + } + + state->sysdb = dom->sysdb; + switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: case SSS_CMD_RENEW: @@ -386,7 +396,7 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, } kr = state->kr; - ret = sysdb_get_user_attr(state, be_ctx->sysdb, state->pd->user, attrs, + ret = sysdb_get_user_attr(state, state->sysdb, state->pd->user, attrs, &res); if (ret) { DEBUG(5, ("sysdb search for upn of user [%s] failed.\n", pd->user)); @@ -793,7 +803,7 @@ static void krb5_child_done(struct tevent_req *subreq) "please remove it manually.\n", kr->old_ccname)); } - ret = krb5_delete_ccname(state, state->be_ctx->sysdb, + ret = krb5_delete_ccname(state, state->sysdb, pd->user, kr->old_ccname); if (ret != EOK) { DEBUG(1, ("krb5_delete_ccname failed.\n")); @@ -882,7 +892,7 @@ static void krb5_child_done(struct tevent_req *subreq) "please remove it manually.\n", kr->old_ccname)); } - ret = krb5_save_ccname(state, state->be_ctx->sysdb, + ret = krb5_save_ccname(state, state->sysdb, pd->user, store_ccname); if (ret) { DEBUG(1, ("krb5_save_ccname failed.\n")); @@ -1048,7 +1058,7 @@ static void krb5_save_ccname_done(struct tevent_req *req) talloc_set_destructor((TALLOC_CTX *)password, password_destructor); - ret = sysdb_cache_password(state->be_ctx->sysdb, pd->user, password); + ret = sysdb_cache_password(state->sysdb, pd->user, password); if (ret) { DEBUG(2, ("Failed to cache password, offline auth may not work." " (%d)[%s]!?\n", ret, strerror(ret))); @@ -1076,7 +1086,7 @@ static void krb5_pam_handler_cache_auth_step(struct tevent_req *req) struct krb5_ctx *krb5_ctx = state->kr->krb5_ctx; int ret; - ret = sysdb_cache_auth(state->be_ctx->sysdb, pd->user, pd->authtok, + ret = sysdb_cache_auth(state->sysdb, pd->user, pd->authtok, pd->authtok_size, state->be_ctx->cdb, true, NULL, NULL); if (ret != EOK) { diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c index 73a711d..7a68b0f 100644 --- a/src/providers/krb5/krb5_utils.c +++ b/src/providers/krb5/krb5_utils.c @@ -1031,3 +1031,22 @@ struct sss_krb5_cc_be dir_cc = { }; #endif /* HAVE_KRB5_DIRCACHE */ + +errno_t get_domain_or_subdomain(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, + char *domain_name, + struct sss_domain_info **dom) +{ + + if (domain_name != NULL && + strcasecmp(domain_name, be_ctx->domain->name) != 0) { + *dom = new_subdomain(mem_ctx, be_ctx->domain, domain_name, NULL, NULL); + if (*dom == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("new_subdomain failed.\n")); + return ENOMEM; + } + } else { + *dom = be_ctx->domain; + } + + return EOK; +} diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h index 00dfc85..43fe77b 100644 --- a/src/providers/krb5/krb5_utils.h +++ b/src/providers/krb5/krb5_utils.h @@ -83,4 +83,7 @@ errno_t cc_dir_create(const char *location, pcre *illegal_re, #endif /* HAVE_KRB5_DIRCACHE */ +errno_t get_domain_or_subdomain(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, + char *domain_name, + struct sss_domain_info **dom); #endif /* __KRB5_UTILS_H__ */ -- 1.7.7.6