From 7f171a9e0f9b5945bd16a1330ba0908090659030 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 9 Nov 2010 14:39:30 +0100 Subject: s4:password_hash and acl LDB modules - handle the "userPassword" attribute according to the "dSHeuristics" --- source4/dsdb/samdb/ldb_modules/acl.c | 25 ++++++++++++++++++++++--- source4/dsdb/samdb/ldb_modules/password_hash.c | 24 ++++++++++++++++-------- source4/dsdb/samdb/ldb_modules/util.c | 20 ++++++++++++++++++++ source4/dsdb/samdb/ldb_modules/wscript_build | 2 +- 4 files changed, 59 insertions(+), 12 deletions(-) (limited to 'source4/dsdb') 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' ) -- cgit