[SSSD] [PATCH] Ignore shadow attributes
Sumit Bose
sbose at redhat.com
Fri Nov 20 20:00:50 UTC 2009
On Mon, Nov 16, 2009 at 09:23:17AM -0500, Simo Sorce wrote:
> On Mon, 2009-11-16 at 14:06 +0100, Sumit Bose wrote:
> > Hi,
> >
> > this patch should fix #279 by ignoring the shadow attributes by
> > default.
>
> I was thinking about this and I think I don't want to go down this way.
> While automatic discovery of the expiration attributes is nice, I think
> it is an issue.
>
> I would rather see an attribute that overrides
> find_password_expiration_attributes() instead.
>
> This way the admin can force what expiration policy should be used
> regardless of what random attributes may be found.
>
> something like: password_policy_type
> choice of: none, ldap_pwd_policy, mit_kerberos, shadow, auto
>
> so if you don't want anything use
> password_policy_type = none
>
> if you want to use only shadow (even if the server supports
> ldap_pwd_policies set password_policy_type = shadow
>
> I am unsure if we want to add "auto", that would be the default and use
> the find_password_expiration_attributes() to autodetect what to use.
>
> Thoughts ?
>
> Simo.
>
The attached patch does most of the above. There is no option "auto"
because I think it might be more confusing than without. Also there is
not option "ldap_pwd_policy", because if there is a server side policy
the client cannot ignore it.
bye,
Sumit
-------------- next part --------------
>From 54edfffe7a41216a2267a57bb68525454dbe85e5 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Mon, 16 Nov 2009 13:56:57 +0100
Subject: [PATCH] Add ldap_pwd_policy option
---
server/config/SSSDConfig.py | 3 +
server/config/etc/sssd.api.d/sssd-ldap.conf | 1 +
server/man/sssd-ldap.5.xml | 33 ++++++++
server/providers/ldap/ldap_auth.c | 114 ++++++++++++++++----------
server/providers/ldap/ldap_common.c | 18 ++++-
server/providers/ldap/ldap_common.h | 4 +
server/providers/ldap/sdap.h | 1 +
7 files changed, 129 insertions(+), 45 deletions(-)
diff --git a/server/config/SSSDConfig.py b/server/config/SSSDConfig.py
index 57d39c7..1cbf1a8 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 34aaa65..314f57f 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 a2aa730..d944392 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 a9f03a7..1f86fb0 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) {
@@ -883,6 +906,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 deffb4a..6263810 100644
--- a/server/providers/ldap/ldap_common.c
+++ b/server/providers/ldap/ldap_common.c
@@ -54,7 +54,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[] = {
@@ -156,6 +157,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);
@@ -194,6 +196,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 96b332c..f02395b 100644
--- a/server/providers/ldap/ldap_common.h
+++ b/server/providers/ldap/ldap_common.h
@@ -25,6 +25,10 @@
#include "providers/dp_backend.h"
#include "providers/ldap/sdap.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;
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index 8330bd6..9348a2e 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -117,6 +117,7 @@ enum sdap_basic_opt {
SDAP_KRB5_KEYTAB,
SDAP_KRB5_KINIT,
SDAP_KRB5_REALM,
+ SDAP_PWD_POLICY,
SDAP_OPTS_BASIC /* opts counter */
};
--
1.6.2.5
More information about the sssd-devel
mailing list