diff options
Diffstat (limited to 'src/providers')
-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 |
6 files changed, 102 insertions, 4 deletions
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index 4c96babc1..fe1257737 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 6daf2c9f5..e98e718b1 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 d5dad3607..61f923333 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 9ef9b70c7..57f849a16 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 df433b69e..a3c560d44 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 66193a6dd..28c857f61 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, |