Documented on http://msdn.microsoft.com/en-us/library/cc220785(v=prot.10).aspx
Introduced in nss_ldap 208: * add support for native Active Directory password policy attributes (enabled if shadowLastChange is mapped to pwdLastSet) --- src/config/SSSDConfig.py | 1 + src/config/etc/sssd.api.d/sssd-ldap.conf | 1 + src/man/sssd-ldap.5.xml | 15 ++++++++++ src/providers/ldap/ldap_auth.c | 9 +++++- src/providers/ldap/ldap_common.c | 43 ++++++++++++++++++++++++++++++ src/providers/ldap/ldap_common.h | 1 + src/providers/ldap/sdap.h | 1 + 7 files changed, 70 insertions(+), 1 deletions(-) diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py index 5135174..992e1f4 100644 --- a/src/config/SSSDConfig.py +++ b/src/config/SSSDConfig.py @@ -167,6 +167,7 @@ option_strings = { 'ldap_user_modify_timestamp' : _('Modification time attribute'), #replaced by ldap_entry_usn# 'ldap_user_entry_usn' : _('entryUSN attribute'), 'ldap_user_shadow_last_change' : _('shadowLastChange attribute'), + 'ldap_user_ads_last_change' : _('pwdLastSet attribute'), 'ldap_user_shadow_min' : _('shadowMin attribute'), 'ldap_user_shadow_max' : _('shadowMax attribute'), 'ldap_user_shadow_warning' : _('shadowWarning attribute'), diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf index 5fd0cfb..6700df9 100644 --- a/src/config/etc/sssd.api.d/sssd-ldap.conf +++ b/src/config/etc/sssd.api.d/sssd-ldap.conf @@ -51,6 +51,7 @@ ldap_user_member_of = str, None, false ldap_user_modify_timestamp = str, None, false ldap_user_entry_usn = str, None, false ldap_user_shadow_last_change = str, None, false +ldap_user_ads_last_change = str, None, false ldap_user_shadow_min = str, None, false ldap_user_shadow_max = str, None, false ldap_user_shadow_warning = str, None, false diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index 2a39732..0db3ce7 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -313,6 +313,21 @@ </varlistentry> <varlistentry> + <term>ldap_user_ads_last_change (string)</term> + <listitem> + <para> + When using ldap_pwd_policy=shadow, this parameter + contains the name of an LDAP attribute corresponding + to pwdLastSet in Active Directory server, fell back to + when ldap_user_shadow_last_change was not available. + </para> + <para> + Default: pwdLastSet + </para> + </listitem> + </varlistentry> + + <varlistentry> <term>ldap_user_shadow_min (string)</term> <listitem> <para> diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c index e45d5b3..5ebd72c 100644 --- a/src/providers/ldap/ldap_auth.c +++ b/src/providers/ldap/ldap_auth.c @@ -286,7 +286,8 @@ static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx, return EINVAL; } } else if (strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) == 0) { - mark = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL); + mark = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL) | + ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_ADS_LASTCHANGE, NULL); if (mark != NULL) { DEBUG(9, ("Found shadow password expiration attributes.\n")) spwd = talloc_zero(mem_ctx, struct spwd); @@ -297,6 +298,12 @@ static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx, val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL); ret = string_to_shadowpw_days(val, &spwd->sp_lstchg); + + /* Fallback to pwdLastSet for ADS */ + if (ret != EOK) { + val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_ADS_LASTCHANGE, NULL); + ret = ads_pwdlastset_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); diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c index 9eb9cc3..22c9bb7 100644 --- a/src/providers/ldap/ldap_common.c +++ b/src/providers/ldap/ldap_common.c @@ -163,6 +163,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = { { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL }, + { "ldap_user_ads_last_change", "pwdLastSet", SYSDB_SHADOWPW_ADS_LASTCHANGE, NULL }, { "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL }, { "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL }, { "ldap_user_shadow_warning", "shadowWarning", SYSDB_SHADOWPW_WARNING, NULL }, @@ -878,6 +879,48 @@ errno_t string_to_shadowpw_days(const char *s, long *d) return EOK; } +errno_t ads_pwdlastset_to_shadowpw_days(const char *s, long *d) +{ + long long ll; + long days; + char *endptr; + + if (s == NULL || *s == '\0') { + *d = -1; + return EOK; + } + + errno = 0; + ll = strtoll(s, &endptr, 10); + if (errno != 0) { + DEBUG(1, ("strtoll failed [%d][%s].\n", errno, strerror(errno))); + return errno; + } + + if (*endptr != '\0') { + DEBUG(1, ("Input string [%s] is invalid.\n", s)); + return EINVAL; + } + + /* Magic value for password reset */ + if (ll = 0LL) { + DEBUG(9, ("Magic pwdLastSet date 0, password change forced.\n")); + *d = 0L; + return EOK; + } + + days = ll / 864000000000LL - 134774LL; + + if (days < 0L) { + DEBUG(1, ("Date is before Jan 1, 1970 [%d].\n", ll)); + return EINVAL; + } + + *d = days; + + return EOK; +} + errno_t get_sysdb_attr_name(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, size_t map_size, diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h index 9146da5..cf301de 100644 --- a/src/providers/ldap/ldap_common.h +++ b/src/providers/ldap/ldap_common.h @@ -146,6 +146,7 @@ int setup_child(struct sdap_id_ctx *ctx); errno_t string_to_shadowpw_days(const char *s, long *d); +errno_t ads_pwdlastset_to_shadowpw_days(const char *s, long *d); errno_t get_sysdb_attr_name(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 32dc344..fdd5b7a 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -115,6 +115,7 @@ struct sdap_ppolicy_data { }; #define SYSDB_SHADOWPW_LASTCHANGE "shadowLastChange" +#define SYSDB_SHADOWPW_ADS_LASTCHANGE "pwdLastSet" #define SYSDB_SHADOWPW_MIN "shadowMin" #define SYSDB_SHADOWPW_MAX "shadowMax" #define SYSDB_SHADOWPW_WARNING "shadowWarning" -- 1.7.4.4 _______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel