summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2012-06-22 08:06:50 -0400
committerStephen Gallagher <sgallagh@redhat.com>2012-06-22 09:15:20 -0400
commitc08c6c7a131fcb0546c70e187c44fc2e6449e8ce (patch)
treea5d0fd89ee50d9d155b91776e45e62859176826e
parentd162c73fd03eeb4b2a8ea358efe4e116f00f3c90 (diff)
downloadsssd-c08c6c7a131fcb0546c70e187c44fc2e6449e8ce.tar.gz
sssd-c08c6c7a131fcb0546c70e187c44fc2e6449e8ce.tar.xz
sssd-c08c6c7a131fcb0546c70e187c44fc2e6449e8ce.zip
IPA: Check nsAccountLock during PAM_ACCT_MGMT
LDAP: Make sdap_access_send/recv public We want to consume this in the IPA provider. IPA: Check nsAccountLock during PAM_ACCT_MGMT https://fedorahosted.org/sssd/ticket/1227 Conflicts: src/providers/ipa/ipa_access.h src/providers/ipa/ipa_init.c
-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 17d3dd6af..7623ed166 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -887,6 +887,7 @@ libsss_ipa_la_SOURCES = \
src/providers/ldap/ldap_id_netgroup.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_accounts.c \
src/providers/ldap/sdap_async_connection.c \
diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index 083d8e7a6..7232c5355 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"
@@ -85,6 +86,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);
@@ -96,14 +98,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 2a6bdad50..c85757fd5 100644
--- a/src/providers/ipa/ipa_access.h
+++ b/src/providers/ipa/ipa_access.h
@@ -44,6 +44,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 hbac_ctx {
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index e7813f655..b59c2b1c5 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -85,7 +85,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 8f7d4d61f..fe9ff8325 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -33,6 +33,7 @@
#include "providers/ipa/ipa_auth.h"
#include "providers/ipa/ipa_access.h"
#include "providers/ipa/ipa_dyndns.h"
+#include "providers/ldap/sdap_access.h"
struct ipa_options *ipa_options = NULL;
@@ -364,6 +365,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 5a6b4a5d3..8757510c3 100644
--- a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@ -52,12 +52,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,
@@ -123,11 +117,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;
@@ -1057,7 +1052,8 @@ static void sdap_access_service_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 32c45b817..d6b80ea2d 100644
--- a/src/providers/ldap/sdap_access.h
+++ b/src/providers/ldap/sdap_access.h
@@ -55,4 +55,13 @@ struct sdap_access_ctx {
void ldap_pam_access_handler(struct be_req *breq);
+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_ */