static bool wbinfo_lookupname(const char *full_name) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainSid sid; char *sid_str; enum wbcSidType type; fstring domain_name; fstring account_name; /* Send off request */ parse_wbinfo_domain_user(full_name, domain_name, account_name); wbc_status = wbcLookupName(domain_name, account_name, &sid, &type); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } wbc_status = wbcSidToString(&sid, &sid_str); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } /* Display response */ d_printf("%s %s (%d)\n", sid_str, sid_type_lookup(type), type); wbcFreeMemory(sid_str); return true; }
static int net_lookup_sid(struct net_context *c, int argc, const char **argv) { const char *dom, *name; struct dom_sid sid; enum lsa_SidType type; if (argc != 1) { d_printf("%s\n%s", _("Usage:"), _(" net lookup sid <sid>\n")); return -1; } if (!string_to_sid(&sid, argv[0])) { d_printf(_("Could not convert %s to SID\n"), argv[0]); return -1; } if (!lookup_sid(talloc_tos(), &sid, &dom, &name, &type)) { d_printf(_("Could not lookup name %s\n"), argv[0]); return -1; } d_printf("%s %d (%s) %s\\%s\n", sid_string_tos(&sid), type, sid_type_lookup(type), dom, name); return 0; }
static NTSTATUS cmd_lsa_lookup_names4(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32_t num_names; struct lsa_String *names; struct lsa_RefDomainList *domains; struct lsa_TransSidArray3 sids; uint32_t count = 0; int i; if (argc == 1) { printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]); return NT_STATUS_OK; } ZERO_STRUCT(sids); num_names = argc-1; names = talloc_array(mem_ctx, struct lsa_String, num_names); NT_STATUS_HAVE_NO_MEMORY(names); for (i=0; i < num_names; i++) { init_lsa_String(&names[i], argv[i+1]); } result = rpccli_lsa_LookupNames4(cli, mem_ctx, num_names, names, &domains, &sids, 1, &count, 0, 0); if (!NT_STATUS_IS_OK(result)) { return result; } for (i = 0; i < sids.count; i++) { fstring sid_str; sid_to_fstring(sid_str, sids.sids[i].sid); printf("%s %s (%s: %d)\n", argv[i+1], sid_str, sid_type_lookup(sids.sids[i].sid_type), sids.sids[i].sid_type); } return result; }
static bool test_lookupsids(struct torture_context *tctx, struct dcerpc_binding_handle *b, struct policy_handle *handle, struct dom_sid **sids, uint32_t num_sids, int level, NTSTATUS expected_result, enum lsa_SidType *types) { struct lsa_TransNameArray names; NTSTATUS status; uint32_t i; bool ret = true; status = lookup_sids(tctx, level, b, handle, sids, num_sids, &names); if (!NT_STATUS_EQUAL(status, expected_result)) { printf("For level %d expected %s, got %s\n", level, nt_errstr(expected_result), nt_errstr(status)); return false; } if (!NT_STATUS_EQUAL(status, NT_STATUS_OK) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) { return true; } for (i=0; i<num_sids; i++) { if (names.names[i].sid_type != types[i]) { printf("In level %d, for sid %s expected %s, " "got %s\n", level, dom_sid_string(tctx, sids[i]), sid_type_lookup(types[i]), sid_type_lookup(names.names[i].sid_type)); ret = false; } } return ret; }
static BOOL test_lookupsids(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p, struct policy_handle *handle, struct dom_sid **sids, uint32_t num_sids, int level, NTSTATUS expected_result, enum lsa_SidType *types) { struct lsa_TransNameArray names; NTSTATUS status; uint32_t i; BOOL ret = True; status = lookup_sids(mem_ctx, level, p, handle, sids, num_sids, &names); if (!NT_STATUS_EQUAL(status, expected_result)) { printf("For level %d expected %s, got %s\n", level, nt_errstr(expected_result), nt_errstr(status)); return False; } if (!NT_STATUS_EQUAL(status, NT_STATUS_OK) && !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) { return True; } for (i=0; i<num_sids; i++) { if (names.names[i].sid_type != types[i]) { printf("In level %d, for sid %s expected %s, " "got %s\n", level, dom_sid_string(mem_ctx, sids[i]), sid_type_lookup(types[i]), sid_type_lookup(names.names[i].sid_type)); ret = False; } } return ret; }
static void print_map_entry (const GROUP_MAP *map, bool long_list) { if (!long_list) d_printf("%s (%s) -> %s\n", map->nt_name, sid_string_tos(&map->sid), gidtoname(map->gid)); else { d_printf("%s\n", map->nt_name); d_printf(_("\tSID : %s\n"), sid_string_tos(&map->sid)); d_printf(_("\tUnix gid : %u\n"), (unsigned int)map->gid); d_printf(_("\tUnix group: %s\n"), gidtoname(map->gid)); d_printf(_("\tGroup type: %s\n"), sid_type_lookup(map->sid_name_use)); d_printf(_("\tComment : %s\n"), map->comment); } }
static NTSTATUS cmd_lsa_lookup_names_level(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID *sids; enum lsa_SidType *types; int i, level; if (argc < 3) { printf("Usage: %s [level] [name1 [name2 [...]]]\n", argv[0]); return NT_STATUS_OK; } result = rpccli_lsa_open_policy(cli, mem_ctx, True, SEC_FLAG_MAXIMUM_ALLOWED, &pol); if (!NT_STATUS_IS_OK(result)) goto done; level = atoi(argv[1]); result = rpccli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 2, (const char**)(argv + 2), NULL, level, &sids, &types); if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) goto done; result = NT_STATUS_OK; /* Print results */ for (i = 0; i < (argc - 2); i++) { fstring sid_str; sid_to_fstring(sid_str, &sids[i]); printf("%s %s (%s: %d)\n", argv[i + 2], sid_str, sid_type_lookup(types[i]), types[i]); } rpccli_lsa_Close(cli, mem_ctx, &pol); done: return result; }
static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID *sids; uint32 *types; int i; if (argc == 1) { printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]); return NT_STATUS_OK; } result = cli_lsa_open_policy(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); if (!NT_STATUS_IS_OK(result)) goto done; result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1, (const char**)(argv + 1), &sids, &types); if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) goto done; result = NT_STATUS_OK; /* Print results */ for (i = 0; i < (argc - 1); i++) { fstring sid_str; sid_to_string(sid_str, &sids[i]); printf("%s %s (%s: %d)\n", argv[i + 1], sid_str, sid_type_lookup(types[i]), types[i]); } cli_lsa_close(cli, mem_ctx, &pol); done: return result; }
NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods, const DOM_SID *sid, struct acct_info *info) { GROUP_MAP map; if (!pdb_getgrsid(&map, *sid)) return NT_STATUS_NO_SUCH_ALIAS; if ((map.sid_name_use != SID_NAME_ALIAS) && (map.sid_name_use != SID_NAME_WKN_GRP)) { DEBUG(2, ("%s is a %s, expected an alias\n", sid_string_dbg(sid), sid_type_lookup(map.sid_name_use))); return NT_STATUS_NO_SUCH_ALIAS; } fstrcpy(info->acct_name, map.nt_name); fstrcpy(info->acct_desc, map.comment); sid_peek_rid(&map.sid, &info->rid); return NT_STATUS_OK; }
static bool wbinfo_lookupname(char *name) { struct winbindd_request request; struct winbindd_response response; /* Send off request */ ZERO_STRUCT(request); ZERO_STRUCT(response); parse_wbinfo_domain_user(name, request.data.name.dom_name, request.data.name.name); if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) != NSS_STATUS_SUCCESS) return false; /* Display response */ d_printf("%s %s (%d)\n", response.data.sid.sid, sid_type_lookup(response.data.sid.type), response.data.sid.type); return true; }
static bool wbinfo_lookupsid(char *sid) { struct winbindd_request request; struct winbindd_response response; ZERO_STRUCT(request); ZERO_STRUCT(response); /* Send off request */ fstrcpy(request.data.sid, sid); if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response) != NSS_STATUS_SUCCESS) return false; /* Display response */ d_printf("%s%c%s %s\n", response.data.name.dom_name, winbind_separator(), response.data.name.name, sid_type_lookup(response.data.name.type)); return true; }
static bool wbinfo_lookuprids(const char *domain, const char *arg) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainInfo *dinfo = NULL; char *domain_name = NULL; const char **names = NULL; enum wbcSidType *types = NULL; size_t i; int num_rids; uint32 *rids = NULL; const char *p; char *ridstr; TALLOC_CTX *mem_ctx = NULL; bool ret = false; if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')) { domain = get_winbind_domain(); } /* Send request */ wbc_status = wbcDomainInfo(domain, &dinfo); if (!WBC_ERROR_IS_OK(wbc_status)) { d_printf("wbcDomainInfo(%s) failed: %s\n", domain, wbcErrorString(wbc_status)); goto done; } mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { d_printf("talloc_new failed\n"); goto done; } num_rids = 0; rids = NULL; p = arg; while (next_token_talloc(mem_ctx, &p, &ridstr, " ,\n")) { uint32 rid = strtoul(ridstr, NULL, 10); ADD_TO_ARRAY(mem_ctx, uint32, rid, &rids, &num_rids); } if (rids == NULL) { d_printf("no rids\n"); goto done; } wbc_status = wbcLookupRids(&dinfo->sid, num_rids, rids, (const char **)&domain_name, &names, &types); if (!WBC_ERROR_IS_OK(wbc_status)) { d_printf("winbind_lookup_rids failed: %s\n", wbcErrorString(wbc_status)); goto done; } d_printf("Domain: %s\n", domain_name); for (i=0; i<num_rids; i++) { d_printf("%8d: %s (%s)\n", rids[i], names[i], sid_type_lookup(types[i])); } ret = true; done: if (dinfo) { wbcFreeMemory(dinfo); } if (domain_name) { wbcFreeMemory(domain_name); } if (names) { wbcFreeMemory(names); } if (types) { wbcFreeMemory(types); } TALLOC_FREE(mem_ctx); return ret; }
static NTSTATUS find_forced_group(bool force_user, int snum, const char *username, DOM_SID *pgroup_sid, gid_t *pgid) { NTSTATUS result = NT_STATUS_NO_SUCH_GROUP; TALLOC_CTX *frame = talloc_stackframe(); DOM_SID group_sid; enum lsa_SidType type; char *groupname; bool user_must_be_member = False; gid_t gid; groupname = talloc_strdup(talloc_tos(), lp_force_group(snum)); if (groupname == NULL) { DEBUG(1, ("talloc_strdup failed\n")); result = NT_STATUS_NO_MEMORY; goto done; } if (groupname[0] == '+') { user_must_be_member = True; groupname += 1; } groupname = talloc_string_sub(talloc_tos(), groupname, "%S", lp_servicename(snum)); if (groupname == NULL) { DEBUG(1, ("talloc_string_sub failed\n")); result = NT_STATUS_NO_MEMORY; goto done; } if (!lookup_name_smbconf(talloc_tos(), groupname, LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP, NULL, NULL, &group_sid, &type)) { DEBUG(10, ("lookup_name_smbconf(%s) failed\n", groupname)); goto done; } if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) && (type != SID_NAME_WKN_GRP)) { DEBUG(10, ("%s is a %s, not a group\n", groupname, sid_type_lookup(type))); goto done; } if (!sid_to_gid(&group_sid, &gid)) { DEBUG(10, ("sid_to_gid(%s) for %s failed\n", sid_string_dbg(&group_sid), groupname)); goto done; } /* * If the user has been forced and the forced group starts with a '+', * then we only set the group to be the forced group if the forced * user is a member of that group. Otherwise, the meaning of the '+' * would be ignored. */ if (force_user && user_must_be_member) { if (user_in_group_sid(username, &group_sid)) { sid_copy(pgroup_sid, &group_sid); *pgid = gid; DEBUG(3,("Forced group %s for member %s\n", groupname, username)); } else { DEBUG(0,("find_forced_group: forced user %s is not a member " "of forced group %s. Disallowing access.\n", username, groupname )); result = NT_STATUS_MEMBER_NOT_IN_GROUP; goto done; } } else { sid_copy(pgroup_sid, &group_sid); *pgid = gid; DEBUG(3,("Forced group %s\n", groupname)); } result = NT_STATUS_OK; done: TALLOC_FREE(frame); return result; }
static bool token_contains_name(TALLOC_CTX *mem_ctx, const char *username, const char *domain, const char *sharename, const struct nt_user_token *token, const char *name) { const char *prefix; DOM_SID sid; enum lsa_SidType type; struct smbd_server_connection *sconn = smbd_server_conn; if (username != NULL) { name = talloc_sub_basic(mem_ctx, username, domain, name); } if (sharename != NULL) { name = talloc_string_sub(mem_ctx, name, "%S", sharename); } if (name == NULL) { /* This is too security sensitive, better panic than return a * result that might be interpreted in a wrong way. */ smb_panic("substitutions failed"); } /* check to see is we already have a SID */ if ( string_to_sid( &sid, name ) ) { DEBUG(5,("token_contains_name: Checking for SID [%s] in token\n", name)); return nt_token_check_sid( &sid, token ); } if (!do_group_checks(&name, &prefix)) { if (!lookup_name_smbconf(mem_ctx, name, LOOKUP_NAME_ALL, NULL, NULL, &sid, &type)) { DEBUG(5, ("lookup_name %s failed\n", name)); return False; } if (type != SID_NAME_USER) { DEBUG(5, ("%s is a %s, expected a user\n", name, sid_type_lookup(type))); return False; } return nt_token_check_sid(&sid, token); } for (/* initialized above */ ; *prefix != '\0'; prefix++) { if (*prefix == '+') { if (!lookup_name_smbconf(mem_ctx, name, LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP, NULL, NULL, &sid, &type)) { DEBUG(5, ("lookup_name %s failed\n", name)); return False; } if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) && (type != SID_NAME_WKN_GRP)) { DEBUG(5, ("%s is a %s, expected a group\n", name, sid_type_lookup(type))); return False; } if (nt_token_check_sid(&sid, token)) { return True; } continue; } if (*prefix == '&') { if (username) { if (user_in_netgroup(sconn, username, name)) { return True; } } continue; } smb_panic("got invalid prefix from do_groups_check"); } return False; }
const DOM_SID *pdb_get_group_sid(struct samu *sampass) { DOM_SID *gsid; struct passwd *pwd; /* Return the cached group SID if we have that */ if ( sampass->group_sid ) { return sampass->group_sid; } /* generate the group SID from the user's primary Unix group */ if ( !(gsid = TALLOC_P( sampass, DOM_SID )) ) { return NULL; } /* No algorithmic mapping, meaning that we have to figure out the primary group SID according to group mapping and the user SID must be a newly allocated one. We rely on the user's Unix primary gid. We have no choice but to fail if we can't find it. */ if ( sampass->unix_pw ) { pwd = sampass->unix_pw; } else { pwd = Get_Pwnam_alloc( sampass, pdb_get_username(sampass) ); } if ( !pwd ) { DEBUG(0,("pdb_get_group_sid: Failed to find Unix account for %s\n", pdb_get_username(sampass) )); return NULL; } if ( pdb_gid_to_sid(pwd->pw_gid, gsid) ) { enum lsa_SidType type = SID_NAME_UNKNOWN; TALLOC_CTX *mem_ctx = talloc_init("pdb_get_group_sid"); bool lookup_ret; if (!mem_ctx) { return NULL; } /* Now check that it's actually a domain group and not something else */ lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type); TALLOC_FREE( mem_ctx ); if ( lookup_ret && (type == SID_NAME_DOM_GRP) ) { sampass->group_sid = gsid; return sampass->group_sid; } DEBUG(3, ("Primary group for user %s is a %s and not a domain group\n", pwd->pw_name, sid_type_lookup(type))); } /* Just set it to the 'Domain Users' RID of 512 which will always resolve to a name */ sid_compose(gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS); sampass->group_sid = gsid; return sampass->group_sid; }
/* Lookup group membership given a rid. */ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const DOM_SID *group_sid, uint32 *num_names, DOM_SID **sid_mem, char ***names, uint32 **name_types) { size_t i, num_members, num_mapped; uint32 *rids; NTSTATUS result; const DOM_SID **sids; struct lsa_dom_info *lsa_domains; struct lsa_name_info *lsa_names; TALLOC_CTX *tmp_ctx; if (!sid_check_is_in_our_domain(group_sid)) { /* There's no groups, only aliases in BUILTIN */ return NT_STATUS_NO_SUCH_GROUP; } if (!(tmp_ctx = talloc_init("lookup_groupmem"))) { return NT_STATUS_NO_MEMORY; } result = pdb_enum_group_members(tmp_ctx, group_sid, &rids, &num_members); if (!NT_STATUS_IS_OK(result)) { TALLOC_FREE(tmp_ctx); return result; } if (num_members == 0) { *num_names = 0; *sid_mem = NULL; *names = NULL; *name_types = NULL; TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; } *sid_mem = TALLOC_ARRAY(mem_ctx, DOM_SID, num_members); *names = TALLOC_ARRAY(mem_ctx, char *, num_members); *name_types = TALLOC_ARRAY(mem_ctx, uint32, num_members); sids = TALLOC_ARRAY(tmp_ctx, const DOM_SID *, num_members); if (((*sid_mem) == NULL) || ((*names) == NULL) || ((*name_types) == NULL) || (sids == NULL)) { TALLOC_FREE(tmp_ctx); return NT_STATUS_NO_MEMORY; } /* * Prepare an array of sid pointers for the lookup_sids calling * convention. */ for (i=0; i<num_members; i++) { DOM_SID *sid = &((*sid_mem)[i]); if (!sid_compose(sid, &domain->sid, rids[i])) { TALLOC_FREE(tmp_ctx); return NT_STATUS_INTERNAL_ERROR; } sids[i] = sid; } result = lookup_sids(tmp_ctx, num_members, sids, 1, &lsa_domains, &lsa_names); if (!NT_STATUS_IS_OK(result)) { TALLOC_FREE(tmp_ctx); return result; } num_mapped = 0; for (i=0; i<num_members; i++) { if (lsa_names[i].type != SID_NAME_USER) { DEBUG(2, ("Got %s as group member -- ignoring\n", sid_type_lookup(lsa_names[i].type))); continue; } if (!((*names)[i] = talloc_strdup((*names), lsa_names[i].name))) { TALLOC_FREE(tmp_ctx); return NT_STATUS_NO_MEMORY; } (*name_types)[i] = lsa_names[i].type; num_mapped += 1; } *num_names = num_mapped; TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; }