summaryrefslogtreecommitdiffstats
path: root/src/providers/ldap/sdap_access.c
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-12-21 13:30:33 +0100
committerStephen Gallagher <sgallagh@redhat.com>2011-01-19 09:53:20 -0500
commit22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18 (patch)
treefb69e82eea580199f7919ecf02a83b3339b8dbcc /src/providers/ldap/sdap_access.c
parent5352c9b3609bca63814f9f6f03dbbbadf6c6333a (diff)
downloadsssd-22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18.tar.gz
sssd-22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18.tar.xz
sssd-22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18.zip
Add LDAP expire policy based on AD attributes
The second bit of userAccountControl is used to determine if the account is enabled or disabled. accountExpires is checked to see if the account is expired.
Diffstat (limited to 'src/providers/ldap/sdap_access.c')
-rw-r--r--src/providers/ldap/sdap_access.c85
1 files changed, 85 insertions, 0 deletions
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));