[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