dcesrv_lsa.c

来自「samba最新软件」· C语言 代码 · 共 2,518 行 · 第 1/5 页

C
2,518
字号
	if (!NT_STATUS_IS_OK(status)) {		return status;	}	/* Ensure this handle goes away at the end of this call */	DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);	talloc_steal(mem_ctx, h);		query.in.trustdom_handle = open.out.trustdom_handle;	query.in.level = r->in.level;	status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);	if (!NT_STATUS_IS_OK(status)) {		return status;	}		r->out.info = query.out.info;	return NT_STATUS_OK;}/*  lsa_SetTrustedDomainInfoByName*/static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,					       TALLOC_CTX *mem_ctx,					       struct lsa_SetTrustedDomainInfoByName *r){	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/*    lsa_QueryTrustedDomainInfoByName*/static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,						 TALLOC_CTX *mem_ctx,						 struct lsa_QueryTrustedDomainInfoByName *r){	NTSTATUS status;	struct lsa_OpenTrustedDomainByName open;	struct lsa_QueryTrustedDomainInfo query;	struct dcesrv_handle *h;	open.in.handle = r->in.handle;	open.in.name = r->in.trusted_domain;	open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;	open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);	if (!open.out.trustdom_handle) {		return NT_STATUS_NO_MEMORY;	}	status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);	if (!NT_STATUS_IS_OK(status)) {		return status;	}		/* Ensure this handle goes away at the end of this call */	DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);	talloc_steal(mem_ctx, h);	query.in.trustdom_handle = open.out.trustdom_handle;	query.in.level = r->in.level;	status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);	if (!NT_STATUS_IS_OK(status)) {		return status;	}		r->out.info = query.out.info;	return NT_STATUS_OK;}/*  lsa_CloseTrustedDomainEx */static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,					 TALLOC_CTX *mem_ctx,					 struct lsa_CloseTrustedDomainEx *r){	/* The result of a bad hair day from an IDL programmer?  Not	 * implmented in Win2k3.  You should always just lsa_Close	 * anyway. */	return NT_STATUS_NOT_IMPLEMENTED;}/*  comparison function for sorting lsa_DomainInformation array*/static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2){	return strcasecmp_m(e1->name.string, e2->name.string);}/*   lsa_EnumTrustDom */static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,				 struct lsa_EnumTrustDom *r){	struct dcesrv_handle *policy_handle;	struct lsa_DomainInfo *entries;	struct lsa_policy_state *policy_state;	struct ldb_message **domains;	const char *attrs[] = {		"flatname", 		"securityIdentifier",		NULL	};	int count, i;	*r->out.resume_handle = 0;	r->out.domains->domains = NULL;	r->out.domains->count = 0;	DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);	policy_state = policy_handle->data;	/* search for all users in this domain. This could possibly be cached and 	   resumed based on resume_key */	count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 			     "objectclass=trustedDomain");	if (count == -1) {		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	if (count == 0 || r->in.max_size == 0) {		return NT_STATUS_OK;	}	/* convert to lsa_TrustInformation format */	entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);	if (!entries) {		return NT_STATUS_NO_MEMORY;	}	for (i=0;i<count;i++) {		entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");		entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);	}	/* sort the results by name */	qsort(entries, count, sizeof(*entries), 	      (comparison_fn_t)compare_DomainInfo);	if (*r->in.resume_handle >= count) {		*r->out.resume_handle = -1;		return NT_STATUS_NO_MORE_ENTRIES;	}	/* return the rest, limit by max_size. Note that we 	   use the w2k3 element size value of 60 */	r->out.domains->count = count - *r->in.resume_handle;	r->out.domains->count = MIN(r->out.domains->count, 				 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));	r->out.domains->domains = entries + *r->in.resume_handle;	r->out.domains->count = r->out.domains->count;	if (r->out.domains->count < count - *r->in.resume_handle) {		*r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;		return STATUS_MORE_ENTRIES;	}	return NT_STATUS_OK;}/*  comparison function for sorting lsa_DomainInformation array*/static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2){	return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);}/*   lsa_EnumTrustedDomainsEx */static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,					struct lsa_EnumTrustedDomainsEx *r){	struct dcesrv_handle *policy_handle;	struct lsa_TrustDomainInfoInfoEx *entries;	struct lsa_policy_state *policy_state;	struct ldb_message **domains;	const char *attrs[] = {		"flatname", 		"trustPartner",		"securityIdentifier",		"trustDirection",		"trustType",		"trustAttributes", 		NULL	};	NTSTATUS nt_status;	int count, i;	*r->out.resume_handle = 0;	r->out.domains->domains = NULL;	r->out.domains->count = 0;	DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);	policy_state = policy_handle->data;	/* search for all users in this domain. This could possibly be cached and 	   resumed based on resume_key */	count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 			     "objectclass=trustedDomain");	if (count == -1) {		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	if (count == 0 || r->in.max_size == 0) {		return NT_STATUS_OK;	}	/* convert to lsa_DomainInformation format */	entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);	if (!entries) {		return NT_STATUS_NO_MEMORY;	}	for (i=0;i<count;i++) {		nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);		if (!NT_STATUS_IS_OK(nt_status)) {			return nt_status;		}	}	/* sort the results by name */	qsort(entries, count, sizeof(*entries), 	      (comparison_fn_t)compare_TrustDomainInfoInfoEx);	if (*r->in.resume_handle >= count) {		*r->out.resume_handle = -1;		return NT_STATUS_NO_MORE_ENTRIES;	}	/* return the rest, limit by max_size. Note that we 	   use the w2k3 element size value of 60 */	r->out.domains->count = count - *r->in.resume_handle;	r->out.domains->count = MIN(r->out.domains->count, 				 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));	r->out.domains->domains = entries + *r->in.resume_handle;	r->out.domains->count = r->out.domains->count;	if (r->out.domains->count < count - *r->in.resume_handle) {		*r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;		return STATUS_MORE_ENTRIES;	}	return NT_STATUS_OK;}/*   lsa_OpenAccount */static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,				struct lsa_OpenAccount *r){	struct dcesrv_handle *h, *ah;	struct lsa_policy_state *state;	struct lsa_account_state *astate;	ZERO_STRUCTP(r->out.acct_handle);	DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);	state = h->data;	astate = talloc(dce_call->conn, struct lsa_account_state);	if (astate == NULL) {		return NT_STATUS_NO_MEMORY;	}	astate->account_sid = dom_sid_dup(astate, r->in.sid);	if (astate->account_sid == NULL) {		talloc_free(astate);		return NT_STATUS_NO_MEMORY;	}		astate->policy = talloc_reference(astate, state);	astate->access_mask = r->in.access_mask;	ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);	if (!ah) {		talloc_free(astate);		return NT_STATUS_NO_MEMORY;	}	ah->data = talloc_steal(ah, astate);	*r->out.acct_handle = ah->wire_handle;	return NT_STATUS_OK;}/*   lsa_EnumPrivsAccount */static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 				     TALLOC_CTX *mem_ctx,				     struct lsa_EnumPrivsAccount *r){	struct dcesrv_handle *h;	struct lsa_account_state *astate;	int ret, i;	struct ldb_message **res;	const char * const attrs[] = { "privilege", NULL};	struct ldb_message_element *el;	const char *sidstr;	DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);	astate = h->data;	r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);	r->out.privs->count = 0;	r->out.privs->unknown = 0;	r->out.privs->set = NULL;	sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);	if (sidstr == NULL) {		return NT_STATUS_NO_MEMORY;	}	ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs, 			   "objectSid=%s", sidstr);	if (ret != 1) {		return NT_STATUS_OK;	}	el = ldb_msg_find_element(res[0], "privilege");	if (el == NULL || el->num_values == 0) {		return NT_STATUS_OK;	}	r->out.privs->set = talloc_array(r->out.privs, 					 struct lsa_LUIDAttribute, el->num_values);	if (r->out.privs->set == NULL) {		return NT_STATUS_NO_MEMORY;	}	for (i=0;i<el->num_values;i++) {		int id = sec_privilege_id((const char *)el->values[i].data);		if (id == -1) {			return NT_STATUS_INTERNAL_DB_CORRUPTION;		}		r->out.privs->set[i].attribute = 0;		r->out.privs->set[i].luid.low = id;		r->out.privs->set[i].luid.high = 0;	}	r->out.privs->count = el->num_values;	return NT_STATUS_OK;}/*   lsa_EnumAccountRights */static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 				      TALLOC_CTX *mem_ctx,				      struct lsa_EnumAccountRights *r){	struct dcesrv_handle *h;	struct lsa_policy_state *state;	int ret, i;	struct ldb_message **res;	const char * const attrs[] = { "privilege", NULL};	const char *sidstr;	struct ldb_message_element *el;	DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);	state = h->data;	sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);	if (sidstr == NULL) {		return NT_STATUS_NO_MEMORY;	}	ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, 			   "(&(objectSid=%s)(privilege=*))", sidstr);	if (ret == 0) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	if (ret > 1) {		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	if (ret == -1) {		DEBUG(3, ("searching for account rights for SID: %s failed: %s", 			  dom_sid_string(mem_ctx, r->in.sid),			  ldb_errstring(state->sam_ldb)));		return NT_STATUS_INTERNAL_DB_CORRUPTION;	}	el = ldb_msg_find_element(res[0], "privilege");	if (el == NULL || el->num_values == 0) {		return NT_STATUS_OBJECT_NAME_NOT_FOUND;	}	r->out.rights->count = el->num_values;	r->out.rights->names = talloc_array(r->out.rights, 					    struct lsa_StringLarge, r->out.rights->count);	if (r->out.rights->names == NULL) {		return NT_STATUS_NO_MEMORY;	}	for (i=0;i<el->num_values;i++) {		r->out.rights->names[i].string = (const char *)el->values[i].data;	}	return NT_STATUS_OK;}/*   helper for lsa_AddAccountRights and lsa_RemoveAccountRights*/static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 					   TALLOC_CTX *mem_ctx,					   struct lsa_policy_state *state,					   int ldb_flag,					   struct dom_sid *sid,					   const struct lsa_RightSet *rights){	const char *sidstr;	struct ldb_message *msg;	struct ldb_message_element *el;	int i, ret;	struct lsa_EnumAccountRights r2;	sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);	if (sidstr == NULL) {		return NT_STATUS_NO_MEMORY;	}	msg = ldb_msg_new(mem_ctx);	if (msg == NULL) {		return NT_STATUS_NO_MEMORY;	}	msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx, 				  NULL, "objectSid=%s", sidstr);	if (msg->dn == NULL) {		NTSTATUS status;		if (ldb_flag == LDB_FLAG_MOD_DELETE) {			return NT_STATUS_OBJECT_NAME_NOT_FOUND;		}		status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx, 								 sid, &msg->dn);		if (!NT_STATUS_IS_OK(status)) {			return status;		}		return NT_STATUS_NO_SUCH_USER;	}	if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {		return NT_STATUS_NO_MEMORY;	}	if (ldb_flag == LDB_FLAG_MOD_ADD) {		NTSTATUS status;		r2.in.handle = &state->handle->wire_handle;		r2.in.sid = sid;		r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);		status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);		if (!NT_STATUS_IS_OK(status)) {			ZERO_STRUCTP(r2.out.rights);		}	}	for (i=0;i<rights->count;i++) {		if (sec_privilege_id(rights->names[i].string) == -1) {			return NT_STATUS_NO_SUCH_PRIVILEGE;		}		if (ldb_flag == LDB_FLAG_MOD_ADD) {			int j;			for (j=0;j<r2.out.rights->count;j++) {				if (strcasecmp_m(r2.out.rights->names[j].string, 					       rights->names[i].string) == 0) {					break;				}			}			if (j != r2.out.rights->count) continue;		}		ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);		if (ret != LDB_SUCCESS) {			return NT_STATUS_NO_MEMORY;		}	}	el = ldb_msg_find_element(msg, "privilege");	if (!el) {		return NT_STATUS_OK;

⌨️ 快捷键说明

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