dcesrv_lsa.c
来自「samba最新软件」· C语言 代码 · 共 2,518 行 · 第 1/5 页
C
2,518 行
/* Unix SMB/CIFS implementation. endpoint server for the lsarpc pipe Copyright (C) Andrew Tridgell 2004 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.*/#include "rpc_server/lsa/lsa.h"#include "util/util_ldb.h"#include "libcli/ldap/ldap_ndr.h"/* this type allows us to distinguish handle types*//* state associated with a lsa_OpenAccount() operation*/struct lsa_account_state { struct lsa_policy_state *policy; uint32_t access_mask; struct dom_sid *account_sid;};/* state associated with a lsa_OpenSecret() operation*/struct lsa_secret_state { struct lsa_policy_state *policy; uint32_t access_mask; struct ldb_dn *secret_dn; struct ldb_context *sam_ldb; bool global;};/* state associated with a lsa_OpenTrustedDomain() operation*/struct lsa_trusted_domain_state { struct lsa_policy_state *policy; uint32_t access_mask; struct ldb_dn *trusted_domain_dn;};static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_EnumAccountRights *r);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);/* lsa_Close */static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_Close *r){ struct dcesrv_handle *h; *r->out.handle = *r->in.handle; DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY); talloc_free(h); ZERO_STRUCTP(r->out.handle); return NT_STATUS_OK;}/* lsa_Delete */static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_Delete *r){ struct dcesrv_handle *h; int ret; DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY); if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) { struct lsa_secret_state *secret_state = h->data; /* Ensure user is permitted to delete this... */ switch (security_session_user_level(dce_call->conn->auth_state.session_info)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: break; default: /* Users and annonymous are not allowed delete things */ return NT_STATUS_ACCESS_DENIED; } ret = ldb_delete(secret_state->sam_ldb, secret_state->secret_dn); talloc_free(h); if (ret != 0) { return NT_STATUS_INVALID_HANDLE; } return NT_STATUS_OK; } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) { struct lsa_trusted_domain_state *trusted_domain_state = h->data; ret = ldb_delete(trusted_domain_state->policy->sam_ldb, trusted_domain_state->trusted_domain_dn); talloc_free(h); if (ret != 0) { return NT_STATUS_INVALID_HANDLE; } return NT_STATUS_OK; } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) { struct lsa_RightSet *rights; struct lsa_account_state *astate; struct lsa_EnumAccountRights r2; NTSTATUS status; rights = talloc(mem_ctx, struct lsa_RightSet); DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT); astate = h->data; r2.in.handle = &astate->policy->handle->wire_handle; r2.in.sid = astate->account_sid; r2.out.rights = rights; status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { return NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { return status; } status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, LDB_FLAG_MOD_DELETE, astate->account_sid, r2.out.rights); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { return NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { return status; } } return NT_STATUS_INVALID_HANDLE;}/* lsa_EnumPrivs */static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_EnumPrivs *r){ struct dcesrv_handle *h; struct lsa_policy_state *state; int i; const char *privname; DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); state = h->data; i = *r->in.resume_handle; if (i == 0) i = 1; while ((privname = sec_privilege_name(i)) && r->out.privs->count < r->in.max_count) { struct lsa_PrivEntry *e; r->out.privs->privs = talloc_realloc(r->out.privs, r->out.privs->privs, struct lsa_PrivEntry, r->out.privs->count+1); if (r->out.privs->privs == NULL) { return NT_STATUS_NO_MEMORY; } e = &r->out.privs->privs[r->out.privs->count]; e->luid.low = i; e->luid.high = 0; e->name.string = privname; r->out.privs->count++; i++; } *r->out.resume_handle = i; return NT_STATUS_OK;}/* lsa_QuerySecObj */static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_QuerySecurity *r){ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/* lsa_SetSecObj */static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_SetSecObj *r){ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/* lsa_ChangePassword */static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_ChangePassword *r){ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/* dssetup_DsRoleGetPrimaryDomainInformation This is not an LSA call, but is the only call left on the DSSETUP pipe (after the pipe was truncated), and needs lsa_get_policy_state*/static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dssetup_DsRoleGetPrimaryDomainInformation *r){ union dssetup_DsRoleInfo *info; info = talloc(mem_ctx, union dssetup_DsRoleInfo); W_ERROR_HAVE_NO_MEMORY(info); switch (r->in.level) { case DS_ROLE_BASIC_INFORMATION: { enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER; uint32_t flags = 0; const char *domain = NULL; const char *dns_domain = NULL; const char *forest = NULL; struct GUID domain_guid; struct lsa_policy_state *state; NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state); if (!NT_STATUS_IS_OK(status)) { return ntstatus_to_werror(status); } ZERO_STRUCT(domain_guid); switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) { case ROLE_STANDALONE: role = DS_ROLE_STANDALONE_SERVER; break; case ROLE_DOMAIN_MEMBER: role = DS_ROLE_MEMBER_SERVER; break; case ROLE_DOMAIN_CONTROLLER: if (samdb_is_pdc(state->sam_ldb)) { role = DS_ROLE_PRIMARY_DC; } else { role = DS_ROLE_BACKUP_DC; } break; } switch (lp_server_role(dce_call->conn->dce_ctx->lp_ctx)) { case ROLE_STANDALONE: domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)); W_ERROR_HAVE_NO_MEMORY(domain); break; case ROLE_DOMAIN_MEMBER: domain = talloc_strdup(mem_ctx, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)); W_ERROR_HAVE_NO_MEMORY(domain); /* TODO: what is with dns_domain and forest and guid? */ break; case ROLE_DOMAIN_CONTROLLER: flags = DS_ROLE_PRIMARY_DS_RUNNING; if (state->mixed_domain == 1) { flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE; } domain = state->domain_name; dns_domain = state->domain_dns; forest = state->forest_dns; domain_guid = state->domain_guid; flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT; break; } info->basic.role = role; info->basic.flags = flags; info->basic.domain = domain; info->basic.dns_domain = dns_domain; info->basic.forest = forest; info->basic.domain_guid = domain_guid; r->out.info = info; return WERR_OK; } case DS_ROLE_UPGRADE_STATUS: { info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING; info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN; r->out.info = info; return WERR_OK; } case DS_ROLE_OP_STATUS: { info->opstatus.status = DS_ROLE_OP_IDLE; r->out.info = info; return WERR_OK; } default: return WERR_INVALID_PARAM; } return WERR_INVALID_PARAM;}/* fill in the AccountDomain info*/static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, struct lsa_DomainInfo *info){ info->name.string = state->domain_name; info->sid = state->domain_sid; return NT_STATUS_OK;}/* fill in the DNS domain info*/static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, struct lsa_DnsDomainInfo *info){ info->name.string = state->domain_name; info->sid = state->domain_sid; info->dns_domain.string = state->domain_dns; info->dns_forest.string = state->forest_dns; info->domain_guid = state->domain_guid; return NT_STATUS_OK;}/* lsa_QueryInfoPolicy2*/static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_QueryInfoPolicy2 *r){ struct lsa_policy_state *state; struct dcesrv_handle *h; r->out.info = NULL; DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); state = h->data; r->out.info = talloc(mem_ctx, union lsa_PolicyInformation); if (!r->out.info) { return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(r->out.info); switch (r->in.level) { case LSA_POLICY_INFO_DOMAIN: case LSA_POLICY_INFO_ACCOUNT_DOMAIN: return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain); case LSA_POLICY_INFO_DNS: return dcesrv_lsa_info_DNS(state, mem_ctx, &r->out.info->dns); case LSA_POLICY_INFO_DB: case LSA_POLICY_INFO_AUDIT_FULL_SET: case LSA_POLICY_INFO_AUDIT_FULL_QUERY: return NT_STATUS_INVALID_PARAMETER; } return NT_STATUS_INVALID_INFO_CLASS;}/* lsa_QueryInfoPolicy */static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_QueryInfoPolicy *r){ struct lsa_QueryInfoPolicy2 r2; NTSTATUS status; r2.in.handle = r->in.handle; r2.in.level = r->in.level; status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2); r->out.info = r2.out.info; return status;}/* lsa_SetInfoPolicy */static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_SetInfoPolicy *r){ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/* lsa_ClearAuditLog */static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_ClearAuditLog *r){ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);}/* lsa_CreateAccount This call does not seem to have any long-term effects, hence no database operations*/static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_CreateAccount *r){ struct lsa_account_state *astate; struct lsa_policy_state *state; struct dcesrv_handle *h, *ah; 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;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?