summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2012-03-08 15:19:07 -0500
committerStephen Gallagher <sgallagh@redhat.com>2012-03-09 08:24:57 -0500
commit2424e15710a3738ce0676445e5b5872d50a27735 (patch)
tree6bac2fe98cc6aeedcfb792ad0a421c71fd553d0a
parent559ce4cdec1a4fe44cf7eb63d5df71638316a87a (diff)
downloadsssd-2424e15710a3738ce0676445e5b5872d50a27735.tar.gz
sssd-2424e15710a3738ce0676445e5b5872d50a27735.tar.xz
sssd-2424e15710a3738ce0676445e5b5872d50a27735.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
5 files changed, 70 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index ce00ef2ff..64f5c42e8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1147,6 +1147,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;