summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2012-03-08 15:10:31 -0500
committerStephen Gallagher <sgallagh@redhat.com>2012-03-09 14:25:09 -0500
commit1ab242911622d838590873d7e76347cb5f42512e (patch)
tree289bd8a70271a8bb2d4abb140b3aa9291386e1e2
parent5a05130ba12de25cceb51462c95f7a8082538328 (diff)
downloadsssd-1ab242911622d838590873d7e76347cb5f42512e.tar.gz
sssd-1ab242911622d838590873d7e76347cb5f42512e.tar.xz
sssd-1ab242911622d838590873d7e76347cb5f42512e.zip
IPA: Check nsAccountLock during PAM_ACCT_MGMT
https://fedorahosted.org/sssd/ticket/1227
-rw-r--r--Makefile.am1
-rw-r--r--src/providers/ipa/ipa_access.c56
-rw-r--r--src/providers/ipa/ipa_access.h1
-rw-r--r--src/providers/ipa/ipa_common.c2
-rw-r--r--src/providers/ipa/ipa_init.c11
-rw-r--r--src/providers/ldap/sdap_access.c20
-rw-r--r--src/providers/ldap/sdap_access.h9
7 files changed, 87 insertions, 13 deletions
diff --git a/Makefile.am b/Makefile.am
index 815816585..f44296580 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1146,6 +1146,7 @@ libsss_ipa_la_SOURCES = \
src/providers/ldap/ldap_id_services.c \
src/providers/ldap/ldap_auth.c \
src/providers/ldap/ldap_common.c \
+ src/providers/ldap/sdap_access.c \
src/providers/ldap/sdap_async.c \
src/providers/ldap/sdap_async_users.c \
src/providers/ldap/sdap_async_groups.c \
diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index 1eed86c33..475ddade2 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -27,6 +27,7 @@
#include "util/util.h"
#include "providers/ldap/sdap_async.h"
+#include "providers/ldap/sdap_access.h"
#include "providers/ipa/ipa_common.h"
#include "providers/ipa/ipa_access.h"
#include "providers/ipa/ipa_hbac.h"
@@ -63,6 +64,7 @@ enum check_result {
RULE_ERROR
};
+static void ipa_hbac_check(struct tevent_req *req);
static int hbac_retry(struct hbac_ctx *hbac_ctx);
static void hbac_connect_done(struct tevent_req *subreq);
static bool hbac_check_step_result(struct hbac_ctx *hbac_ctx, int ret);
@@ -74,14 +76,68 @@ static void ipa_hbac_evaluate_rules(struct hbac_ctx *hbac_ctx);
void ipa_access_handler(struct be_req *be_req)
{
struct pam_data *pd;
+ struct ipa_access_ctx *ipa_access_ctx;
+ struct tevent_req *req;
+
+ pd = talloc_get_type(be_req->req_data, struct pam_data);
+
+ ipa_access_ctx = talloc_get_type(
+ be_req->be_ctx->bet_info[BET_ACCESS].pvt_bet_data,
+ struct ipa_access_ctx);
+
+ /* 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_req->be_ctx->ev,
+ be_req->be_ctx,
+ ipa_access_ctx->sdap_access_ctx,
+ pd);
+ if (!req) {
+ be_req->fn(be_req, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL);
+ return;
+ }
+ tevent_req_set_callback(req, ipa_hbac_check, be_req);
+}
+
+static void ipa_hbac_check(struct tevent_req *req)
+{
+ struct be_req *be_req;
+ struct pam_data *pd;
struct hbac_ctx *hbac_ctx;
const char *deny_method;
int pam_status = PAM_SYSTEM_ERR;
struct ipa_access_ctx *ipa_access_ctx;
int ret;
+ be_req = tevent_req_callback_data(req, struct be_req);
pd = talloc_get_type(be_req->req_data, struct pam_data);
+ ret = sdap_access_recv(req, &pam_status);
+ if (ret != EOK) goto fail;
+
+ switch(pam_status) {
+ case PAM_SUCCESS:
+ /* Account wasn't locked. Continue below
+ * to HBAC processing.
+ */
+ break;
+ case PAM_PERM_DENIED:
+ /* Account was locked. Return permission denied
+ * here.
+ */
+ pd->pam_status = PAM_PERM_DENIED;
+ be_req->fn(be_req, DP_ERR_OK, PAM_PERM_DENIED, NULL);
+ return;
+ default:
+ /* We got an unexpected error. Return it as-is */
+ pd->pam_status = PAM_SYSTEM_ERR;
+ be_req->fn(be_req, DP_ERR_FATAL, pam_status, NULL);
+ return;
+ }
+
hbac_ctx = talloc_zero(be_req, struct hbac_ctx);
if (hbac_ctx == NULL) {
DEBUG(1, ("talloc failed.\n"));
diff --git a/src/providers/ipa/ipa_access.h b/src/providers/ipa/ipa_access.h
index ddfb2cf56..5234e9319 100644
--- a/src/providers/ipa/ipa_access.h
+++ b/src/providers/ipa/ipa_access.h
@@ -37,6 +37,7 @@ struct ipa_access_ctx {
struct dp_option *ipa_options;
struct time_rules_ctx *tr_ctx;
time_t last_update;
+ struct sdap_access_ctx *sdap_access_ctx;
struct sdap_search_base **host_search_bases;
struct sdap_search_base **hbac_search_bases;
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index e95eeab77..375b02016 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -100,7 +100,7 @@ struct dp_option ipa_def_ldap_opts[] = {
{ "ldap_netgroup_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_group_nesting_level", DP_OPT_NUMBER, { .number = 2 }, NULL_NUMBER },
{ "ldap_deref", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_account_expire_policy", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "ldap_account_expire_policy", DP_OPT_STRING, { "ipa" }, NULL_STRING },
{ "ldap_access_order", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_chpass_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_chpass_dns_service_name", DP_OPT_STRING, NULL_STRING, NULL_STRING },
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 20745c11f..f02a84bfe 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -36,6 +36,7 @@
#include "providers/ipa/ipa_hostid.h"
#include "providers/ipa/ipa_dyndns.h"
#include "providers/ipa/ipa_session.h"
+#include "providers/ldap/sdap_access.h"
struct ipa_options *ipa_options = NULL;
@@ -396,6 +397,16 @@ int sssm_ipa_access_init(struct be_ctx *bectx,
goto done;
}
+ /* Set up an sdap_access_ctx for checking expired/locked
+ * accounts.
+ */
+ ipa_access_ctx->sdap_access_ctx =
+ talloc_zero(ipa_access_ctx, struct sdap_access_ctx);
+
+ ipa_access_ctx->sdap_access_ctx->id_ctx = ipa_access_ctx->sdap_ctx;
+ ipa_access_ctx->sdap_access_ctx->access_rule[0] = LDAP_ACCESS_EXPIRE;
+ ipa_access_ctx->sdap_access_ctx->access_rule[1] = LDAP_ACCESS_EMPTY;
+
*ops = &ipa_access_ops;
*pvt_data = ipa_access_ctx;
diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c
index 1e923fd32..9df087894 100644
--- a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@ -55,12 +55,6 @@ static void sdap_access_reply(struct be_req *be_req, int pam_status)
}
}
-static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct be_ctx *be_ctx,
- struct sdap_access_ctx *access_ctx,
- struct pam_data *pd);
-
static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct be_ctx *be_ctx,
@@ -133,11 +127,12 @@ struct sdap_access_req_ctx {
};
static errno_t select_next_rule(struct tevent_req *req);
-static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct be_ctx *be_ctx,
- struct sdap_access_ctx *access_ctx,
- struct pam_data *pd)
+struct tevent_req *
+sdap_access_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
+ struct sdap_access_ctx *access_ctx,
+ struct pam_data *pd)
{
errno_t ret;
struct sdap_access_req_ctx *state;
@@ -1366,7 +1361,8 @@ static void sdap_access_host_done(struct tevent_req *subreq)
return;
}
-static errno_t sdap_access_recv(struct tevent_req *req, int *pam_status)
+errno_t
+sdap_access_recv(struct tevent_req *req, int *pam_status)
{
struct sdap_access_req_ctx *state =
tevent_req_data(req, struct sdap_access_req_ctx);
diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h
index 013645b9b..0cbee41f9 100644
--- a/src/providers/ldap/sdap_access.h
+++ b/src/providers/ldap/sdap_access.h
@@ -56,4 +56,13 @@ struct sdap_access_ctx {
int access_rule[LDAP_ACCESS_LAST + 1];
};
+struct tevent_req *
+sdap_access_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
+ struct sdap_access_ctx *access_ctx,
+ struct pam_data *pd);
+errno_t
+sdap_access_recv(struct tevent_req *req, int *pam_status);
+
#endif /* SDAP_ACCESS_H_ */