1 /* w32_account.c - Account related W32 functions.
2 Copyright (C) 2007 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.
43 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
47 /* Return a malloced name of our user group. */
52 TOKEN_GROUPS *ptg = NULL;
55 SID_IDENTIFIER_AUTHORITY SystemSidAuthority = { SECURITY_NT_AUTHORITY };
63 /* Every user belongs to the users group, hence
64 users comes before guests */
65 {DOMAIN_ALIAS_RID_USERS, "User"},
66 {DOMAIN_ALIAS_RID_GUESTS, "Guest"},
67 {DOMAIN_ALIAS_RID_POWER_USERS, "Power"},
68 {DOMAIN_ALIAS_RID_ADMINS, "Admin"}
73 if (GetVersion() & 0x80000000)
75 /* This is not NT; thus we are always Admin. */
78 else if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hThread)
79 || OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hThread))
81 /* With the token for the current thread or process in hand we
82 query the size of the associated group information. Note
83 that we expect an error because buffer has been passed as
84 NULL. cbTokenGroups will then tell use the required size. */
85 if (!GetTokenInformation (hThread, TokenGroups, NULL, 0, &cbTokenGroups)
86 && GetLastError () == ERROR_INSUFFICIENT_BUFFER)
88 ptg = GlobalAlloc (GPTR, cbTokenGroups);
91 if (GetTokenInformation ( hThread, TokenGroups, ptg,
92 cbTokenGroups, &cbTokenGroups))
95 /* Now iterate through the list of groups for this
96 access token looking for a match against the SID
98 for (i = 0; i < DIM (groups); i++)
102 AllocateAndInitializeSid (&SystemSidAuthority,
104 SECURITY_BUILTIN_DOMAIN_RID,
110 for (j = 0; j < ptg->GroupCount; j++)
111 if (EqualSid(ptg->Groups[j].Sid, psid))
112 group = groups[i].name;
121 CloseHandle(hThread);
124 return group? strdup (group):NULL;
128 /* Return true if we are an administrator. The chekc is done only
129 once so if the current user has been hadded to the Administrator
130 group the process needs to be rerstarted. */
132 w32_is_administrator (void)
139 char *name = get_group_name ();
141 if (name && !strcmp (name, "Admin"))