summaryrefslogtreecommitdiff
path: root/src/providers/ldap
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-02-26 16:25:07 -0500
committerJakub Hrozek <jhrozek@redhat.com>2013-03-19 14:07:41 +0100
commit233a3c6c48972b177e60d6ef4cecfacd3cf31659 (patch)
treee67d6eaed705d8c76173af0c06b49072224460be /src/providers/ldap
parent4f2e932acd5266e9d4e3f55966baafbdbd2ae210 (diff)
downloadsssd-233a3c6c48972b177e60d6ef4cecfacd3cf31659.tar.gz
sssd-233a3c6c48972b177e60d6ef4cecfacd3cf31659.tar.bz2
sssd-233a3c6c48972b177e60d6ef4cecfacd3cf31659.zip
Use common error facility instead of sdap_result
Simplifies and consolidates error reporting for ldap authentication paths. Adds 3 new error codes: ERR_CHPASS_DENIED - Used when password constraints deny password changes ERR_ACCOUNT_EXPIRED - Account is expired ERR_PASSWORD_EXPIRED - Password is expired
Diffstat (limited to 'src/providers/ldap')
-rw-r--r--src/providers/ldap/ldap_auth.c276
-rw-r--r--src/providers/ldap/sdap.h13
-rw-r--r--src/providers/ldap/sdap_async.c48
-rw-r--r--src/providers/ldap/sdap_async.h29
-rw-r--r--src/providers/ldap/sdap_async_connection.c152
5 files changed, 202 insertions, 316 deletions
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index bc91e2f7..e10c5b0e 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -86,19 +86,16 @@ static errno_t add_expired_warning(struct pam_data *pd, long exp_time)
static errno_t check_pwexpire_kerberos(const char *expire_date, time_t now,
struct pam_data *pd,
- enum sdap_result *result,
int pwd_exp_warning)
{
char *end;
struct tm tm;
time_t expire_time;
int expiration_warning;
- int ret;
+ int ret = ERR_INTERNAL;
memset(&tm, 0, sizeof(tm));
- *result = SDAP_AUTH_FAILED;
-
end = strptime(expire_date, "%Y%m%d%H%M%SZ", &tm);
if (end == NULL) {
DEBUG(1, ("Kerberos expire date [%s] invalid.\n", expire_date));
@@ -124,10 +121,8 @@ static errno_t check_pwexpire_kerberos(const char *expire_date, time_t now,
if (difftime(now, expire_time) > 0.0) {
DEBUG(4, ("Kerberos password expired.\n"));
- *result = SDAP_AUTH_PW_EXPIRED;
+ ret = ERR_PASSWORD_EXPIRED;
} else {
- *result = SDAP_AUTH_SUCCESS;
-
if (pwd_exp_warning >= 0) {
expiration_warning = pwd_exp_warning;
} else {
@@ -141,14 +136,14 @@ static errno_t check_pwexpire_kerberos(const char *expire_date, time_t now,
DEBUG(1, ("add_expired_warning failed.\n"));
}
}
+ ret = EOK;
}
- return EOK;
+ return ret;
}
static errno_t check_pwexpire_shadow(struct spwd *spwd, time_t now,
- struct pam_data *pd,
- enum sdap_result *result)
+ struct pam_data *pd)
{
long today;
long password_age;
@@ -157,15 +152,13 @@ static errno_t check_pwexpire_shadow(struct spwd *spwd, time_t now,
if (spwd->sp_lstchg <= 0) {
DEBUG(4, ("Last change day is not set, new password needed.\n"));
- *result = SDAP_AUTH_PW_EXPIRED;
- return EOK;
+ return ERR_PASSWORD_EXPIRED;
}
today = (long) (now / (60 * 60 *24));
password_age = today - spwd->sp_lstchg;
if (password_age < 0) {
DEBUG(2, ("The last password change time is in the future!.\n"));
- *result = SDAP_AUTH_SUCCESS;
return EOK;
}
@@ -174,14 +167,12 @@ static errno_t check_pwexpire_shadow(struct spwd *spwd, time_t now,
password_age > spwd->sp_max + spwd->sp_inact))
{
DEBUG(4, ("Account expired.\n"));
- *result = SDAP_ACCT_EXPIRED;
- return EOK;
+ return ERR_ACCOUNT_EXPIRED;
}
if (spwd->sp_max != -1 && password_age > spwd->sp_max) {
DEBUG(4, ("Password expired.\n"));
- *result = SDAP_AUTH_PW_EXPIRED;
- return EOK;
+ return ERR_PASSWORD_EXPIRED;
}
if (pd != NULL && spwd->sp_max != -1 && spwd->sp_warn != -1 &&
@@ -200,19 +191,18 @@ static errno_t check_pwexpire_shadow(struct spwd *spwd, time_t now,
}
}
- *result = SDAP_AUTH_SUCCESS;
return EOK;
}
static errno_t check_pwexpire_ldap(struct pam_data *pd,
struct sdap_ppolicy_data *ppolicy,
- enum sdap_result *result,
int pwd_exp_warning)
{
+ int ret = EOK;
+
if (ppolicy->grace > 0 || ppolicy->expire > 0) {
uint32_t *data;
uint32_t *ptr;
- int ret;
if (pwd_exp_warning < 0) {
pwd_exp_warning = 0;
@@ -245,13 +235,11 @@ static errno_t check_pwexpire_ldap(struct pam_data *pd,
(uint8_t*)data);
if (ret != EOK) {
DEBUG(1, ("pam_add_response failed.\n"));
- return ret;
}
}
done:
- *result = SDAP_AUTH_SUCCESS;
- return EOK;
+ return ret;
}
static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx,
@@ -469,7 +457,6 @@ struct auth_state {
struct sdap_handle *sh;
- enum sdap_result result;
char *dn;
enum pwexpire pw_expire_type;
void *pw_expire_data;
@@ -497,8 +484,7 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx,
/* The token must be a password token */
if (sss_authtok_get_type(authtok) != SSS_AUTHTOK_TYPE_PASSWORD) {
- state->result = SDAP_AUTH_FAILED;
- tevent_req_done(req);
+ tevent_req_error(req, ERR_AUTH_FAILED);
return tevent_req_post(req, ev);
}
@@ -646,54 +632,38 @@ static void auth_bind_user_done(struct tevent_req *subreq)
struct auth_state *state = tevent_req_data(req,
struct auth_state);
int ret;
- struct sdap_ppolicy_data *ppolicy;
+ struct sdap_ppolicy_data *ppolicy = NULL;
- ret = sdap_auth_recv(subreq, state, &state->result, &ppolicy);
+ ret = sdap_auth_recv(subreq, state, &ppolicy);
+ talloc_zfree(subreq);
if (ppolicy != NULL) {
DEBUG(9,("Found ppolicy data, "
"assuming LDAP password policies are active.\n"));
state->pw_expire_type = PWEXPIRE_LDAP_PASSWORD_POLICY;
state->pw_expire_data = ppolicy;
}
- talloc_zfree(subreq);
- if (ret != EOK) {
+ switch (ret) {
+ case EOK:
+ break;
+ case ETIMEDOUT:
+ case ERR_NETWORK_IO:
if (auth_get_server(req) == NULL) {
tevent_req_error(req, ENOMEM);
}
return;
+ default:
+ tevent_req_error(req, ret);
+ return;
}
tevent_req_done(req);
}
-int auth_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- struct sdap_handle **sh,
- enum sdap_result *result, char **dn,
- enum pwexpire *pw_expire_type, void **pw_expire_data)
+static errno_t auth_recv(struct tevent_req *req, TALLOC_CTX *memctx,
+ struct sdap_handle **sh, char **dn,
+ enum pwexpire *pw_expire_type, void **pw_expire_data)
{
struct auth_state *state = tevent_req_data(req, struct auth_state);
- enum tevent_req_state tstate;
- uint64_t err;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- switch (tstate) {
- case TEVENT_REQ_USER_ERROR:
- if (err == ETIMEDOUT) {
- *result = SDAP_UNAVAIL;
- return EOK;
- } else if (err == EACCES) {
- *result = SDAP_AUTH_FAILED;
- return EOK;
- } else {
- *result = SDAP_ERROR;
- return err;
- }
- default:
- *result = SDAP_ERROR;
- return EIO;
- }
- }
if (sh != NULL) {
*sh = talloc_steal(memctx, state->sh);
@@ -711,7 +681,8 @@ int auth_recv(struct tevent_req *req,
*pw_expire_type = state->pw_expire_type;
- *result = state->result;
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
return EOK;
}
@@ -793,22 +764,15 @@ static void sdap_auth4chpass_done(struct tevent_req *req)
tevent_req_callback_data(req, struct sdap_pam_chpass_state);
struct be_ctx *be_ctx = be_req_get_be_ctx(state->breq);
struct tevent_req *subreq;
- enum sdap_result result;
enum pwexpire pw_expire_type;
void *pw_expire_data;
int dp_err = DP_ERR_FATAL;
int ret;
- ret = auth_recv(req, state, &state->sh,
- &result, &state->dn,
+ ret = auth_recv(req, state, &state->sh, &state->dn,
&pw_expire_type, &pw_expire_data);
talloc_zfree(req);
- if (ret) {
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
-
- if ( (result == SDAP_AUTH_SUCCESS || result == SDAP_AUTH_PW_EXPIRED ) &&
+ if ((ret == EOK || ret == ERR_PASSWORD_EXPIRED) &&
state->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
DEBUG(9, ("Initial authentication for change password operation "
"successful.\n"));
@@ -817,46 +781,35 @@ static void sdap_auth4chpass_done(struct tevent_req *req)
goto done;
}
- if (result == SDAP_AUTH_SUCCESS) {
+ if (ret == EOK) {
switch (pw_expire_type) {
- case PWEXPIRE_SHADOW:
- ret = check_pwexpire_shadow(pw_expire_data, time(NULL), NULL,
- &result);
- if (ret != EOK) {
- DEBUG(1, ("check_pwexpire_shadow failed.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- break;
- case PWEXPIRE_KERBEROS:
- ret = check_pwexpire_kerberos(pw_expire_data, time(NULL), NULL, &result,
- be_ctx->domain->pwd_expiration_warning);
- if (ret != EOK) {
- DEBUG(1, ("check_pwexpire_kerberos failed.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
+ case PWEXPIRE_SHADOW:
+ ret = check_pwexpire_shadow(pw_expire_data, time(NULL), NULL);
+ break;
+ case PWEXPIRE_KERBEROS:
+ ret = check_pwexpire_kerberos(pw_expire_data, time(NULL), NULL,
+ be_ctx->domain->pwd_expiration_warning);
- if (result == SDAP_AUTH_PW_EXPIRED) {
- DEBUG(1, ("LDAP provider cannot change kerberos "
- "passwords.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- break;
- case PWEXPIRE_LDAP_PASSWORD_POLICY:
- case PWEXPIRE_NONE:
- break;
- default:
- DEBUG(1, ("Unknow pasword expiration type.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
+ if (ret == ERR_PASSWORD_EXPIRED) {
+ DEBUG(1, ("LDAP provider cannot change kerberos "
+ "passwords.\n"));
+ state->pd->pam_status = PAM_SYSTEM_ERR;
+ goto done;
+ }
+ break;
+ case PWEXPIRE_LDAP_PASSWORD_POLICY:
+ case PWEXPIRE_NONE:
+ break;
+ default:
+ DEBUG(1, ("Unknow pasword expiration type.\n"));
+ state->pd->pam_status = PAM_SYSTEM_ERR;
+ goto done;
}
}
- switch (result) {
- case SDAP_AUTH_SUCCESS:
- case SDAP_AUTH_PW_EXPIRED:
+ switch (ret) {
+ case EOK:
+ case ERR_PASSWORD_EXPIRED:
DEBUG(7, ("user [%s] successfully authenticated.\n", state->dn));
if (pw_expire_type == PWEXPIRE_SHADOW) {
/* TODO: implement async ldap modify request */
@@ -891,10 +844,12 @@ static void sdap_auth4chpass_done(struct tevent_req *req)
return;
}
break;
- case SDAP_AUTH_FAILED:
+ case ERR_AUTH_DENIED:
+ case ERR_AUTH_FAILED:
state->pd->pam_status = PAM_AUTH_ERR;
break;
- case SDAP_UNAVAIL:
+ case ETIMEDOUT:
+ case ERR_NETWORK_IO:
state->pd->pam_status = PAM_AUTHINFO_UNAVAIL;
be_mark_offline(be_ctx);
dp_err = DP_ERR_OFFLINE;
@@ -912,7 +867,6 @@ static void sdap_pam_chpass_done(struct tevent_req *req)
struct sdap_pam_chpass_state *state =
tevent_req_callback_data(req, struct sdap_pam_chpass_state);
struct be_ctx *be_ctx = be_req_get_be_ctx(state->breq);
- enum sdap_result result;
int dp_err = DP_ERR_FATAL;
int ret;
char *user_error_message = NULL;
@@ -921,24 +875,23 @@ static void sdap_pam_chpass_done(struct tevent_req *req)
size_t msg_len;
uint8_t *msg;
- ret = sdap_exop_modify_passwd_recv(req, state, &result, &user_error_message);
+ ret = sdap_exop_modify_passwd_recv(req, state, &user_error_message);
talloc_zfree(req);
- if (ret && ret != EIO) {
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- switch (result) {
- case SDAP_SUCCESS:
+ switch (ret) {
+ case EOK:
state->pd->pam_status = PAM_SUCCESS;
dp_err = DP_ERR_OK;
break;
- case SDAP_AUTH_PW_CONSTRAINT_VIOLATION:
+ case ERR_CHPASS_DENIED:
state->pd->pam_status = PAM_NEW_AUTHTOK_REQD;
break;
- default:
+ case ERR_NETWORK_IO:
state->pd->pam_status = PAM_AUTHTOK_ERR;
break;
+ default:
+ state->pd->pam_status = PAM_SYSTEM_ERR;
+ break;
}
if (state->pd->pam_status != PAM_SUCCESS && user_error_message != NULL) {
@@ -1068,76 +1021,72 @@ static void sdap_pam_auth_done(struct tevent_req *req)
struct sdap_pam_auth_state *state =
tevent_req_callback_data(req, struct sdap_pam_auth_state);
struct be_ctx *be_ctx = be_req_get_be_ctx(state->breq);
- enum sdap_result result;
enum pwexpire pw_expire_type;
void *pw_expire_data;
const char *password;
int dp_err = DP_ERR_OK;
int ret;
- ret = auth_recv(req, state, NULL,
- &result, NULL,
+ ret = auth_recv(req, state, NULL, NULL,
&pw_expire_type, &pw_expire_data);
talloc_zfree(req);
- if (ret != EOK) {
- state->pd->pam_status = PAM_SYSTEM_ERR;
- dp_err = DP_ERR_FATAL;
- goto done;
- }
- if (result == SDAP_AUTH_SUCCESS) {
+ if (ret == EOK) {
switch (pw_expire_type) {
- case PWEXPIRE_SHADOW:
- ret = check_pwexpire_shadow(pw_expire_data, time(NULL),
- state->pd, &result);
- if (ret != EOK) {
- DEBUG(1, ("check_pwexpire_shadow failed.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- break;
- case PWEXPIRE_KERBEROS:
- ret = check_pwexpire_kerberos(pw_expire_data, time(NULL),
- state->pd, &result,
- be_ctx->domain->pwd_expiration_warning);
- if (ret != EOK) {
- DEBUG(1, ("check_pwexpire_kerberos failed.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- break;
- case PWEXPIRE_LDAP_PASSWORD_POLICY:
- ret = check_pwexpire_ldap(state->pd, pw_expire_data, &result,
+ case PWEXPIRE_SHADOW:
+ ret = check_pwexpire_shadow(pw_expire_data, time(NULL), state->pd);
+ if (ret != EOK) {
+ DEBUG(1, ("check_pwexpire_shadow failed.\n"));
+ state->pd->pam_status = PAM_SYSTEM_ERR;
+ goto done;
+ }
+ break;
+ case PWEXPIRE_KERBEROS:
+ ret = check_pwexpire_kerberos(pw_expire_data, time(NULL),
+ state->pd,
be_ctx->domain->pwd_expiration_warning);
- if (ret != EOK) {
- DEBUG(1, ("check_pwexpire_ldap failed.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- break;
- case PWEXPIRE_NONE:
- break;
- default:
- DEBUG(1, ("Unknow pasword expiration type.\n"));
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
+ if (ret != EOK) {
+ DEBUG(1, ("check_pwexpire_kerberos failed.\n"));
+ state->pd->pam_status = PAM_SYSTEM_ERR;
+ goto done;
+ }
+ break;
+ case PWEXPIRE_LDAP_PASSWORD_POLICY:
+ ret = check_pwexpire_ldap(state->pd, pw_expire_data,
+ be_ctx->domain->pwd_expiration_warning);
+ if (ret != EOK) {
+ DEBUG(1, ("check_pwexpire_ldap failed.\n"));
+ state->pd->pam_status = PAM_SYSTEM_ERR;
+ goto done;
+ }
+ break;
+ case PWEXPIRE_NONE:
+ break;
+ default:
+ DEBUG(1, ("Unknow pasword expiration type.\n"));
+ state->pd->pam_status = PAM_SYSTEM_ERR;
+ goto done;
}
}
- switch (result) {
- case SDAP_AUTH_SUCCESS:
+ switch (ret) {
+ case EOK:
state->pd->pam_status = PAM_SUCCESS;
break;
- case SDAP_AUTH_FAILED:
+ case ERR_AUTH_DENIED:
state->pd->pam_status = PAM_PERM_DENIED;
break;
- case SDAP_UNAVAIL:
+ case ERR_AUTH_FAILED:
+ state->pd->pam_status = PAM_AUTH_ERR;
+ break;
+ case ETIMEDOUT:
+ case ERR_NETWORK_IO:
state->pd->pam_status = PAM_AUTHINFO_UNAVAIL;
break;
- case SDAP_ACCT_EXPIRED:
+ case ERR_ACCOUNT_EXPIRED:
state->pd->pam_status = PAM_ACCT_EXPIRED;
break;
- case SDAP_AUTH_PW_EXPIRED:
+ case ERR_PASSWORD_EXPIRED:
state->pd->pam_status = PAM_NEW_AUTHTOK_REQD;
break;
default:
@@ -1145,13 +1094,13 @@ static void sdap_pam_auth_done(struct tevent_req *req)
dp_err = DP_ERR_FATAL;
}
- if (result == SDAP_UNAVAIL) {
+ if (ret == ETIMEDOUT || ret == ERR_NETWORK_IO) {
be_mark_offline(be_ctx);
dp_err = DP_ERR_OFFLINE;
goto done;
}
- if (result == SDAP_AUTH_SUCCESS && be_ctx->domain->cache_credentials) {
+ if (ret == EOK && be_ctx->domain->cache_credentials) {
ret = sss_authtok_get_password(&state->pd->authtok, &password, NULL);
if (ret == EOK) {
@@ -1167,7 +1116,6 @@ static void sdap_pam_auth_done(struct tevent_req *req)
DEBUG(4, ("Password successfully cached for %s\n",
state->pd->user));
}
- goto done;
}
done:
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index d1436579..27f18ae1 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -136,19 +136,6 @@ struct sdap_ppolicy_data {
#define SDAP_AD_USN "uSNChanged"
#define SDAP_AD_LAST_USN "highestCommittedUSN"
-enum sdap_result {
- SDAP_SUCCESS,
- SDAP_NOT_FOUND,
- SDAP_UNAVAIL,
- SDAP_RETRY,
- SDAP_ERROR,
- SDAP_AUTH_SUCCESS,
- SDAP_AUTH_FAILED,
- SDAP_AUTH_PW_EXPIRED,
- SDAP_AUTH_PW_CONSTRAINT_VIOLATION,
- SDAP_ACCT_EXPIRED
-};
-
enum sdap_basic_opt {
SDAP_URI = 0,
SDAP_BACKUP_URI,
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index b7d98392..7ac32b95 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -490,7 +490,6 @@ struct sdap_exop_modify_passwd_state {
struct sdap_op *op;
- int result;
char *user_error_message;
};
@@ -552,6 +551,7 @@ struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) {
DEBUG(1, ("sdap_control_create failed to create "
"Password Policy control.\n"));
+ ret = ERR_INTERNAL;
goto fail;
}
request_controls = ctrls;
@@ -564,6 +564,7 @@ struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
if (ctrls[0]) ldap_control_free(ctrls[0]);
if (ret == -1 || msgid == -1) {
DEBUG(1, ("ldap_extended_operation failed\n"));
+ ret = ERR_NETWORK_IO;
goto fail;
}
DEBUG(8, ("ldap_extended_operation sent, msgid = %d\n", msgid));
@@ -573,13 +574,14 @@ struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
sdap_exop_modify_passwd_done, req, 5, &state->op);
if (ret) {
DEBUG(1, ("Failed to set up operation!\n"));
+ ret = ERR_INTERNAL;
goto fail;
}
return req;
fail:
- tevent_req_error(req, EIO);
+ tevent_req_error(req, ret);
tevent_req_post(req, ev);
return req;
}
@@ -598,6 +600,7 @@ static void sdap_exop_modify_passwd_done(struct sdap_op *op,
ber_int_t pp_grace;
ber_int_t pp_expire;
LDAPPasswordPolicyError pp_error;
+ int result;
if (error) {
tevent_req_error(req, error);
@@ -605,11 +608,11 @@ static void sdap_exop_modify_passwd_done(struct sdap_op *op,
}
ret = ldap_parse_result(state->sh->ldap, reply->msg,
- &state->result, NULL, &errmsg, NULL,
+ &result, NULL, &errmsg, NULL,
&response_controls, 0);
if (ret != LDAP_SUCCESS) {
DEBUG(2, ("ldap_parse_result failed (%d)\n", state->op->msgid));
- ret = EIO;
+ ret = ERR_INTERNAL;
goto done;
}
@@ -627,7 +630,7 @@ static void sdap_exop_modify_passwd_done(struct sdap_op *op,
&pp_error);
if (ret != LDAP_SUCCESS) {
DEBUG(1, ("ldap_parse_passwordpolicy_control failed.\n"));
- ret = EIO;
+ ret = ERR_NETWORK_IO;
goto done;
}
@@ -639,9 +642,16 @@ static void sdap_exop_modify_passwd_done(struct sdap_op *op,
}
DEBUG(3, ("ldap_extended_operation result: %s(%d), %s\n",
- sss_ldap_err2string(state->result), state->result, errmsg));
+ sss_ldap_err2string(result), result, errmsg));
- if (state->result != LDAP_SUCCESS) {
+ switch (result) {
+ case LDAP_SUCCESS:
+ ret = EOK;
+ break;
+ case LDAP_CONSTRAINT_VIOLATION:
+ ret = ERR_CHPASS_DENIED;
+ break;
+ default:
if (errmsg) {
state->user_error_message = talloc_strdup(state, errmsg);
if (state->user_error_message == NULL) {
@@ -650,11 +660,10 @@ static void sdap_exop_modify_passwd_done(struct sdap_op *op,
goto done;
}
}
- ret = EIO;
- goto done;
+ ret = ERR_NETWORK_IO;
+ break;
}
- ret = EOK;
done:
ldap_controls_free(response_controls);
ldap_memfree(errmsg);
@@ -666,28 +675,15 @@ done:
}
}
-int sdap_exop_modify_passwd_recv(struct tevent_req *req,
- TALLOC_CTX * mem_ctx,
- enum sdap_result *result,
- char **user_error_message)
+errno_t sdap_exop_modify_passwd_recv(struct tevent_req *req,
+ TALLOC_CTX * mem_ctx,
+ char **user_error_message)
{
struct sdap_exop_modify_passwd_state *state = tevent_req_data(req,
struct sdap_exop_modify_passwd_state);
*user_error_message = talloc_steal(mem_ctx, state->user_error_message);
- switch (state->result) {
- case LDAP_SUCCESS:
- *result = SDAP_SUCCESS;
- break;
- case LDAP_CONSTRAINT_VIOLATION:
- *result = SDAP_AUTH_PW_CONSTRAINT_VIOLATION;
- break;
- default:
- *result = SDAP_ERROR;
- break;
- }
-
TEVENT_REQ_RETURN_ON_ERROR(req);
return EOK;
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 69590b9e..59269110 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -86,22 +86,6 @@ int sdap_get_netgroups_recv(struct tevent_req *req,
size_t *reply_count,
struct sysdb_attrs ***reply);
-struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct be_ctx *be,
- struct sdap_handle *sh,
- const char *service_name,
- int timeout,
- const char *keytab,
- const char *principal,
- const char *realm,
- bool canonicalize,
- int lifetime);
-
-int sdap_kinit_recv(struct tevent_req *req,
- enum sdap_result *result,
- time_t *expire_time);
-
struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sdap_handle *sh,
@@ -110,10 +94,9 @@ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
const char *user_dn,
struct sss_auth_token *authtok);
-int sdap_auth_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- enum sdap_result *result,
- struct sdap_ppolicy_data **ppolicy);
+errno_t sdap_auth_recv(struct tevent_req *req,
+ TALLOC_CTX *memctx,
+ struct sdap_ppolicy_data **ppolicy);
struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
@@ -129,9 +112,9 @@ struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
char *user_dn,
const char *password,
const char *new_password);
-int sdap_exop_modify_passwd_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- enum sdap_result *result,
- char **user_error_msg);
+errno_t sdap_exop_modify_passwd_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ char **user_error_msg);
struct tevent_req *
sdap_modify_shadow_lastchange_send(TALLOC_CTX *mem_ctx,
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index b673daf6..d9ea4091 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -446,7 +446,6 @@ struct simple_bind_state {
struct sdap_msg *reply;
struct sdap_ppolicy_data *ppolicy;
- int result;
};
static void simple_bind_done(struct sdap_op *op,
@@ -529,7 +528,7 @@ fail:
if (ret == LDAP_SERVER_DOWN) {
tevent_req_error(req, ETIMEDOUT);
} else {
- tevent_req_error(req, EIO);
+ tevent_req_error(req, ERR_NETWORK_IO);
}
tevent_req_post(req, ev);
return req;
@@ -544,13 +543,14 @@ static void simple_bind_done(struct sdap_op *op,
struct simple_bind_state);
char *errmsg = NULL;
char *nval;
- errno_t ret;
+ errno_t ret = ERR_INTERNAL;
int lret;
LDAPControl **response_controls;
int c;
ber_int_t pp_grace;
ber_int_t pp_expire;
LDAPPasswordPolicyError pp_error;
+ int result = LDAP_OTHER;
if (error) {
tevent_req_error(req, error);
@@ -560,15 +560,21 @@ static void simple_bind_done(struct sdap_op *op,
state->reply = talloc_steal(state, reply);
lret = ldap_parse_result(state->sh->ldap, state->reply->msg,
- &state->result, NULL, &errmsg, NULL,
+ &result, NULL, &errmsg, NULL,
&response_controls, 0);
if (lret != LDAP_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
("ldap_parse_result failed (%d)\n", state->op->msgid));
- ret = EIO;
+ ret = ERR_INTERNAL;
goto done;
}
+ if (result == LDAP_SUCCESS) {
+ ret = EOK;
+ } else {
+ ret = ERR_AUTH_FAILED;
+ }
+
if (response_controls == NULL) {
DEBUG(SSSDBG_TRACE_LIBS, ("Server returned no controls.\n"));
state->ppolicy = NULL;
@@ -586,7 +592,7 @@ static void simple_bind_done(struct sdap_op *op,
if (lret != LDAP_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
("ldap_parse_passwordpolicy_control failed.\n"));
- ret = EIO;
+ ret = ERR_INTERNAL;
goto done;
}
@@ -602,12 +608,13 @@ static void simple_bind_done(struct sdap_op *op,
}
state->ppolicy->grace = pp_grace;
state->ppolicy->expire = pp_expire;
- if (state->result == LDAP_SUCCESS) {
+ if (result == LDAP_SUCCESS) {
+
if (pp_error == PP_changeAfterReset) {
DEBUG(SSSDBG_TRACE_LIBS,
("Password was reset. "
"User must set a new password.\n"));
- state->result = LDAP_X_SSSD_PASSWORD_EXPIRED;
+ ret = ERR_PASSWORD_EXPIRED;
} else if (pp_grace > 0) {
DEBUG(SSSDBG_TRACE_LIBS,
("Password expired. "
@@ -618,17 +625,17 @@ static void simple_bind_done(struct sdap_op *op,
("Password will expire in [%d] seconds.\n",
pp_expire));
}
- } else if (state->result == LDAP_INVALID_CREDENTIALS &&
+ } else if (result == LDAP_INVALID_CREDENTIALS &&
pp_error == PP_passwordExpired) {
DEBUG(SSSDBG_TRACE_LIBS,
("Password expired user must set a new password.\n"));
- state->result = LDAP_X_SSSD_PASSWORD_EXPIRED;
+ ret = ERR_PASSWORD_EXPIRED;
}
} else if (strcmp(response_controls[c]->ldctl_oid,
LDAP_CONTROL_PWEXPIRED) == 0) {
DEBUG(SSSDBG_TRACE_LIBS,
("Password expired user must set a new password.\n"));
- state->result = LDAP_X_SSSD_PASSWORD_EXPIRED;
+ ret = ERR_PASSWORD_EXPIRED;
} else if (strcmp(response_controls[c]->ldctl_oid,
LDAP_CONTROL_PWEXPIRING) == 0) {
/* ignore controls with suspiciously long values */
@@ -670,10 +677,13 @@ static void simple_bind_done(struct sdap_op *op,
}
DEBUG(SSSDBG_TRACE_FUNC, ("Bind result: %s(%d), %s\n",
- sss_ldap_err2string(state->result), state->result,
+ sss_ldap_err2string(result), result,
errmsg ? errmsg : "no errmsg set"));
- ret = EOK;
+ if (result != LDAP_SUCCESS && ret == EOK) {
+ ret = ERR_AUTH_FAILED;
+ }
+
done:
ldap_controls_free(response_controls);
ldap_memfree(errmsg);
@@ -685,19 +695,19 @@ done:
}
}
-static int simple_bind_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- int *ldaperr,
- struct sdap_ppolicy_data **ppolicy)
+static errno_t simple_bind_recv(struct tevent_req *req,
+ TALLOC_CTX *memctx,
+ struct sdap_ppolicy_data **ppolicy)
{
struct simple_bind_state *state = tevent_req_data(req,
struct simple_bind_state);
- *ldaperr = LDAP_OTHER;
+ if (ppolicy != NULL) {
+ *ppolicy = talloc_steal(memctx, state->ppolicy);
+ }
+
TEVENT_REQ_RETURN_ON_ERROR(req);
- *ldaperr = state->result;
- *ppolicy = talloc_steal(memctx, state->ppolicy);
return EOK;
}
@@ -710,8 +720,6 @@ struct sasl_bind_state {
const char *sasl_mech;
const char *sasl_user;
struct berval *sasl_cred;
-
- int result;
};
static int sdap_sasl_interact(LDAP *ld, unsigned flags,
@@ -749,7 +757,6 @@ static struct tevent_req *sasl_bind_send(TALLOC_CTX *memctx,
sasl_mech, NULL, NULL,
LDAP_SASL_QUIET,
(*sdap_sasl_interact), state);
- state->result = ret;
if (ret != LDAP_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE,
("ldap_sasl_bind failed (%d)[%s]\n",
@@ -771,14 +778,20 @@ static struct tevent_req *sasl_bind_send(TALLOC_CTX *memctx,
if (ret) goto fail;
}
+ /* This is a hack, relies on the fact that tevent_req_done() will always
+ * set the state but will not complain if no callback has been set.
+ * tevent_req_post() will only set the immediate event and then just call
+ * the async callback set by the caller right after we return using the
+ * state value set previously by tevent_req_done() */
+ tevent_req_done(req);
tevent_req_post(req, ev);
return req;
fail:
- if (ret == LDAP_SERVER_DOWN) {
+ if (ret == LDAP_SERVER_DOWN || ret == LDAP_TIMEOUT) {
tevent_req_error(req, ETIMEDOUT);
} else {
- tevent_req_error(req, EIO);
+ tevent_req_error(req, ERR_AUTH_FAILED);
}
tevent_req_post(req, ev);
return req;
@@ -830,21 +843,10 @@ fail:
return LDAP_UNAVAILABLE;
}
-static int sasl_bind_recv(struct tevent_req *req, int *ldaperr)
+static errno_t sasl_bind_recv(struct tevent_req *req)
{
- struct sasl_bind_state *state = tevent_req_data(req,
- struct sasl_bind_state);
- enum tevent_req_state tstate;
- uint64_t err = EIO;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- if (tstate != TEVENT_REQ_IN_PROGRESS) {
- *ldaperr = LDAP_OTHER;
- return err;
- }
- }
+ TEVENT_REQ_RETURN_ON_ERROR(req);
- *ldaperr = state->result;
return EOK;
}
@@ -862,7 +864,6 @@ struct sdap_kinit_state {
struct be_ctx *be;
struct fo_server *kdc_srv;
- int result;
time_t expire_time;
};
@@ -870,6 +871,7 @@ static void sdap_kinit_done(struct tevent_req *subreq);
static struct tevent_req *sdap_kinit_next_kdc(struct tevent_req *req);
static void sdap_kinit_kdc_resolved(struct tevent_req *subreq);
+static
struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct be_ctx *be,
@@ -899,7 +901,6 @@ struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx,
req = tevent_req_create(memctx, &state, struct sdap_kinit_state);
if (!req) return NULL;
- state->result = SDAP_AUTH_FAILED;
state->keytab = keytab;
state->principal = principal;
state->realm = realm;
@@ -974,7 +975,7 @@ static void sdap_kinit_kdc_resolved(struct tevent_req *subreq)
if (ret != EOK) {
/* all servers have been tried and none
* was found good, go offline */
- tevent_req_error(req, EIO);
+ tevent_req_error(req, ERR_NETWORK_IO);
return;
}
@@ -1021,7 +1022,6 @@ static void sdap_kinit_done(struct tevent_req *subreq)
return;
} else if (ret != EOK) {
/* A severe error while executing the child. Abort the operation. */
- state->result = SDAP_AUTH_FAILED;
DEBUG(1, ("child failed (%d [%s])\n", ret, strerror(ret)));
tevent_req_error(req, ret);
return;
@@ -1031,12 +1031,10 @@ static void sdap_kinit_done(struct tevent_req *subreq)
ret = setenv("KRB5CCNAME", ccname, 1);
if (ret == -1) {
DEBUG(2, ("Unable to set env. variable KRB5CCNAME!\n"));
- state->result = SDAP_AUTH_FAILED;
- tevent_req_error(req, EFAULT);
+ tevent_req_error(req, ERR_AUTH_FAILED);
}
state->expire_time = expire_time;
- state->result = SDAP_AUTH_SUCCESS;
tevent_req_done(req);
return;
} else {
@@ -1052,28 +1050,24 @@ static void sdap_kinit_done(struct tevent_req *subreq)
}
- DEBUG(4, ("Could not get TGT: %d [%s]\n", result, strerror(result)));
- state->result = SDAP_AUTH_FAILED;
- tevent_req_error(req, EIO);
+ DEBUG(4, ("Could not get TGT: %d [%s]\n", result, sss_strerror(result)));
+ tevent_req_error(req, ERR_AUTH_FAILED);
}
-int sdap_kinit_recv(struct tevent_req *req,
- enum sdap_result *result,
- time_t *expire_time)
+static errno_t sdap_kinit_recv(struct tevent_req *req,
+ time_t *expire_time)
{
struct sdap_kinit_state *state = tevent_req_data(req,
struct sdap_kinit_state);
enum tevent_req_state tstate;
- uint64_t err = EIO;
+ uint64_t err = ERR_INTERNAL;
if (tevent_req_is_error(req, &tstate, &err)) {
if (tstate != TEVENT_REQ_IN_PROGRESS) {
- *result = SDAP_ERROR;
return err;
}
}
- *result = state->result;
*expire_time = state->expire_time;
return EOK;
}
@@ -1084,7 +1078,6 @@ int sdap_kinit_recv(struct tevent_req *req,
struct sdap_auth_state {
struct sdap_ppolicy_data *ppolicy;
bool is_sasl;
- int result;
};
static void sdap_auth_done(struct tevent_req *subreq);
@@ -1171,46 +1164,31 @@ static void sdap_auth_done(struct tevent_req *subreq)
int ret;
if (state->is_sasl) {
- ret = sasl_bind_recv(subreq, &state->result);
+ ret = sasl_bind_recv(subreq);
state->ppolicy = NULL;
} else {
- ret = simple_bind_recv(subreq, state, &state->result, &state->ppolicy);
+ ret = simple_bind_recv(subreq, state, &state->ppolicy);
}
- if (ret != EOK) {
- tevent_req_error(req, ret);
+
+ if (tevent_req_error(req, ret)) {
return;
}
tevent_req_done(req);
}
-int sdap_auth_recv(struct tevent_req *req,
- TALLOC_CTX *memctx,
- enum sdap_result *result,
- struct sdap_ppolicy_data **ppolicy)
+errno_t sdap_auth_recv(struct tevent_req *req,
+ TALLOC_CTX *memctx,
+ struct sdap_ppolicy_data **ppolicy)
{
struct sdap_auth_state *state = tevent_req_data(req,
struct sdap_auth_state);
- *result = SDAP_ERROR;
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
if (ppolicy != NULL) {
*ppolicy = talloc_steal(memctx, state->ppolicy);
}
- switch (state->result) {
- case LDAP_SUCCESS:
- *result = SDAP_AUTH_SUCCESS;
- break;
- case LDAP_INVALID_CREDENTIALS:
- *result = SDAP_AUTH_FAILED;
- break;
- case LDAP_X_SSSD_PASSWORD_EXPIRED:
- *result = SDAP_AUTH_PW_EXPIRED;
- break;
- default:
- break;
- }
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
return EOK;
}
@@ -1564,17 +1542,16 @@ static void sdap_cli_kinit_done(struct tevent_req *subreq)
struct tevent_req);
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
- enum sdap_result result;
time_t expire_time;
- int ret;
+ errno_t ret;
- ret = sdap_kinit_recv(subreq, &result, &expire_time);
+ ret = sdap_kinit_recv(subreq, &expire_time);
talloc_zfree(subreq);
- if (ret != EOK || result != SDAP_AUTH_SUCCESS) {
+ if (ret != EOK) {
/* We're not able to authenticate to the LDAP server.
* There's not much we can do except for going offline */
DEBUG(SSSDBG_TRACE_FUNC,
- ("Cannot get a TGT: ret [%d] result [%d]\n", ret, result));
+ ("Cannot get a TGT: ret [%d](%s)\n", ret, sss_strerror(ret)));
tevent_req_error(req, EACCES);
return;
}
@@ -1660,19 +1637,14 @@ static void sdap_cli_auth_done(struct tevent_req *subreq)
struct tevent_req);
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
- enum sdap_result result;
int ret;
- ret = sdap_auth_recv(subreq, NULL, &result, NULL);
+ ret = sdap_auth_recv(subreq, NULL, NULL);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
return;
}
- if (result != SDAP_AUTH_SUCCESS) {
- tevent_req_error(req, EACCES);
- return;
- }
if (state->use_rootdse && !state->rootdse) {
/* We weren't able to read rootDSE during unauthenticated bind.