diff options
| -rw-r--r-- | source4/dsdb/samdb/ldb_modules/acl.c | 25 | ||||
| -rw-r--r-- | source4/dsdb/samdb/ldb_modules/password_hash.c | 24 | ||||
| -rw-r--r-- | source4/dsdb/samdb/ldb_modules/util.c | 20 | ||||
| -rw-r--r-- | source4/dsdb/samdb/ldb_modules/wscript_build | 2 | 
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'  	)  | 
