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 + -
显示快捷键?