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