diff options
-rw-r--r-- | src/man/sssd-ldap.5.xml | 27 | ||||
-rw-r--r-- | src/providers/ldap/ldap_access.c | 12 | ||||
-rw-r--r-- | src/providers/ldap/ldap_auth.c | 1 | ||||
-rw-r--r-- | src/providers/ldap/ldap_init.c | 9 | ||||
-rw-r--r-- | src/providers/ldap/sdap_access.c | 62 | ||||
-rw-r--r-- | src/providers/ldap/sdap_access.h | 6 | ||||
-rw-r--r-- | src/util/util_errors.h | 3 |
7 files changed, 119 insertions, 1 deletions
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index 9f2e9ac34..dca9938b8 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -1959,6 +1959,33 @@ ldap_access_filter = (employeeType=admin) ldap_account_expire_policy </para> <para> + <emphasis>pwd_expire_policy_reject, + pwd_expire_policy_warn, + pwd_expire_policy_renew: + </emphasis> + These options are useful if users are interested + in being warned that password is about to expire + and authentication is based on using a different + method than passwords - for example SSH keys. + </para> + <para> + The difference between these options is the action + taken if user password is expired: + pwd_expire_policy_reject - user is denied to log in, + pwd_expire_policy_warn - user is still able to log in, + pwd_expire_policy_renew - user is prompted to change + his password immediately. + </para> + <para> + Note If user password is expired no explicit message + is prompted by SSSD. + </para> + <para> + Please note that 'access_provider = ldap' must + be set for this feature to work. Also 'ldap_pwd_policy' + must be set to an appropriate password policy. + </para> + <para> <emphasis>authorized_service</emphasis>: use the authorizedService attribute to determine access diff --git a/src/providers/ldap/ldap_access.c b/src/providers/ldap/ldap_access.c index 1913cd9a9..7ebdb20c0 100644 --- a/src/providers/ldap/ldap_access.c +++ b/src/providers/ldap/ldap_access.c @@ -96,6 +96,18 @@ static void sdap_access_done(struct tevent_req *req) case ERR_ACCOUNT_EXPIRED: pam_status = PAM_ACCT_EXPIRED; break; + case ERR_PASSWORD_EXPIRED: + pam_status = PAM_PERM_DENIED; + break; + case ERR_PASSWORD_EXPIRED_REJECT: + pam_status = PAM_PERM_DENIED; + break; + case ERR_PASSWORD_EXPIRED_WARN: + pam_status = PAM_SUCCESS; + break; + case ERR_PASSWORD_EXPIRED_RENEW: + pam_status = PAM_NEW_AUTHTOK_REQD; + break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Error retrieving access check result.\n"); pam_status = PAM_SYSTEM_ERR; diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c index 4035aaf58..bdcc4505d 100644 --- a/src/providers/ldap/ldap_auth.c +++ b/src/providers/ldap/ldap_auth.c @@ -47,6 +47,7 @@ #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_auth.h" +#include "providers/ldap/sdap_access.h" #define LDAP_PWEXPIRE_WARNING_TIME 0 diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c index 44333a9a3..8d5619779 100644 --- a/src/providers/ldap/ldap_init.c +++ b/src/providers/ldap/ldap_init.c @@ -423,6 +423,15 @@ int sssm_ldap_access_init(struct be_ctx *bectx, access_ctx->access_rule[c] = LDAP_ACCESS_HOST; } else if (strcasecmp(order_list[c], LDAP_ACCESS_LOCK_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_LOCKOUT; + } else if (strcasecmp(order_list[c], + LDAP_ACCESS_EXPIRE_POLICY_REJECT_NAME) == 0) { + access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_REJECT; + } else if (strcasecmp(order_list[c], + LDAP_ACCESS_EXPIRE_POLICY_WARN_NAME) == 0) { + access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_WARN; + } else if (strcasecmp(order_list[c], + LDAP_ACCESS_EXPIRE_POLICY_RENEW_NAME) == 0) { + access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_RENEW; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected access rule name [%s].\n", order_list[c]); diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c index 52ea50ae2..3c8053cf7 100644 --- a/src/providers/ldap/sdap_access.c +++ b/src/providers/ldap/sdap_access.c @@ -39,10 +39,16 @@ #include "providers/ldap/sdap_async.h" #include "providers/data_provider.h" #include "providers/dp_backend.h" +#include "providers/ldap/ldap_auth.h" #define PERMANENTLY_LOCKED_ACCOUNT "000001010000Z" #define MALFORMED_FILTER "Malformed access control filter [%s]\n" +static errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct pam_data *pd, + struct sdap_options *opts); + static errno_t sdap_save_user_cache_bool(struct sss_domain_info *domain, const char *username, const char *attr_name, @@ -237,6 +243,30 @@ static errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx *state, state->pd, state->user_entry); break; + case LDAP_ACCESS_EXPIRE_POLICY_REJECT: + ret = perform_pwexpire_policy(state, state->domain, state->pd, + state->access_ctx->id_ctx->opts); + if (ret == ERR_PASSWORD_EXPIRED) { + ret = ERR_PASSWORD_EXPIRED_REJECT; + } + break; + + case LDAP_ACCESS_EXPIRE_POLICY_WARN: + ret = perform_pwexpire_policy(state, state->domain, state->pd, + state->access_ctx->id_ctx->opts); + if (ret == ERR_PASSWORD_EXPIRED) { + ret = ERR_PASSWORD_EXPIRED_WARN; + } + break; + + case LDAP_ACCESS_EXPIRE_POLICY_RENEW: + ret = perform_pwexpire_policy(state, state->domain, state->pd, + state->access_ctx->id_ctx->opts); + if (ret == ERR_PASSWORD_EXPIRED) { + ret = ERR_PASSWORD_EXPIRED_RENEW; + } + break; + case LDAP_ACCESS_SERVICE: ret = sdap_access_service( state->pd, state->user_entry); break; @@ -651,7 +681,6 @@ static errno_t sdap_account_expired_nds(struct pam_data *pd, return EOK; } - static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx, struct pam_data *pd, struct ldb_message *user_entry) @@ -714,6 +743,37 @@ static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx, return ret; } +static errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct pam_data *pd, + struct sdap_options *opts) +{ + enum pwexpire pw_expire_type; + void *pw_expire_data; + errno_t ret; + char *dn; + + ret = get_user_dn(mem_ctx, domain, opts, pd->user, &dn, &pw_expire_type, + &pw_expire_data); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "get_user_dn returned %d:[%s].\n", + ret, sss_strerror(ret)); + goto done; + } + + ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, pd, + domain->pwd_expiration_warning); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "check_pwexpire_policy returned %d:[%s].\n", + ret, sss_strerror(ret)); + goto done; + } + +done: + return ret; +} + struct sdap_access_filter_req_ctx { const char *username; const char *filter; diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h index f085e6199..a8c663910 100644 --- a/src/providers/ldap/sdap_access.h +++ b/src/providers/ldap/sdap_access.h @@ -39,6 +39,9 @@ #define LDAP_ACCESS_FILTER_NAME "filter" #define LDAP_ACCESS_EXPIRE_NAME "expire" +#define LDAP_ACCESS_EXPIRE_POLICY_REJECT_NAME "pwd_expire_policy_reject" +#define LDAP_ACCESS_EXPIRE_POLICY_WARN_NAME "pwd_expire_policy_warn" +#define LDAP_ACCESS_EXPIRE_POLICY_RENEW_NAME "pwd_expire_policy_renew" #define LDAP_ACCESS_SERVICE_NAME "authorized_service" #define LDAP_ACCESS_HOST_NAME "host" #define LDAP_ACCESS_LOCK_NAME "lockout" @@ -57,6 +60,9 @@ enum ldap_access_rule { LDAP_ACCESS_SERVICE, LDAP_ACCESS_HOST, LDAP_ACCESS_LOCKOUT, + LDAP_ACCESS_EXPIRE_POLICY_REJECT, + LDAP_ACCESS_EXPIRE_POLICY_WARN, + LDAP_ACCESS_EXPIRE_POLICY_RENEW, LDAP_ACCESS_LAST }; diff --git a/src/util/util_errors.h b/src/util/util_errors.h index 39455dc8a..97e210e31 100644 --- a/src/util/util_errors.h +++ b/src/util/util_errors.h @@ -64,6 +64,9 @@ enum sssd_errors { ERR_NETWORK_IO, ERR_ACCOUNT_EXPIRED, ERR_PASSWORD_EXPIRED, + ERR_PASSWORD_EXPIRED_REJECT, + ERR_PASSWORD_EXPIRED_WARN, + ERR_PASSWORD_EXPIRED_RENEW, ERR_ACCESS_DENIED, ERR_SRV_NOT_FOUND, ERR_SRV_LOOKUP_ERROR, |