⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 password_hash.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
static int password_hash_modify(struct ldb_module *module, struct ldb_request *req){	struct ldb_handle *h;	struct ph_context *ac;	struct ldb_message_element *sambaAttr;	struct ldb_message_element *ntAttr;	struct ldb_message_element *lmAttr;	struct ldb_message *msg;	ldb_debug(module->ldb, LDB_DEBUG_TRACE, "password_hash_modify\n");	if (ldb_dn_is_special(req->op.mod.message->dn)) { /* do not manipulate our control entries */		return ldb_next_request(module, req);	}		/* If the caller is manipulating the local passwords directly, let them pass */	if (ldb_dn_compare_base(ldb_dn_new(req, module->ldb, LOCAL_BASE),				req->op.mod.message->dn) == 0) {		return ldb_next_request(module, req);	}	/* nobody must touch password Histories */	if (ldb_msg_find_element(req->op.add.message, "ntPwdHistory")) {		return LDB_ERR_UNWILLING_TO_PERFORM;	}	if (ldb_msg_find_element(req->op.add.message, "lmPwdHistory")) {		return LDB_ERR_UNWILLING_TO_PERFORM;	}	if (ldb_msg_find_element(req->op.add.message, "supplementalCredentials")) {		return LDB_ERR_UNWILLING_TO_PERFORM;	}	sambaAttr = ldb_msg_find_element(req->op.mod.message, "sambaPassword");	ntAttr = ldb_msg_find_element(req->op.mod.message, "unicodePwd");	lmAttr = ldb_msg_find_element(req->op.mod.message, "dBCSPwd");	/* If no part of this touches the sambaPassword OR unicodePwd and/or dBCSPwd, then we don't	 * need to make any changes.  For password changes/set there should	 * be a 'delete' or a 'modify' on this attribute. */	if ((!sambaAttr) && (!ntAttr) && (!lmAttr)) {		return ldb_next_request(module, req);	}	/* check passwords are single valued here */	/* TODO: remove this when passwords will be single valued in schema */	if (sambaAttr && (sambaAttr->num_values > 1)) {		return LDB_ERR_CONSTRAINT_VIOLATION;	}	if (ntAttr && (ntAttr->num_values > 1)) {		return LDB_ERR_CONSTRAINT_VIOLATION;	}	if (lmAttr && (lmAttr->num_values > 1)) {		return LDB_ERR_CONSTRAINT_VIOLATION;	}	h = ph_init_handle(req, module, PH_MOD);	if (!h) {		return LDB_ERR_OPERATIONS_ERROR;	}	ac = talloc_get_type(h->private_data, struct ph_context);	/* return or own handle to deal with this call */	req->handle = h;	/* prepare the first operation */	ac->down_req = talloc_zero(ac, struct ldb_request);	if (ac->down_req == NULL) {		ldb_set_errstring(module->ldb, "Out of memory!");		return LDB_ERR_OPERATIONS_ERROR;	}	*(ac->down_req) = *req; /* copy the request */	/* use a new message structure so that we can modify it */	ac->down_req->op.mod.message = msg = ldb_msg_copy_shallow(ac->down_req, req->op.mod.message);	/* - remove any imodification to the password from the first commit	 *   we will make the real modification later */	if (sambaAttr) ldb_msg_remove_attr(msg, "sambaPassword");	if (ntAttr) ldb_msg_remove_attr(msg, "unicodePwd");	if (lmAttr) ldb_msg_remove_attr(msg, "dBCSPwd");	/* if there was nothing else to be modify skip to next step */	if (msg->num_elements == 0) {		talloc_free(ac->down_req);		ac->down_req = NULL;		return password_hash_mod_search_self(h);	}		ac->down_req->context = NULL;	ac->down_req->callback = NULL;	ac->step = PH_MOD_DO_REQ;	ldb_set_timeout_from_prev_req(module->ldb, req, ac->down_req);	return ldb_next_request(module, ac->down_req);}static int get_self_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares){	struct ph_context *ac;	ac = talloc_get_type(context, struct ph_context);	/* we are interested only in the single reply (base search) we receive here */	if (ares->type == LDB_REPLY_ENTRY) {		if (ac->search_res != NULL) {			ldb_set_errstring(ldb, "Too many results");			talloc_free(ares);			return LDB_ERR_OPERATIONS_ERROR;		}		/* if it is not an entry of type person this is an error */		/* TODO: remove this when sambaPassword will be in schema */		if (!ldb_msg_check_string_attribute(ares->message, "objectClass", "person")) {			ldb_set_errstring(ldb, "Object class violation");			talloc_free(ares);			return LDB_ERR_OBJECT_CLASS_VIOLATION;		}		ac->search_res = talloc_steal(ac, ares);	} else {		talloc_free(ares);	}	return LDB_SUCCESS;}static int password_hash_mod_search_self(struct ldb_handle *h) {	struct ph_context *ac;	static const char * const attrs[] = { "userAccountControl", "lmPwdHistory", 					      "ntPwdHistory", 					      "objectSid", "msDS-KeyVersionNumber", 					      "objectClass", "userPrincipalName",					      "sAMAccountName", 					      "dBCSPwd", "unicodePwd",					      "supplementalCredentials",					      NULL };	ac = talloc_get_type(h->private_data, struct ph_context);	/* prepare the search operation */	ac->search_req = talloc_zero(ac, struct ldb_request);	if (ac->search_req == NULL) {		ldb_debug(ac->module->ldb, LDB_DEBUG_ERROR, "Out of Memory!\n");		return LDB_ERR_OPERATIONS_ERROR;	}	ac->search_req->operation = LDB_SEARCH;	ac->search_req->op.search.base = ac->orig_req->op.mod.message->dn;	ac->search_req->op.search.scope = LDB_SCOPE_BASE;	ac->search_req->op.search.tree = ldb_parse_tree(ac->search_req, NULL);	if (ac->search_req->op.search.tree == NULL) {		ldb_set_errstring(ac->module->ldb, "Invalid search filter");		return LDB_ERR_OPERATIONS_ERROR;	}	ac->search_req->op.search.attrs = attrs;	ac->search_req->controls = NULL;	ac->search_req->context = ac;	ac->search_req->callback = get_self_callback;	ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->search_req);	ac->step = PH_MOD_SEARCH_SELF;	return ldb_next_request(ac->module, ac->search_req);}static int password_hash_mod_search_dom(struct ldb_handle *h) {	struct ph_context *ac;	int ret;	ac = talloc_get_type(h->private_data, struct ph_context);	/* get object domain sid */	ac->domain_sid = samdb_result_sid_prefix(ac, ac->search_res->message, "objectSid");	if (ac->domain_sid == NULL) {		ldb_debug(ac->module->ldb, LDB_DEBUG_ERROR, "can't handle entry with missing objectSid!\n");		return LDB_ERR_OPERATIONS_ERROR;	}	/* get user domain data */	ret = build_domain_data_request(ac);	if (ret != LDB_SUCCESS) {		return ret;	}	ac->step = PH_MOD_SEARCH_DOM;	return ldb_next_request(ac->module, ac->dom_req);}static int password_hash_mod_do_mod(struct ldb_handle *h) {	struct ph_context *ac;	struct domain_data *domain;	struct smb_krb5_context *smb_krb5_context;	struct ldb_message *msg;	struct ldb_message *orig_msg;	struct ldb_message *searched_msg;	struct setup_password_fields_io io;	int ret;	ac = talloc_get_type(h->private_data, struct ph_context);	domain = get_domain_data(ac->module, ac, ac->dom_res);	if (domain == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	ac->mod_req = talloc(ac, struct ldb_request);	if (ac->mod_req == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	*(ac->mod_req) = *(ac->orig_req);		/* use a new message structure so that we can modify it */	ac->mod_req->op.mod.message = msg = ldb_msg_new(ac->mod_req);	if (msg == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	/* modify dn */	msg->dn = ac->orig_req->op.mod.message->dn;	/* Some operations below require kerberos contexts */	if (smb_krb5_init_context(ac->mod_req, 				  ldb_get_opaque(h->module->ldb, "EventContext"), 				  (struct loadparm_context *)ldb_get_opaque(h->module->ldb, "loadparm"), 				  &smb_krb5_context) != 0) {		return LDB_ERR_OPERATIONS_ERROR;	}	orig_msg	= discard_const(ac->orig_req->op.mod.message);	searched_msg	= ac->search_res->message;	ZERO_STRUCT(io);	io.ac				= ac;	io.domain			= domain;	io.smb_krb5_context		= smb_krb5_context;	io.u.user_account_control	= samdb_result_uint(searched_msg, "userAccountControl", 0);	io.u.sAMAccountName		= samdb_result_string(searched_msg, "samAccountName", NULL);	io.u.user_principal_name	= samdb_result_string(searched_msg, "userPrincipalName", NULL);	io.u.is_computer		= ldb_msg_check_string_attribute(searched_msg, "objectClass", "computer");	io.n.cleartext			= samdb_result_string(orig_msg, "sambaPassword", NULL);	io.n.nt_hash			= samdb_result_hash(io.ac, orig_msg, "unicodePwd");	io.n.lm_hash			= samdb_result_hash(io.ac, orig_msg, "dBCSPwd");	io.o.kvno			= samdb_result_uint(searched_msg, "msDs-KeyVersionNumber", 0);	io.o.nt_history_len		= samdb_result_hashes(io.ac, searched_msg, "ntPwdHistory", &io.o.nt_history);	io.o.lm_history_len		= samdb_result_hashes(io.ac, searched_msg, "lmPwdHistory", &io.o.lm_history);	io.o.supplemental		= ldb_msg_find_ldb_val(searched_msg, "supplementalCredentials");	ret = setup_password_fields(&io);	if (ret != LDB_SUCCESS) {		return ret;	}	/* make sure we replace all the old attributes */	ret = ldb_msg_add_empty(msg, "unicodePwd", LDB_FLAG_MOD_REPLACE, NULL);	ret = ldb_msg_add_empty(msg, "dBCSPwd", LDB_FLAG_MOD_REPLACE, NULL);	ret = ldb_msg_add_empty(msg, "ntPwdHistory", LDB_FLAG_MOD_REPLACE, NULL);	ret = ldb_msg_add_empty(msg, "lmPwdHistory", LDB_FLAG_MOD_REPLACE, NULL);	ret = ldb_msg_add_empty(msg, "supplementalCredentials", LDB_FLAG_MOD_REPLACE, NULL);	ret = ldb_msg_add_empty(msg, "pwdLastSet", LDB_FLAG_MOD_REPLACE, NULL);	ret = ldb_msg_add_empty(msg, "msDs-KeyVersionNumber", LDB_FLAG_MOD_REPLACE, NULL);	if (io.g.nt_hash) {		ret = samdb_msg_add_hash(ac->module->ldb, ac, msg,					 "unicodePwd", io.g.nt_hash);		if (ret != LDB_SUCCESS) {			return ret;		}	}	if (io.g.lm_hash) {		ret = samdb_msg_add_hash(ac->module->ldb, ac, msg,					 "dBCSPwd", io.g.lm_hash);		if (ret != LDB_SUCCESS) {			return ret;		}	}	if (io.g.nt_history_len > 0) {		ret = samdb_msg_add_hashes(ac, msg,					   "ntPwdHistory",					   io.g.nt_history,					   io.g.nt_history_len);		if (ret != LDB_SUCCESS) {			return ret;		}	}	if (io.g.lm_history_len > 0) {		ret = samdb_msg_add_hashes(ac, msg,					   "lmPwdHistory",					   io.g.lm_history,					   io.g.lm_history_len);		if (ret != LDB_SUCCESS) {			return ret;		}	}	if (io.g.supplemental.length > 0) {		ret = ldb_msg_add_value(msg, "supplementalCredentials",					&io.g.supplemental, NULL);		if (ret != LDB_SUCCESS) {			return ret;		}	}	ret = samdb_msg_add_uint64(ac->module->ldb, ac, msg,				   "pwdLastSet",				   io.g.last_set);	if (ret != LDB_SUCCESS) {		return ret;	}	ret = samdb_msg_add_uint(ac->module->ldb, ac, msg,				 "msDs-KeyVersionNumber",				 io.g.kvno);	if (ret != LDB_SUCCESS) {		return ret;	}	h->state = LDB_ASYNC_INIT;	h->status = LDB_SUCCESS;	ac->step = PH_MOD_DO_MOD;	ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->mod_req);	/* perform the search */	return ldb_next_request(ac->module, ac->mod_req);}static int ph_wait(struct ldb_handle *handle) {	struct ph_context *ac;	int ret;    	if (!handle || !handle->private_data) {		return LDB_ERR_OPERATIONS_ERROR;	}	if (handle->state == LDB_ASYNC_DONE) {		return handle->status;	}	handle->state = LDB_ASYNC_PENDING;	handle->status = LDB_SUCCESS;	ac = talloc_get_type(handle->private_data, struct ph_context);	switch (ac->step) {	case PH_ADD_SEARCH_DOM:		ret = ldb_wait(ac->dom_req->handle, LDB_WAIT_NONE);		if (ret != LDB_SUCCESS) {			handle->status = ret;			goto done;		}		if (ac->dom_req->handle->status != LDB_SUCCESS) {			handle->status = ac->dom_req->handle->status;			goto done;		}		if (ac->dom_req->handle->state != LDB_ASYNC_DONE) {			return LDB_SUCCESS;		}		/* domain search done, go on */		return password_hash_add_do_add(handle);	case PH_ADD_DO_ADD:		ret = ldb_wait(ac->down_req->handle, LDB_WAIT_NONE);		if (ret != LDB_SUCCESS) {			handle->status = ret;			goto done;		}		if (ac->down_req->handle->status != LDB_SUCCESS) {			handle->status = ac->down_req->handle->status;			goto done;		}		if (ac->down_req->handle->state != LDB_ASYNC_DONE) {			return LDB_SUCCESS;		}		break;			case PH_MOD_DO_REQ:		ret = ldb_wait(ac->down_req->handle, LDB_WAIT_NONE);		if (ret != LDB_SUCCESS) {			handle->status = ret;			goto done;		}		if (ac->down_req->handle->status != LDB_SUCCESS) {			handle->status = ac->down_req->handle->status;			goto done;		}		if (ac->down_req->handle->state != LDB_ASYNC_DONE) {			return LDB_SUCCESS;		}		/* non-password mods done, go on */		return password_hash_mod_search_self(handle);			case PH_MOD_SEARCH_SELF:		ret = ldb_wait(ac->search_req->handle, LDB_WAIT_NONE);		if (ret != LDB_SUCCESS) {			handle->status = ret;			goto done;		}		if (ac->search_req->handle->status != LDB_SUCCESS) {			handle->status = ac->search_req->handle->status;			goto done;		}		if (ac->search_req->handle->state != LDB_ASYNC_DONE) {			return LDB_SUCCESS;		}		if (ac->search_res == NULL) {			return LDB_ERR_NO_SUCH_OBJECT;		}		/* self search done, go on */		return password_hash_mod_search_dom(handle);			case PH_MOD_SEARCH_DOM:		ret = ldb_wait(ac->dom_req->handle, LDB_WAIT_NONE);		if (ret != LDB_SUCCESS) {			handle->status = ret;			goto done;		}		if (ac->dom_req->handle->status != LDB_SUCCESS) {			handle->status = ac->dom_req->handle->status;			goto done;		}		if (ac->dom_req->handle->state != LDB_ASYNC_DONE) {			return LDB_SUCCESS;		}		/* domain search done, go on */		return password_hash_mod_do_mod(handle);	case PH_MOD_DO_MOD:		ret = ldb_wait(ac->mod_req->handle, LDB_WAIT_NONE);		if (ret != LDB_SUCCESS) {			handle->status = ret;			goto done;		}		if (ac->mod_req->handle->status != LDB_SUCCESS) {			handle->status = ac->mod_req->handle->status;			goto done;		}		if (ac->mod_req->handle->state != LDB_ASYNC_DONE) {			return LDB_SUCCESS;		}		break;			default:		ret = LDB_ERR_OPERATIONS_ERROR;		goto done;	}	ret = LDB_SUCCESS;done:	handle->state = LDB_ASYNC_DONE;	return ret;}static int ph_wait_all(struct ldb_handle *handle) {	int ret;	while (handle->state != LDB_ASYNC_DONE) {		ret = ph_wait(handle);		if (ret != LDB_SUCCESS) {			return ret;		}	}	return handle->status;}static int password_hash_wait(struct ldb_handle *handle, enum ldb_wait_type type){	if (type == LDB_WAIT_ALL) {		return ph_wait_all(handle);	} else {		return ph_wait(handle);	}}_PUBLIC_ const struct ldb_module_ops ldb_password_hash_module_ops = {	.name          = "password_hash",	.add           = password_hash_add,	.modify        = password_hash_modify,	.wait          = password_hash_wait};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -