summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2012-03-08 15:19:07 -0500
committerStephen Gallagher <sgallagh@redhat.com>2012-06-22 15:37:42 -0400
commit61bc05a867eaa3950137ae1c076cdef3a392c377 (patch)
treea027081362eae8b80f273ca23a28d72a32efb29b
parent58f437644772f76c50c24efeaf707ded941f5bd9 (diff)
downloadsssd-61bc05a867eaa3950137ae1c076cdef3a392c377.tar.gz
sssd-61bc05a867eaa3950137ae1c076cdef3a392c377.tar.xz
sssd-61bc05a867eaa3950137ae1c076cdef3a392c377.zip
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
5 files changed, 70 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 9f63bb6e8..156de2503 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -896,6 +896,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 7f5806870..7f71d6b40 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;