/* Unix SMB/CIFS implementation. Lookup routines for well-known SIDs Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Luke Kenneth Caseson Leighton 1998-1999 Copyright (C) Jeremy Allison 1999 Copyright (C) Volker Lendecke 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 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 . */ #include "includes.h" #include "../libcli/security/security.h" struct rid_name_map { uint32_t rid; const char *name; }; struct sid_name_map_info { const struct dom_sid *sid; const char *name; const struct rid_name_map *known_users; }; static const struct rid_name_map everyone_users[] = { { 0, "Everyone" }, { 0, NULL}}; static const struct rid_name_map local_authority_users[] = { { 0, "Local" }, { 1, "Console Logon" }, { 0, NULL}}; static const struct rid_name_map creator_owner_users[] = { { 0, "Creator Owner" }, { 1, "Creator Group" }, { 2, "Creator Owner Server" }, { 3, "Creator Group Server" }, { 4, "Owner Rights" }, { 0, NULL}}; static const struct rid_name_map nt_authority_users[] = { { 1, "Dialup" }, { 2, "Network"}, { 3, "Batch"}, { 4, "Interactive"}, { 6, "Service"}, { 7, "Anonymous Logon"}, { 8, "Proxy"}, { 9, "Enterprise Domain Controllers"}, { 10, "Self"}, { 11, "Authenticated Users"}, { 12, "Restricted"}, { 13, "Terminal Server User"}, { 14, "Remote Interactive Logon"}, { 15, "This Organization"}, { 17, "IUSR"}, { 18, "SYSTEM"}, { 19, "Local Service"}, { 20, "Network Service"}, { 0, NULL}}; static struct sid_name_map_info special_domains[] = { { &global_sid_World_Domain, "", everyone_users }, { &global_sid_Local_Authority, "", local_authority_users }, { &global_sid_Creator_Owner_Domain, "", creator_owner_users }, { &global_sid_NT_Authority, "NT Authority", nt_authority_users }, { NULL, NULL, NULL }}; bool sid_check_is_wellknown_domain(const struct dom_sid *sid, const char **name) { int i; for (i=0; special_domains[i].sid != NULL; i++) { if (dom_sid_equal(sid, special_domains[i].sid)) { if (name != NULL) { *name = special_domains[i].name; } return True; } } return False; } bool sid_check_is_in_wellknown_domain(const struct dom_sid *sid) { struct dom_sid dom_sid; sid_copy(&dom_sid, sid); sid_split_rid(&dom_sid, NULL); return sid_check_is_wellknown_domain(&dom_sid, NULL); } /************************************************************************** Looks up a known username from one of the known domains. ***************************************************************************/ bool lookup_wellknown_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, const char **domain, const char **name) { int i; struct dom_sid dom_sid; uint32_t rid; const struct rid_name_map *users = NULL; struct dom_sid_buf buf; sid_copy(&dom_sid, sid); if (!sid_split_rid(&dom_sid, &rid)) { DEBUG(2, ("Could not split rid from SID\n")); return False; } for (i=0; special_domains[i].sid != NULL; i++) { if (dom_sid_equal(&dom_sid, special_domains[i].sid)) { *domain = talloc_strdup(mem_ctx, special_domains[i].name); users = special_domains[i].known_users; break; } } if (users == NULL) { DEBUG(10, ("SID %s is no special sid\n", dom_sid_str_buf(sid, &buf))); return False; } for (i=0; users[i].name != NULL; i++) { if (rid == users[i].rid) { *name = talloc_strdup(mem_ctx, users[i].name); return True; } } DEBUG(10, ("RID of special SID %s not found\n", dom_sid_str_buf(sid, &buf))); return False; } /************************************************************************** Try and map a name to one of the well known SIDs. ***************************************************************************/ bool lookup_wellknown_name(TALLOC_CTX *mem_ctx, const char *name, struct dom_sid *sid, const char **pdomain) { int i, j; const char *domain = *pdomain; DEBUG(10,("map_name_to_wellknown_sid: looking up %s\\%s\n", domain, name)); for (i=0; special_domains[i].sid != NULL; i++) { const struct rid_name_map *users = special_domains[i].known_users; if (domain[0] != '\0') { if (!strequal(domain, special_domains[i].name)) { continue; } } if (users == NULL) continue; for (j=0; users[j].name != NULL; j++) { if ( strequal(users[j].name, name) ) { sid_compose(sid, special_domains[i].sid, users[j].rid); *pdomain = talloc_strdup( mem_ctx, special_domains[i].name); return True; } } } return False; }