diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config/SSSDConfig.py | 2 | ||||
-rw-r--r-- | src/config/etc/sssd.api.d/sssd-ldap.conf | 2 | ||||
-rw-r--r-- | src/man/sssd-ldap.5.xml | 35 | ||||
-rw-r--r-- | src/providers/ipa/ipa_common.c | 4 | ||||
-rw-r--r-- | src/providers/ldap/ldap_common.c | 8 | ||||
-rw-r--r-- | src/providers/ldap/ldap_init.c | 3 | ||||
-rw-r--r-- | src/providers/ldap/sdap.h | 5 | ||||
-rw-r--r-- | src/providers/ldap/sdap_access.c | 85 | ||||
-rw-r--r-- | src/providers/ldap/sdap_access.h | 1 |
9 files changed, 141 insertions, 4 deletions
diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py index b3861a55..d84509c1 100644 --- a/src/config/SSSDConfig.py +++ b/src/config/SSSDConfig.py @@ -172,6 +172,8 @@ option_strings = { 'ldap_user_krb_last_pwd_change' : _('krbLastPwdChange attribute'), 'ldap_user_krb_password_expiration' : _('krbPasswordExpiration attribute'), 'ldap_pwd_attribute' : _('Attribute indicating that server side password policies are active'), + 'ldap_user_ad_account_expires' : _('accountExpires attribute of AD'), + 'ldap_user_ad_user_account_control' : _('userAccountControl attribute of AD'), 'ldap_group_search_base' : _('Base DN for group lookups'), # not used # 'ldap_group_search_scope' : _('Scope of group lookups'), diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf index 8aaecd5d..06443831 100644 --- a/src/config/etc/sssd.api.d/sssd-ldap.conf +++ b/src/config/etc/sssd.api.d/sssd-ldap.conf @@ -58,6 +58,8 @@ ldap_user_krb_last_pwd_change = str, None, false ldap_user_krb_password_expiration = str, None, false ldap_user_authorized_service = str, None, false ldap_pwd_attribute = str, None, false +ldap_user_ad_account_expires = str, None, false +ldap_user_ad_user_account_control = str, None, false ldap_group_search_base = str, None, false ldap_group_search_scope = str, None, false ldap_group_search_filter = str, None, false diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index 175ec356..65c679d6 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -436,6 +436,34 @@ </varlistentry> <varlistentry> + <term>ldap_user_ad_account_expires (string)</term> + <listitem> + <para> + When using ldap_account_expire_policy=ad, this + parameter contains the name of an LDAP attribute + storing the expiration time of the account. + </para> + <para> + Default: accountExpires + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>ldap_user_ad_user_account_control (string)</term> + <listitem> + <para> + When using ldap_account_expire_policy=ad, this + parameter contains the name of an LDAP attribute + storing the user account control bit field. + </para> + <para> + Default: userAccountControl + </para> + </listitem> + </varlistentry> + + <varlistentry> <term>ldap_user_principal (string)</term> <listitem> <para> @@ -1128,6 +1156,13 @@ ldap_access_filter = memberOf=cn=allowedusers,ou=Groups,dc=example,dc=com is expired. </para> <para> + <emphasis>ad</emphasis>: use the value of the 32bit + field ldap_user_ad_user_account_control and allow + access if the second bit is not set. If the + attribute is missing access is granted. Also the + expiration time of the account is checked. + </para> + <para> Default: Empty </para> </listitem> diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index 4c96babc..fe125773 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -115,7 +115,9 @@ struct sdap_attr_map ipa_user_map[] = { { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL }, { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL }, { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }, - { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL } + { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL }, + { "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL}, + { "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL} }; struct sdap_attr_map ipa_group_map[] = { diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c index 6daf2c9f..e98e718b 100644 --- a/src/providers/ldap/ldap_common.c +++ b/src/providers/ldap/ldap_common.c @@ -121,7 +121,9 @@ struct sdap_attr_map rfc2307_user_map[] = { { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL }, { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL }, { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }, - { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL } + { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL }, + { "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL}, + { "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL} }; struct sdap_attr_map rfc2307_group_map[] = { @@ -161,7 +163,9 @@ struct sdap_attr_map rfc2307bis_user_map[] = { { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL }, { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL }, { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }, - { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL } + { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL }, + { "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL}, + { "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL} }; struct sdap_attr_map rfc2307bis_group_map[] = { diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c index d5dad360..61f92333 100644 --- a/src/providers/ldap/ldap_init.c +++ b/src/providers/ldap/ldap_init.c @@ -345,7 +345,8 @@ int sssm_ldap_access_init(struct be_ctx *bectx, "but no ldap_account_expire_policy configured. " "All domain users will be denied access.\n")); } else { - if (strcasecmp(dummy, LDAP_ACCOUNT_EXPIRE_SHADOW) != 0) { + if (strcasecmp(dummy, LDAP_ACCOUNT_EXPIRE_SHADOW) != 0 && + strcasecmp(dummy, LDAP_ACCOUNT_EXPIRE_AD) != 0) { DEBUG(1, ("Unsupported LDAP account expire policy [%s].\n", dummy)); ret = EINVAL; diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 9ef9b70c..57f849a1 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -127,6 +127,9 @@ struct sdap_ppolicy_data { #define SYSDB_PWD_ATTRIBUTE "pwdAttribute" +#define SYSDB_AD_ACCOUNT_EXPIRES "adAccountExpires" +#define SYSDB_AD_USER_ACCOUNT_CONTROL "adUserAccountControl" + #define SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS "namingContexts" #define SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT "defaultNamingContext" @@ -231,6 +234,8 @@ enum sdap_user_attrs { SDAP_AT_KP_EXPIRATION, SDAP_AT_PWD_ATTRIBUTE, SDAP_AT_AUTH_SVC, + SDAP_AT_AD_ACCOUNT_EXPIRES, + SDAP_AT_AD_USER_ACCOUNT_CONTROL, SDAP_OPTS_USER /* attrs counter */ }; diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c index df433b69..a3c560d4 100644 --- a/src/providers/ldap/sdap_access.c +++ b/src/providers/ldap/sdap_access.c @@ -340,6 +340,84 @@ static errno_t sdap_account_expired_shadow(struct pam_data *pd, return EOK; } +#define UAC_ACCOUNTDISABLE 0x00000002 +#define AD_NEVER_EXP 0x7fffffffffffffffLL +#define AD_TO_UNIX_TIME_CONST 11644473600LL +#define AD_DISABLE_MESSAGE "The user account is disabled on the AD server" +#define AD_EXPIRED_MESSAGE "The user account is expired on the AD server" + +static bool ad_account_expired(uint64_t expiration_time) +{ + time_t now; + int err; + uint64_t nt_now; + + if (expiration_time == 0 || expiration_time == AD_NEVER_EXP) { + return false; + } + + now = time(NULL); + if (now == ((time_t) -1)) { + err = errno; + DEBUG(1, ("time failed [%d][%s].\n", err, strerror(err))); + return true; + } + + /* NT timestamps start at 1601-01-01 and use a 100ns base */ + nt_now = (now + AD_TO_UNIX_TIME_CONST) * 1000 * 1000 * 10; + + if (nt_now > expiration_time) { + return true; + } + + return false; +} + +static errno_t sdap_account_expired_ad(struct pam_data *pd, + struct ldb_message *user_entry, + int *pam_status) +{ + uint32_t uac; + uint64_t expiration_time; + int ret; + + DEBUG(6, ("Performing AD access check for user [%s]\n", pd->user)); + + uac = ldb_msg_find_attr_as_uint(user_entry, SYSDB_AD_USER_ACCOUNT_CONTROL, + 0); + DEBUG(9, ("User account control for user [%s] is [%X].\n", + pd->user, uac)); + + expiration_time = ldb_msg_find_attr_as_uint64(user_entry, + SYSDB_AD_ACCOUNT_EXPIRES, 0); + DEBUG(9, ("Expiration time for user [%s] is [%lld].\n", + pd->user, expiration_time)); + + if (uac & UAC_ACCOUNTDISABLE) { + *pam_status = PAM_PERM_DENIED; + + ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, + sizeof(AD_DISABLE_MESSAGE), + (const uint8_t *) AD_DISABLE_MESSAGE); + if (ret != EOK) { + DEBUG(1, ("pam_add_response failed.\n")); + } + } else if (ad_account_expired(expiration_time)) { + *pam_status = PAM_ACCT_EXPIRED; + + ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, + sizeof(AD_EXPIRED_MESSAGE), + (const uint8_t *) AD_EXPIRED_MESSAGE); + if (ret != EOK) { + DEBUG(1, ("pam_add_response failed.\n")); + } + } else { + *pam_status = PAM_SUCCESS; + } + + return EOK; +} + struct sdap_account_expired_req_ctx { int pam_status; }; @@ -379,6 +457,13 @@ static struct tevent_req *sdap_account_expired_send(TALLOC_CTX *mem_ctx, DEBUG(1, ("sdap_account_expired_shadow failed.\n")); goto done; } + } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_AD) == 0) { + ret = sdap_account_expired_ad(pd, user_entry, + &state->pam_status); + if (ret != EOK) { + DEBUG(1, ("sdap_account_expired_ad failed.\n")); + goto done; + } } else { DEBUG(1, ("Unsupported LDAP account expire policy [%s]. " "Access denied.\n", expire)); diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h index 66193a6d..28c857f6 100644 --- a/src/providers/ldap/sdap_access.h +++ b/src/providers/ldap/sdap_access.h @@ -34,6 +34,7 @@ #define LDAP_ACCESS_SERVICE_NAME "authorized_service" #define LDAP_ACCOUNT_EXPIRE_SHADOW "shadow" +#define LDAP_ACCOUNT_EXPIRE_AD "ad" enum ldap_access_rule { LDAP_ACCESS_EMPTY = -1, |