summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-03-03 18:06:13 -0500
committerJakub Hrozek <jhrozek@redhat.com>2013-03-19 22:49:51 +0100
commitdfd71fc92db940b2892cc996911cec03d7b6c52b (patch)
tree069370fe1a4a61d899f0bc2cb8825bdef9c659d3
parentc0bca1722d6f9dfb654ad78397be70f79ff39af1 (diff)
downloadsssd-dfd71fc92db940b2892cc996911cec03d7b6c52b.tar.gz
sssd-dfd71fc92db940b2892cc996911cec03d7b6c52b.tar.bz2
sssd-dfd71fc92db940b2892cc996911cec03d7b6c52b.zip
Convert sdap_access to new error codes
Also simplify sdap_access_send to avoid completely fake _send() routines.
-rw-r--r--src/providers/ad/ad_access.c32
-rw-r--r--src/providers/ipa/ipa_access.c21
-rw-r--r--src/providers/ldap/ldap_access.c14
-rw-r--r--src/providers/ldap/sdap_access.c622
-rw-r--r--src/providers/ldap/sdap_access.h3
-rw-r--r--src/util/util_errors.c1
-rw-r--r--src/util/util_errors.h1
7 files changed, 214 insertions, 480 deletions
diff --git a/src/providers/ad/ad_access.c b/src/providers/ad/ad_access.c
index 0fa7d6d3..ef1775d7 100644
--- a/src/providers/ad/ad_access.c
+++ b/src/providers/ad/ad_access.c
@@ -69,30 +69,28 @@ static void
ad_access_done(struct tevent_req *req)
{
errno_t ret;
- int pam_status;
struct be_req *breq =
tevent_req_callback_data(req, struct be_req);
struct pam_data *pd =
talloc_get_type(be_req_get_data(breq), struct pam_data);
- ret = sdap_access_recv(req, &pam_status);
+ ret = sdap_access_recv(req);
talloc_zfree(req);
- if (ret != EOK) {
- be_req_terminate(breq, DP_ERR_FATAL, PAM_SYSTEM_ERR, strerror(ret));
+ switch (ret) {
+ case EOK:
+ pd->pam_status = PAM_SUCCESS;
+ be_req_terminate(breq, DP_ERR_OK, PAM_SUCCESS, NULL);
return;
- }
-
- pd->pam_status = pam_status;
-
- if (pam_status == PAM_SUCCESS || pam_status == PAM_PERM_DENIED) {
- /* We got the proper approval or denial */
- be_req_terminate(breq, DP_ERR_OK, pam_status, NULL);
+ case ERR_ACCESS_DENIED:
+ /* We got the proper denial */
+ pd->pam_status = PAM_PERM_DENIED;
+ be_req_terminate(breq, DP_ERR_OK, PAM_PERM_DENIED, NULL);
+ return;
+ default:
+ /* Something went wrong */
+ pd->pam_status = PAM_SYSTEM_ERR;
+ be_req_terminate(breq, DP_ERR_FATAL,
+ PAM_SYSTEM_ERR, sss_strerror(ret));
return;
}
-
- /* Something went wrong */
- pd->pam_status = PAM_SYSTEM_ERR;
- be_req_terminate(breq, DP_ERR_FATAL, pam_status,
- pam_strerror(NULL, pam_status));
- return;
}
diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index 430b2f7a..c43974e3 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -106,7 +106,6 @@ static void ipa_hbac_check(struct tevent_req *req)
struct pam_data *pd;
struct hbac_ctx *hbac_ctx = NULL;
const char *deny_method;
- int pam_status = PAM_SYSTEM_ERR;
struct ipa_access_ctx *ipa_access_ctx;
int ret;
@@ -114,33 +113,34 @@ static void ipa_hbac_check(struct tevent_req *req)
be_ctx = be_req_get_be_ctx(be_req);
pd = talloc_get_type(be_req_get_data(be_req), struct pam_data);
- ret = sdap_access_recv(req, &pam_status);
+ ret = sdap_access_recv(req);
talloc_zfree(req);
- if (ret != EOK) goto fail;
- switch(pam_status) {
- case PAM_SUCCESS:
+ switch(ret) {
+ case EOK:
/* Account wasn't locked. Continue below
* to HBAC processing.
*/
break;
- case PAM_PERM_DENIED:
+ case ERR_ACCESS_DENIED:
/* Account was locked. Return permission denied
* here.
*/
pd->pam_status = PAM_PERM_DENIED;
- be_req_terminate(be_req, DP_ERR_OK, PAM_PERM_DENIED, NULL);
+ be_req_terminate(be_req, DP_ERR_OK, pd->pam_status, NULL);
return;
default:
/* We got an unexpected error. Return it as-is */
pd->pam_status = PAM_SYSTEM_ERR;
- be_req_terminate(be_req, DP_ERR_FATAL, pam_status, NULL);
+ be_req_terminate(be_req, DP_ERR_FATAL, pd->pam_status,
+ sss_strerror(ret));
return;
}
hbac_ctx = talloc_zero(be_req, struct hbac_ctx);
if (hbac_ctx == NULL) {
DEBUG(1, ("talloc failed.\n"));
+ ret = ENOMEM;
goto fail;
}
@@ -155,6 +155,7 @@ static void ipa_hbac_check(struct tevent_req *req)
hbac_ctx->search_bases = ipa_access_ctx->hbac_search_bases;
if (hbac_ctx->search_bases == NULL) {
DEBUG(1, ("No HBAC search base found.\n"));
+ ret = EINVAL;
goto fail;
}
@@ -176,9 +177,9 @@ static void ipa_hbac_check(struct tevent_req *req)
fail:
if (hbac_ctx) {
/* Return an proper error */
- ipa_access_reply(hbac_ctx, pam_status);
+ ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);
} else {
- be_req_terminate(be_req, DP_ERR_FATAL, pam_status, NULL);
+ be_req_terminate(be_req, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL);
}
}
diff --git a/src/providers/ldap/ldap_access.c b/src/providers/ldap/ldap_access.c
index 5a8e12f0..4a06e66b 100644
--- a/src/providers/ldap/ldap_access.c
+++ b/src/providers/ldap/ldap_access.c
@@ -69,15 +69,23 @@ void sdap_pam_access_handler(struct be_req *breq)
static void sdap_access_done(struct tevent_req *req)
{
errno_t ret;
- int pam_status = PAM_SYSTEM_ERR;
+ int pam_status;
struct be_req *breq =
tevent_req_callback_data(req, struct be_req);
- ret = sdap_access_recv(req, &pam_status);
+ ret = sdap_access_recv(req);
talloc_zfree(req);
- if (ret != EOK) {
+ switch (ret) {
+ case EOK:
+ pam_status = PAM_SUCCESS;
+ break;
+ case ERR_ACCESS_DENIED:
+ pam_status = PAM_PERM_DENIED;
+ break;
+ default:
DEBUG(SSSDBG_CRIT_FAILURE, ("Error retrieving access check result.\n"));
pam_status = PAM_SYSTEM_ERR;
+ break;
}
sdap_access_reply(breq, pam_status);
diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c
index a7eadfde..1b2f6993 100644
--- a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@ -47,33 +47,16 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
struct sdap_access_ctx *access_ctx,
const char *username,
struct ldb_message *user_entry);
-static void sdap_access_filter_done(struct tevent_req *subreq);
-
-static struct tevent_req *sdap_account_expired_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sdap_access_ctx *access_ctx,
- struct pam_data *pd,
- struct ldb_message *user_entry);
-static errno_t sdap_access_service_recv(struct tevent_req *req,
- int *pam_status);
-static void sdap_access_service_done(struct tevent_req *subreq);
+static errno_t sdap_access_filter_recv(struct tevent_req *req);
-static struct tevent_req *sdap_access_service_send(
- TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct pam_data *pd,
- struct ldb_message *user_entry);
+static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx,
+ struct pam_data *pd,
+ struct ldb_message *user_entry);
-static void sdap_account_expired_done(struct tevent_req *subreq);
+static errno_t sdap_access_service(struct pam_data *pd,
+ struct ldb_message *user_entry);
-static errno_t sdap_access_host_recv(struct tevent_req *req,
- int *pam_status);
-static void sdap_access_host_done(struct tevent_req *subreq);
-
-static struct tevent_req *sdap_access_host_send(
- TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct ldb_message *user_entry);
+static errno_t sdap_access_host(struct ldb_message *user_entry);
struct sdap_access_req_ctx {
struct pam_data *pd;
@@ -81,12 +64,14 @@ struct sdap_access_req_ctx {
struct sdap_access_ctx *access_ctx;
struct be_ctx *be_ctx;
struct sss_domain_info *domain;
- int pam_status;
struct ldb_message *user_entry;
size_t current_rule;
};
-static errno_t select_next_rule(struct tevent_req *req);
+static errno_t check_next_rule(struct sdap_access_req_ctx *state,
+ struct tevent_req *req);
+static void sdap_access_filter_done(struct tevent_req *subreq);
+
struct tevent_req *
sdap_access_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -111,7 +96,6 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
state->be_ctx = be_ctx;
state->domain = domain;
state->pd = pd;
- state->pam_status = PAM_SYSTEM_ERR;
state->ev = ev;
state->access_ctx = access_ctx;
state->current_rule = 0;
@@ -120,8 +104,7 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
if (access_ctx->access_rule[0] == LDAP_ACCESS_EMPTY) {
DEBUG(3, ("No access rules defined, access denied.\n"));
- state->pam_status = PAM_PERM_DENIED;
- ret = EOK;
+ ret = ERR_ACCESS_DENIED;
goto done;
}
@@ -142,18 +125,16 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
}
if (ret != EOK) {
if (ret == ENOENT) {
- /* If we can't find the user, return permission denied */
- state->pam_status = PAM_PERM_DENIED;
- ret = EOK;
+ /* If we can't find the user, return access denied */
+ ret = ERR_ACCESS_DENIED;
goto done;
}
goto done;
}
else {
if (res->count == 0) {
- /* If we can't find the user, return permission denied */
- state->pam_status = PAM_PERM_DENIED;
- ret = EOK;
+ /* If we can't find the user, return access denied */
+ ret = ERR_ACCESS_DENIED;
goto done;
}
@@ -166,19 +147,11 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
state->user_entry = res->msgs[0];
- ret = select_next_rule(req);
- if (ret != EOK) {
- if (ret == EACCES) {
- state->pam_status = PAM_PERM_DENIED;
- ret = EOK;
- goto done;
- }
- DEBUG(1, ("select_next_rule failed.\n"));
- goto done;
+ ret = check_next_rule(state, req);
+ if (ret == EAGAIN) {
+ return req;
}
- return req;
-
done:
if (ret == EOK) {
tevent_req_done(req);
@@ -189,16 +162,17 @@ done:
return req;
}
-static errno_t select_next_rule(struct tevent_req *req)
+static errno_t check_next_rule(struct sdap_access_req_ctx *state,
+ struct tevent_req *req)
{
- struct sdap_access_req_ctx *state =
- tevent_req_data(req, struct sdap_access_req_ctx);
struct tevent_req *subreq;
+ int ret = EOK;
- switch (state->access_ctx->access_rule[state->current_rule]) {
+ while (ret == EOK) {
+ switch (state->access_ctx->access_rule[state->current_rule]) {
case LDAP_ACCESS_EMPTY:
- return ENOENT;
- break;
+ /* we are done with no errors */
+ return EOK;
case LDAP_ACCESS_FILTER:
subreq = sdap_access_filter_send(state, state->ev, state->be_ctx,
@@ -212,85 +186,74 @@ static errno_t select_next_rule(struct tevent_req *req)
}
tevent_req_set_callback(subreq, sdap_access_filter_done, req);
- return EOK;
+ return EAGAIN;
case LDAP_ACCESS_EXPIRE:
- subreq = sdap_account_expired_send(state, state->ev,
- state->access_ctx,
- state->pd,
- state->user_entry);
- if (subreq == NULL) {
- DEBUG(1, ("sdap_account_expired_send failed.\n"));
- return ENOMEM;
- }
-
- tevent_req_set_callback(subreq, sdap_account_expired_done, req);
- return EOK;
+ ret = sdap_account_expired(state->access_ctx,
+ state->pd, state->user_entry);
+ break;
case LDAP_ACCESS_SERVICE:
- subreq = sdap_access_service_send(state, state->ev,
- state->pd,
- state->user_entry);
- if (subreq == NULL) {
- DEBUG(1, ("sdap_access_service_send failed.\n"));
- return ENOMEM;
- }
- tevent_req_set_callback(subreq, sdap_access_service_done, req);
- return EOK;
+ ret = sdap_access_service( state->pd, state->user_entry);
+ break;
case LDAP_ACCESS_HOST:
- subreq = sdap_access_host_send(state, state->ev,
- state->user_entry);
- if (subreq == NULL) {
- DEBUG(1, ("sdap_access_host_send failed.\n"));
- return ENOMEM;
- }
- tevent_req_set_callback(subreq, sdap_access_host_done, req);
- return EOK;
+ ret = sdap_access_host(state->user_entry);
+ break;
default:
DEBUG(1, ("Unexpected access rule type. Access denied.\n"));
+ ret = ERR_ACCESS_DENIED;
+ }
+
+ state->current_rule++;
}
- return EACCES;
+ return ret;
}
-static void next_access_rule(struct tevent_req *req)
+static void sdap_access_filter_done(struct tevent_req *subreq)
{
+ errno_t ret;
+ struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
struct sdap_access_req_ctx *state =
tevent_req_data(req, struct sdap_access_req_ctx);
- int ret;
- if (state->pam_status == PAM_PERM_DENIED ||
- state->pam_status == PAM_ACCT_EXPIRED) {
- tevent_req_done(req);
+ ret = sdap_access_filter_recv(subreq);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(1, ("Error retrieving access check result.\n"));
+ tevent_req_error(req, ret);
return;
}
state->current_rule++;
- ret = select_next_rule(req);
- if (ret != EOK) {
- if (ret == ENOENT) {
- state->pam_status = PAM_SUCCESS;
- tevent_req_done(req);
- return;
- } else if (ret == EACCES) {
- state->pam_status = PAM_PERM_DENIED;
- tevent_req_done(req);
- } else {
- tevent_req_error(req, ret);
- }
+ ret = check_next_rule(state, req);
+ switch (ret) {
+ case EAGAIN:
+ return;
+ case EOK:
+ tevent_req_done(req);
+ return;
+ default:
+ tevent_req_error(req, ret);
+ return;
}
+}
+
+errno_t sdap_access_recv(struct tevent_req *req)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
- return;
+ return EOK;
}
+
#define SHADOW_EXPIRE_MSG "Account expired according to shadow attributes"
static errno_t sdap_account_expired_shadow(struct pam_data *pd,
- struct ldb_message *user_entry,
- int *pam_status)
+ struct ldb_message *user_entry)
{
int ret;
const char *val;
@@ -303,7 +266,6 @@ static errno_t sdap_account_expired_shadow(struct pam_data *pd,
if (val == NULL) {
DEBUG(3, ("Shadow expire attribute not found. "
"Access will be granted.\n"));
- *pam_status = PAM_SUCCESS;
return EOK;
}
ret = string_to_shadowpw_days(val, &sp_expire);
@@ -314,7 +276,6 @@ static errno_t sdap_account_expired_shadow(struct pam_data *pd,
today = (long) (time(NULL) / (60 * 60 * 24));
if (sp_expire > 0 && today > sp_expire) {
- *pam_status = PAM_ACCT_EXPIRED;
ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
sizeof(SHADOW_EXPIRE_MSG),
@@ -322,8 +283,8 @@ static errno_t sdap_account_expired_shadow(struct pam_data *pd,
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
- } else {
- *pam_status = PAM_SUCCESS;
+
+ return ERR_ACCOUNT_EXPIRED;
}
return EOK;
@@ -363,8 +324,7 @@ static bool ad_account_expired(uint64_t expiration_time)
}
static errno_t sdap_account_expired_ad(struct pam_data *pd,
- struct ldb_message *user_entry,
- int *pam_status)
+ struct ldb_message *user_entry)
{
uint32_t uac;
uint64_t expiration_time;
@@ -383,7 +343,6 @@ static errno_t sdap_account_expired_ad(struct pam_data *pd,
pd->user, expiration_time));
if (uac & UAC_ACCOUNTDISABLE) {
- *pam_status = PAM_PERM_DENIED;
ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
sizeof(AD_DISABLE_MESSAGE),
@@ -391,8 +350,10 @@ static errno_t sdap_account_expired_ad(struct pam_data *pd,
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
+
+ return ERR_ACCESS_DENIED;
+
} else if (ad_account_expired(expiration_time)) {
- *pam_status = PAM_ACCT_EXPIRED;
ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
sizeof(AD_EXPIRED_MESSAGE),
@@ -400,8 +361,8 @@ static errno_t sdap_account_expired_ad(struct pam_data *pd,
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
- } else {
- *pam_status = PAM_SUCCESS;
+
+ return ERR_ACCOUNT_EXPIRED;
}
return EOK;
@@ -410,8 +371,7 @@ static errno_t sdap_account_expired_ad(struct pam_data *pd,
#define RHDS_LOCK_MSG "The user account is locked on the server"
static errno_t sdap_account_expired_rhds(struct pam_data *pd,
- struct ldb_message *user_entry,
- int *pam_status)
+ struct ldb_message *user_entry)
{
bool locked;
int ret;
@@ -429,9 +389,9 @@ static errno_t sdap_account_expired_rhds(struct pam_data *pd,
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
- }
- *pam_status = locked ? PAM_PERM_DENIED : PAM_SUCCESS;
+ return ERR_ACCESS_DENIED;
+ }
return EOK;
}
@@ -543,8 +503,7 @@ static bool nds_check_time_map(const struct ldb_val *time_map)
}
static errno_t sdap_account_expired_nds(struct pam_data *pd,
- struct ldb_message *user_entry,
- int *pam_status)
+ struct ldb_message *user_entry)
{
bool locked = true;
int ret;
@@ -565,6 +524,9 @@ static errno_t sdap_account_expired_nds(struct pam_data *pd,
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
+
+ return ERR_ACCESS_DENIED;
+
} else {
exp_time_str = ldb_msg_find_attr_as_string(user_entry,
SYSDB_NDS_LOGIN_EXPIRATION_TIME,
@@ -581,6 +543,9 @@ static errno_t sdap_account_expired_nds(struct pam_data *pd,
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
+
+ return ERR_ACCESS_DENIED;
+
} else {
time_map = ldb_msg_find_ldb_val(user_entry,
SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP);
@@ -597,132 +562,61 @@ static errno_t sdap_account_expired_nds(struct pam_data *pd,
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
+
+ return ERR_ACCESS_DENIED;
}
}
}
- *pam_status = locked ? PAM_PERM_DENIED : PAM_SUCCESS;
-
return EOK;
}
-struct sdap_account_expired_req_ctx {
- int pam_status;
-};
-static struct tevent_req *sdap_account_expired_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sdap_access_ctx *access_ctx,
- struct pam_data *pd,
- struct ldb_message *user_entry)
+static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx,
+ struct pam_data *pd,
+ struct ldb_message *user_entry)
{
- struct tevent_req *req;
- struct sdap_account_expired_req_ctx *state;
- int ret;
const char *expire;
-
- req = tevent_req_create(mem_ctx, &state, struct sdap_account_expired_req_ctx);
- if (req == NULL) {
- DEBUG(1, ("tevent_req_create failed.\n"));
- return NULL;
- }
-
- state->pam_status = PAM_SYSTEM_ERR;
+ int ret;
expire = dp_opt_get_cstring(access_ctx->id_ctx->opts->basic,
SDAP_ACCOUNT_EXPIRE_POLICY);
if (expire == NULL) {
DEBUG(1, ("Missing account expire policy. Access denied\n"));
- state->pam_status = PAM_PERM_DENIED;
- ret = EOK;
- goto done;
+ return ERR_ACCESS_DENIED;
} else {
if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_SHADOW) == 0) {
- ret = sdap_account_expired_shadow(pd, user_entry,
- &state->pam_status);
+ ret = sdap_account_expired_shadow(pd, user_entry);
if (ret != EOK) {
DEBUG(1, ("sdap_account_expired_shadow failed.\n"));
- goto done;
}
} else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_AD) == 0) {
- ret = sdap_account_expired_ad(pd, user_entry,
- &state->pam_status);
+ ret = sdap_account_expired_ad(pd, user_entry);
if (ret != EOK) {
DEBUG(1, ("sdap_account_expired_ad failed.\n"));
- goto done;
}
} else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_RHDS) == 0 ||
strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_IPA) == 0 ||
strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_389DS) == 0) {
- ret = sdap_account_expired_rhds(pd, user_entry,
- &state->pam_status);
+ ret = sdap_account_expired_rhds(pd, user_entry);
if (ret != EOK) {
DEBUG(1, ("sdap_account_expired_rhds failed.\n"));
- goto done;
}
} else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_NDS) == 0) {
- ret = sdap_account_expired_nds(pd, user_entry, &state->pam_status);
+ ret = sdap_account_expired_nds(pd, user_entry);
if (ret != EOK) {
DEBUG(1, ("sdap_account_expired_nds failed.\n"));
- goto done;
}
} else {
DEBUG(1, ("Unsupported LDAP account expire policy [%s]. "
"Access denied.\n", expire));
- state->pam_status = PAM_PERM_DENIED;
- ret = EOK;
- goto done;
+ ret = ERR_ACCESS_DENIED;
}
}
- ret = EOK;
-
-done:
- if (ret == EOK) {
- tevent_req_done(req);
- } else {
- tevent_req_error(req, ret);
- }
- tevent_req_post(req, ev);
-
- return req;
+ return ret;
}
-static errno_t sdap_account_expired_recv(struct tevent_req *req, int *pam_status)
-{
- struct sdap_account_expired_req_ctx *state =
- tevent_req_data(req, struct sdap_account_expired_req_ctx);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *pam_status = state->pam_status;
-
- return EOK;
-}
-
-static void sdap_account_expired_done(struct tevent_req *subreq)
-{
- errno_t ret;
- struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
- struct sdap_access_req_ctx *state =
- tevent_req_data(req, struct sdap_access_req_ctx);
-
- ret = sdap_account_expired_recv(subreq, &state->pam_status);
- talloc_zfree(subreq);
- if (ret != EOK) {
- DEBUG(1, ("Error retrieving access check result.\n"));
- state->pam_status = PAM_SYSTEM_ERR;
- tevent_req_error(req, ret);
- return;
- }
-
- next_access_rule(req);
-
- return;
-}
-
-
-
struct sdap_access_filter_req_ctx {
const char *username;
const char *filter;
@@ -732,12 +626,11 @@ struct sdap_access_filter_req_ctx {
struct sdap_id_op *sdap_op;
struct sysdb_handle *handle;
struct sss_domain_info *domain;
- int pam_status;
bool cached_access;
char *basedn;
};
-static void sdap_access_filter_decide_offline(struct tevent_req *req);
+static errno_t sdap_access_filter_decide_offline(struct tevent_req *req);
static int sdap_access_filter_retry(struct tevent_req *req);
static void sdap_access_filter_connect_done(struct tevent_req *subreq);
static void sdap_access_filter_get_access_done(struct tevent_req *req);
@@ -749,11 +642,11 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
const char *username,
struct ldb_message *user_entry)
{
- errno_t ret;
struct sdap_access_filter_req_ctx *state;
struct tevent_req *req;
const char *basedn;
char *clean_username;
+ errno_t ret = ERR_INTERNAL;
req = tevent_req_create(mem_ctx, &state, struct sdap_access_filter_req_ctx);
if (req == NULL) {
@@ -763,15 +656,12 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
if (access_ctx->filter == NULL || *access_ctx->filter == '\0') {
/* If no filter is set, default to restrictive */
DEBUG(6, ("No filter set. Access is denied.\n"));
- state->pam_status = PAM_PERM_DENIED;
- tevent_req_done(req);
- tevent_req_post(req, ev);
- return req;
+ ret = ERR_ACCESS_DENIED;
+ goto done;
}
state->filter = NULL;
state->username = username;
- state->pam_status = PAM_SYSTEM_ERR;
state->sdap_ctx = access_ctx->id_ctx;
state->ev = ev;
state->access_ctx = access_ctx;
@@ -785,31 +675,31 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
/* Ok, we have one result, check if we are online or offline */
if (be_is_offline(be_ctx)) {
/* Ok, we're offline. Return from the cache */
- sdap_access_filter_decide_offline(req);
- goto finished;
+ ret = sdap_access_filter_decide_offline(req);
+ goto done;
}
/* Perform online operation */
- basedn = ldb_msg_find_attr_as_string(user_entry,
- SYSDB_ORIG_DN,
- NULL);
- if(basedn == NULL) {
+ basedn = ldb_msg_find_attr_as_string(user_entry, SYSDB_ORIG_DN, NULL);
+ if (basedn == NULL) {
DEBUG(1,("Could not find originalDN for user [%s]\n",
state->username));
- goto failed;
+ ret = EINVAL;
+ goto done;
}
state->basedn = talloc_strdup(state, basedn);
if (state->basedn == NULL) {
DEBUG(1, ("Could not allocate memory for originalDN\n"));
- goto failed;
+ ret = ENOMEM;
+ goto done;
}
/* Construct the filter */
ret = sss_filter_sanitize(state, state->username, &clean_username);
if (ret != EOK) {
- goto failed;
+ goto done;
}
state->filter = talloc_asprintf(
@@ -821,7 +711,8 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
state->access_ctx->filter);
if (state->filter == NULL) {
DEBUG(0, ("Could not construct access filter\n"));
- goto failed;
+ ret = ENOMEM;
+ goto done;
}
talloc_zfree(clean_username);
@@ -830,37 +721,38 @@ static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
state->sdap_op = sdap_id_op_create(state, state->sdap_ctx->conn_cache);
if (!state->sdap_op) {
DEBUG(2, ("sdap_id_op_create failed\n"));
- goto failed;
+ ret = ENOMEM;
+ goto done;
}
ret = sdap_access_filter_retry(req);
if (ret != EOK) {
- goto failed;
+ goto done;
}
return req;
-failed:
- talloc_free(req);
- return NULL;
-
-finished:
- tevent_req_done(req);
+done:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
tevent_req_post(req, ev);
return req;
}
-static void sdap_access_filter_decide_offline(struct tevent_req *req)
+static errno_t sdap_access_filter_decide_offline(struct tevent_req *req)
{
struct sdap_access_filter_req_ctx *state =
tevent_req_data(req, struct sdap_access_filter_req_ctx);
if (state->cached_access) {
DEBUG(6, ("Access granted by cached credentials\n"));
- state->pam_status = PAM_SUCCESS;
+ return EOK;
} else {
DEBUG(6, ("Access denied by cached credentials\n"));
- state->pam_status = PAM_PERM_DENIED;
+ return ERR_ACCESS_DENIED;
}
}
@@ -894,9 +786,11 @@ static void sdap_access_filter_connect_done(struct tevent_req *subreq)
if (ret != EOK) {
if (dp_error == DP_ERR_OFFLINE) {
- sdap_access_filter_decide_offline(req);
- tevent_req_done(req);
- return;
+ ret = sdap_access_filter_decide_offline(req);
+ if (ret == EOK) {
+ tevent_req_done(req);
+ return;
+ }
}
tevent_req_error(req, ret);
@@ -919,7 +813,6 @@ static void sdap_access_filter_connect_done(struct tevent_req *subreq)
false);
if (subreq == NULL) {
DEBUG(1, ("Could not start LDAP communication\n"));
- state->pam_status = PAM_SYSTEM_ERR;
tevent_req_error(req, EIO);
return;
}
@@ -929,7 +822,7 @@ static void sdap_access_filter_connect_done(struct tevent_req *subreq)
static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
{
- int ret, dp_error;
+ int ret, tret, dp_error;
size_t num_results;
bool found = false;
struct sysdb_attrs *attrs;
@@ -938,6 +831,7 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
tevent_req_callback_data(subreq, struct tevent_req);
struct sdap_access_filter_req_ctx *state =
tevent_req_data(req, struct sdap_access_filter_req_ctx);
+
ret = sdap_get_generic_recv(subreq, state,
&num_results, &results);
talloc_zfree(subreq);
@@ -946,17 +840,15 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
if (ret != EOK) {
if (dp_error == DP_ERR_OK) {
/* retry */
- ret = sdap_access_filter_retry(req);
- if (ret == EOK) {
+ tret = sdap_access_filter_retry(req);
+ if (tret == EOK) {
return;
}
- state->pam_status = PAM_SYSTEM_ERR;
} else if (dp_error == DP_ERR_OFFLINE) {
- sdap_access_filter_decide_offline(req);
+ ret = sdap_access_filter_decide_offline(req);
} else {
DEBUG(1, ("sdap_get_generic_send() returned error [%d][%s]\n",
ret, strerror(ret)));
- state->pam_status = PAM_SYSTEM_ERR;
}
goto done;
@@ -974,8 +866,7 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
}
else if (results == NULL) {
DEBUG(1, ("num_results > 0, but results is NULL\n"));
- ret = EIO;
- state->pam_status = PAM_SYSTEM_ERR;
+ ret = ERR_INTERNAL;
goto done;
}
else if (num_results > 1) {
@@ -983,8 +874,7 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
* here, since we're doing a base-scoped search
*/
DEBUG(1, ("Received multiple replies\n"));
- ret = EIO;
- state->pam_status = PAM_SYSTEM_ERR;
+ ret = ERR_INTERNAL;
goto done;
}
else { /* Ok, we got a single reply */
@@ -993,17 +883,17 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
if (found) {
/* Save "allow" to the cache for future offline
- * access checks.
+ :q* access checks.
*/
DEBUG(6, ("Access granted by online lookup\n"));
- state->pam_status = PAM_SUCCESS;
+ ret = EOK;
}
else {
/* Save "disallow" to the cache for future offline
* access checks.
*/
DEBUG(6, ("Access denied by online lookup\n"));
- state->pam_status = PAM_PERM_DENIED;
+ ret = ERR_ACCESS_DENIED;
}
attrs = sysdb_new_attrs(state);
@@ -1013,28 +903,22 @@ static void sdap_access_filter_get_access_done(struct tevent_req *subreq)
goto done;
}
- ret = sysdb_attrs_add_bool(attrs, SYSDB_LDAP_ACCESS_FILTER,
- state->pam_status == PAM_SUCCESS ?
- true :
- false);
- if (ret != EOK) {
+ tret = sysdb_attrs_add_bool(attrs, SYSDB_LDAP_ACCESS_FILTER,
+ ret == EOK ? true : false);
+ if (tret != EOK) {
/* Failing to save to the cache is non-fatal.
* Just return the result.
*/
- ret = EOK;
DEBUG(1, ("Could not set up attrs\n"));
goto done;
}
- ret = sysdb_set_user_attr(state->domain->sysdb,
- state->domain,
- state->username,
- attrs, SYSDB_MOD_REP);
- if (ret != EOK) {
+ tret = sysdb_set_user_attr(state->domain->sysdb, state->domain,
+ state->username, attrs, SYSDB_MOD_REP);
+ if (tret != EOK) {
/* Failing to save to the cache is non-fatal.
* Just return the result.
*/
- ret = EOK;
DEBUG(1, ("Failed to set user access attribute\n"));
goto done;
}
@@ -1048,43 +932,13 @@ done:
}
}
-static errno_t sdap_access_filter_recv(struct tevent_req *req, int *pam_status)
+static errno_t sdap_access_filter_recv(struct tevent_req *req)
{
- struct sdap_access_filter_req_ctx *state =
- tevent_req_data(req, struct sdap_access_filter_req_ctx);
-
TEVENT_REQ_RETURN_ON_ERROR(req);
- *pam_status = state->pam_status;
-
return EOK;
}
-static void sdap_access_filter_done(struct tevent_req *subreq)
-{
- errno_t ret;
- struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
- struct sdap_access_req_ctx *state =
- tevent_req_data(req, struct sdap_access_req_ctx);
-
- ret = sdap_access_filter_recv(subreq, &state->pam_status);
- talloc_zfree(subreq);
- if (ret != EOK) {
- DEBUG(1, ("Error retrieving access check result.\n"));
- state->pam_status = PAM_SYSTEM_ERR;
- tevent_req_error(req, ret);
- return;
- }
-
- next_access_rule(req);
-
- return;
-}
-
-
-struct sdap_access_service_ctx {
- int pam_status;
-};
#define AUTHR_SRV_MISSING_MSG "Authorized service attribute missing, " \
"access denied"
@@ -1092,170 +946,97 @@ struct sdap_access_service_ctx {
#define AUTHR_SRV_NO_MATCH_MSG "Authorized service attribute has " \
"no matching rule, access denied"
-static struct tevent_req *sdap_access_service_send(
- TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct pam_data *pd,
- struct ldb_message *user_entry)
+static errno_t sdap_access_service(struct pam_data *pd,
+ struct ldb_message *user_entry)
{
- errno_t ret;
- struct tevent_req *req;
- struct sdap_access_service_ctx *state;
+ errno_t ret, tret;
struct ldb_message_element *el;
unsigned int i;
char *service;
- req = tevent_req_create(mem_ctx, &state, struct sdap_access_service_ctx);
- if (!req) {
- return NULL;
- }
-
- state->pam_status = PAM_PERM_DENIED;
-
el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_SERVICE);
if (!el || el->num_values == 0) {
DEBUG(1, ("Missing authorized services. Access denied\n"));
- ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
+ tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
sizeof(AUTHR_SRV_MISSING_MSG),
(const uint8_t *) AUTHR_SRV_MISSING_MSG);
- if (ret != EOK) {
+ if (tret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
- ret = EOK;
- goto done;
+ return ERR_ACCESS_DENIED;
}
+ ret = ENOENT;
+
for (i = 0; i < el->num_values; i++) {
service = (char *)el->values[i].data;
if (service[0] == '!' &&
strcasecmp(pd->service, service+1) == 0) {
/* This service is explicitly denied */
- state->pam_status = PAM_PERM_DENIED;
DEBUG(4, ("Access denied by [%s]\n", service));
- ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
+ tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
sizeof(AUTHR_SRV_DENY_MSG),
(const uint8_t *) AUTHR_SRV_DENY_MSG);
- if (ret != EOK) {
+ if (tret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
/* A denial trumps all. Break here */
- ret = EOK;
- goto done;
+ return ERR_ACCESS_DENIED;
} else if (strcasecmp(pd->service, service) == 0) {
/* This service is explicitly allowed */
- state->pam_status = PAM_SUCCESS;
DEBUG(4, ("Access granted for [%s]\n", service));
/* We still need to loop through to make sure
* that it's not also explicitly denied
*/
+ ret = EOK;
} else if (strcmp("*", service) == 0) {
/* This user has access to all services */
- state->pam_status = PAM_SUCCESS;
DEBUG(4, ("Access granted to all services\n"));
/* We still need to loop through to make sure
* that it's not also explicitly denied
*/
+ ret = EOK;
}
}
- if (state->pam_status != PAM_SUCCESS) {
+ if (ret == ENOENT) {
DEBUG(4, ("No matching service rule found\n"));
- ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
+ tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
sizeof(AUTHR_SRV_NO_MATCH_MSG),
(const uint8_t *) AUTHR_SRV_NO_MATCH_MSG);
- if (ret != EOK) {
+ if (tret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
}
- }
-
- ret = EOK;
-
-done:
- if (ret == EOK) {
- tevent_req_done(req);
- } else {
- tevent_req_error(req, ret);
- }
- tevent_req_post(req, ev);
-
- return req;
-}
-
-static errno_t sdap_access_service_recv(struct tevent_req *req,
- int *pam_status)
-{
- struct sdap_access_service_ctx *state =
- tevent_req_data(req, struct sdap_access_service_ctx);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
- *pam_status = state->pam_status;
-
- return EOK;
-}
-
-static void sdap_access_service_done(struct tevent_req *subreq)
-{
- errno_t ret;
- struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
- struct sdap_access_req_ctx *state =
- tevent_req_data(req, struct sdap_access_req_ctx);
-
- ret = sdap_access_service_recv(subreq, &state->pam_status);
- talloc_zfree(subreq);
- if (ret != EOK) {
- DEBUG(1, ("Error retrieving access check result.\n"));
- state->pam_status = PAM_SYSTEM_ERR;
- tevent_req_error(req, ret);
- return;
+ ret = ERR_ACCESS_DENIED;
}
- next_access_rule(req);
-
- return;
+ return ret;
}
-struct sdap_access_host_ctx {
- int pam_status;
-};
-
-static struct tevent_req *sdap_access_host_send(
- TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct ldb_message *user_entry)
+static errno_t sdap_access_host(struct ldb_message *user_entry)
{
errno_t ret;
- struct tevent_req *req;
- struct sdap_access_host_ctx *state;
struct ldb_message_element *el;
unsigned int i;
char *host;
char hostname[HOST_NAME_MAX+1];
- req = tevent_req_create(mem_ctx, &state, struct sdap_access_host_ctx);
- if (!req) {
- return NULL;
- }
-
- state->pam_status = PAM_PERM_DENIED;
-
el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_HOST);
if (!el || el->num_values == 0) {
DEBUG(1, ("Missing hosts. Access denied\n"));
- ret = EOK;
- goto done;
+ return ERR_ACCESS_DENIED;
}
if (gethostname(hostname, sizeof(hostname)) == -1) {
DEBUG(1, ("Unable to get system hostname. Access denied\n"));
- ret = EOK;
- goto done;
+ return ERR_ACCESS_DENIED;
}
/* FIXME: PADL's pam_ldap also calls gethostbyname() on the hostname
@@ -1264,93 +1045,38 @@ static struct tevent_req *sdap_access_host_send(
* order to be compatible...
*/
+ ret = ENOENT;
+
for (i = 0; i < el->num_values; i++) {
host = (char *)el->values[i].data;
if (host[0] == '!' &&
strcasecmp(hostname, host+1) == 0) {
/* This host is explicitly denied */
- state->pam_status = PAM_PERM_DENIED;
DEBUG(4, ("Access denied by [%s]\n", host));
/* A denial trumps all. Break here */
- break;
+ return ERR_ACCESS_DENIED;
} else if (strcasecmp(hostname, host) == 0) {
/* This host is explicitly allowed */
- state->pam_status = PAM_SUCCESS;
DEBUG(4, ("Access granted for [%s]\n", host));
/* We still need to loop through to make sure
* that it's not also explicitly denied
*/
+ ret = EOK;
} else if (strcmp("*", host) == 0) {
/* This user has access to all hosts */
- state->pam_status = PAM_SUCCESS;
DEBUG(4, ("Access granted to all hosts\n"));
/* We still need to loop through to make sure
* that it's not also explicitly denied
*/
+ ret = EOK;
}
}
- if (state->pam_status != PAM_SUCCESS) {
+ if (ret == ENOENT) {
DEBUG(4, ("No matching host rule found\n"));
+ ret = ERR_ACCESS_DENIED;
}
- ret = EOK;
-
-done:
- if (ret == EOK) {
- tevent_req_done(req);
- } else {
- tevent_req_error(req, ret);
- }
- tevent_req_post(req, ev);
-
- return req;
-}
-
-static errno_t sdap_access_host_recv(struct tevent_req *req,
- int *pam_status)
-{
- struct sdap_access_host_ctx *state =
- tevent_req_data(req, struct sdap_access_host_ctx);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *pam_status = state->pam_status;
-
- return EOK;
-}
-
-static void sdap_access_host_done(struct tevent_req *subreq)
-{
- errno_t ret;
- struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
- struct sdap_access_req_ctx *state =
- tevent_req_data(req, struct sdap_access_req_ctx);
-
- ret = sdap_access_host_recv(subreq, &state->pam_status);
- talloc_zfree(subreq);
- if (ret != EOK) {
- DEBUG(1, ("Error retrieving access check result.\n"));
- state->pam_status = PAM_SYSTEM_ERR;
- tevent_req_error(req, ret);
- return;
- }
-
- next_access_rule(req);
-
- return;
-}
-
-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);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *pam_status = state->pam_status;
-
- return EOK;
+ return ret;
}
diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h
index 4f5f7201..cda07868 100644
--- a/src/providers/ldap/sdap_access.h
+++ b/src/providers/ldap/sdap_access.h
@@ -63,7 +63,6 @@ sdap_access_send(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
struct sdap_access_ctx *access_ctx,
struct pam_data *pd);
-errno_t
-sdap_access_recv(struct tevent_req *req, int *pam_status);
+errno_t sdap_access_recv(struct tevent_req *req);
#endif /* SDAP_ACCESS_H_ */
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
index 88806f53..a292fa6b 100644
--- a/src/util/util_errors.c
+++ b/src/util/util_errors.c
@@ -39,6 +39,7 @@ struct err_string error_to_str[] = {
{ "Password Change Failed" }, /* ERR_CHPASS_FAILED */
{ "Network I/O Error" }, /* ERR_NETWORK_IO */
{ "Account Expired" }, /* ERR_ACCOUNT_EXPIRED */
+ { "Host Access Denied" }, /* ERR_ACEESS_DENIED */
{ "Password Expired" }, /* ERR_PASSWORD_EXPIRED */
};
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
index 3e74de64..b4dfaf85 100644
--- a/src/util/util_errors.h
+++ b/src/util/util_errors.h
@@ -62,6 +62,7 @@ enum sssd_errors {
ERR_NETWORK_IO,
ERR_ACCOUNT_EXPIRED,
ERR_PASSWORD_EXPIRED,
+ ERR_ACCESS_DENIED,
ERR_LAST /* ALWAYS LAST */
};