diff options
author | Matthias Dieter Wallnöfer <mdw@samba.org> | 2013-06-08 23:45:43 +0200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2013-06-10 07:32:35 +0200 |
commit | 7f760ed84b4b34937b3a65577f971cc95f452e0f (patch) | |
tree | 623ad74184748df921f5e05e2e0786b4c2e52b8b /source4/dsdb/samdb | |
parent | 2f7d9fddf7102d76b182fbd50ccaf18cb5a10014 (diff) | |
download | samba-7f760ed84b4b34937b3a65577f971cc95f452e0f.tar.gz samba-7f760ed84b4b34937b3a65577f971cc95f452e0f.tar.bz2 samba-7f760ed84b4b34937b3a65577f971cc95f452e0f.zip |
s4:samldb LDB module - MS-SAMR 3.1.1.8.10 "userAccountControl"
"UF_LOCKOUT" and "UF_PASSWORD_EXPIRED" are never stored but rather are
used for special semantics.
"UF_LOCKOUT" performs an account lockout and "UF_PASSWORD_EXPIRED"
forces password expiration.
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Mon Jun 10 07:32:35 CEST 2013 on sn-devel-104
Diffstat (limited to 'source4/dsdb/samdb')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samldb.c | 82 |
1 files changed, 66 insertions, 16 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 5bb0b61d61..603370fd62 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -1049,6 +1049,18 @@ static int samldb_objectclass_trigger(struct samldb_ctx *ac) uac_generated = true; } + /* + * As per MS-SAMR 3.1.1.8.10 these flags have not to be set + */ + if ((user_account_control & UF_LOCKOUT) != 0) { + user_account_control &= ~UF_LOCKOUT; + uac_generated = true; + } + if ((user_account_control & UF_PASSWORD_EXPIRED) != 0) { + user_account_control &= ~UF_PASSWORD_EXPIRED; + uac_generated = true; + } + /* Temporary duplicate accounts aren't allowed */ if ((user_account_control & UF_TEMP_DUPLICATE_ACCOUNT) != 0) { return LDB_ERR_OTHER; @@ -1442,9 +1454,10 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) struct ldb_message *tmp_msg; int ret; struct ldb_result *res; - const char * const attrs[] = { "userAccountControl", "objectClass", NULL }; + const char * const attrs[] = { "userAccountControl", "objectClass", + "lockoutTime", NULL }; unsigned int i; - bool is_computer = false; + bool is_computer = false, uac_generated = false; el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl", ac->req->operation); @@ -1517,8 +1530,6 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) account_type = ds_uf2atype(user_account_control); if (account_type == 0) { - char *tempstr; - /* * When there is no account type embedded in "userAccountControl" * fall back to default "UF_NORMAL_ACCOUNT". @@ -1530,18 +1541,7 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) } user_account_control |= UF_NORMAL_ACCOUNT; - - tempstr = talloc_asprintf(ac->msg, "%d", user_account_control); - if (tempstr == NULL) { - return ldb_module_oom(ac->module); - } - - /* Overwrite "userAccountControl" with "UF_NORMAL_ACCOUNT" added */ - el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl", - ac->req->operation); - el->values[0].data = (uint8_t *) tempstr; - el->values[0].length = strlen(tempstr); - + uac_generated = true; account_type = ATYPE_NORMAL_ACCOUNT; } ret = samdb_msg_add_uint(ldb, ac->msg, ac->msg, "sAMAccountType", @@ -1552,6 +1552,41 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) el = ldb_msg_find_element(ac->msg, "sAMAccountType"); el->flags = LDB_FLAG_MOD_REPLACE; + /* As per MS-SAMR 3.1.1.8.10 these flags have not to be set */ + if ((user_account_control & UF_LOCKOUT) != 0) { + /* "lockoutTime" reset as per MS-SAMR 3.1.1.8.10 */ + uint64_t lockout_time = ldb_msg_find_attr_as_uint64(res->msgs[0], + "lockoutTime", + 0); + if (lockout_time != 0) { + ldb_msg_remove_attr(ac->msg, "lockoutTime"); + ret = samdb_msg_add_uint64(ldb, ac->msg, ac->msg, + "lockoutTime", (NTTIME)0); + if (ret != LDB_SUCCESS) { + return ret; + } + el = ldb_msg_find_element(ac->msg, "lockoutTime"); + el->flags = LDB_FLAG_MOD_REPLACE; + } + + user_account_control &= ~UF_LOCKOUT; + uac_generated = true; + } + if ((user_account_control & UF_PASSWORD_EXPIRED) != 0) { + /* "pwdLastSet" reset as password expiration has been forced */ + ldb_msg_remove_attr(ac->msg, "pwdLastSet"); + ret = samdb_msg_add_uint64(ldb, ac->msg, ac->msg, "pwdLastSet", + (NTTIME)0); + if (ret != LDB_SUCCESS) { + return ret; + } + el = ldb_msg_find_element(ac->msg, "pwdLastSet"); + el->flags = LDB_FLAG_MOD_REPLACE; + + user_account_control &= ~UF_PASSWORD_EXPIRED; + uac_generated = true; + } + /* "isCriticalSystemObject" might be set/changed */ if (user_account_control & (UF_SERVER_TRUST_ACCOUNT | UF_PARTIAL_SECRETS_ACCOUNT)) { @@ -1595,6 +1630,21 @@ static int samldb_user_account_control_change(struct samldb_ctx *ac) el->flags = LDB_FLAG_MOD_REPLACE; } + /* Propagate eventual "userAccountControl" attribute changes */ + if (uac_generated) { + char *tempstr = talloc_asprintf(ac->msg, "%d", + user_account_control); + if (tempstr == NULL) { + return ldb_module_oom(ac->module); + } + + /* Overwrite "userAccountControl" correctly */ + el = dsdb_get_single_valued_attr(ac->msg, "userAccountControl", + ac->req->operation); + el->values[0].data = (uint8_t *) tempstr; + el->values[0].length = strlen(tempstr); + } + return LDB_SUCCESS; } |