1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose/*
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose SSSD
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose Kerberos 5 Backend Module - access control
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose Authors:
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose Sumit Bose <sbose@redhat.com>
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose Copyright (C) 2010 Red Hat
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose This program is free software; you can redistribute it and/or modify
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose it under the terms of the GNU General Public License as published by
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose the Free Software Foundation; either version 3 of the License, or
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose (at your option) any later version.
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose This program is distributed in the hope that it will be useful,
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose GNU General Public License for more details.
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose You should have received a copy of the GNU General Public License
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose*/
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose#include "util/util.h"
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose#include "providers/krb5/krb5_auth.h"
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose#include "providers/krb5/krb5_common.h"
964628ab89229e9266adc5f4f8a26222734788b7Sumit Bose#include "providers/krb5/krb5_utils.h"
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bosestruct krb5_access_state {
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct tevent_context *ev;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct be_ctx *be_ctx;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct pam_data *pd;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct krb5_ctx *krb5_ctx;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose struct krb5child_req *kr;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose bool access_allowed;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose};
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
7baccb545ac9829b7e1990f45ff6f70e2de55c2aSimo Sorcestatic void krb5_access_done(struct tevent_req *subreq);
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bosestruct tevent_req *krb5_access_send(TALLOC_CTX *mem_ctx,
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct tevent_context *ev,
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct be_ctx *be_ctx,
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct pam_data *pd,
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct krb5_ctx *krb5_ctx)
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose{
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct krb5_access_state *state;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct tevent_req *req;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose struct tevent_req *subreq;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose int ret;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose const char **attrs;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose struct ldb_result *res;
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek struct sss_domain_info *dom;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose req = tevent_req_create(mem_ctx, &state, struct krb5_access_state);
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose if (req == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n");
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose return NULL;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose }
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose state->ev = ev;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose state->be_ctx = be_ctx;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose state->pd = pd;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose state->krb5_ctx = krb5_ctx;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose state->access_allowed = false;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek ret = get_domain_or_subdomain(be_ctx, pd->domain, &dom);
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek if (ret != EOK) {
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "get_domain_or_subdomain failed.\n");
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek goto done;
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek }
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek
fedfb7c62b4efa89d18d0d3a7895a2a34ec4ce42Jakub Hrozek ret = krb5_setup(state, pd, dom, krb5_ctx, &state->kr);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "krb5_setup failed.\n");
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto done;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose if (pd->cmd != SSS_PAM_ACCT_MGMT) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected pam task.\n");
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose ret = EINVAL;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose goto done;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose }
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
764aa04ee92dbbd0d1eca6703294135eb97fda6dSumit Bose attrs = talloc_array(state, const char *, 5);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose if (attrs == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n");
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose ret = ENOMEM;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto done;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose attrs[0] = SYSDB_UPN;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose attrs[1] = SYSDB_UIDNUM;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose attrs[2] = SYSDB_GIDNUM;
764aa04ee92dbbd0d1eca6703294135eb97fda6dSumit Bose attrs[3] = SYSDB_CANONICAL_UPN;
764aa04ee92dbbd0d1eca6703294135eb97fda6dSumit Bose attrs[4] = NULL;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
b3292840ebaa747a9fd596ff47cc5d18198361d0Michal Zidek ret = sysdb_get_user_attr(state, be_ctx->domain, state->pd->user, attrs,
b3292840ebaa747a9fd596ff47cc5d18198361d0Michal Zidek &res);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose if (ret) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FUNC_DATA,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "sysdb search for upn of user [%s] failed.\n", pd->user);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto done;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose switch (res->count) {
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose case 0:
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FUNC_DATA,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "No attributes for user [%s] found.\n", pd->user);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose ret = ENOENT;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto done;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose break;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose case 1:
aa8a8318aaa3270e9d9957d0c22dec6342360a37Pavel Reichl ret = find_or_guess_upn(state, res->msgs[0], krb5_ctx, be_ctx->domain,
aa8a8318aaa3270e9d9957d0c22dec6342360a37Pavel Reichl state->kr->user, pd->domain, &state->kr->upn);
964628ab89229e9266adc5f4f8a26222734788b7Sumit Bose if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "find_or_guess_upn failed.\n");
964628ab89229e9266adc5f4f8a26222734788b7Sumit Bose goto done;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose state->kr->uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM,
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose 0);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose if (state->kr->uid == 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "UID for user [%s] not known.\n", pd->user);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose ret = ENOENT;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto done;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose state->kr->gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM,
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose 0);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose if (state->kr->gid == 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "GID for user [%s] not known.\n", pd->user);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose ret = ENOENT;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto done;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose break;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose default:
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "User search for [%s] returned > 1 results!\n", pd->user);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose ret = EINVAL;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto done;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose break;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose subreq = handle_child_send(state, state->ev, state->kr);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose if (subreq == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "handle_child_send failed.\n");
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose ret = ENOMEM;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto done;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
7baccb545ac9829b7e1990f45ff6f70e2de55c2aSimo Sorce tevent_req_set_callback(subreq, krb5_access_done, req);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose return req;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bosedone:
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose if (ret == EOK) {
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose tevent_req_done(req);
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose } else {
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose tevent_req_error(req, ret);
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose }
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose tevent_req_post(req, state->ev);
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose return req;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose}
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
7baccb545ac9829b7e1990f45ff6f70e2de55c2aSimo Sorcestatic void krb5_access_done(struct tevent_req *subreq)
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose{
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose struct krb5_access_state *state = tevent_req_data(req,
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose struct krb5_access_state);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose int ret;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose uint8_t *buf = NULL;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose ssize_t len = -1;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose int32_t msg_status;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose ret = handle_child_recv(subreq, state, &buf, &len);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose talloc_free(subreq);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "child failed [%d][%s].\n", ret, strerror(ret));
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto fail;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose if ((size_t) len != sizeof(int32_t)) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "message has the wrong size.\n");
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose ret = EINVAL;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose goto fail;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose SAFEALIGN_COPY_INT32(&msg_status, buf, NULL);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose if (msg_status == EOK) {
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose state->access_allowed = true;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose } else {
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose state->access_allowed = false;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose }
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose tevent_req_done(req);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose return;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bosefail:
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose tevent_req_error(req, ret);
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose return;
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose}
e7a4ea98c6751a8c3d8405ca31481006f29b901eSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Boseint krb5_access_recv(struct tevent_req *req, bool *access_allowed)
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose{
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct krb5_access_state *state = tevent_req_data(req,
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose struct krb5_access_state);
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose TEVENT_REQ_RETURN_ON_ERROR(req);
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose *access_allowed = state->access_allowed;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose return EOK;
1e29e68388c2e9c5da9cb0afe997bc1b4e6933beSumit Bose}