📄 srv_lsa_nt.c
字号:
/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997, * Copyright (C) Jeremy Allison 2001, * Copyright (C) Rafal Szczesniak 2002, * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002, * Copyright (C) Simo Sorce 2003. * Copyright (C) Gerald (Jerry) Carter 2005. * * 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 2 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* This is the implementation of the lsa server code. */#include "includes.h"#undef DBGC_CLASS#define DBGC_CLASS DBGC_RPC_SRVextern PRIVS privs[];struct lsa_info { DOM_SID sid; uint32 access;};struct generic_mapping lsa_generic_mapping = { POLICY_READ, POLICY_WRITE, POLICY_EXECUTE, POLICY_ALL_ACCESS};/******************************************************************* Function to free the per handle data. ********************************************************************/static void free_lsa_info(void *ptr){ struct lsa_info *lsa = (struct lsa_info *)ptr; SAFE_FREE(lsa);}/***************************************************************************Init dom_query ***************************************************************************/static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_sid){ d_q->buffer_dom_name = (dom_name != NULL) ? 1 : 0; /* domain buffer pointer */ d_q->buffer_dom_sid = (dom_sid != NULL) ? 1 : 0; /* domain sid pointer */ /* this string is supposed to be non-null terminated. */ /* But the maxlen in this UNISTR2 must include the terminating null. */ init_unistr2(&d_q->uni_domain_name, dom_name, UNI_BROKEN_NON_NULL); /* * I'm not sure why this really odd combination of length * values works, but it does appear to. I need to look at * this *much* more closely - but at the moment leave alone * until it's understood. This allows a W2k client to join * a domain with both odd and even length names... JRA. */ /* * IMPORTANT NOTE !!!! * The two fields below probably are reversed in meaning, ie. * the first field is probably the str_len, the second the max * len. Both are measured in bytes anyway. */ d_q->uni_dom_str_len = d_q->uni_domain_name.uni_max_len * 2; d_q->uni_dom_max_len = d_q->uni_domain_name.uni_str_len * 2; if (dom_sid != NULL) init_dom_sid2(&d_q->dom_sid, dom_sid);}/*************************************************************************** init_dom_ref - adds a domain if it's not already in, returns the index.***************************************************************************/static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid){ int num = 0; if (dom_name != NULL) { for (num = 0; num < ref->num_ref_doms_1; num++) { fstring domname; rpcstr_pull(domname, ref->ref_dom[num].uni_dom_name.buffer, sizeof(domname), -1, 0); if (strequal(domname, dom_name)) return num; } } else { num = ref->num_ref_doms_1; } if (num >= MAX_REF_DOMAINS) { /* index not found, already at maximum domain limit */ return -1; } ref->num_ref_doms_1 = num+1; ref->ptr_ref_dom = 1; ref->max_entries = MAX_REF_DOMAINS; ref->num_ref_doms_2 = num+1; ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0; init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE); init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name); init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid ); return num;}/*************************************************************************** init_lsa_rid2s ***************************************************************************/static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2, int num_entries, UNISTR2 *name, uint32 *mapped_count, BOOL endian){ int i; int total = 0; *mapped_count = 0; SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS); become_root(); /* lookup_name can require root privs */ for (i = 0; i < num_entries; i++) { BOOL status = False; DOM_SID sid; uint32 rid = 0xffffffff; int dom_idx = -1; pstring full_name; fstring dom_name, user; enum SID_NAME_USE name_type = SID_NAME_UNKNOWN; /* Split name into domain and user component */ unistr2_to_ascii(full_name, &name[i], sizeof(full_name)); split_domain_name(full_name, dom_name, user); /* Lookup name */ DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name)); status = lookup_name(dom_name, user, &sid, &name_type); if((name_type == SID_NAME_UNKNOWN) && (lp_server_role() == ROLE_DOMAIN_MEMBER) && (strncmp(dom_name, full_name, strlen(dom_name)) != 0)) { DEBUG(5, ("init_lsa_rid2s: domain name not provided and local account not found, using member domain\n")); fstrcpy(dom_name, lp_workgroup()); status = lookup_name(dom_name, user, &sid, &name_type); } if (name_type == SID_NAME_WKN_GRP) { /* BUILTIN aliases are still aliases :-) */ name_type = SID_NAME_ALIAS; } DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" : "not found")); if (status && name_type != SID_NAME_UNKNOWN) { sid_split_rid(&sid, &rid); dom_idx = init_dom_ref(ref, dom_name, &sid); (*mapped_count)++; } else { dom_idx = -1; rid = 0; name_type = SID_NAME_UNKNOWN; } init_dom_rid2(&rid2[total], rid, name_type, dom_idx); total++; } unbecome_root();}/*************************************************************************** init_reply_lookup_names ***************************************************************************/static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l, DOM_R_REF *ref, uint32 num_entries, DOM_RID2 *rid2, uint32 mapped_count){ r_l->ptr_dom_ref = 1; r_l->dom_ref = ref; r_l->num_entries = num_entries; r_l->ptr_entries = 1; r_l->num_entries2 = num_entries; r_l->dom_rid = rid2; r_l->mapped_count = mapped_count;}/*************************************************************************** Init lsa_trans_names. ***************************************************************************/static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn, int num_entries, DOM_SID2 *sid, uint32 *mapped_count){ int i; int total = 0; *mapped_count = 0; /* Allocate memory for list of names */ if (num_entries > 0) { if (!(trn->name = TALLOC_ARRAY(ctx, LSA_TRANS_NAME, num_entries))) { DEBUG(0, ("init_lsa_trans_names(): out of memory\n")); return; } if (!(trn->uni_name = TALLOC_ARRAY(ctx, UNISTR2, num_entries))) { DEBUG(0, ("init_lsa_trans_names(): out of memory\n")); return; } } become_root(); /* Need root to get to passdb to for local sids */ for (i = 0; i < num_entries; i++) { BOOL status = False; DOM_SID find_sid = sid[i].sid; uint32 rid = 0xffffffff; int dom_idx = -1; fstring name, dom_name; enum SID_NAME_USE sid_name_use = (enum SID_NAME_USE)0; sid_to_string(name, &find_sid); DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name)); /* Lookup sid from winbindd */ status = lookup_sid(&find_sid, dom_name, name, &sid_name_use); DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" : "not found")); if (!status) { sid_name_use = SID_NAME_UNKNOWN; memset(dom_name, '\0', sizeof(dom_name)); sid_to_string(name, &find_sid); dom_idx = -1; DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to " "referenced list.\n", name )); } else { (*mapped_count)++; /* Store domain sid in ref array */ if (find_sid.num_auths == 5) { sid_split_rid(&find_sid, &rid); } dom_idx = init_dom_ref(ref, dom_name, &find_sid); DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' (%d) to referenced list.\n", sid_type_lookup(sid_name_use), dom_name, name, sid_name_use )); } init_lsa_trans_name(&trn->name[total], &trn->uni_name[total], sid_name_use, name, dom_idx); total++; } unbecome_root(); trn->num_entries = total; trn->ptr_trans_names = 1; trn->num_entries2 = total;}/*************************************************************************** Init_reply_lookup_sids. ***************************************************************************/static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l, DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names, uint32 mapped_count){ r_l->ptr_dom_ref = 1; r_l->dom_ref = ref; r_l->names = names; r_l->mapped_count = mapped_count;}static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size){ DOM_SID local_adm_sid; DOM_SID adm_sid; SEC_ACE ace[3]; SEC_ACCESS mask; SEC_ACL *psa = NULL; init_sec_access(&mask, POLICY_EXECUTE); init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); sid_copy(&adm_sid, get_global_sam_sid()); sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS); init_sec_access(&mask, POLICY_ALL_ACCESS); init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); sid_copy(&local_adm_sid, &global_sid_Builtin); sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS); init_sec_access(&mask, POLICY_ALL_ACCESS); init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL) return NT_STATUS_NO_MEMORY; if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK;}#if 0 /* AD DC work in ongoing in Samba 4 *//*************************************************************************** Init_dns_dom_info.***************************************************************************/static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name, const char *dns_name, const char *forest_name, struct uuid *dom_guid, DOM_SID *dom_sid){ if (nb_name && *nb_name) { init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE); init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name); r_l->hdr_nb_dom_name.uni_max_len += 2; r_l->uni_nb_dom_name.uni_max_len += 1; } if (dns_name && *dns_name) { init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE); init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name); r_l->hdr_dns_dom_name.uni_max_len += 2; r_l->uni_dns_dom_name.uni_max_len += 1; } if (forest_name && *forest_name) { init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE); init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name); r_l->hdr_forest_name.uni_max_len += 2; r_l->uni_forest_name.uni_max_len += 1; } /* how do we init the guid ? probably should write an init fn */ if (dom_guid) { memcpy(&r_l->dom_guid, dom_guid, sizeof(struct uuid)); } if (dom_sid) { r_l->ptr_dom_sid = 1; init_dom_sid2(&r_l->dom_sid, dom_sid); }}#endif /* AD DC work in ongoing in Samba 4 *//*************************************************************************** _lsa_open_policy2. ***************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -