summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-10-28 12:38:28 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-11-04 15:04:20 -0400
commit1e29e68388c2e9c5da9cb0afe997bc1b4e6933be (patch)
treef4bca6f200570e78f59870f9f2b9adc772161df0
parent0b0a1e478e2ac7f30429c0c1d00b92b8f990d687 (diff)
downloadsssd-1e29e68388c2e9c5da9cb0afe997bc1b4e6933be.tar.gz
sssd-1e29e68388c2e9c5da9cb0afe997bc1b4e6933be.tar.xz
sssd-1e29e68388c2e9c5da9cb0afe997bc1b4e6933be.zip
Add infrastructure for Kerberos access provider
-rw-r--r--Makefile.am4
-rw-r--r--src/providers/krb5/krb5_access.c91
-rw-r--r--src/providers/krb5/krb5_auth.c104
-rw-r--r--src/providers/krb5/krb5_auth.h8
-rw-r--r--src/providers/krb5/krb5_init.c7
5 files changed, 187 insertions, 27 deletions
diff --git a/Makefile.am b/Makefile.am
index 3da400722..c0dfb3711 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -823,6 +823,7 @@ libsss_krb5_la_SOURCES = \
src/providers/krb5/krb5_become_user.c \
src/providers/krb5/krb5_delayed_online_authentication.c \
src/providers/krb5/krb5_auth.c \
+ src/providers/krb5/krb5_access.c \
src/providers/krb5/krb5_common.c \
src/providers/krb5/krb5_init.c \
src/util/sss_krb5.c
@@ -868,7 +869,8 @@ libsss_ipa_la_SOURCES = \
src/providers/krb5/krb5_become_user.c \
src/providers/krb5/krb5_delayed_online_authentication.c \
src/providers/krb5/krb5_common.c \
- src/providers/krb5/krb5_auth.c
+ src/providers/krb5/krb5_auth.c \
+ src/providers/krb5/krb5_access.c
libsss_ipa_la_CFLAGS = \
$(AM_CFLAGS) \
$(LDAP_CFLAGS) \
diff --git a/src/providers/krb5/krb5_access.c b/src/providers/krb5/krb5_access.c
new file mode 100644
index 000000000..215493366
--- /dev/null
+++ b/src/providers/krb5/krb5_access.c
@@ -0,0 +1,91 @@
+/*
+ SSSD
+
+ Kerberos 5 Backend Module - access control
+
+ Authors:
+ Sumit Bose <sbose@redhat.com>
+
+ Copyright (C) 2010 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "util/util.h"
+#include "providers/krb5/krb5_auth.h"
+
+struct krb5_access_state {
+ struct tevent_context *ev;
+ struct be_ctx *be_ctx;
+
+ struct pam_data *pd;
+ struct krb5_ctx *krb5_ctx;
+ const char *upn;
+
+ bool access_allowed;
+};
+
+struct tevent_req *krb5_access_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
+ struct pam_data *pd,
+ struct krb5_ctx *krb5_ctx)
+{
+ struct krb5_access_state *state;
+ struct tevent_req *req;
+ int ret;
+
+ req = tevent_req_create(mem_ctx, &state, struct krb5_access_state);
+ if (req == NULL) {
+ DEBUG(1, ("tevent_req_create failed.\n"));
+ return NULL;
+ }
+
+ state->ev = ev;
+ state->be_ctx = be_ctx;
+ state->pd = pd;
+ state->krb5_ctx = krb5_ctx;
+ state->upn = NULL;
+ state->access_allowed = false;
+
+ if (pd->cmd != SSS_PAM_ACCT_MGMT) {
+ DEBUG(1, ("Unexpected pam task.\n"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ state->access_allowed = true;
+ ret = EOK;
+
+done:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+ tevent_req_post(req, state->ev);
+ return req;
+}
+
+int krb5_access_recv(struct tevent_req *req, bool *access_allowed)
+{
+ struct krb5_access_state *state = tevent_req_data(req,
+ struct krb5_access_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *access_allowed = state->access_allowed;
+
+ return EOK;
+}
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index 4299ca892..626df2ffd 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);
+}
diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h
index 9dbf7c6db..4178082a7 100644
--- a/src/providers/krb5/krb5_auth.h
+++ b/src/providers/krb5/krb5_auth.h
@@ -74,4 +74,12 @@ errno_t add_user_to_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
errno_t init_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
struct be_ctx *be_ctx,
struct tevent_context *ev);
+
+/* krb5_access.c */
+struct tevent_req *krb5_access_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
+ struct pam_data *pd,
+ struct krb5_ctx *krb5_ctx);
+int krb5_access_recv(struct tevent_req *req, bool *access_allowed);
#endif /* __KRB5_AUTH_H__ */
diff --git a/src/providers/krb5/krb5_init.c b/src/providers/krb5/krb5_init.c
index 0c8d2250d..f2b5dd790 100644
--- a/src/providers/krb5/krb5_init.c
+++ b/src/providers/krb5/krb5_init.c
@@ -189,3 +189,10 @@ int sssm_krb5_chpass_init(struct be_ctx *bectx,
{
return sssm_krb5_auth_init(bectx, ops, pvt_auth_data);
}
+
+int sssm_krb5_access_init(struct be_ctx *bectx,
+ struct bet_ops **ops,
+ void **pvt_auth_data)
+{
+ return sssm_krb5_auth_init(bectx, ops, pvt_auth_data);
+}