1 /* w32_account.c - Account related W32 functions.
2 Copyright (C) 2007-2009 g10 Code GmbH
3 Copyright (C) 1999-2005 Nullsoft, Inc.
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any
7 damages arising from the use of this software.
9 Permission is granted to anyone to use this software for any
10 purpose, including commercial applications, and to alter it and
11 redistribute it freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must
14 not claim that you wrote the original software. If you use this
15 software in a product, an acknowledgment in the product
16 documentation would be appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must
19 not be misrepresented as being the original software.
21 3. This notice may not be removed or altered from any source
24 =======[ wk 2007-05-21 ]====
25 The code for get_group_name has been taken from NSIS 2.05, module
26 UserInfo.c. NSIS bears the above license and along with the
28 This license applies to everything in the NSIS package, except where
30 Thus we make this module available under the same license - note,
31 that this lincese is fully compatibe with the GNU GPL 2.0.
40 #include <sddl.h> // for ConvertSidToStringSid()
46 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
50 /* Return a malloced name of our user group. */
55 TOKEN_GROUPS *ptg = NULL;
58 SID_IDENTIFIER_AUTHORITY SystemSidAuthority = { SECURITY_NT_AUTHORITY };
66 /* Every user belongs to the users group, hence
67 users comes before guests */
68 {DOMAIN_ALIAS_RID_USERS, "User"},
69 {DOMAIN_ALIAS_RID_GUESTS, "Guest"},
70 {DOMAIN_ALIAS_RID_POWER_USERS, "Power"},
71 {DOMAIN_ALIAS_RID_ADMINS, "Admin"}
76 if (GetVersion() & 0x80000000)
78 /* This is not NT; thus we are always Admin. */
81 else if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hThread)
82 || OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hThread))
84 /* With the token for the current thread or process in hand we
85 query the size of the associated group information. Note
86 that we expect an error because buffer has been passed as
87 NULL. cbTokenGroups will then tell use the required size. */
88 if (!GetTokenInformation (hThread, TokenGroups, NULL, 0, &cbTokenGroups)
89 && GetLastError () == ERROR_INSUFFICIENT_BUFFER)
91 ptg = GlobalAlloc (GPTR, cbTokenGroups);
94 if (GetTokenInformation ( hThread, TokenGroups, ptg,
95 cbTokenGroups, &cbTokenGroups))
98 /* Now iterate through the list of groups for this
99 access token looking for a match against the SID
101 for (i = 0; i < DIM (groups); i++)
105 AllocateAndInitializeSid (&SystemSidAuthority,
107 SECURITY_BUILTIN_DOMAIN_RID,
113 for (j = 0; j < ptg->GroupCount; j++)
114 if (EqualSid(ptg->Groups[j].Sid, psid))
115 group = groups[i].name;
124 CloseHandle(hThread);
127 return group? strdup (group):NULL;
131 /* Return true if we are an administrator. The chekc is done only
132 once so if the current user has been hadded to the Administrator
133 group the process needs to be rerstarted. */
135 w32_is_administrator (void)
142 char *name = get_group_name ();
144 if (name && !strcmp (name, "Admin"))