From 1e29e68388c2e9c5da9cb0afe997bc1b4e6933be Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 28 Oct 2010 12:38:28 +0200 Subject: Add infrastructure for Kerberos access provider --- src/providers/krb5/krb5_auth.c | 104 ++++++++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 26 deletions(-) (limited to 'src/providers/krb5/krb5_auth.c') diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index 4299ca89..626df2ff 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -280,12 +280,16 @@ static struct krb5_ctx *get_krb5_ctx(struct be_req *be_req) switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: return talloc_get_type(be_req->be_ctx->bet_info[BET_AUTH].pvt_bet_data, - struct krb5_ctx); + struct krb5_ctx); + break; + case SSS_PAM_ACCT_MGMT: + return talloc_get_type(be_req->be_ctx->bet_info[BET_ACCESS].pvt_bet_data, + struct krb5_ctx); break; case SSS_PAM_CHAUTHTOK: case SSS_PAM_CHAUTHTOK_PRELIM: return talloc_get_type(be_req->be_ctx->bet_info[BET_CHPASS].pvt_bet_data, - struct krb5_ctx); + struct krb5_ctx); break; default: DEBUG(1, ("Unsupported PAM task.\n")); @@ -649,20 +653,11 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, goto done; } break; - case SSS_PAM_ACCT_MGMT: - case SSS_PAM_SETCRED: - case SSS_PAM_OPEN_SESSION: - case SSS_PAM_CLOSE_SESSION: - state->pam_status = PAM_SUCCESS; - state->dp_err = DP_ERR_OK; - ret = EOK; - goto done; - break; default: - DEBUG(4, ("krb5 does not handles pam task %d.\n", pd->cmd)); - state->pam_status = PAM_MODULE_UNKNOWN; - state->dp_err = DP_ERR_OK; - ret = EOK; + DEBUG(4, ("Unexpected pam task %d.\n", pd->cmd)); + state->pam_status = PAM_SYSTEM_ERR; + state->dp_err = DP_ERR_FATAL; + ret = EINVAL; goto done; } @@ -1352,35 +1347,65 @@ static void krb_reply(struct be_req *req, int dp_err, int result) } void krb5_auth_done(struct tevent_req *req); +static void krb5_access_done(struct tevent_req *req); void krb5_pam_handler(struct be_req *be_req) { struct tevent_req *req; struct pam_data *pd; struct krb5_ctx *krb5_ctx; + int dp_err = DP_ERR_FATAL; pd = talloc_get_type(be_req->req_data, struct pam_data); + pd->pam_status = PAM_SYSTEM_ERR; krb5_ctx = get_krb5_ctx(be_req); if (krb5_ctx == NULL) { DEBUG(1, ("Kerberos context not available.\n")); - goto failed; + goto done; } - req = krb5_auth_send(be_req, be_req->be_ctx->ev, be_req->be_ctx, pd, - krb5_ctx); - if (req == NULL) { - DEBUG(1, ("krb5_auth_send failed.\n")); - goto failed; - } + switch (pd->cmd) { + case SSS_PAM_AUTHENTICATE: + case SSS_PAM_CHAUTHTOK_PRELIM: + case SSS_PAM_CHAUTHTOK: + req = krb5_auth_send(be_req, be_req->be_ctx->ev, be_req->be_ctx, pd, + krb5_ctx); + if (req == NULL) { + DEBUG(1, ("krb5_auth_send failed.\n")); + goto done; + } - tevent_req_set_callback(req, krb5_auth_done, be_req); + tevent_req_set_callback(req, krb5_auth_done, be_req); + break; + case SSS_PAM_ACCT_MGMT: + req = krb5_access_send(be_req, be_req->be_ctx->ev, be_req->be_ctx, + pd, krb5_ctx); + if (req == NULL) { + DEBUG(1, ("krb5_access_send failed.\n")); + goto done; + } + + tevent_req_set_callback(req, krb5_access_done, be_req); + break; + case SSS_PAM_SETCRED: + case SSS_PAM_OPEN_SESSION: + case SSS_PAM_CLOSE_SESSION: + pd->pam_status = PAM_SUCCESS; + dp_err = DP_ERR_OK; + goto done; + break; + default: + DEBUG(4, ("krb5 does not handles pam task %d.\n", pd->cmd)); + pd->pam_status = PAM_MODULE_UNKNOWN; + dp_err = DP_ERR_OK; + goto done; + } return; -failed: - pd->pam_status = PAM_SYSTEM_ERR; - krb_reply(be_req, DP_ERR_FATAL, pd->pam_status); +done: + krb_reply(be_req, dp_err, pd->pam_status); } void krb5_auth_done(struct tevent_req *req) @@ -1404,3 +1429,30 @@ void krb5_auth_done(struct tevent_req *req) krb_reply(be_req, dp_err, pd->pam_status); } + +static void krb5_access_done(struct tevent_req *req) +{ + int ret; + struct be_req *be_req = tevent_req_callback_data(req, struct be_req); + bool access_allowed; + struct pam_data *pd; + int dp_err = DP_ERR_OK; + + pd = talloc_get_type(be_req->req_data, struct pam_data); + pd->pam_status = PAM_SYSTEM_ERR; + + ret = krb5_access_recv(req, &access_allowed); + talloc_zfree(req); + if (ret != EOK) { + DEBUG(1, ("krb5_access request failed [%d][%s]\n", ret, strerror(ret))); + goto done; + } + + DEBUG(7, ("Access %s for user [%s].\n", + access_allowed ? "allowed" : "denied", pd->user)); + pd->pam_status = access_allowed ? PAM_SUCCESS : PAM_PERM_DENIED; + dp_err = DP_ERR_OK; + +done: + krb_reply(be_req, dp_err, pd->pam_status); +} -- cgit