summaryrefslogtreecommitdiff
path: root/src/providers/ldap
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
parent5352c9b3609bca63814f9f6f03dbbbadf6c6333a (diff)
downloadsssd-22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18.tar.gz
sssd-22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18.tar.bz2
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')
-rw-r--r--src/providers/ldap/ldap_common.c8
-rw-r--r--src/providers/ldap/ldap_init.c3
-rw-r--r--src/providers/ldap/sdap.h5
-rw-r--r--src/providers/ldap/sdap_access.c85
-rw-r--r--src/providers/ldap/sdap_access.h1
5 files changed, 99 insertions, 3 deletions
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,