summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2009-11-16 13:56:57 +0100
committerStephen Gallagher <sgallagh@redhat.com>2009-11-23 12:46:29 -0500
commitbe1697216fc62578c00606458b0ff390c575ef67 (patch)
tree7b4226269267824c1eb68a1555d0266dfa9fbf00
parente115c25af2df3549fb44b260e516d8c93d2adc8a (diff)
downloadsssd-be1697216fc62578c00606458b0ff390c575ef67.tar.gz
sssd-be1697216fc62578c00606458b0ff390c575ef67.tar.xz
sssd-be1697216fc62578c00606458b0ff390c575ef67.zip
Add ldap_pwd_policy option
-rw-r--r--server/config/SSSDConfig.py3
-rw-r--r--server/config/etc/sssd.api.d/sssd-ldap.conf1
-rw-r--r--server/man/sssd-ldap.5.xml33
-rw-r--r--server/providers/ldap/ldap_auth.c114
-rw-r--r--server/providers/ldap/ldap_common.c18
-rw-r--r--server/providers/ldap/ldap_common.h4
-rw-r--r--server/providers/ldap/sdap.h1
7 files changed, 129 insertions, 45 deletions
diff --git a/server/config/SSSDConfig.py b/server/config/SSSDConfig.py
index 57d39c7b8..1cbf1a84d 100644
--- a/server/config/SSSDConfig.py
+++ b/server/config/SSSDConfig.py
@@ -136,6 +136,9 @@ option_strings = {
'ldap_user_member_of' : _('memberOf attribute'),
'ldap_user_modify_timestamp' : _('Modification time attribute'),
+ # [provider/ldap/auth]
+ 'ldap_pwd_policy' : _('Policy to evaluate the password expiration'),
+
# [provider/local/id]
'default_shell' : _('Default shell, /bin/bash'),
'base_directory' : _('Base for home directories'),
diff --git a/server/config/etc/sssd.api.d/sssd-ldap.conf b/server/config/etc/sssd.api.d/sssd-ldap.conf
index 34aaa65b9..314f57fb3 100644
--- a/server/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/server/config/etc/sssd.api.d/sssd-ldap.conf
@@ -61,6 +61,7 @@ ldap_group_modify_timestamp = str, None
ldap_force_upper_case_realm = bool, None
[provider/ldap/auth]
+ldap_pwd_policy = str, None
[provider/ldap/chpass]
diff --git a/server/man/sssd-ldap.5.xml b/server/man/sssd-ldap.5.xml
index a2aa73065..d944392f9 100644
--- a/server/man/sssd-ldap.5.xml
+++ b/server/man/sssd-ldap.5.xml
@@ -582,6 +582,39 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>ldap_pwd_policy (string)</term>
+ <listitem>
+ <para>
+ Select the policy to evaluate the password
+ expiration on the client side. The following values
+ are allowed:
+ </para>
+ <para>
+ <emphasis>none</emphasis> No evaluation on the
+ client side. This option cannot disable server side
+ password policies.
+ </para>
+ <para>
+ <emphasis>shadow</emphasis> use
+ <citerefentry><refentrytitle>shadow</refentrytitle>
+ <manvolnum>5</manvolnum></citerefentry> style
+ attributes to evaluate if the password is expired.
+ Please note that the current version of sssd cannot
+ update this attribute during a password change.
+ </para>
+ <para>
+ <emphasis>mit_kerberos</emphasis> use the attributes
+ used by MIT Kerberos to evaluate if the password is
+ expired. Use chpass_provider=krb5 to update these
+ attributes when the password is changed.
+ </para>
+ <para>
+ Default: none
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</para>
</refsect1>
diff --git a/server/providers/ldap/ldap_auth.c b/server/providers/ldap/ldap_auth.c
index 6a80df447..81c966662 100644
--- a/server/providers/ldap/ldap_auth.c
+++ b/server/providers/ldap/ldap_auth.c
@@ -34,6 +34,7 @@
#undef _XOPEN_SOURCE
#include <errno.h>
#include <sys/time.h>
+#include <strings.h>
#include <shadow.h>
#include <security/pam_modules.h>
@@ -168,16 +169,24 @@ static errno_t string_to_shadowpw_days(const char *s, long *d)
static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx,
const struct ldb_message *msg,
+ struct dp_option *opts,
enum pwexpire *type, void **data)
{
const char *mark;
const char *val;
struct spwd *spwd;
+ const char *pwd_policy;
int ret;
*type = PWEXPIRE_NONE;
*data = NULL;
+ pwd_policy = dp_opt_get_string(opts, SDAP_PWD_POLICY);
+ if (pwd_policy == NULL) {
+ DEBUG(1, ("Missing password policy.\n"));
+ return EINVAL;
+ }
+
mark = ldb_msg_find_attr_as_string(msg, SYSDB_PWD_ATTRIBUTE, NULL);
if (mark != NULL) {
DEBUG(9, ("Found pwdAttribute, "
@@ -187,60 +196,73 @@ static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx,
return EOK;
}
- mark = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_LASTCHANGE, NULL);
- if (mark != NULL) {
- DEBUG(9, ("Found Kerberos password expiration attributes.\n"))
- val = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_EXPIRATION,
- NULL);
- if (val != NULL) {
- *data = talloc_strdup(mem_ctx, val);
- if (*data == NULL) {
- DEBUG(1, ("talloc_strdup failed.\n"));
- return ENOMEM;
- }
- *type = PWEXPIRE_KERBEROS;
-
- return EOK;
- }
- }
+ if (strcasecmp(pwd_policy, PWD_POL_OPT_NONE) == 0) {
+ DEBUG(9, ("No password policy requested.\n"));
+ return EOK;
+ } else if (strcasecmp(pwd_policy, PWD_POL_OPT_MIT) == 0) {
+ mark = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_LASTCHANGE, NULL);
+ if (mark != NULL) {
+ DEBUG(9, ("Found Kerberos password expiration attributes.\n"))
+ val = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_EXPIRATION,
+ NULL);
+ if (val != NULL) {
+ *data = talloc_strdup(mem_ctx, val);
+ if (*data == NULL) {
+ DEBUG(1, ("talloc_strdup failed.\n"));
+ return ENOMEM;
+ }
+ *type = PWEXPIRE_KERBEROS;
- mark = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
- if (mark != NULL) {
- DEBUG(9, ("Found shadow password expiration attributes.\n"))
- spwd = talloc_zero(mem_ctx, struct spwd);
- if (spwd == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- return ENOMEM;
+ return EOK;
+ }
+ } else {
+ DEBUG(1, ("No Kerberos password expiration attributes found, "
+ "but MIT Kerberos password policy was requested.\n"));
+ return EINVAL;
}
+ } else if (strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) == 0) {
+ mark = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
+ if (mark != NULL) {
+ DEBUG(9, ("Found shadow password expiration attributes.\n"))
+ spwd = talloc_zero(mem_ctx, struct spwd);
+ if (spwd == NULL) {
+ DEBUG(1, ("talloc failed.\n"));
+ return ENOMEM;
+ }
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_lstchg);
- if (ret != EOK) goto shadow_fail;
+ val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
+ ret = string_to_shadowpw_days(val, &spwd->sp_lstchg);
+ if (ret != EOK) goto shadow_fail;
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MIN, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_min);
- if (ret != EOK) goto shadow_fail;
+ val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MIN, NULL);
+ ret = string_to_shadowpw_days(val, &spwd->sp_min);
+ if (ret != EOK) goto shadow_fail;
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MAX, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_max);
- if (ret != EOK) goto shadow_fail;
+ val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MAX, NULL);
+ ret = string_to_shadowpw_days(val, &spwd->sp_max);
+ if (ret != EOK) goto shadow_fail;
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_WARNING, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_warn);
- if (ret != EOK) goto shadow_fail;
+ val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_WARNING, NULL);
+ ret = string_to_shadowpw_days(val, &spwd->sp_warn);
+ if (ret != EOK) goto shadow_fail;
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_INACTIVE, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_inact);
- if (ret != EOK) goto shadow_fail;
+ val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_INACTIVE, NULL);
+ ret = string_to_shadowpw_days(val, &spwd->sp_inact);
+ if (ret != EOK) goto shadow_fail;
- val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_EXPIRE, NULL);
- ret = string_to_shadowpw_days(val, &spwd->sp_expire);
- if (ret != EOK) goto shadow_fail;
+ val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_EXPIRE, NULL);
+ ret = string_to_shadowpw_days(val, &spwd->sp_expire);
+ if (ret != EOK) goto shadow_fail;
- *data = spwd;
- *type = PWEXPIRE_SHADOW;
+ *data = spwd;
+ *type = PWEXPIRE_SHADOW;
- return EOK;
+ return EOK;
+ } else {
+ DEBUG(1, ("No shadow password attributes found, "
+ "but shadow password policy was requested.\n"));
+ return EINVAL;
+ }
}
DEBUG(9, ("No password expiration attributes found.\n"));
@@ -360,6 +382,7 @@ static void get_user_dn_done(void *pvt, int err, struct ldb_result *res)
}
ret = find_password_expiration_attributes(state, res->msgs[0],
+ state->ctx->opts->basic,
&state->pw_expire_type,
&state->pw_expire_data);
if (ret != EOK) {
@@ -917,6 +940,9 @@ static void sdap_pam_auth_done(struct tevent_req *req)
case SDAP_UNAVAIL:
state->pd->pam_status = PAM_AUTHINFO_UNAVAIL;
break;
+ case SDAP_ACCT_EXPIRED:
+ state->pd->pam_status = PAM_ACCT_EXPIRED;
+ break;
case SDAP_AUTH_PW_EXPIRED:
state->pd->pam_status = PAM_AUTHTOK_EXPIRED;
break;
diff --git a/server/providers/ldap/ldap_common.c b/server/providers/ldap/ldap_common.c
index 6236707fe..58c6d692f 100644
--- a/server/providers/ldap/ldap_common.c
+++ b/server/providers/ldap/ldap_common.c
@@ -55,7 +55,8 @@ struct dp_option default_basic_opts[] = {
{ "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
/* use the same parm name as the krb5 module so we set it only once */
- { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }
+ { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "ldap_pwd_policy", DP_OPT_STRING, { "none" } , NULL_STRING }
};
struct sdap_attr_map generic_attr_map[] = {
@@ -157,6 +158,7 @@ int ldap_get_options(TALLOC_CTX *memctx,
struct sdap_attr_map *default_group_map;
struct sdap_options *opts;
char *schema;
+ const char *pwd_policy;
int ret;
opts = talloc_zero(memctx, struct sdap_options);
@@ -195,6 +197,20 @@ int ldap_get_options(TALLOC_CTX *memctx,
dp_opt_get_string(opts->basic, SDAP_GROUP_SEARCH_BASE)));
}
+ pwd_policy = dp_opt_get_string(opts->basic, SDAP_PWD_POLICY);
+ if (pwd_policy == NULL) {
+ DEBUG(1, ("Missing password policy, this may not happen.\n"));
+ ret = EINVAL;
+ goto done;
+ }
+ if (strcasecmp(pwd_policy, PWD_POL_OPT_NONE) != 0 &&
+ strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) != 0 &&
+ strcasecmp(pwd_policy, PWD_POL_OPT_MIT) != 0) {
+ DEBUG(1, ("Unsupported password policy [%s].\n", pwd_policy));
+ ret = EINVAL;
+ goto done;
+ }
+
/* schema type */
schema = dp_opt_get_string(opts->basic, SDAP_SCHEMA);
if (strcasecmp(schema, "rfc2307") == 0) {
diff --git a/server/providers/ldap/ldap_common.h b/server/providers/ldap/ldap_common.h
index 6adb785a3..111027672 100644
--- a/server/providers/ldap/ldap_common.h
+++ b/server/providers/ldap/ldap_common.h
@@ -26,6 +26,10 @@
#include "providers/ldap/sdap.h"
#include "providers/fail_over.h"
+#define PWD_POL_OPT_NONE "none"
+#define PWD_POL_OPT_SHADOW "shadow"
+#define PWD_POL_OPT_MIT "mit_kerberos"
+
struct sdap_id_ctx {
struct be_ctx *be;
struct sdap_options *opts;
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index a63d8580d..2909f4172 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -122,6 +122,7 @@ enum sdap_basic_opt {
SDAP_KRB5_KEYTAB,
SDAP_KRB5_KINIT,
SDAP_KRB5_REALM,
+ SDAP_PWD_POLICY,
SDAP_OPTS_BASIC /* opts counter */
};