summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/man/sssd-ldap.5.xml27
-rw-r--r--src/providers/ldap/ldap_access.c12
-rw-r--r--src/providers/ldap/ldap_auth.c1
-rw-r--r--src/providers/ldap/ldap_init.c9
-rw-r--r--src/providers/ldap/sdap_access.c62
-rw-r--r--src/providers/ldap/sdap_access.h6
-rw-r--r--src/util/util_errors.h3
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,