summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/acl.c25
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c24
-rw-r--r--source4/dsdb/samdb/ldb_modules/util.c20
-rw-r--r--source4/dsdb/samdb/ldb_modules/wscript_build2
4 files changed, 59 insertions, 12 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index 3cf768e522..b6635b1a20 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -61,6 +61,7 @@ struct acl_context {
bool allowedChildClasses;
bool allowedChildClassesEffective;
bool sDRightsEffective;
+ bool userPassword;
const char * const *attrs;
struct dsdb_schema *schema;
};
@@ -542,7 +543,8 @@ static int acl_check_password_rights(TALLOC_CTX *mem_ctx,
struct ldb_request *req,
struct security_descriptor *sd,
struct dom_sid *sid,
- const struct GUID *oc_guid)
+ const struct GUID *oc_guid,
+ bool userPassword)
{
int ret = LDB_SUCCESS;
unsigned int del_attr_cnt = 0, add_attr_cnt = 0, rep_attr_cnt = 0;
@@ -557,6 +559,10 @@ static int acl_check_password_rights(TALLOC_CTX *mem_ctx,
return ldb_module_oom(module);
}
for (l = passwordAttrs; *l != NULL; l++) {
+ if ((!userPassword) && (ldb_attr_cmp(*l, "userPassword") == 0)) {
+ continue;
+ }
+
while ((el = ldb_msg_find_element(msg, *l)) != NULL) {
if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
++del_attr_cnt;
@@ -632,6 +638,7 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req)
struct security_descriptor *sd;
struct dom_sid *sid = NULL;
struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID);
+ bool userPassword = dsdb_user_password_support(module, req);
TALLOC_CTX *tmp_ctx = talloc_new(req);
static const char *acl_attrs[] = {
"nTSecurityDescriptor",
@@ -732,14 +739,15 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req)
continue;
}
else if (ldb_attr_cmp("unicodePwd", req->op.mod.message->elements[i].name) == 0 ||
- ldb_attr_cmp("userPassword", req->op.mod.message->elements[i].name) == 0 ||
+ (userPassword && ldb_attr_cmp("userPassword", req->op.mod.message->elements[i].name) == 0) ||
ldb_attr_cmp("clearTextPassword", req->op.mod.message->elements[i].name) == 0) {
ret = acl_check_password_rights(tmp_ctx,
module,
req,
sd,
sid,
- guid);
+ guid,
+ userPassword);
if (ret != LDB_SUCCESS) {
goto fail;
}
@@ -1074,6 +1082,11 @@ static int acl_search_callback(struct ldb_request *req, struct ldb_reply *ares)
if (data && data->password_attrs) {
if (!ac->am_system) {
for (i = 0; data->password_attrs[i]; i++) {
+ if ((!ac->userPassword) &&
+ (ldb_attr_cmp(data->password_attrs[i],
+ "userPassword") == 0))
+ continue;
+
ldb_msg_remove_attr(ares->message, data->password_attrs[i]);
}
}
@@ -1115,6 +1128,7 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req)
ac->allowedChildClasses = ldb_attr_in_list(req->op.search.attrs, "allowedChildClasses");
ac->allowedChildClassesEffective = ldb_attr_in_list(req->op.search.attrs, "allowedChildClassesEffective");
ac->sDRightsEffective = ldb_attr_in_list(req->op.search.attrs, "sDRightsEffective");
+ ac->userPassword = dsdb_user_password_support(module, ac);
ac->schema = dsdb_get_schema(ldb, ac);
/* replace any attributes in the parse tree that are private,
@@ -1125,6 +1139,11 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req)
/* remove password attributes */
if (data && data->password_attrs) {
for (i = 0; data->password_attrs[i]; i++) {
+ if ((!ac->userPassword) &&
+ (ldb_attr_cmp(data->password_attrs[i],
+ "userPassword") == 0))
+ continue;
+
ldb_parse_tree_attr_replace(req->op.search.tree,
data->password_attrs[i],
"kludgeACLredactedattribute");
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 2e89d7f821..9b6cf8cd35 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -33,19 +33,16 @@
*/
#include "includes.h"
-#include "libcli/ldap/ldap_ndr.h"
#include "ldb_module.h"
-#include "librpc/gen_ndr/misc.h"
-#include "librpc/gen_ndr/samr.h"
+#include "auth/session.h"
#include "libcli/auth/libcli_auth.h"
#include "libcli/security/security.h"
+#include "libcli/security/session.h"
#include "system/kerberos.h"
#include "auth/kerberos/kerberos.h"
-#include "system/time.h"
#include "dsdb/samdb/samdb.h"
-#include "../libds/common/flags.h"
+#include "dsdb/samdb/ldb_modules/util.h"
#include "dsdb/samdb/ldb_modules/password_modules.h"
-#include "librpc/ndr/libndr.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
#include "../lib/crypto/crypto.h"
#include "param/param.h"
@@ -2293,7 +2290,7 @@ static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
*ntAttr, *lmAttr;
int ret;
struct ldb_control *bypass = NULL;
- bool userPassword = true;
+ bool userPassword = dsdb_user_password_support(module, req);
ldb = ldb_module_get_ctx(module);
@@ -2336,6 +2333,11 @@ static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
if (userPassword) {
userPasswordAttr = ldb_msg_find_element(req->op.add.message,
"userPassword");
+ /* MS-ADTS 3.1.1.3.1.5.2 */
+ if ((userPasswordAttr != NULL) &&
+ (dsdb_functional_level(ldb) < DS_DOMAIN_FUNCTION_2003)) {
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
}
clearTextPasswordAttr = ldb_msg_find_element(req->op.add.message, "clearTextPassword");
ntAttr = ldb_msg_find_element(req->op.add.message, "unicodePwd");
@@ -2487,7 +2489,7 @@ static int password_hash_modify(struct ldb_module *module, struct ldb_request *r
struct ldb_request *down_req;
int ret;
struct ldb_control *bypass = NULL;
- bool userPassword = true;
+ bool userPassword = dsdb_user_password_support(module, req);
ldb = ldb_module_get_ctx(module);
@@ -2534,6 +2536,12 @@ static int password_hash_modify(struct ldb_module *module, struct ldb_request *r
}
if (ldb_msg_find_element(req->op.mod.message, *l) != NULL) {
+ /* MS-ADTS 3.1.1.3.1.5.2 */
+ if ((ldb_attr_cmp(*l, "userPassword") == 0) &&
+ (dsdb_functional_level(ldb) < DS_DOMAIN_FUNCTION_2003)) {
+ return LDB_ERR_CONSTRAINT_VIOLATION;
+ }
+
++attr_cnt;
}
}
diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c
index 123f03f15d..01d7347d3e 100644
--- a/source4/dsdb/samdb/ldb_modules/util.c
+++ b/source4/dsdb/samdb/ldb_modules/util.c
@@ -1099,6 +1099,26 @@ bool dsdb_block_anonymous_ops(struct ldb_module *module,
return result;
}
+bool dsdb_user_password_support(struct ldb_module *module,
+ TALLOC_CTX *mem_ctx)
+{
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ bool result;
+ const struct ldb_val *hr_val = dsdb_module_find_dsheuristics(module,
+ tmp_ctx);
+ if (hr_val == NULL || hr_val->length < DS_HR_USER_PASSWORD_SUPPORT) {
+ result = false;
+ } else if ((hr_val->data[DS_HR_USER_PASSWORD_SUPPORT -1] == '2') ||
+ (hr_val->data[DS_HR_USER_PASSWORD_SUPPORT -1] == '0')) {
+ result = false;
+ } else {
+ result = true;
+ }
+
+ talloc_free(tmp_ctx);
+ return result;
+}
+
/*
show the chain of requests, useful for debugging async requests
*/
diff --git a/source4/dsdb/samdb/ldb_modules/wscript_build b/source4/dsdb/samdb/ldb_modules/wscript_build
index 50ec9f25bb..4cf1cfe19a 100644
--- a/source4/dsdb/samdb/ldb_modules/wscript_build
+++ b/source4/dsdb/samdb/ldb_modules/wscript_build
@@ -160,7 +160,7 @@ bld.SAMBA_MODULE('ldb_password_hash',
init_function='ldb_password_hash_module_init',
module_init_name='ldb_init_module',
internal_module=False,
- deps='talloc events samdb LIBCLI_AUTH NDR_DRSBLOBS authkrb5 hdb krb5 com_err'
+ deps='talloc events samdb LIBCLI_AUTH NDR_DRSBLOBS authkrb5 krb5 DSDB_MODULE_HELPERS'
)