lsa_lookup.c
来自「samba最新软件」· C语言 代码 · 共 933 行 · 第 1/2 页
C
933 行
/* 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"static const struct { const char *domain; const char *name; const char *sid; int rtype;} well_known[] = { { .name = "EVERYONE", .sid = SID_WORLD, .rtype = SID_NAME_WKN_GRP, }, { .name = "CREATOR OWNER", .sid = SID_CREATOR_OWNER, .rtype = SID_NAME_WKN_GRP, }, { .name = "CREATOR GROUP", .sid = SID_CREATOR_GROUP, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Dialup", .sid = SID_NT_DIALUP, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Network", .sid = SID_NT_NETWORK, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Batch", .sid = SID_NT_BATCH, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Interactive", .sid = SID_NT_INTERACTIVE, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Service", .sid = SID_NT_SERVICE, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "ANONYMOUS LOGON", .sid = SID_NT_ANONYMOUS, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Proxy", .sid = SID_NT_PROXY, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "ServerLogon", .sid = SID_NT_ENTERPRISE_DCS, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Self", .sid = SID_NT_SELF, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Authenticated Users", .sid = SID_NT_AUTHENTICATED_USERS, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Restricted", .sid = SID_NT_RESTRICTED, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Termainal Server User", .sid = SID_NT_TERMINAL_SERVER_USERS, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Remote Interactive Logon", .sid = SID_NT_REMOTE_INTERACTIVE, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "This Organization", .sid = SID_NT_THIS_ORGANISATION, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "SYSTEM", .sid = SID_NT_SYSTEM, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Local Service", .sid = SID_NT_LOCAL_SERVICE, .rtype = SID_NAME_WKN_GRP, }, { .domain = "NT AUTHORITY", .name = "Network Service", .sid = SID_NT_NETWORK_SERVICE, .rtype = SID_NAME_WKN_GRP, }, { .sid = NULL, }};static NTSTATUS lookup_well_known_names(TALLOC_CTX *mem_ctx, const char *domain, const char *name, const char **authority_name, struct dom_sid **sid, uint32_t *rtype) { int i; for (i=0; well_known[i].sid; i++) { if (domain) { if (strcasecmp_m(domain, well_known[i].domain) == 0 && strcasecmp_m(name, well_known[i].name) == 0) { *authority_name = well_known[i].domain; *sid = dom_sid_parse_talloc(mem_ctx, well_known[i].sid); *rtype = well_known[i].rtype; return NT_STATUS_OK; } } else { if (strcasecmp_m(name, well_known[i].name) == 0) { *authority_name = well_known[i].domain; *sid = dom_sid_parse_talloc(mem_ctx, well_known[i].sid); *rtype = well_known[i].rtype; return NT_STATUS_OK; } } } return NT_STATUS_NOT_FOUND; }static NTSTATUS lookup_well_known_sids(TALLOC_CTX *mem_ctx, const char *sid_str, const char **authority_name, const char **name, uint32_t *rtype) { int i; for (i=0; well_known[i].sid; i++) { if (strcasecmp_m(sid_str, well_known[i].sid) == 0) { *authority_name = well_known[i].domain; *name = well_known[i].name; *rtype = well_known[i].rtype; return NT_STATUS_OK; } } return NT_STATUS_NOT_FOUND; }/* lookup a SID for 1 name*/static NTSTATUS dcesrv_lsa_lookup_name(struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, const char *name, const char **authority_name, struct dom_sid **sid, enum lsa_SidType *rtype){ int ret, atype, i; struct ldb_message **res; const char * const attrs[] = { "objectSid", "sAMAccountType", NULL}; const char *p; const char *domain; const char *username; struct ldb_dn *domain_dn; struct dom_sid *domain_sid; NTSTATUS status; p = strchr_m(name, '\\'); if (p != NULL) { domain = talloc_strndup(mem_ctx, name, p-name); if (!domain) { return NT_STATUS_NO_MEMORY; } username = p + 1; } else if (strchr_m(name, '@')) { status = crack_name_to_nt4_name(mem_ctx, ev_ctx, lp_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name, nt_errstr(status))); return status; } } else { domain = NULL; username = name; } if (!domain) { /* Look up table of well known names */ status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype); if (NT_STATUS_IS_OK(status)) { return NT_STATUS_OK; } if (strcasecmp_m(username, NAME_NT_AUTHORITY) == 0) { *authority_name = NAME_NT_AUTHORITY; *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY); *rtype = SID_NAME_DOMAIN; return NT_STATUS_OK; } if (strcasecmp_m(username, NAME_BUILTIN) == 0) { *authority_name = NAME_BUILTIN; *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN); *rtype = SID_NAME_DOMAIN; return NT_STATUS_OK; } if (strcasecmp_m(username, state->domain_dns) == 0) { *authority_name = state->domain_name; *sid = state->domain_sid; *rtype = SID_NAME_DOMAIN; return NT_STATUS_OK; } if (strcasecmp_m(username, state->domain_name) == 0) { *authority_name = state->domain_name; *sid = state->domain_sid; *rtype = SID_NAME_DOMAIN; return NT_STATUS_OK; } /* Perhaps this is a well known user? */ name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_NT_AUTHORITY, username); if (!name) { return NT_STATUS_NO_MEMORY; } status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype); if (NT_STATUS_IS_OK(status)) { return status; } /* Perhaps this is a BUILTIN user? */ name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_BUILTIN, username); if (!name) { return NT_STATUS_NO_MEMORY; } status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype); if (NT_STATUS_IS_OK(status)) { return status; } /* OK, I give up - perhaps we need to assume the user is in our domain? */ name = talloc_asprintf(mem_ctx, "%s\\%s", state->domain_name, username); if (!name) { return NT_STATUS_NO_MEMORY; } status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype); if (NT_STATUS_IS_OK(status)) { return status; } return STATUS_SOME_UNMAPPED; } else if (strcasecmp_m(domain, NAME_NT_AUTHORITY) == 0) { if (!*username) { *authority_name = NAME_NT_AUTHORITY; *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY); *rtype = SID_NAME_DOMAIN; return NT_STATUS_OK; } /* Look up table of well known names */ return lookup_well_known_names(mem_ctx, domain, username, authority_name, sid, rtype); } else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) { *authority_name = NAME_BUILTIN; domain_dn = state->builtin_dn; } else if (strcasecmp_m(domain, state->domain_dns) == 0) { *authority_name = state->domain_name; domain_dn = state->domain_dn; } else if (strcasecmp_m(domain, state->domain_name) == 0) { *authority_name = state->domain_name; domain_dn = state->domain_dn; } else { /* Not local, need to ask winbind in future */ return STATUS_SOME_UNMAPPED; } ret = gendb_search_dn(state->sam_ldb, mem_ctx, domain_dn, &res, attrs); if (ret == 1) { domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid"); if (domain_sid == NULL) { return NT_STATUS_INVALID_SID; } } else { return NT_STATUS_INVALID_SID; } if (!*username) { *sid = domain_sid; *rtype = SID_NAME_DOMAIN; return NT_STATUS_OK; } ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, "(&(sAMAccountName=%s)(objectSid=*))", ldb_binary_encode_string(mem_ctx, username)); if (ret == -1) { return NT_STATUS_INVALID_SID; } for (i=0; i < ret; i++) { *sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid"); if (*sid == NULL) { return NT_STATUS_INVALID_SID; } /* Check that this is in the domain */ if (!dom_sid_in_domain(domain_sid, *sid)) { continue; } atype = samdb_result_uint(res[i], "sAMAccountType", 0); *rtype = samdb_atype_map(atype); if (*rtype == SID_NAME_UNKNOWN) { return STATUS_SOME_UNMAPPED; } return NT_STATUS_OK; } /* need to check for an allocated sid */ return NT_STATUS_INVALID_SID;}/* add to the lsa_RefDomainList for LookupSids and LookupNames*/static NTSTATUS dcesrv_lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, enum lsa_SidType rtype, const char *authority_name, struct dom_sid *sid, struct lsa_RefDomainList *domains, uint32_t *sid_index){ struct dom_sid *authority_sid; int i; if (rtype != SID_NAME_DOMAIN) { authority_sid = dom_sid_dup(mem_ctx, sid); if (authority_sid == NULL) { return NT_STATUS_NO_MEMORY; } authority_sid->num_auths--; } else { authority_sid = sid; } /* see if we've already done this authority name */ for (i=0;i<domains->count;i++) { if (strcasecmp_m(authority_name, domains->domains[i].name.string) == 0) { *sid_index = i; return NT_STATUS_OK; } } domains->domains = talloc_realloc(domains, domains->domains, struct lsa_DomainInfo, domains->count+1); if (domains->domains == NULL) { return NT_STATUS_NO_MEMORY; } domains->domains[i].name.string = authority_name; domains->domains[i].sid = authority_sid; domains->count++; domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count; *sid_index = i; return NT_STATUS_OK;}/* lookup a name for 1 SID*/static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, struct dom_sid *sid, const char *sid_str, const char **authority_name, const char **name, enum lsa_SidType *rtype){ NTSTATUS status; int ret; uint32_t atype; struct ldb_message **res; struct ldb_dn *domain_dn; const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "cn", NULL}; status = lookup_well_known_sids(mem_ctx, sid_str, authority_name, name, rtype); if (NT_STATUS_IS_OK(status)) { return status; } if (dom_sid_in_domain(state->domain_sid, sid)) { *authority_name = state->domain_name; domain_dn = state->domain_dn; } else if (dom_sid_in_domain(state->builtin_sid, sid)) { *authority_name = NAME_BUILTIN; domain_dn = state->builtin_dn; } else { /* Not well known, our domain or built in */ /* In future, we must look at SID histories, and at trusted domains via winbind */ return NT_STATUS_NOT_FOUND; } ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid)); if (ret == 1) { *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL); if (!*name) { *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL); if (!*name) { *name = talloc_strdup(mem_ctx, sid_str); NT_STATUS_HAVE_NO_MEMORY(*name); } } atype = samdb_result_uint(res[0], "sAMAccountType", 0); *rtype = samdb_atype_map(atype); return NT_STATUS_OK;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?