ReactOS  0.4.13-dev-544-gede3fdd
security.c
Go to the documentation of this file.
1 /*
2  * Unit tests for security functions
3  *
4  * Copyright (c) 2004 Mike McCormack
5  * Copyright (c) 2011,2013,2014,2016 Dmitry Timoshkov
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <stdarg.h>
23 #include <stdio.h>
24 
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winternl.h"
31 #include "aclapi.h"
32 #include "winnt.h"
33 #include "sddl.h"
34 #include "ntsecapi.h"
35 #include "lmcons.h"
36 
37 #include "wine/test.h"
38 
39 /* FIXME: Inspect */
40 #define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3)
41 #define GetCurrentThreadToken() ((HANDLE)~(ULONG_PTR)4)
42 #define GetCurrentThreadEffectiveToken() ((HANDLE)~(ULONG_PTR)5)
43 
44 #ifndef PROCESS_QUERY_LIMITED_INFORMATION
45 #define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
46 #endif
47 
48 /* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
49 #define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000)
50 #define PROCESS_ALL_ACCESS_VISTA (PROCESS_ALL_ACCESS | 0xf000)
51 
52 #ifndef EVENT_QUERY_STATE
53 #define EVENT_QUERY_STATE 0x0001
54 #endif
55 
56 #ifndef SEMAPHORE_QUERY_STATE
57 #define SEMAPHORE_QUERY_STATE 0x0001
58 #endif
59 
60 #ifndef THREAD_SET_LIMITED_INFORMATION
61 #define THREAD_SET_LIMITED_INFORMATION 0x0400
62 #define THREAD_QUERY_LIMITED_INFORMATION 0x0800
63 #endif
64 
65 #define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
66 #define THREAD_ALL_ACCESS_VISTA (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff)
67 
68 #define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_, #expr " expected " format " got " format "\n", (value), (ret_)); }
69 
70 static BOOL (WINAPI *pAddAccessAllowedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
71 static BOOL (WINAPI *pAddAccessDeniedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
72 static BOOL (WINAPI *pAddAuditAccessAceEx)(PACL, DWORD, DWORD, DWORD, PSID, BOOL, BOOL);
73 static BOOL (WINAPI *pAddMandatoryAce)(PACL,DWORD,DWORD,DWORD,PSID);
74 static VOID (WINAPI *pBuildTrusteeWithSidA)( PTRUSTEEA pTrustee, PSID pSid );
75 static VOID (WINAPI *pBuildTrusteeWithNameA)( PTRUSTEEA pTrustee, LPSTR pName );
76 static VOID (WINAPI *pBuildTrusteeWithObjectsAndNameA)( PTRUSTEEA pTrustee,
81  LPSTR Name );
82 static VOID (WINAPI *pBuildTrusteeWithObjectsAndSidA)( PTRUSTEEA pTrustee,
86  PSID pSid );
87 static LPSTR (WINAPI *pGetTrusteeNameA)( PTRUSTEEA pTrustee );
88 static BOOL (WINAPI *pMakeSelfRelativeSD)( PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, LPDWORD );
89 static BOOL (WINAPI *pConvertStringSidToSidA)( LPCSTR str, PSID pSid );
90 static BOOL (WINAPI *pCheckTokenMembership)(HANDLE, PSID, PBOOL);
91 static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR, DWORD,
93 static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorW)(LPCWSTR, DWORD,
95 static BOOL (WINAPI *pConvertSecurityDescriptorToStringSecurityDescriptorA)(PSECURITY_DESCRIPTOR, DWORD,
97 static BOOL (WINAPI *pGetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
99 static BOOL (WINAPI *pSetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
101 static DWORD (WINAPI *pGetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
102  PSID*, PSID*, PACL*, PACL*,
104 static DWORD (WINAPI *pSetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
105  PSID, PSID, PACL, PACL);
106 static PDWORD (WINAPI *pGetSidSubAuthority)(PSID, DWORD);
107 static PUCHAR (WINAPI *pGetSidSubAuthorityCount)(PSID);
108 static BOOL (WINAPI *pIsValidSid)(PSID);
109 static DWORD (WINAPI *pRtlAdjustPrivilege)(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN);
110 static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*);
111 static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,
113 
114 static NTSTATUS (WINAPI *pLsaQueryInformationPolicy)(LSA_HANDLE,POLICY_INFORMATION_CLASS,PVOID*);
115 static NTSTATUS (WINAPI *pLsaClose)(LSA_HANDLE);
116 static NTSTATUS (WINAPI *pLsaFreeMemory)(PVOID);
119 static DWORD (WINAPI *pSetEntriesInAclW)(ULONG, PEXPLICIT_ACCESSW, PACL, PACL*);
120 static DWORD (WINAPI *pSetEntriesInAclA)(ULONG, PEXPLICIT_ACCESSA, PACL, PACL*);
121 static BOOL (WINAPI *pSetSecurityDescriptorControl)(PSECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL,
123 static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
125 static DWORD (WINAPI *pSetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
126  PSID, PSID, PACL, PACL);
129 static BOOL (WINAPI *pCreateRestrictedToken)(HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD,
131 static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
132 static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*);
133 static NTSTATUS (WINAPI *pNtSetSecurityObject)(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
135 static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*);
136 static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_STRING,BOOLEAN);
137 static BOOL (WINAPI *pGetWindowsAccountDomainSid)(PSID,PSID,DWORD*);
138 static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ);
139 static NTSTATUS (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
140 static PSID_IDENTIFIER_AUTHORITY (WINAPI *pGetSidIdentifierAuthority)(PSID);
141 static DWORD (WINAPI *pGetExplicitEntriesFromAclW)(PACL,PULONG,PEXPLICIT_ACCESSW*);
142 
143 static HMODULE hmod;
144 static int myARGC;
145 static char** myARGV;
146 
147 #define SID_SLOTS 4
148 static char debugsid_str[SID_SLOTS][256];
149 static int debugsid_index = 0;
150 static const char* debugstr_sid(PSID sid)
151 {
152  LPSTR sidstr;
153  DWORD le = GetLastError();
156 
157  if (!ConvertSidToStringSidA(sid, &sidstr))
158  sprintf(res, "ConvertSidToStringSidA failed le=%u", GetLastError());
159  else if (strlen(sidstr) > sizeof(*debugsid_str) - 1)
160  {
161  memcpy(res, sidstr, sizeof(*debugsid_str) - 4);
162  strcpy(res + sizeof(*debugsid_str) - 4, "...");
163  LocalFree(sidstr);
164  }
165  else
166  {
167  strcpy(res, sidstr);
168  LocalFree(sidstr);
169  }
170  /* Restore the last error in case ConvertSidToStringSidA() modified it */
171  SetLastError(le);
172  return res;
173 }
174 
175 static void init(void)
176 {
177  HMODULE hntdll;
178 
179  hntdll = GetModuleHandleA("ntdll.dll");
180  pNtQueryObject = (void *)GetProcAddress( hntdll, "NtQueryObject" );
181  pNtAccessCheck = (void *)GetProcAddress( hntdll, "NtAccessCheck" );
182  pNtSetSecurityObject = (void *)GetProcAddress(hntdll, "NtSetSecurityObject");
183  pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
184  pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
185  pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");
186  pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString");
187  pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
188 
189  hmod = GetModuleHandleA("advapi32.dll");
190  pAddAccessAllowedAceEx = (void *)GetProcAddress(hmod, "AddAccessAllowedAceEx");
191  pAddAccessDeniedAceEx = (void *)GetProcAddress(hmod, "AddAccessDeniedAceEx");
192  pAddAuditAccessAceEx = (void *)GetProcAddress(hmod, "AddAuditAccessAceEx");
193  pAddMandatoryAce = (void *)GetProcAddress(hmod, "AddMandatoryAce");
194  pCheckTokenMembership = (void *)GetProcAddress(hmod, "CheckTokenMembership");
195  pConvertStringSecurityDescriptorToSecurityDescriptorA =
196  (void *)GetProcAddress(hmod, "ConvertStringSecurityDescriptorToSecurityDescriptorA" );
197  pConvertStringSecurityDescriptorToSecurityDescriptorW =
198  (void *)GetProcAddress(hmod, "ConvertStringSecurityDescriptorToSecurityDescriptorW" );
199  pConvertSecurityDescriptorToStringSecurityDescriptorA =
200  (void *)GetProcAddress(hmod, "ConvertSecurityDescriptorToStringSecurityDescriptorA" );
201  pGetFileSecurityA = (void *)GetProcAddress(hmod, "GetFileSecurityA" );
202  pSetFileSecurityA = (void *)GetProcAddress(hmod, "SetFileSecurityA" );
203  pCreateWellKnownSid = (void *)GetProcAddress( hmod, "CreateWellKnownSid" );
204  pGetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "GetNamedSecurityInfoA");
205  pSetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "SetNamedSecurityInfoA");
206  pGetSidSubAuthority = (void *)GetProcAddress(hmod, "GetSidSubAuthority");
207  pGetSidSubAuthorityCount = (void *)GetProcAddress(hmod, "GetSidSubAuthorityCount");
208  pIsValidSid = (void *)GetProcAddress(hmod, "IsValidSid");
209  pMakeSelfRelativeSD = (void *)GetProcAddress(hmod, "MakeSelfRelativeSD");
210  pSetEntriesInAclW = (void *)GetProcAddress(hmod, "SetEntriesInAclW");
211  pSetEntriesInAclA = (void *)GetProcAddress(hmod, "SetEntriesInAclA");
212  pSetSecurityDescriptorControl = (void *)GetProcAddress(hmod, "SetSecurityDescriptorControl");
213  pGetSecurityInfo = (void *)GetProcAddress(hmod, "GetSecurityInfo");
214  pSetSecurityInfo = (void *)GetProcAddress(hmod, "SetSecurityInfo");
215  pCreateRestrictedToken = (void *)GetProcAddress(hmod, "CreateRestrictedToken");
216  pConvertStringSidToSidA = (void *)GetProcAddress(hmod, "ConvertStringSidToSidA");
217  pGetAclInformation = (void *)GetProcAddress(hmod, "GetAclInformation");
218  pGetAce = (void *)GetProcAddress(hmod, "GetAce");
219  pGetWindowsAccountDomainSid = (void *)GetProcAddress(hmod, "GetWindowsAccountDomainSid");
220  pGetSidIdentifierAuthority = (void *)GetProcAddress(hmod, "GetSidIdentifierAuthority");
221  pDuplicateTokenEx = (void *)GetProcAddress(hmod, "DuplicateTokenEx");
222  pGetExplicitEntriesFromAclW = (void *)GetProcAddress(hmod, "GetExplicitEntriesFromAclW");
223 
225 }
226 
228 {
229  /* use HeapFree(GetProcessHeap(), 0, sd); when done */
230  DWORD ret, length, needed;
232 
233  needed = 0xdeadbeef;
234  SetLastError(0xdeadbeef);
236  NULL, 0, &needed);
237  ok_(__FILE__, line)(!ret, "GetKernelObjectSecurity should fail\n");
238  ok_(__FILE__, line)(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
239  ok_(__FILE__, line)(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n");
240 
241  length = needed;
243 
244  needed = 0xdeadbeef;
245  SetLastError(0xdeadbeef);
247  sd, length, &needed);
248  ok_(__FILE__, line)(ret, "GetKernelObjectSecurity error %d\n", GetLastError());
249  ok_(__FILE__, line)(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed);
250  return sd;
251 }
252 
254 {
255  BOOL res;
256  SECURITY_DESCRIPTOR *queriedSD = NULL;
257  PSID owner;
258  BOOL owner_defaulted;
259 
260  queriedSD = test_get_security_descriptor( Handle, line );
261 
262  res = GetSecurityDescriptorOwner(queriedSD, &owner, &owner_defaulted);
263  ok_(__FILE__, line)(res, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
264 
265  ok_(__FILE__, line)(EqualSid(owner, expected), "Owner SIDs are not equal %s != %s\n",
267  ok_(__FILE__, line)(!owner_defaulted, "Defaulted is true\n");
268 
269  HeapFree(GetProcessHeap(), 0, queriedSD);
270 }
271 
273 {
274  BOOL res;
275  SECURITY_DESCRIPTOR *queriedSD = NULL;
276  PSID group;
277  BOOL group_defaulted;
278 
279  queriedSD = test_get_security_descriptor( Handle, line );
280 
281  res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted);
282  ok_(__FILE__, line)(res, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
283 
284  ok_(__FILE__, line)(EqualSid(group, expected), "Group SIDs are not equal %s != %s\n",
286  ok_(__FILE__, line)(!group_defaulted, "Defaulted is true\n");
287 
288  HeapFree(GetProcessHeap(), 0, queriedSD);
289 }
290 
291 static void test_sid(void)
292 {
293  static struct
294  {
296  const char *refStr;
297  } refs[] = {
298  { { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" },
299  { { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1" },
300  { { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1" },
301  { { {0x00,0x00,0x00,0x00,0x01,0x02} }, "S-1-258-1" },
302  { { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" },
303  { { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" },
304  };
305  static const struct
306  {
307  const char *str;
308  WELL_KNOWN_SID_TYPE sid_type;
309  BOOL optional;
310  } strsid_table[] = {
311  /* Please keep the list sorted. */
312  { "AC", WinBuiltinAnyPackageSid, TRUE },
313  { "AN", WinAnonymousSid },
314  { "AO", WinBuiltinAccountOperatorsSid },
315  { "AU", WinAuthenticatedUserSid },
316  { "BA", WinBuiltinAdministratorsSid },
317  { "BG", WinBuiltinGuestsSid },
318  { "BO", WinBuiltinBackupOperatorsSid },
319  { "BU", WinBuiltinUsersSid },
320  { "CA", WinAccountCertAdminsSid, TRUE},
321  { "CG", WinCreatorGroupSid },
322  { "CO", WinCreatorOwnerSid },
323  { "DA", WinAccountDomainAdminsSid, TRUE},
324  { "DC", WinAccountComputersSid, TRUE},
325  { "DD", WinAccountControllersSid, TRUE},
326  { "DG", WinAccountDomainGuestsSid, TRUE},
327  { "DU", WinAccountDomainUsersSid, TRUE},
328  { "EA", WinAccountEnterpriseAdminsSid, TRUE},
329  { "ED", WinEnterpriseControllersSid },
330  { "IU", WinInteractiveSid },
331  { "LA", WinAccountAdministratorSid },
332  { "LG", WinAccountGuestSid },
333  { "LS", WinLocalServiceSid },
334  { "NO", WinBuiltinNetworkConfigurationOperatorsSid },
335  { "NS", WinNetworkServiceSid },
336  { "NU", WinNetworkSid },
337  { "PA", WinAccountPolicyAdminsSid, TRUE},
338  { "PO", WinBuiltinPrintOperatorsSid },
339  { "PS", WinSelfSid },
340  { "PU", WinBuiltinPowerUsersSid },
341  { "RC", WinRestrictedCodeSid },
342  { "RD", WinBuiltinRemoteDesktopUsersSid },
343  { "RE", WinBuiltinReplicatorSid },
344  { "RS", WinAccountRasAndIasServersSid, TRUE },
345  { "RU", WinBuiltinPreWindows2000CompatibleAccessSid },
346  { "SA", WinAccountSchemaAdminsSid, TRUE },
347  { "SO", WinBuiltinSystemOperatorsSid },
348  { "SU", WinServiceSid },
349  { "SY", WinLocalSystemSid },
350  { "WD", WinWorldSid },
351  };
353  const char noSubAuthStr[] = "S-1-5";
354  unsigned int i;
355  PSID psid, domain_sid;
356  SID *pisid;
357  BOOL r;
358  LPSTR str;
359 
360  if( !pConvertStringSidToSidA )
361  {
362  win_skip("ConvertSidToStringSidA or ConvertStringSidToSidA not available\n");
363  return;
364  }
365 
366  r = pConvertStringSidToSidA( NULL, NULL );
367  ok( !r, "expected failure with NULL parameters\n" );
369  return;
371  "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n",
372  GetLastError() );
373 
374  r = pConvertStringSidToSidA( refs[0].refStr, NULL );
376  "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n",
377  GetLastError() );
378 
379  r = pConvertStringSidToSidA( NULL, &str );
381  "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n",
382  GetLastError() );
383 
384  r = pConvertStringSidToSidA( noSubAuthStr, &psid );
385  ok( !r,
386  "expected failure with no sub authorities\n" );
388  "expected GetLastError() is ERROR_INVALID_SID, got %d\n",
389  GetLastError() );
390 
391  ok(pConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid), "ConvertStringSidToSidA failed\n");
392  pisid = psid;
393  ok(pisid->SubAuthorityCount == 4, "Invalid sub authority count - expected 4, got %d\n", pisid->SubAuthorityCount);
394  ok(pisid->SubAuthority[0] == 21, "Invalid subauthority 0 - expected 21, got %d\n", pisid->SubAuthority[0]);
395  ok(pisid->SubAuthority[3] == 4576, "Invalid subauthority 0 - expected 4576, got %d\n", pisid->SubAuthority[3]);
396  LocalFree(str);
397  LocalFree(psid);
398 
399  for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
400  {
401  r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
402  &psid );
403  ok( r, "failed to allocate sid\n" );
404  r = ConvertSidToStringSidA( psid, &str );
405  ok( r, "failed to convert sid\n" );
406  if (r)
407  {
408  ok( !strcmp( str, refs[i].refStr ),
409  "incorrect sid, expected %s, got %s\n", refs[i].refStr, str );
410  LocalFree( str );
411  }
412  if( psid )
413  FreeSid( psid );
414 
415  r = pConvertStringSidToSidA( refs[i].refStr, &psid );
416  ok( r, "failed to parse sid string\n" );
417  pisid = psid;
418  ok( pisid &&
419  !memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value,
420  sizeof(refs[i].auth) ),
421  "string sid %s didn't parse to expected value\n"
422  "(got 0x%04x%08x, expected 0x%04x%08x)\n",
423  refs[i].refStr,
425  pisid->IdentifierAuthority.Value[0] ),
427  pisid->IdentifierAuthority.Value[4] ),
429  pisid->IdentifierAuthority.Value[2] ) ),
430  MAKEWORD( refs[i].auth.Value[1], refs[i].auth.Value[0] ),
431  MAKELONG( MAKEWORD( refs[i].auth.Value[5], refs[i].auth.Value[4] ),
432  MAKEWORD( refs[i].auth.Value[3], refs[i].auth.Value[2] ) ) );
433  if( psid )
434  LocalFree( psid );
435  }
436 
437  /* string constant format not supported before XP */
438  r = pConvertStringSidToSidA("AN", &psid);
439  if(!r)
440  {
441  win_skip("String constant format not supported\n");
442  return;
443  }
444  LocalFree(psid);
445 
446  AllocateAndInitializeSid(&domain_ident, 4, SECURITY_NT_NON_UNIQUE, 0, 0, 0, 0, 0, 0, 0, &domain_sid);
447 
448  for(i = 0; i < sizeof(strsid_table) / sizeof(strsid_table[0]); i++)
449  {
450  SetLastError(0xdeadbeef);
451  r = pConvertStringSidToSidA(strsid_table[i].str, &psid);
452 
453  if (!(strsid_table[i].optional))
454  {
455  ok(r, "%s: got %u\n", strsid_table[i].str, GetLastError());
456  }
457 
458  if (r)
459  {
461  char *sid_string, *well_known_sid_string;
462  DWORD n, size;
463 
464  /* zero out domain id before comparison to simplify things */
465  if (strsid_table[i].sid_type == WinAccountAdministratorSid ||
466  strsid_table[i].sid_type == WinAccountGuestSid)
467  {
468  for (n = 1; n <= 3; n++)
469  *GetSidSubAuthority(psid, n) = 0;
470  }
471 
472  r = ConvertSidToStringSidA(psid, &sid_string);
473  ok(r, "%s: ConvertSidToStringSid error %u\n", strsid_table[i].str, GetLastError());
474  if (winetest_debug > 1)
475  trace("%s => %s\n", strsid_table[i].str, sid_string);
476 
477  size = sizeof(buf);
478  r = pCreateWellKnownSid(strsid_table[i].sid_type, domain_sid, buf, &size);
479  ok(r, "%u: CreateWellKnownSid(%u) error %u\n", i, strsid_table[i].sid_type, GetLastError());
480 
481  r = ConvertSidToStringSidA(buf, &well_known_sid_string);
482  ok(r, "%u: ConvertSidToStringSi(%u) error %u\n", i, strsid_table[i].sid_type, GetLastError());
483  if (winetest_debug > 1)
484  trace("%u => %s\n", strsid_table[i].sid_type, well_known_sid_string);
485 
486  ok(strcmp(sid_string, well_known_sid_string) == 0,
487  "%u: (%u) expected %s, got %s\n", i, strsid_table[i].sid_type, well_known_sid_string, sid_string);
488 
489  LocalFree(well_known_sid_string);
490  LocalFree(sid_string);
491  LocalFree(psid);
492  }
493  else
494  {
496  trace(" %s: couldn't be converted, returned %d\n", strsid_table[i].str, GetLastError());
497  else
498  trace(" %s: couldn't be converted\n", strsid_table[i].str);
499  }
500  }
501 
502  LocalFree(domain_sid);
503 }
504 
505 static void test_trustee(void)
506 {
507  GUID ObjectType = {0x12345678, 0x1234, 0x5678, {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}};
508  GUID InheritedObjectType = {0x23456789, 0x2345, 0x6786, {0x2, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}};
509  GUID ZeroGuid;
510  OBJECTS_AND_NAME_A oan;
511  OBJECTS_AND_SID oas;
512  TRUSTEEA trustee;
513  PSID psid;
514  char szObjectTypeName[] = "ObjectTypeName";
515  char szInheritedObjectTypeName[] = "InheritedObjectTypeName";
516  char szTrusteeName[] = "szTrusteeName";
517  SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} };
518 
519  memset( &ZeroGuid, 0x00, sizeof (ZeroGuid) );
520 
521  pBuildTrusteeWithSidA = (void *)GetProcAddress( hmod, "BuildTrusteeWithSidA" );
522  pBuildTrusteeWithNameA = (void *)GetProcAddress( hmod, "BuildTrusteeWithNameA" );
523  pBuildTrusteeWithObjectsAndNameA = (void *)GetProcAddress (hmod, "BuildTrusteeWithObjectsAndNameA" );
524  pBuildTrusteeWithObjectsAndSidA = (void *)GetProcAddress (hmod, "BuildTrusteeWithObjectsAndSidA" );
525  pGetTrusteeNameA = (void *)GetProcAddress (hmod, "GetTrusteeNameA" );
526  if( !pBuildTrusteeWithSidA || !pBuildTrusteeWithNameA ||
527  !pBuildTrusteeWithObjectsAndNameA || !pBuildTrusteeWithObjectsAndSidA ||
528  !pGetTrusteeNameA )
529  return;
530 
531  if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )
532  {
533  trace( "failed to init SID\n" );
534  return;
535  }
536 
537  /* test BuildTrusteeWithSidA */
538  memset( &trustee, 0xff, sizeof trustee );
539  pBuildTrusteeWithSidA( &trustee, psid );
540 
541  ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
543  "MultipleTrusteeOperation wrong\n");
544  ok( trustee.TrusteeForm == TRUSTEE_IS_SID, "TrusteeForm wrong\n");
545  ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
546  ok( trustee.ptstrName == psid, "ptstrName wrong\n" );
547 
548  /* test BuildTrusteeWithObjectsAndSidA (test 1) */
549  memset( &trustee, 0xff, sizeof trustee );
550  memset( &oas, 0xff, sizeof(oas) );
551  pBuildTrusteeWithObjectsAndSidA(&trustee, &oas, &ObjectType,
552  &InheritedObjectType, psid);
553 
554  ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
555  ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
556  ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_SID, "TrusteeForm wrong\n");
557  ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
558  ok(trustee.ptstrName == (LPSTR)&oas, "ptstrName wrong\n");
559 
560  ok(oas.ObjectsPresent == (ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT), "ObjectsPresent wrong\n");
561  ok(!memcmp(&oas.ObjectTypeGuid, &ObjectType, sizeof(GUID)), "ObjectTypeGuid wrong\n");
562  ok(!memcmp(&oas.InheritedObjectTypeGuid, &InheritedObjectType, sizeof(GUID)), "InheritedObjectTypeGuid wrong\n");
563  ok(oas.pSid == psid, "pSid wrong\n");
564 
565  /* test GetTrusteeNameA */
566  ok(pGetTrusteeNameA(&trustee) == (LPSTR)&oas, "GetTrusteeName returned wrong value\n");
567 
568  /* test BuildTrusteeWithObjectsAndSidA (test 2) */
569  memset( &trustee, 0xff, sizeof trustee );
570  memset( &oas, 0xff, sizeof(oas) );
571  pBuildTrusteeWithObjectsAndSidA(&trustee, &oas, NULL,
572  &InheritedObjectType, psid);
573 
574  ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
575  ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
576  ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_SID, "TrusteeForm wrong\n");
577  ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
578  ok(trustee.ptstrName == (LPSTR)&oas, "ptstrName wrong\n");
579 
580  ok(oas.ObjectsPresent == ACE_INHERITED_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n");
581  ok(!memcmp(&oas.ObjectTypeGuid, &ZeroGuid, sizeof(GUID)), "ObjectTypeGuid wrong\n");
582  ok(!memcmp(&oas.InheritedObjectTypeGuid, &InheritedObjectType, sizeof(GUID)), "InheritedObjectTypeGuid wrong\n");
583  ok(oas.pSid == psid, "pSid wrong\n");
584 
585  FreeSid( psid );
586 
587  /* test BuildTrusteeWithNameA */
588  memset( &trustee, 0xff, sizeof trustee );
589  pBuildTrusteeWithNameA( &trustee, szTrusteeName );
590 
591  ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
593  "MultipleTrusteeOperation wrong\n");
594  ok( trustee.TrusteeForm == TRUSTEE_IS_NAME, "TrusteeForm wrong\n");
595  ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
596  ok( trustee.ptstrName == szTrusteeName, "ptstrName wrong\n" );
597 
598  /* test BuildTrusteeWithObjectsAndNameA (test 1) */
599  memset( &trustee, 0xff, sizeof trustee );
600  memset( &oan, 0xff, sizeof(oan) );
601  pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, szObjectTypeName,
602  szInheritedObjectTypeName, szTrusteeName);
603 
604  ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
605  ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
606  ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n");
607  ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
608  ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n");
609 
610  ok(oan.ObjectsPresent == (ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT), "ObjectsPresent wrong\n");
611  ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n");
612  ok(oan.InheritedObjectTypeName == szInheritedObjectTypeName, "InheritedObjectTypeName wrong\n");
613  ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n");
614 
615  /* test GetTrusteeNameA */
616  ok(pGetTrusteeNameA(&trustee) == (LPSTR)&oan, "GetTrusteeName returned wrong value\n");
617 
618  /* test BuildTrusteeWithObjectsAndNameA (test 2) */
619  memset( &trustee, 0xff, sizeof trustee );
620  memset( &oan, 0xff, sizeof(oan) );
621  pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, NULL,
622  szInheritedObjectTypeName, szTrusteeName);
623 
624  ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
625  ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
626  ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n");
627  ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
628  ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n");
629 
630  ok(oan.ObjectsPresent == ACE_INHERITED_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n");
631  ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n");
632  ok(oan.InheritedObjectTypeName == szInheritedObjectTypeName, "InheritedObjectTypeName wrong\n");
633  ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n");
634 
635  /* test BuildTrusteeWithObjectsAndNameA (test 3) */
636  memset( &trustee, 0xff, sizeof trustee );
637  memset( &oan, 0xff, sizeof(oan) );
638  pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, szObjectTypeName,
639  NULL, szTrusteeName);
640 
641  ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
642  ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
643  ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n");
644  ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
645  ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n");
646 
647  ok(oan.ObjectsPresent == ACE_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n");
648  ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n");
649  ok(oan.InheritedObjectTypeName == NULL, "InheritedObjectTypeName wrong\n");
650  ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n");
651 }
652 
653 /* If the first isn't defined, assume none is */
654 #ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
655 #define SE_MIN_WELL_KNOWN_PRIVILEGE 2L
656 #define SE_CREATE_TOKEN_PRIVILEGE 2L
657 #define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L
658 #define SE_LOCK_MEMORY_PRIVILEGE 4L
659 #define SE_INCREASE_QUOTA_PRIVILEGE 5L
660 #define SE_MACHINE_ACCOUNT_PRIVILEGE 6L
661 #define SE_TCB_PRIVILEGE 7L
662 #define SE_SECURITY_PRIVILEGE 8L
663 #define SE_TAKE_OWNERSHIP_PRIVILEGE 9L
664 #define SE_LOAD_DRIVER_PRIVILEGE 10L
665 #define SE_SYSTEM_PROFILE_PRIVILEGE 11L
666 #define SE_SYSTEMTIME_PRIVILEGE 12L
667 #define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
668 #define SE_INC_BASE_PRIORITY_PRIVILEGE 14L
669 #define SE_CREATE_PAGEFILE_PRIVILEGE 15L
670 #define SE_CREATE_PERMANENT_PRIVILEGE 16L
671 #define SE_BACKUP_PRIVILEGE 17L
672 #define SE_RESTORE_PRIVILEGE 18L
673 #define SE_SHUTDOWN_PRIVILEGE 19L
674 #define SE_DEBUG_PRIVILEGE 20L
675 #define SE_AUDIT_PRIVILEGE 21L
676 #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
677 #define SE_CHANGE_NOTIFY_PRIVILEGE 23L
678 #define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
679 #define SE_UNDOCK_PRIVILEGE 25L
680 #define SE_SYNC_AGENT_PRIVILEGE 26L
681 #define SE_ENABLE_DELEGATION_PRIVILEGE 27L
682 #define SE_MANAGE_VOLUME_PRIVILEGE 28L
683 #define SE_IMPERSONATE_PRIVILEGE 29L
684 #define SE_CREATE_GLOBAL_PRIVILEGE 30L
685 #define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE
686 #endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
687 
688 static void test_allocateLuid(void)
689 {
690  BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);
691  LUID luid1, luid2;
692  BOOL ret;
693 
694  pAllocateLocallyUniqueId = (void*)GetProcAddress(hmod, "AllocateLocallyUniqueId");
695  if (!pAllocateLocallyUniqueId) return;
696 
697  ret = pAllocateLocallyUniqueId(&luid1);
699  return;
700 
701  ok(ret,
702  "AllocateLocallyUniqueId failed: %d\n", GetLastError());
703  ret = pAllocateLocallyUniqueId(&luid2);
704  ok( ret,
705  "AllocateLocallyUniqueId failed: %d\n", GetLastError());
706  ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0,
707  "AllocateLocallyUniqueId returned a well-known LUID\n");
708  ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart,
709  "AllocateLocallyUniqueId returned non-unique LUIDs\n");
710  ret = pAllocateLocallyUniqueId(NULL);
711  ok( !ret && GetLastError() == ERROR_NOACCESS,
712  "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %d\n",
713  GetLastError());
714 }
715 
716 static void test_lookupPrivilegeName(void)
717 {
718  BOOL (WINAPI *pLookupPrivilegeNameA)(LPCSTR, PLUID, LPSTR, LPDWORD);
719  char buf[MAX_PATH]; /* arbitrary, seems long enough */
720  DWORD cchName = sizeof(buf);
721  LUID luid = { 0, 0 };
722  LONG i;
723  BOOL ret;
724 
725  /* check whether it's available first */
726  pLookupPrivilegeNameA = (void*)GetProcAddress(hmod, "LookupPrivilegeNameA");
727  if (!pLookupPrivilegeNameA) return;
729  ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
731  return;
732 
733  /* check with a short buffer */
734  cchName = 0;
736  ret = pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName);
738  "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %d\n",
739  GetLastError());
740  ok(cchName == strlen("SeCreateTokenPrivilege") + 1,
741  "LookupPrivilegeNameA returned an incorrect required length for\n"
742  "SeCreateTokenPrivilege (got %d, expected %d)\n", cchName,
743  lstrlenA("SeCreateTokenPrivilege") + 1);
744  /* check a known value and its returned length on success */
745  cchName = sizeof(buf);
746  ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
747  cchName == strlen("SeCreateTokenPrivilege"),
748  "LookupPrivilegeNameA returned an incorrect output length for\n"
749  "SeCreateTokenPrivilege (got %d, expected %d)\n", cchName,
750  (int)strlen("SeCreateTokenPrivilege"));
751  /* check known values */
753  {
754  luid.LowPart = i;
755  cchName = sizeof(buf);
756  ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
758  "LookupPrivilegeNameA(0.%d) failed: %d\n", i, GetLastError());
759  }
760  /* check a bogus LUID */
761  luid.LowPart = 0xdeadbeef;
762  cchName = sizeof(buf);
763  ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
765  "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n",
766  GetLastError());
767  /* check on a bogus system */
769  cchName = sizeof(buf);
770  ret = pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName);
772  GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */,
773  "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d\n",
774  GetLastError());
775 }
776 
778 {
779  const char *name;
781 };
782 
783 static void test_lookupPrivilegeValue(void)
784 {
785  static const struct NameToLUID privs[] = {
786  { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE },
787  { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE },
788  { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE },
789  { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE },
790  { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE },
791  { "SeTcbPrivilege", SE_TCB_PRIVILEGE },
792  { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE },
793  { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE },
794  { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE },
795  { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE },
796  { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE },
797  { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE },
798  { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE },
799  { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE },
800  { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE },
801  { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE },
802  { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE },
803  { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE },
804  { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },
805  { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },
806  { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },
807  { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILEGE },
808  { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },
809  { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },
810  { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },
811  { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE },
812  { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE },
813  { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE },
814  { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },
815  };
816  BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
817  unsigned int i;
818  LUID luid;
819  BOOL ret;
820 
821  /* check whether it's available first */
822  pLookupPrivilegeValueA = (void*)GetProcAddress(hmod, "LookupPrivilegeValueA");
823  if (!pLookupPrivilegeValueA) return;
824  ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid);
826  return;
827 
828  /* check a bogus system name */
829  ret = pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid);
831  GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */,
832  "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d\n",
833  GetLastError());
834  /* check a NULL string */
835  ret = pLookupPrivilegeValueA(NULL, 0, &luid);
837  "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n",
838  GetLastError());
839  /* check a bogus privilege name */
840  ret = pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid);
842  "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n",
843  GetLastError());
844  /* check case insensitive */
845  ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid);
846  ok( ret,
847  "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %d\n",
848  GetLastError());
849  for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++)
850  {
851  /* Not all privileges are implemented on all Windows versions, so
852  * don't worry if the call fails
853  */
854  if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))
855  {
856  ok(luid.LowPart == privs[i].lowPart,
857  "LookupPrivilegeValueA returned an invalid LUID for %s\n",
858  privs[i].name);
859  }
860  }
861 }
862 
863 static void test_luid(void)
864 {
868 }
869 
870 static void test_FileSecurity(void)
871 {
872  char wintmpdir [MAX_PATH];
873  char path [MAX_PATH];
874  char file [MAX_PATH];
875  HANDLE fh, token;
876  DWORD sdSize, retSize, rc, granted, priv_set_len;
877  PRIVILEGE_SET priv_set;
878  BOOL status;
879  BYTE *sd;
884 
885  if (!pGetFileSecurityA) {
886  win_skip ("GetFileSecurity is not available\n");
887  return;
888  }
889 
890  if (!pSetFileSecurityA) {
891  win_skip ("SetFileSecurity is not available\n");
892  return;
893  }
894 
895  if (!GetTempPathA (sizeof (wintmpdir), wintmpdir)) {
896  win_skip ("GetTempPathA failed\n");
897  return;
898  }
899 
900  /* Create a temporary directory and in it a temporary file */
901  strcat (strcpy (path, wintmpdir), "rary");
902  SetLastError(0xdeadbeef);
903  rc = CreateDirectoryA (path, NULL);
904  ok (rc || GetLastError() == ERROR_ALREADY_EXISTS, "CreateDirectoryA "
905  "failed for '%s' with %d\n", path, GetLastError());
906 
907  strcat (strcpy (file, path), "\\ess");
908  SetLastError(0xdeadbeef);
910  ok (fh != INVALID_HANDLE_VALUE, "CreateFileA "
911  "failed for '%s' with %d\n", file, GetLastError());
912  CloseHandle (fh);
913 
914  /* For the temporary file ... */
915 
916  /* Get size needed */
917  retSize = 0;
918  SetLastError(0xdeadbeef);
919  rc = pGetFileSecurityA (file, request, NULL, 0, &retSize);
920  if (!rc && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
921  win_skip("GetFileSecurityA is not implemented\n");
922  goto cleanup;
923  }
924  ok (!rc, "GetFileSecurityA "
925  "was expected to fail for '%s'\n", file);
926  ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
927  "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
928  ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize);
929 
930  sdSize = retSize;
931  sd = HeapAlloc (GetProcessHeap (), 0, sdSize);
932 
933  /* Get security descriptor for real */
934  retSize = -1;
935  SetLastError(0xdeadbeef);
936  rc = pGetFileSecurityA (file, request, sd, sdSize, &retSize);
937  ok (rc, "GetFileSecurityA "
938  "was not expected to fail '%s': %d\n", file, GetLastError());
939  ok (retSize == sdSize ||
940  broken(retSize == 0), /* NT4 */
941  "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize);
942 
943  /* Use it to set security descriptor */
944  SetLastError(0xdeadbeef);
945  rc = pSetFileSecurityA (file, request, sd);
946  ok (rc, "SetFileSecurityA "
947  "was not expected to fail '%s': %d\n", file, GetLastError());
948 
949  HeapFree (GetProcessHeap (), 0, sd);
950 
951  /* Repeat for the temporary directory ... */
952 
953  /* Get size needed */
954  retSize = 0;
955  SetLastError(0xdeadbeef);
956  rc = pGetFileSecurityA (path, request, NULL, 0, &retSize);
957  ok (!rc, "GetFileSecurityA "
958  "was expected to fail for '%s'\n", path);
959  ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
960  "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
961  ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize);
962 
963  sdSize = retSize;
964  sd = HeapAlloc (GetProcessHeap (), 0, sdSize);
965 
966  /* Get security descriptor for real */
967  retSize = -1;
968  SetLastError(0xdeadbeef);
969  rc = pGetFileSecurityA (path, request, sd, sdSize, &retSize);
970  ok (rc, "GetFileSecurityA "
971  "was not expected to fail '%s': %d\n", path, GetLastError());
972  ok (retSize == sdSize ||
973  broken(retSize == 0), /* NT4 */
974  "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize);
975 
976  /* Use it to set security descriptor */
977  SetLastError(0xdeadbeef);
978  rc = pSetFileSecurityA (path, request, sd);
979  ok (rc, "SetFileSecurityA "
980  "was not expected to fail '%s': %d\n", path, GetLastError());
981  HeapFree (GetProcessHeap (), 0, sd);
982 
983  /* Old test */
984  strcpy (wintmpdir, "\\Should not exist");
985  SetLastError(0xdeadbeef);
986  rc = pGetFileSecurityA (wintmpdir, OWNER_SECURITY_INFORMATION, NULL, 0, &sdSize);
987  ok (!rc, "GetFileSecurityA should fail for not existing directories/files\n");
989  "last error ERROR_FILE_NOT_FOUND expected, got %d\n", GetLastError());
990 
991 cleanup:
992  /* Remove temporary file and directory */
993  DeleteFileA(file);
995 
996  /* Test file access permissions for a file with FILE_ATTRIBUTE_ARCHIVE */
997  SetLastError(0xdeadbeef);
998  rc = GetTempPathA(sizeof(wintmpdir), wintmpdir);
999  ok(rc, "GetTempPath error %d\n", GetLastError());
1000 
1001  SetLastError(0xdeadbeef);
1002  rc = GetTempFileNameA(wintmpdir, "tmp", 0, file);
1003  ok(rc, "GetTempFileName error %d\n", GetLastError());
1004 
1005  rc = GetFileAttributesA(file);
1007  ok(rc == FILE_ATTRIBUTE_ARCHIVE, "expected FILE_ATTRIBUTE_ARCHIVE got %#x\n", rc);
1008 
1010  NULL, 0, &sdSize);
1011  ok(!rc, "GetFileSecurity should fail\n");
1013  "expected ERROR_INSUFFICIENT_BUFFER got %d\n", GetLastError());
1014  ok(sdSize > sizeof(SECURITY_DESCRIPTOR), "got sd size %d\n", sdSize);
1015 
1016  sd = HeapAlloc(GetProcessHeap (), 0, sdSize);
1017  retSize = 0xdeadbeef;
1018  SetLastError(0xdeadbeef);
1020  sd, sdSize, &retSize);
1021  ok(rc, "GetFileSecurity error %d\n", GetLastError());
1022  ok(retSize == sdSize || broken(retSize == 0) /* NT4 */, "expected %d, got %d\n", sdSize, retSize);
1023 
1024  SetLastError(0xdeadbeef);
1026  ok(!rc, "OpenThreadToken should fail\n");
1027  ok(GetLastError() == ERROR_NO_TOKEN, "expected ERROR_NO_TOKEN, got %d\n", GetLastError());
1028 
1029  SetLastError(0xdeadbeef);
1031  ok(rc, "ImpersonateSelf error %d\n", GetLastError());
1032 
1033  SetLastError(0xdeadbeef);
1035  ok(rc, "OpenThreadToken error %d\n", GetLastError());
1036 
1037  SetLastError(0xdeadbeef);
1038  rc = RevertToSelf();
1039  ok(rc, "RevertToSelf error %d\n", GetLastError());
1040 
1041  priv_set_len = sizeof(priv_set);
1042  granted = 0xdeadbeef;
1043  status = 0xdeadbeef;
1044  SetLastError(0xdeadbeef);
1045  rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1046  ok(rc, "AccessCheck error %d\n", GetLastError());
1047  ok(status == 1, "expected 1, got %d\n", status);
1048  ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#x\n", granted);
1049 
1050  granted = 0xdeadbeef;
1051  status = 0xdeadbeef;
1052  SetLastError(0xdeadbeef);
1053  rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1054  ok(rc, "AccessCheck error %d\n", GetLastError());
1055  ok(status == 1, "expected 1, got %d\n", status);
1056  ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#x\n", granted);
1057 
1058  granted = 0xdeadbeef;
1059  status = 0xdeadbeef;
1060  SetLastError(0xdeadbeef);
1061  rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1062  ok(rc, "AccessCheck error %d\n", GetLastError());
1063  ok(status == 1, "expected 1, got %d\n", status);
1064  ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#x\n", granted);
1065 
1066  granted = 0xdeadbeef;
1067  status = 0xdeadbeef;
1068  SetLastError(0xdeadbeef);
1069  rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1070  ok(rc, "AccessCheck error %d\n", GetLastError());
1071  ok(status == 1, "expected 1, got %d\n", status);
1072  ok(granted == DELETE, "expected DELETE, got %#x\n", granted);
1073 
1074  granted = 0xdeadbeef;
1075  status = 0xdeadbeef;
1076  SetLastError(0xdeadbeef);
1077  rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status);
1078  ok(rc, "AccessCheck error %d\n", GetLastError());
1079  ok(status == 1, "expected 1, got %d\n", status);
1080  ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#x\n", granted);
1081 
1082  granted = 0xdeadbeef;
1083  status = 0xdeadbeef;
1084  SetLastError(0xdeadbeef);
1085  rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status);
1086  ok(rc, "AccessCheck error %d\n", GetLastError());
1087  ok(status == 1, "expected 1, got %d\n", status);
1088  ok(granted == 0x1ff, "expected 0x1ff, got %#x\n", granted);
1089 
1090  granted = 0xdeadbeef;
1091  status = 0xdeadbeef;
1092  SetLastError(0xdeadbeef);
1093  rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status);
1094  ok(rc, "AccessCheck error %d\n", GetLastError());
1095  ok(status == 1, "expected 1, got %d\n", status);
1096  ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", granted);
1097 
1098  SetLastError(0xdeadbeef);
1099  rc = AccessCheck(sd, token, 0xffffffff, &mapping, &priv_set, &priv_set_len, &granted, &status);
1100  ok(!rc, "AccessCheck should fail\n");
1101  ok(GetLastError() == ERROR_GENERIC_NOT_MAPPED, "expected ERROR_GENERIC_NOT_MAPPED, got %d\n", GetLastError());
1102 
1103  /* Test file access permissions for a file with FILE_ATTRIBUTE_READONLY */
1104  SetLastError(0xdeadbeef);
1106  ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
1107  retSize = 0xdeadbeef;
1108  SetLastError(0xdeadbeef);
1109  rc = WriteFile(fh, "1", 1, &retSize, NULL);
1110  ok(!rc, "WriteFile should fail\n");
1111  ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1112  ok(retSize == 0, "expected 0, got %d\n", retSize);
1113  CloseHandle(fh);
1114 
1115  rc = GetFileAttributesA(file);
1117 todo_wine
1119  "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#x\n", rc);
1120 
1121  SetLastError(0xdeadbeef);
1123  ok(rc, "SetFileAttributes error %d\n", GetLastError());
1124  SetLastError(0xdeadbeef);
1125  rc = DeleteFileA(file);
1126  ok(rc, "DeleteFile error %d\n", GetLastError());
1127 
1128  SetLastError(0xdeadbeef);
1130  ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
1131  retSize = 0xdeadbeef;
1132  SetLastError(0xdeadbeef);
1133  rc = WriteFile(fh, "1", 1, &retSize, NULL);
1134  ok(!rc, "WriteFile should fail\n");
1135  ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1136  ok(retSize == 0, "expected 0, got %d\n", retSize);
1137  CloseHandle(fh);
1138 
1139  rc = GetFileAttributesA(file);
1142  "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#x\n", rc);
1143 
1144  retSize = 0xdeadbeef;
1145  SetLastError(0xdeadbeef);
1147  sd, sdSize, &retSize);
1148  ok(rc, "GetFileSecurity error %d\n", GetLastError());
1149  ok(retSize == sdSize || broken(retSize == 0) /* NT4 */, "expected %d, got %d\n", sdSize, retSize);
1150 
1151  priv_set_len = sizeof(priv_set);
1152  granted = 0xdeadbeef;
1153  status = 0xdeadbeef;
1154  SetLastError(0xdeadbeef);
1155  rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1156  ok(rc, "AccessCheck error %d\n", GetLastError());
1157  ok(status == 1, "expected 1, got %d\n", status);
1158  ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#x\n", granted);
1159 
1160  granted = 0xdeadbeef;
1161  status = 0xdeadbeef;
1162  SetLastError(0xdeadbeef);
1163  rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1164  ok(rc, "AccessCheck error %d\n", GetLastError());
1165 todo_wine {
1166  ok(status == 1, "expected 1, got %d\n", status);
1167  ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#x\n", granted);
1168 }
1169  granted = 0xdeadbeef;
1170  status = 0xdeadbeef;
1171  SetLastError(0xdeadbeef);
1172  rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1173  ok(rc, "AccessCheck error %d\n", GetLastError());
1174  ok(status == 1, "expected 1, got %d\n", status);
1175  ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#x\n", granted);
1176 
1177  granted = 0xdeadbeef;
1178  status = 0xdeadbeef;
1179  SetLastError(0xdeadbeef);
1180  rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1181  ok(rc, "AccessCheck error %d\n", GetLastError());
1182 todo_wine {
1183  ok(status == 1, "expected 1, got %d\n", status);
1184  ok(granted == DELETE, "expected DELETE, got %#x\n", granted);
1185 }
1186  granted = 0xdeadbeef;
1187  status = 0xdeadbeef;
1188  SetLastError(0xdeadbeef);
1189  rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status);
1190  ok(rc, "AccessCheck error %d\n", GetLastError());
1191 todo_wine {
1192  ok(status == 1, "expected 1, got %d\n", status);
1193  ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#x\n", granted);
1194 }
1195  granted = 0xdeadbeef;
1196  status = 0xdeadbeef;
1197  SetLastError(0xdeadbeef);
1198  rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status);
1199  ok(rc, "AccessCheck error %d\n", GetLastError());
1200 todo_wine {
1201  ok(status == 1, "expected 1, got %d\n", status);
1202  ok(granted == 0x1ff, "expected 0x1ff, got %#x\n", granted);
1203 }
1204  granted = 0xdeadbeef;
1205  status = 0xdeadbeef;
1206  SetLastError(0xdeadbeef);
1207  rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status);
1208  ok(rc, "AccessCheck error %d\n", GetLastError());
1209 todo_wine {
1210  ok(status == 1, "expected 1, got %d\n", status);
1211  ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", granted);
1212 }
1213  SetLastError(0xdeadbeef);
1214  rc = DeleteFileA(file);
1215  ok(!rc, "DeleteFile should fail\n");
1216  ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1217  SetLastError(0xdeadbeef);
1219  ok(rc, "SetFileAttributes error %d\n", GetLastError());
1220  SetLastError(0xdeadbeef);
1221  rc = DeleteFileA(file);
1222  ok(rc, "DeleteFile error %d\n", GetLastError());
1223 
1224  CloseHandle(token);
1225  HeapFree(GetProcessHeap(), 0, sd);
1226 }
1227 
1228 static void test_AccessCheck(void)
1229 {
1230  PSID EveryoneSid = NULL, AdminSid = NULL, UsersSid = NULL;
1231  PACL Acl = NULL;
1236  ACCESS_MASK Access;
1238  HANDLE Token;
1239  HANDLE ProcessToken;
1240  BOOL ret;
1241  DWORD PrivSetLen;
1242  PRIVILEGE_SET *PrivSet;
1243  BOOL res;
1244  HMODULE NtDllModule;
1245  BOOLEAN Enabled;
1246  DWORD err;
1247  NTSTATUS ntret, ntAccessStatus;
1248 
1249  NtDllModule = GetModuleHandleA("ntdll.dll");
1250  if (!NtDllModule)
1251  {
1252  skip("not running on NT, skipping test\n");
1253  return;
1254  }
1255  pRtlAdjustPrivilege = (void *)GetProcAddress(NtDllModule, "RtlAdjustPrivilege");
1256  if (!pRtlAdjustPrivilege)
1257  {
1258  win_skip("missing RtlAdjustPrivilege, skipping test\n");
1259  return;
1260  }
1261 
1262  Acl = HeapAlloc(GetProcessHeap(), 0, 256);
1263  res = InitializeAcl(Acl, 256, ACL_REVISION);
1265  {
1266  skip("ACLs not implemented - skipping tests\n");
1267  HeapFree(GetProcessHeap(), 0, Acl);
1268  return;
1269  }
1270  ok(res, "InitializeAcl failed with error %d\n", GetLastError());
1271 
1272  res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
1273  ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
1274 
1276  DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdminSid);
1277  ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
1278 
1280  DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
1281  ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
1282 
1284 
1286  ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError());
1287 
1289  ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
1290 
1291  PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1292  PrivSet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, PrivSetLen);
1293  PrivSet->PrivilegeCount = 16;
1294 
1296  ok(res, "OpenProcessToken failed with error %d\n", GetLastError());
1297 
1298  pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, FALSE, TRUE, &Enabled);
1299 
1300  res = DuplicateToken(ProcessToken, SecurityImpersonation, &Token);
1301  ok(res, "DuplicateToken failed with error %d\n", GetLastError());
1302 
1303  /* SD without owner/group */
1304  SetLastError(0xdeadbeef);
1305  Access = AccessStatus = 0x1abe11ed;
1307  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1308  err = GetLastError();
1309  ok(!ret && err == ERROR_INVALID_SECURITY_DESCR, "AccessCheck should have "
1310  "failed with ERROR_INVALID_SECURITY_DESCR, instead of %d\n", err);
1311  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1312  "Access and/or AccessStatus were changed!\n");
1313 
1314  /* Set owner and group */
1316  ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError());
1318  ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
1319 
1320  /* Generic access mask */
1321  SetLastError(0xdeadbeef);
1322  Access = AccessStatus = 0x1abe11ed;
1324  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1325  err = GetLastError();
1326  ok(!ret && err == ERROR_GENERIC_NOT_MAPPED, "AccessCheck should have failed "
1327  "with ERROR_GENERIC_NOT_MAPPED, instead of %d\n", err);
1328  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1329  "Access and/or AccessStatus were changed!\n");
1330 
1331  /* Generic access mask - no privilegeset buffer */
1332  SetLastError(0xdeadbeef);
1333  Access = AccessStatus = 0x1abe11ed;
1335  NULL, &PrivSetLen, &Access, &AccessStatus);
1336  err = GetLastError();
1337  ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1338  "with ERROR_NOACCESS, instead of %d\n", err);
1339  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1340  "Access and/or AccessStatus were changed!\n");
1341 
1342  /* Generic access mask - no returnlength */
1343  SetLastError(0xdeadbeef);
1344  Access = AccessStatus = 0x1abe11ed;
1346  PrivSet, NULL, &Access, &AccessStatus);
1347  err = GetLastError();
1348  ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1349  "with ERROR_NOACCESS, instead of %d\n", err);
1350  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1351  "Access and/or AccessStatus were changed!\n");
1352 
1353  /* Generic access mask - no privilegeset buffer, no returnlength */
1354  SetLastError(0xdeadbeef);
1355  Access = AccessStatus = 0x1abe11ed;
1357  NULL, NULL, &Access, &AccessStatus);
1358  err = GetLastError();
1359  ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1360  "with ERROR_NOACCESS, instead of %d\n", err);
1361  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1362  "Access and/or AccessStatus were changed!\n");
1363 
1364  /* sd with no dacl present */
1365  Access = AccessStatus = 0x1abe11ed;
1367  ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
1369  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1370  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1371  ok(AccessStatus && (Access == KEY_READ),
1372  "AccessCheck failed to grant access with error %d\n",
1373  GetLastError());
1374 
1375  /* sd with no dacl present - no privilegeset buffer */
1376  SetLastError(0xdeadbeef);
1377  Access = AccessStatus = 0x1abe11ed;
1379  NULL, &PrivSetLen, &Access, &AccessStatus);
1380  err = GetLastError();
1381  ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1382  "with ERROR_NOACCESS, instead of %d\n", err);
1383  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1384  "Access and/or AccessStatus were changed!\n");
1385 
1386  if(pNtAccessCheck)
1387  {
1388  /* Generic access mask - no privilegeset buffer */
1389  SetLastError(0xdeadbeef);
1390  Access = ntAccessStatus = 0x1abe11ed;
1391  ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1392  NULL, &PrivSetLen, &Access, &ntAccessStatus);
1393  err = GetLastError();
1394  ok(ntret == STATUS_ACCESS_VIOLATION,
1395  "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret);
1396  ok(err == 0xdeadbeef,
1397  "NtAccessCheck shouldn't set last error, got %d\n", err);
1398  ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1399  "Access and/or AccessStatus were changed!\n");
1400 
1401  /* Generic access mask - no returnlength */
1402  SetLastError(0xdeadbeef);
1403  Access = ntAccessStatus = 0x1abe11ed;
1404  ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1405  PrivSet, NULL, &Access, &ntAccessStatus);
1406  err = GetLastError();
1407  ok(ntret == STATUS_ACCESS_VIOLATION,
1408  "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret);
1409  ok(err == 0xdeadbeef,
1410  "NtAccessCheck shouldn't set last error, got %d\n", err);
1411  ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1412  "Access and/or AccessStatus were changed!\n");
1413 
1414  /* Generic access mask - no privilegeset buffer, no returnlength */
1415  SetLastError(0xdeadbeef);
1416  Access = ntAccessStatus = 0x1abe11ed;
1417  ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1418  NULL, NULL, &Access, &ntAccessStatus);
1419  err = GetLastError();
1420  ok(ntret == STATUS_ACCESS_VIOLATION,
1421  "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret);
1422  ok(err == 0xdeadbeef,
1423  "NtAccessCheck shouldn't set last error, got %d\n", err);
1424  ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1425  "Access and/or AccessStatus were changed!\n");
1426  }
1427  else
1428  win_skip("NtAccessCheck unavailable. Skipping.\n");
1429 
1430  /* sd with NULL dacl */
1431  Access = AccessStatus = 0x1abe11ed;
1433  ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
1435  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1436  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1437  ok(AccessStatus && (Access == KEY_READ),
1438  "AccessCheck failed to grant access with error %d\n",
1439  GetLastError());
1441  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1442  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1443  ok(AccessStatus && (Access == KEY_ALL_ACCESS),
1444  "AccessCheck failed to grant access with error %d\n",
1445  GetLastError());
1446 
1447  /* sd with blank dacl */
1449  ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
1451  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1452  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1453  err = GetLastError();
1454  ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed "
1455  "with ERROR_ACCESS_DENIED, instead of %d\n", err);
1456  ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access);
1457 
1458  res = AddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, EveryoneSid);
1459  ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
1460 
1462  ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError());
1463 
1464  /* sd with dacl */
1465  Access = AccessStatus = 0x1abe11ed;
1467  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1468  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1469  ok(AccessStatus && (Access == KEY_READ),
1470  "AccessCheck failed to grant access with error %d\n",
1471  GetLastError());
1472 
1474  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1475  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1476  ok(AccessStatus,
1477  "AccessCheck failed to grant any access with error %d\n",
1478  GetLastError());
1479  trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08x\n", Access);
1480 
1481  /* Null PrivSet with null PrivSetLen pointer */
1482  SetLastError(0xdeadbeef);
1483  Access = AccessStatus = 0x1abe11ed;
1485  NULL, NULL, &Access, &AccessStatus);
1486  err = GetLastError();
1487  ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1488  "failed with ERROR_NOACCESS, instead of %d\n", err);
1489  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1490  "Access and/or AccessStatus were changed!\n");
1491 
1492  /* Null PrivSet with zero PrivSetLen */
1493  SetLastError(0xdeadbeef);
1494  Access = AccessStatus = 0x1abe11ed;
1495  PrivSetLen = 0;
1497  0, &PrivSetLen, &Access, &AccessStatus);
1498  err = GetLastError();
1499  ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1500  "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1501  ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1502  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1503  "Access and/or AccessStatus were changed!\n");
1504 
1505  /* Null PrivSet with insufficient PrivSetLen */
1506  SetLastError(0xdeadbeef);
1507  Access = AccessStatus = 0x1abe11ed;
1508  PrivSetLen = 1;
1510  0, &PrivSetLen, &Access, &AccessStatus);
1511  err = GetLastError();
1512  ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1513  "failed with ERROR_NOACCESS, instead of %d\n", err);
1514  ok(PrivSetLen == 1, "PrivSetLen returns %d\n", PrivSetLen);
1515  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1516  "Access and/or AccessStatus were changed!\n");
1517 
1518  /* Null PrivSet with insufficient PrivSetLen */
1519  SetLastError(0xdeadbeef);
1520  Access = AccessStatus = 0x1abe11ed;
1521  PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
1523  0, &PrivSetLen, &Access, &AccessStatus);
1524  err = GetLastError();
1525  ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1526  "failed with ERROR_NOACCESS, instead of %d\n", err);
1527  ok(PrivSetLen == sizeof(PRIVILEGE_SET) - 1, "PrivSetLen returns %d\n", PrivSetLen);
1528  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1529  "Access and/or AccessStatus were changed!\n");
1530 
1531  /* Null PrivSet with minimal sufficient PrivSetLen */
1532  SetLastError(0xdeadbeef);
1533  Access = AccessStatus = 0x1abe11ed;
1534  PrivSetLen = sizeof(PRIVILEGE_SET);
1536  0, &PrivSetLen, &Access, &AccessStatus);
1537  err = GetLastError();
1538  ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1539  "failed with ERROR_NOACCESS, instead of %d\n", err);
1540  ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1541  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1542  "Access and/or AccessStatus were changed!\n");
1543 
1544  /* Valid PrivSet with zero PrivSetLen */
1545  SetLastError(0xdeadbeef);
1546  Access = AccessStatus = 0x1abe11ed;
1547  PrivSetLen = 0;
1549  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1550  err = GetLastError();
1551  ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1552  "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1553  ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1554  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1555  "Access and/or AccessStatus were changed!\n");
1556 
1557  /* Valid PrivSet with insufficient PrivSetLen */
1558  SetLastError(0xdeadbeef);
1559  Access = AccessStatus = 0x1abe11ed;
1560  PrivSetLen = 1;
1562  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1563  err = GetLastError();
1564 todo_wine
1565  ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1566  "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1567 todo_wine
1568  ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1569  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1570  "Access and/or AccessStatus were changed!\n");
1571 
1572  /* Valid PrivSet with insufficient PrivSetLen */
1573  SetLastError(0xdeadbeef);
1574  Access = AccessStatus = 0x1abe11ed;
1575  PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
1577  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1578  err = GetLastError();
1579 todo_wine
1580  ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1581  "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1582 todo_wine
1583  ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1584 todo_wine
1585  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1586  "Access and/or AccessStatus were changed!\n");
1587 
1588  /* Valid PrivSet with minimal sufficient PrivSetLen */
1589  SetLastError(0xdeadbeef);
1590  Access = AccessStatus = 0x1abe11ed;
1591  PrivSetLen = sizeof(PRIVILEGE_SET);
1592  memset(PrivSet, 0xcc, PrivSetLen);
1594  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1595  err = GetLastError();
1596  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1597 todo_wine
1598  ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1599  ok(AccessStatus && (Access == KEY_READ),
1600  "AccessCheck failed to grant access with error %d\n", GetLastError());
1601  ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n",
1602  PrivSet->PrivilegeCount);
1603 
1604  /* Valid PrivSet with sufficient PrivSetLen */
1605  SetLastError(0xdeadbeef);
1606  Access = AccessStatus = 0x1abe11ed;
1607  PrivSetLen = sizeof(PRIVILEGE_SET) + 1;
1608  memset(PrivSet, 0xcc, PrivSetLen);
1610  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1611  err = GetLastError();
1612  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1613 todo_wine
1614  ok(PrivSetLen == sizeof(PRIVILEGE_SET) + 1, "PrivSetLen returns %d\n", PrivSetLen);
1615  ok(AccessStatus && (Access == KEY_READ),
1616  "AccessCheck failed to grant access with error %d\n", GetLastError());
1617  ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n",
1618  PrivSet->PrivilegeCount);
1619 
1620  PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1621 
1622  /* Null PrivSet with valid PrivSetLen */
1623  SetLastError(0xdeadbeef);
1624  Access = AccessStatus = 0x1abe11ed;
1626  0, &PrivSetLen, &Access, &AccessStatus);
1627  err = GetLastError();
1628  ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1629  "failed with ERROR_NOACCESS, instead of %d\n", err);
1630  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1631  "Access and/or AccessStatus were changed!\n");
1632 
1633  /* Access denied by SD */
1634  SetLastError(0xdeadbeef);
1635  Access = AccessStatus = 0x1abe11ed;
1637  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1638  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1639  err = GetLastError();
1640  ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed "
1641  "with ERROR_ACCESS_DENIED, instead of %d\n", err);
1642  ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access);
1643 
1644  SetLastError(0xdeadbeef);
1645  PrivSet->PrivilegeCount = 16;
1647  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1649  "AccessCheck should have failed with ERROR_PRIVILEGE_NOT_HELD, instead of %d\n",
1650  GetLastError());
1651 
1653  ok(ret, "ImpersonateLoggedOnUser failed with error %d\n", GetLastError());
1654  ret = pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, TRUE, TRUE, &Enabled);
1655  if (!ret)
1656  {
1657  /* Valid PrivSet with zero PrivSetLen */
1658  SetLastError(0xdeadbeef);
1659  Access = AccessStatus = 0x1abe11ed;
1660  PrivSetLen = 0;
1662  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1663  err = GetLastError();
1664  ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1665  "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1666  ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1667  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1668  "Access and/or AccessStatus were changed!\n");
1669 
1670  /* Valid PrivSet with insufficient PrivSetLen */
1671  SetLastError(0xdeadbeef);
1672  Access = AccessStatus = 0x1abe11ed;
1673  PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
1675  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1676  err = GetLastError();
1677  todo_wine
1678  ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1679  "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1680  todo_wine
1681  ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1682  todo_wine
1683  ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1684  "Access and/or AccessStatus were changed!\n");
1685 
1686  /* Valid PrivSet with minimal sufficient PrivSetLen */
1687  SetLastError(0xdeadbeef);
1688  Access = AccessStatus = 0x1abe11ed;
1689  PrivSetLen = sizeof(PRIVILEGE_SET);
1690  memset(PrivSet, 0xcc, PrivSetLen);
1692  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1693  ok(ret && AccessStatus && GetLastError() == 0xdeadbeef,
1694  "AccessCheck should have succeeded, error %d\n",
1695  GetLastError());
1696  ok(Access == ACCESS_SYSTEM_SECURITY,
1697  "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n",
1698  Access);
1699  ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n",
1700  PrivSet->PrivilegeCount);
1701 
1702  /* Valid PrivSet with large PrivSetLen */
1703  SetLastError(0xdeadbeef);
1704  Access = AccessStatus = 0x1abe11ed;
1705  PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1706  memset(PrivSet, 0xcc, PrivSetLen);
1708  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1709  ok(ret && AccessStatus && GetLastError() == 0xdeadbeef,
1710  "AccessCheck should have succeeded, error %d\n",
1711  GetLastError());
1712  ok(Access == ACCESS_SYSTEM_SECURITY,
1713  "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n",
1714  Access);
1715  ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n",
1716  PrivSet->PrivilegeCount);
1717  }
1718  else
1719  trace("Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test\n",
1720  ret);
1721  ret = RevertToSelf();
1722  ok(ret, "RevertToSelf failed with error %d\n", GetLastError());
1723 
1724  /* test INHERIT_ONLY_ACE */
1725  ret = InitializeAcl(Acl, 256, ACL_REVISION);
1726  ok(ret, "InitializeAcl failed with error %d\n", GetLastError());
1727 
1728  /* NT doesn't have AddAccessAllowedAceEx. Skipping this call/test doesn't influence
1729  * the next ones.
1730  */
1731  if (pAddAccessAllowedAceEx)
1732  {
1733  ret = pAddAccessAllowedAceEx(Acl, ACL_REVISION, INHERIT_ONLY_ACE, KEY_READ, EveryoneSid);
1734  ok(ret, "AddAccessAllowedAceEx failed with error %d\n", GetLastError());
1735  }
1736  else
1737  win_skip("AddAccessAllowedAceEx is not available\n");
1738 
1740  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1741  ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1742  err = GetLastError();
1743  ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed "
1744  "with ERROR_ACCESS_DENIED, instead of %d\n", err);
1745  ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access);
1746 
1747  CloseHandle(Token);
1748 
1749  res = DuplicateToken(ProcessToken, SecurityAnonymous, &Token);
1750  ok(res, "DuplicateToken failed with error %d\n", GetLastError());
1751 
1752  SetLastError(0xdeadbeef);
1754  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1755  err = GetLastError();
1756  ok(!ret && err == ERROR_BAD_IMPERSONATION_LEVEL, "AccessCheck should have failed "
1757  "with ERROR_BAD_IMPERSONATION_LEVEL, instead of %d\n", err);
1758 
1759  CloseHandle(Token);
1760 
1761  SetLastError(0xdeadbeef);
1762  ret = AccessCheck(SecurityDescriptor, ProcessToken, KEY_READ, &Mapping,
1763  PrivSet, &PrivSetLen, &Access, &AccessStatus);
1764  err = GetLastError();
1765  ok(!ret && err == ERROR_NO_IMPERSONATION_TOKEN, "AccessCheck should have failed "
1766  "with ERROR_NO_IMPERSONATION_TOKEN, instead of %d\n", err);
1767 
1768  CloseHandle(ProcessToken);
1769 
1770  if (EveryoneSid)
1771  FreeSid(EveryoneSid);
1772  if (AdminSid)
1773  FreeSid(AdminSid);
1774  if (UsersSid)
1775  FreeSid(UsersSid);
1776  HeapFree(GetProcessHeap(), 0, Acl);
1778  HeapFree(GetProcessHeap(), 0, PrivSet);
1779 }
1780 
1781 /* test GetTokenInformation for the various attributes */
1782 static void test_token_attr(void)
1783 {
1784  HANDLE Token, ImpersonationToken;
1785  DWORD Size, Size2;
1788  TOKEN_USER *User;
1790  BOOL ret;
1791  DWORD i, GLE;
1792  LPSTR SidString;
1794  ACL *acl;
1795 
1796  /* cygwin-like use case */
1797  SetLastError(0xdeadbeef);
1800  {
1801  win_skip("OpenProcessToken is not implemented\n");
1802  return;
1803  }
1804  ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1805  if (ret)
1806  {
1807  DWORD buf[256]; /* GetTokenInformation wants a dword-aligned buffer */
1808  Size = sizeof(buf);
1810  ok(ret, "GetTokenInformation failed with error %d\n", GetLastError());
1811  Size = sizeof(ImpersonationLevel);
1813  GLE = GetLastError();
1814  ok(!ret && (GLE == ERROR_INVALID_PARAMETER), "GetTokenInformation(TokenImpersonationLevel) on primary token should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GLE);
1815  CloseHandle(Token);
1816  }
1817 
1818  SetLastError(0xdeadbeef);
1820  ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1821 
1822  /* groups */
1823  /* insufficient buffer length */
1824  SetLastError(0xdeadbeef);
1825  Size2 = 0;
1826  ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size2);
1827  ok(Size2 > 1, "got %d\n", Size2);
1829  "%d with error %d\n", ret, GetLastError());
1830  Size2 -= 1;
1831  Groups = HeapAlloc(GetProcessHeap(), 0, Size2);
1832  memset(Groups, 0xcc, Size2);
1833  Size = 0;
1835  ok(Size > 1, "got %d\n", Size);
1836  ok((!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) || broken(ret) /* wow64 */,
1837  "%d with error %d\n", ret, GetLastError());
1838  if(!ret)
1839  ok(*((BYTE*)Groups) == 0xcc, "buffer altered\n");
1840 
1842 
1843  SetLastError(0xdeadbeef);
1846  "GetTokenInformation(TokenGroups) %s with error %d\n",
1847  ret ? "succeeded" : "failed", GetLastError());
1849  SetLastError(0xdeadbeef);
1851  ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n", GetLastError());
1852  ok(GetLastError() == 0xdeadbeef,
1853  "GetTokenInformation shouldn't have set last error to %d\n",
1854  GetLastError());
1855  trace("TokenGroups:\n");
1856  for (i = 0; i < Groups->GroupCount; i++)
1857  {
1858  DWORD NameLength = 255;
1859  CHAR Name[255];
1860  DWORD DomainLength = 255;
1861  CHAR Domain[255];
1862  SID_NAME_USE SidNameUse;
1863  Name[0] = '\0';
1864  Domain[0] = '\0';
1865  ret = LookupAccountSidA(NULL, Groups->Groups[i].Sid, Name, &NameLength, Domain, &DomainLength, &SidNameUse);
1866  if (ret)
1867  {
1868  ConvertSidToStringSidA(Groups->Groups[i].Sid, &SidString);
1869  trace("%s, %s\\%s use: %d attr: 0x%08x\n", SidString, Domain, Name, SidNameUse, Groups->Groups[i].Attributes);
1870  LocalFree(SidString);
1871  }
1872  else trace("attr: 0x%08x LookupAccountSid failed with error %d\n", Groups->Groups[i].Attributes, GetLastError());
1873  }
1875 
1876  /* user */
1879  "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
1880  User = HeapAlloc(GetProcessHeap(), 0, Size);
1882  ok(ret,
1883  "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
1884 
1885  ConvertSidToStringSidA(User->User.Sid, &SidString);
1886  trace("TokenUser: %s attr: 0x%08x\n", SidString, User->User.Attributes);
1887  LocalFree(SidString);
1888  HeapFree(GetProcessHeap(), 0, User);
1889 
1890  /* logon */
1892  if (!ret && (GetLastError() == ERROR_INVALID_PARAMETER))
1893  todo_wine win_skip("TokenLogonSid not supported. Skipping tests\n");
1894  else
1895  {
1897  "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError());
1900  ok(ret,
1901  "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError());
1902  if (ret)
1903  {
1904  ok(Groups->GroupCount == 1, "got %d\n", Groups->GroupCount);
1905  if(Groups->GroupCount == 1)
1906  {
1907  ConvertSidToStringSidA(Groups->Groups[0].Sid, &SidString);
1908  trace("TokenLogon: %s\n", SidString);
1909  LocalFree(SidString);
1910 
1911  /* S-1-5-5-0-XXXXXX */
1912  ret = IsWellKnownSid(Groups->Groups[0].Sid, WinLogonIdsSid);
1913  ok(ret, "Unknown SID\n");
1914  }
1915  }
1916 
1918  }
1919 
1920  /* privileges */
1923  "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError());
1926  ok(ret,
1927  "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError());
1928  trace("TokenPrivileges:\n");
1929  for (i = 0; i < Privileges->PrivilegeCount; i++)
1930  {
1931  CHAR Name[256];
1932  DWORD NameLen = sizeof(Name)/sizeof(Name[0]);
1933  LookupPrivilegeNameA(NULL, &Privileges->Privileges[i].Luid, Name, &NameLen);
1934  trace("\t%s, 0x%x\n", Name, Privileges->Privileges[i].Attributes);
1935  }
1937 
1938  ret = DuplicateToken(Token, SecurityAnonymous, &ImpersonationToken);
1939  ok(ret, "DuplicateToken failed with error %d\n", GetLastError());
1940 
1941  Size = sizeof(ImpersonationLevel);
1943  ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
1944  ok(ImpersonationLevel == SecurityAnonymous, "ImpersonationLevel should have been SecurityAnonymous instead of %d\n", ImpersonationLevel);
1945 
1946  CloseHandle(ImpersonationToken);
1947 
1948  /* default dacl */
1951  "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1952 
1953  Dacl = HeapAlloc(GetProcessHeap(), 0, Size);
1955  ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1956 
1957  SetLastError(0xdeadbeef);
1959  GLE = GetLastError();
1960  ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n");
1961  ok(GLE == ERROR_BAD_LENGTH, "expected ERROR_BAD_LENGTH got %u\n", GLE);
1962 
1963  SetLastError(0xdeadbeef);
1965  GLE = GetLastError();
1966  ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n");
1967  ok(GLE == ERROR_NOACCESS, "expected ERROR_NOACCESS got %u\n", GLE);
1968 
1969  acl = Dacl->DefaultDacl;
1970  Dacl->DefaultDacl = NULL;
1971 
1973  ok(ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n");
1974 
1975  Size2 = 0;
1976  Dacl->DefaultDacl = (ACL *)0xdeadbeef;
1978  ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1979  ok(Dacl->DefaultDacl == NULL, "expected NULL, got %p\n", Dacl->DefaultDacl);
1980  ok(Size2 == sizeof(TOKEN_DEFAULT_DACL) || broken(Size2 == 2*sizeof(TOKEN_DEFAULT_DACL)), /* WoW64 */
1981  "got %u expected sizeof(TOKEN_DEFAULT_DACL)\n", Size2);
1982 
1983  Dacl->DefaultDacl = acl;
1985  ok(ret, "SetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1986 
1987  if (Size2 == sizeof(TOKEN_DEFAULT_DACL)) {
1989  ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1990  } else
1991  win_skip("TOKEN_DEFAULT_DACL size too small on WoW64\n");
1992 
1993  HeapFree(GetProcessHeap(), 0, Dacl);
1994  CloseHandle(Token);
1995 }
1996 
1997 static void test_GetTokenInformation(void)
1998 {
1999  DWORD is_app_container, size;
2000  HANDLE token;
2001  BOOL ret;
2002 
2004  ok(ret, "OpenProcessToken failed: %u\n", GetLastError());
2005 
2006  size = 0;
2007  is_app_container = 0xdeadbeef;
2008  ret = GetTokenInformation(token, TokenIsAppContainer, &is_app_container,
2009  sizeof(is_app_container), &size);
2011  GetLastError() == ERROR_INVALID_FUNCTION), /* pre-win8 */
2012  "GetTokenInformation failed: %u\n", GetLastError());
2013  if(ret) {
2014  ok(size == sizeof(is_app_container), "size = %u\n", size);
2015  ok(!is_app_container, "is_app_container = %x\n", is_app_container);
2016  }
2017 
2018  CloseHandle(token);
2019 }
2020 
2021 typedef union _MAX_SID
2022 {
2025 } MAX_SID;
2026 
2027 static void test_sid_str(PSID * sid)
2028 {
2029  char *str_sid;
2030  BOOL ret = ConvertSidToStringSidA(sid, &str_sid);
2031  ok(ret, "ConvertSidToStringSidA() failed: %d\n", GetLastError());
2032  if (ret)
2033  {
2034  char account[MAX_PATH], domain[MAX_PATH];
2035  SID_NAME_USE use;
2036  DWORD acc_size = MAX_PATH;
2037  DWORD dom_size = MAX_PATH;
2038  ret = LookupAccountSidA (NULL, sid, account, &acc_size, domain, &dom_size, &use);
2040  "LookupAccountSid(%s) failed: %d\n", str_sid, GetLastError());
2041  if (ret)
2042  trace(" %s %s\\%s %d\n", str_sid, domain, account, use);
2043  else if (GetLastError() == ERROR_NONE_MAPPED)
2044  trace(" %s couldn't be mapped\n", str_sid);
2045  LocalFree(str_sid);
2046  }
2047 }
2048 
2049 static const struct well_known_sid_value
2050 {
2052  const char *sid_string;
2053 } well_known_sid_values[] = {
2054 /* 0 */ {TRUE, "S-1-0-0"}, {TRUE, "S-1-1-0"}, {TRUE, "S-1-2-0"}, {TRUE, "S-1-3-0"},
2055 /* 4 */ {TRUE, "S-1-3-1"}, {TRUE, "S-1-3-2"}, {TRUE, "S-1-3-3"}, {TRUE, "S-1-5"},
2056 /* 8 */ {FALSE, "S-1-5-1"}, {TRUE, "S-1-5-2"}, {TRUE, "S-1-5-3"}, {TRUE, "S-1-5-4"},
2057 /* 12 */ {TRUE, "S-1-5-6"}, {TRUE, "S-1-5-7"}, {TRUE, "S-1-5-8"}, {TRUE, "S-1-5-9"},
2058 /* 16 */ {TRUE, "S-1-5-10"}, {TRUE, "S-1-5-11"}, {TRUE, "S-1-5-12"}, {TRUE, "S-1-5-13"},
2059 /* 20 */ {TRUE, "S-1-5-14"}, {FALSE, NULL}, {TRUE, "S-1-5-18"}, {TRUE, "S-1-5-19"},
2060 /* 24 */ {TRUE, "S-1-5-20"}, {TRUE, "S-1-5-32"},
2061 /* 26 */ {FALSE, "S-1-5-32-544"}, {TRUE, "S-1-5-32-545"}, {TRUE, "S-1-5-32-546"},
2062 /* 29 */ {TRUE, "S-1-5-32-547"}, {TRUE, "S-1-5-32-548"}, {TRUE, "S-1-5-32-549"},
2063 /* 32 */ {TRUE, "S-1-5-32-550"}, {TRUE, "S-1-5-32-551"}, {TRUE, "S-1-5-32-552"},
2064 /* 35 */ {TRUE, "S-1-5-32-554"}, {TRUE, "S-1-5-32-555"}, {TRUE, "S-1-5-32-556"},
2065 /* 38 */ {FALSE, "S-1-5-21-12-23-34-45-56-500"}, {FALSE, "S-1-5-21-12-23-34-45-56-501"},
2066 /* 40 */ {FALSE, "S-1-5-21-12-23-34-45-56-502"}, {FALSE, "S-1-5-21-12-23-34-45-56-512"},
2067 /* 42 */ {FALSE, "S-1-5-21-12-23-34-45-56-513"}, {FALSE, "S-1-5-21-12-23-34-45-56-514"},
2068 /* 44 */ {FALSE, "S-1-5-21-12-23-34-45-56-515"}, {FALSE, "S-1-5-21-12-23-34-45-56-516"},
2069 /* 46 */ {FALSE, "S-1-5-21-12-23-34-45-56-517"}, {FALSE, "S-1-5-21-12-23-34-45-56-518"},
2070 /* 48 */ {FALSE, "S-1-5-21-12-23-34-45-56-519"}, {FALSE, "S-1-5-21-12-23-34-45-56-520"},
2071 /* 50 */ {FALSE, "S-1-5-21-12-23-34-45-56-553"},
2072 /* Added in Windows Server 2003 */
2073 /* 51 */ {TRUE, "S-1-5-64-10"}, {TRUE, "S-1-5-64-21"}, {TRUE, "S-1-5-64-14"},
2074 /* 54 */ {TRUE, "S-1-5-15"}, {TRUE, "S-1-5-1000"}, {FALSE, "S-1-5-32-557"},
2075 /* 57 */ {TRUE, "S-1-5-32-558"}, {TRUE, "S-1-5-32-559"}, {TRUE, "S-1-5-32-560"},
2076 /* 60 */ {TRUE, "S-1-5-32-561"}, {TRUE, "S-1-5-32-562"},
2077 /* Added in Windows Vista: */
2078 /* 62 */ {TRUE, "S-1-5-32-568"},
2079 /* 63 */ {TRUE, "S-1-5-17"}, {FALSE, "S-1-5-32-569"}, {TRUE, "S-1-16-0"},
2080 /* 66 */ {TRUE, "S-1-16-4096"}, {TRUE, "S-1-16-8192"}, {TRUE, "S-1-16-12288"},
2081 /* 69 */ {TRUE, "S-1-16-16384"}, {TRUE, "S-1-5-33"}, {TRUE, "S-1-3-4"},
2082 /* 72 */ {FALSE, "S-1-5-21-12-23-34-45-56-571"}, {FALSE, "S-1-5-21-12-23-34-45-56-572"},
2083 /* 74 */ {TRUE, "S-1-5-22"}, {FALSE, "S-1-5-21-12-23-34-45-56-521"}, {TRUE, "S-1-5-32-573"},
2084 /* 77 */ {FALSE, "S-1-5-21-12-23-34-45-56-498"}, {TRUE, "S-1-5-32-574"}, {TRUE, "S-1-16-8448"},
2085 /* 80 */ {FALSE, NULL}, {TRUE, "S-1-2-1"}, {TRUE, "S-1-5-65-1"}, {FALSE, NULL},
2086 /* 84 */ {TRUE, "S-1-15-2-1"},
2087 };
2088 
2089 static void test_CreateWellKnownSid(void)
2090 {
2092  PSID domainsid, sid;
2093  DWORD size, error;
2094  BOOL ret;
2095  unsigned int i;
2096 
2097  if (!pCreateWellKnownSid)
2098  {
2099  win_skip("CreateWellKnownSid not available\n");
2100  return;
2101  }
2102 
2103  size = 0;
2104  SetLastError(0xdeadbeef);
2105  ret = pCreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size);
2106  error = GetLastError();
2107  ok(!ret, "CreateWellKnownSid succeeded\n");
2108  ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
2109  ok(size, "expected size > 0\n");
2110 
2111  SetLastError(0xdeadbeef);
2112  ret = pCreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size);
2113  error = GetLastError();
2114  ok(!ret, "CreateWellKnownSid succeeded\n");
2115  ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2116 
2117  sid = HeapAlloc(GetProcessHeap(), 0, size);
2118  ret = pCreateWellKnownSid(WinInteractiveSid, NULL, sid, &size);
2119  ok(ret, "CreateWellKnownSid failed %u\n", GetLastError());
2120  HeapFree(GetProcessHeap(), 0, sid);
2121 
2122  /* a domain sid usually have three subauthorities but we test that CreateWellKnownSid doesn't check it */
2123  AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid);
2124 
2125  for (i = 0; i < sizeof(well_known_sid_values)/sizeof(well_known_sid_values[0]); i++)
2126  {
2128  char sid_buffer[SECURITY_MAX_SID_SIZE];
2129  LPSTR str;
2130  DWORD cb;
2131 
2132  if (value->sid_string == NULL)
2133  continue;
2134 
2135  /* some SIDs aren't implemented by all Windows versions - detect it */
2136  cb = sizeof(sid_buffer);
2137  if (!pCreateWellKnownSid(i, NULL, sid_buffer, &cb))
2138  {
2139  skip("Well known SID %u not implemented\n", i);
2140  continue;
2141  }
2142 
2143  cb = sizeof(sid_buffer);
2144  ok(pCreateWellKnownSid(i, value->without_domain ? NULL : domainsid, sid_buffer, &cb), "Couldn't create well known sid %u\n", i);
2146  ok(IsValidSid(sid_buffer), "The sid is not valid\n");
2147  ok(ConvertSidToStringSidA(sid_buffer, &str), "Couldn't convert SID to string\n");
2148  ok(strcmp(str, value->sid_string) == 0, "%d: SID mismatch - expected %s, got %s\n", i,
2149  value->sid_string, str);
2150  LocalFree(str);
2151 
2152  if (value->without_domain)
2153  {
2154  char buf2[SECURITY_MAX_SID_SIZE];
2155  cb = sizeof(buf2);
2156  ok(pCreateWellKnownSid(i, domainsid, buf2, &cb), "Couldn't create well known sid %u with optional domain\n", i);
2158  ok(memcmp(buf2, sid_buffer, cb) == 0, "SID create with domain is different than without (%u)\n", i);
2159  }
2160  }
2161 
2162  FreeSid(domainsid);
2163 }
2164 
2165 static void test_LookupAccountSid(void)
2166 {
2168  CHAR accountA[MAX_PATH], domainA[MAX_PATH], usernameA[MAX_PATH];
2169  DWORD acc_sizeA, dom_sizeA, user_sizeA;
2170  DWORD real_acc_sizeA, real_dom_sizeA;
2171  WCHAR accountW[MAX_PATH], domainW[MAX_PATH];
2172  DWORD acc_sizeW, dom_sizeW;
2173  DWORD real_acc_sizeW, real_dom_sizeW;
2174  PSID pUsersSid = NULL;
2175  SID_NAME_USE use;
2176  BOOL ret;
2177  DWORD error, size, cbti = 0;
2178  MAX_SID max_sid;
2179  CHAR *str_sidA;
2180  int i;
2181  HANDLE hToken;
2182  PTOKEN_USER ptiUser = NULL;
2183 
2184  /* native windows crashes if account size, domain size, or name use is NULL */
2185 
2187  DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pUsersSid);
2189  "AllocateAndInitializeSid failed with error %d\n", GetLastError());
2190 
2191  /* not running on NT so give up */
2193  return;
2194 
2195  real_acc_sizeA = MAX_PATH;
2196  real_dom_sizeA = MAX_PATH;
2197  ret = LookupAccountSidA(NULL, pUsersSid, accountA, &real_acc_sizeA, domainA, &real_dom_sizeA, &use);
2198  ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2199 
2200  /* try NULL account */
2201  acc_sizeA = MAX_PATH;
2202  dom_sizeA = MAX_PATH;
2203  ret = LookupAccountSidA(NULL, pUsersSid, NULL, &acc_sizeA, domainA, &dom_sizeA, &use);
2204  ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2205 
2206  /* try NULL domain */
2207  acc_sizeA = MAX_PATH;
2208  dom_sizeA = MAX_PATH;
2209  ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, NULL, &dom_sizeA, &use);
2210  ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2211 
2212  /* try a small account buffer */
2213  acc_sizeA = 1;
2214  dom_sizeA = MAX_PATH;
2215  accountA[0] = 0;
2216  ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2217  ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
2219  "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
2220 
2221  /* try a 0 sized account buffer */
2222  acc_sizeA = 0;
2223  dom_sizeA = MAX_PATH;
2224  accountA[0] = 0;
2225  LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2226  /* this can fail or succeed depending on OS version but the size will always be returned */
2227  ok(acc_sizeA == real_acc_sizeA + 1,
2228  "LookupAccountSidA() Expected acc_size = %u, got %u\n",
2229  real_acc_sizeA + 1, acc_sizeA);
2230 
2231  /* try a 0 sized account buffer */
2232  acc_sizeA = 0;
2233  dom_sizeA = MAX_PATH;
2234  LookupAccountSidA(NULL, pUsersSid, NULL, &acc_sizeA, domainA, &dom_sizeA, &use);
2235  /* this can fail or succeed depending on OS version but the size will always be returned */
2236  ok(acc_sizeA == real_acc_sizeA + 1,
2237  "LookupAccountSid() Expected acc_size = %u, got %u\n",
2238  real_acc_sizeA + 1, acc_sizeA);
2239 
2240  /* try a small domain buffer */
2241  dom_sizeA = 1;
2242  acc_sizeA = MAX_PATH;
2243  accountA[0] = 0;
2244  ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2245  ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
2247  "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
2248 
2249  /* try a 0 sized domain buffer */
2250  dom_sizeA = 0;
2251  acc_sizeA = MAX_PATH;
2252  accountA[0] = 0;
2253  LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2254  /* this can fail or succeed depending on OS version but the size will always be returned */
2255  ok(dom_sizeA == real_dom_sizeA + 1,
2256  "LookupAccountSidA() Expected dom_size = %u, got %u\n",
2257  real_dom_sizeA + 1, dom_sizeA);
2258 
2259  /* try a 0 sized domain buffer */
2260  dom_sizeA = 0;
2261  acc_sizeA = MAX_PATH;
2262  LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, NULL, &dom_sizeA, &use);
2263  /* this can fail or succeed depending on OS version but the size will always be returned */
2264  ok(dom_sizeA == real_dom_sizeA + 1,
2265  "LookupAccountSidA() Expected dom_size = %u, got %u\n",
2266  real_dom_sizeA + 1, dom_sizeA);
2267 
2268  real_acc_sizeW = MAX_PATH;
2269  real_dom_sizeW = MAX_PATH;
2270  ret = LookupAccountSidW(NULL, pUsersSid, accountW, &real_acc_sizeW, domainW, &real_dom_sizeW, &use);
2271  ok(ret, "LookupAccountSidW() Expected TRUE, got FALSE\n");
2272 
2273  /* try an invalid system name */
2274  real_acc_sizeA = MAX_PATH;
2275  real_dom_sizeA = MAX_PATH;
2276  ret = LookupAccountSidA("deepthought", pUsersSid, accountA, &real_acc_sizeA, domainA, &real_dom_sizeA, &use);
2277  ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
2279  "LookupAccountSidA() Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %u\n", GetLastError());
2280 
2281  /* native windows crashes if domainW or accountW is NULL */
2282 
2283  /* try a small account buffer */
2284  acc_sizeW = 1;
2285  dom_sizeW = MAX_PATH;
2286  accountW[0] = 0;
2287  ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2288  ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n");
2290  "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
2291 
2292  /* try a 0 sized account buffer */
2293  acc_sizeW = 0;
2294  dom_sizeW = MAX_PATH;
2295  accountW[0] = 0;
2296  LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2297  /* this can fail or succeed depending on OS version but the size will always be returned */
2298  ok(acc_sizeW == real_acc_sizeW + 1,
2299  "LookupAccountSidW() Expected acc_size = %u, got %u\n",
2300  real_acc_sizeW + 1, acc_sizeW);
2301 
2302  /* try a 0 sized account buffer */
2303  acc_sizeW = 0;
2304  dom_sizeW = MAX_PATH;
2305  LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, domainW, &dom_sizeW, &use);
2306  /* this can fail or succeed depending on OS version but the size will always be returned */
2307  ok(acc_sizeW == real_acc_sizeW + 1,
2308  "LookupAccountSidW() Expected acc_size = %u, got %u\n",
2309  real_acc_sizeW + 1, acc_sizeW);
2310 
2311  /* try a small domain buffer */
2312  dom_sizeW = 1;
2313  acc_sizeW = MAX_PATH;
2314  accountW[0] = 0;
2315  ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2316  ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n");
2318  "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
2319 
2320  /* try a 0 sized domain buffer */
2321  dom_sizeW = 0;
2322  acc_sizeW = MAX_PATH;
2323  accountW[0] = 0;
2324  LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2325  /* this can fail or succeed depending on OS version but the size will always be returned */
2326  ok(dom_sizeW == real_dom_sizeW + 1,
2327  "LookupAccountSidW() Expected dom_size = %u, got %u\n",
2328  real_dom_sizeW + 1, dom_sizeW);
2329 
2330  /* try a 0 sized domain buffer */
2331  dom_sizeW = 0;
2332  acc_sizeW = MAX_PATH;
2333  LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, NULL, &dom_sizeW, &use);
2334  /* this can fail or succeed depending on OS version but the size will always be returned */
2335  ok(dom_sizeW == real_dom_sizeW + 1,
2336  "LookupAccountSidW() Expected dom_size = %u, got %u\n",
2337  real_dom_sizeW + 1, dom_sizeW);
2338 
2339  acc_sizeW = dom_sizeW = use = 0;
2340  SetLastError(0xdeadbeef);
2341  ret = LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, NULL, &dom_sizeW, &use);
2342  error = GetLastError();
2343  ok(!ret, "LookupAccountSidW failed %u\n", GetLastError());
2344  ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
2345  ok(acc_sizeW, "expected non-zero account size\n");
2346  ok(dom_sizeW, "expected non-zero domain size\n");
2347  ok(!use, "expected zero use %u\n", use);
2348 
2349  FreeSid(pUsersSid);
2350 
2351  /* Test LookupAccountSid with Sid retrieved from token information.
2352  This assumes this process is running under the account of the current user.*/
2354  ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
2355  ret = GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti);
2356  ok(!ret, "GetTokenInformation failed with error %d\n", GetLastError());
2357  ptiUser = HeapAlloc(GetProcessHeap(), 0, cbti);
2358  if (GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti))
2359  {
2360  acc_sizeA = dom_sizeA = MAX_PATH;
2361  ret = LookupAccountSidA(NULL, ptiUser->User.Sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2362  ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2363  user_sizeA = MAX_PATH;
2364  ret = GetUserNameA(usernameA , &user_sizeA);
2365  ok(ret, "GetUserNameA() Expected TRUE, got FALSE\n");
2366  ok(lstrcmpA(usernameA, accountA) == 0, "LookupAccountSidA() Expected account name: %s got: %s\n", usernameA, accountA );
2367  }
2368  HeapFree(GetProcessHeap(), 0, ptiUser);
2369 
2370  if (pCreateWellKnownSid)
2371  {
2372  trace("Well Known SIDs:\n");
2373  for (i = 0; i <= 84; i++)
2374  {
2376  if (pCreateWellKnownSid(i, NULL, &max_sid.sid, &size))
2377  {
2378  if (ConvertSidToStringSidA(&max_sid.sid, &str_sidA))
2379  {
2380  acc_sizeA = MAX_PATH;
2381  dom_sizeA = MAX_PATH;
2382  if (LookupAccountSidA(NULL, &max_sid.sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use))
2383  trace(" %d: %s %s\\%s %d\n", i, str_sidA, domainA, accountA, use);
2384  LocalFree(str_sidA);
2385  }
2386  }
2387  else
2388  {
2390  trace(" CreateWellKnownSid(%d) failed: %d\n", i, GetLastError());
2391  else
2392  trace(" %d: not supported\n", i);
2393  }
2394  }
2395 
2396  pLsaQueryInformationPolicy = (void *)GetProcAddress( hmod, "LsaQueryInformationPolicy");
2397  pLsaOpenPolicy = (void *)GetProcAddress( hmod, "LsaOpenPolicy");
2398  pLsaFreeMemory = (void *)GetProcAddress( hmod, "LsaFreeMemory");
2399  pLsaClose = (void *)GetProcAddress( hmod, "LsaClose");
2400 
2401  if (pLsaQueryInformationPolicy && pLsaOpenPolicy && pLsaFreeMemory && pLsaClose)
2402  {
2403  NTSTATUS status;
2405  LSA_OBJECT_ATTRIBUTES object_attributes;
2406 
2407  ZeroMemory(&object_attributes, sizeof(object_attributes));
2408  object_attributes.Length = sizeof(object_attributes);
2409 
2410  status = pLsaOpenPolicy( NULL, &object_attributes, POLICY_ALL_ACCESS, &handle);
2412  "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x\n", status);
2413 
2414  /* try a more restricted access mask if necessary */
2415  if (status == STATUS_ACCESS_DENIED) {
2416  trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n");
2417  status = pLsaOpenPolicy( NULL, &object_attributes, POLICY_VIEW_LOCAL_INFORMATION, &handle);
2418  ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x\n", status);
2419  }
2420 
2421  if (status == STATUS_SUCCESS)
2422  {
2424  status = pLsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (PVOID*)&info);
2425  ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy() failed, returned 0x%08x\n", status);
2426  if (status == STATUS_SUCCESS)
2427  {
2428  ok(info->DomainSid!=0, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) missing SID\n");
2429  if (info->DomainSid)
2430  {
2431  int count = *GetSidSubAuthorityCount(info->DomainSid);
2432  CopySid(GetSidLengthRequired(count), &max_sid, info->DomainSid);
2433  test_sid_str((PSID)&max_sid.sid);
2435  max_sid.sid.SubAuthorityCount = count + 1;
2436  test_sid_str((PSID)&max_sid.sid);
2438  test_sid_str((PSID)&max_sid.sid);
2440  test_sid_str((PSID)&max_sid.sid);
2442  test_sid_str((PSID)&max_sid.sid);
2444  test_sid_str((PSID)&max_sid.sid);
2446  test_sid_str((PSID)&max_sid.sid);
2448  test_sid_str((PSID)&max_sid.sid);
2450  test_sid_str((PSID)&max_sid.sid);
2452  test_sid_str((PSID)&max_sid.sid);
2454  test_sid_str((PSID)&max_sid.sid);
2456  test_sid_str((PSID)&max_sid.sid);
2458  test_sid_str((PSID)&max_sid.sid);
2459  max_sid.sid.SubAuthority[count] = 1000; /* first user account */
2460  test_sid_str((PSID)&max_sid.sid);
2461  }
2462 
2463  pLsaFreeMemory((LPVOID)info);
2464  }
2465 
2466  status = pLsaClose(handle);
2467  ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status);
2468  }
2469  }
2470  }
2471 }
2472 
2473 static BOOL get_sid_info(PSID psid, LPSTR *user, LPSTR *dom)
2474 {
2475  static CHAR account[UNLEN + 1];
2476  static CHAR domain[UNLEN + 1];
2477  DWORD size, dom_size;
2478  SID_NAME_USE use;
2479 
2480  *user = account;
2481  *dom = domain;
2482 
2483  size = dom_size = UNLEN + 1;
2484  account[0] = '\0';
2485  domain[0] = '\0';
2486  SetLastError(0xdeadbeef);
2487  return LookupAccountSidA(NULL, psid, account, &size, domain, &dom_size, &use);
2488 }
2489 
2491 {
2493  PSID domainsid = NULL;
2494  char wk_sid[SECURITY_MAX_SID_SIZE];
2495  DWORD cb;
2496 
2497  DWORD sid_size, domain_size;
2498  SID_NAME_USE sid_use;
2499  LPSTR domain, account, sid_domain, wk_domain, wk_account;
2500  PSID psid;
2501  BOOL ret ,ret2;
2502 
2503  sid_size = 0;
2504  domain_size = 0;
2505  ret = LookupAccountNameA(NULL, name, NULL, &sid_size, NULL, &domain_size, &sid_use);
2506  ok(!ret, " %s Should have failed to lookup account name\n", name);
2507  psid = HeapAlloc(GetProcessHeap(),0,sid_size);
2508  domain = HeapAlloc(GetProcessHeap(),0,domain_size);
2509  ret = LookupAccountNameA(NULL, name, psid, &sid_size, domain, &domain_size, &sid_use);
2510 
2511  if (!result)
2512  {
2513  ok(!ret, " %s Should have failed to lookup account name\n",name);
2514  goto cleanup;
2515  }
2516 
2517  AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid);
2518  cb = sizeof(wk_sid);
2519  if (!pCreateWellKnownSid(result, domainsid, wk_sid, &cb))
2520  {
2521  win_skip("SID %i is not available on the system\n",result);
2522  goto cleanup;
2523  }
2524 
2525  ret2 = get_sid_info(wk_sid, &wk_account, &wk_domain);
2526  if (!ret2 && GetLastError() == ERROR_NONE_MAPPED)
2527  {
2528  win_skip("CreateWellKnownSid() succeeded but the account '%s' is not present (W2K)\n", name);
2529  goto cleanup;
2530  }
2531 
2532  get_sid_info(psid, &account, &sid_domain);
2533 
2534  ok(ret, "Failed to lookup account name %s\n",name);
2535  ok(sid_size != 0, "sid_size was zero\n");
2536 
2537  ok(EqualSid(psid,wk_sid),"%s Sid %s fails to match well known sid %s!\n",
2538  name, debugstr_sid(psid), debugstr_sid(wk_sid));
2539 
2540  ok(!lstrcmpA(account, wk_account), "Expected %s , got %s\n", account, wk_account);
2541  ok(!lstrcmpA(domain, wk_domain), "Expected %s, got %s\n", wk_domain, domain);
2542  ok(sid_use == SidTypeWellKnownGroup , "Expected Use (5), got %d\n", sid_use);
2543 
2544 cleanup:
2545  FreeSid(domainsid);
2546  HeapFree(GetProcessHeap(),0,psid);
2547  HeapFree(GetProcessHeap(),0,domain);
2548 }
2549 
2550 static void test_LookupAccountName(void)
2551 {
2552  DWORD sid_size, domain_size, user_size;
2553  DWORD sid_save, domain_save;
2554  CHAR user_name[UNLEN + 1];
2555  CHAR computer_name[UNLEN + 1];
2556  SID_NAME_USE sid_use;
2557  LPSTR domain, account, sid_dom;
2558  PSID psid;
2559  BOOL ret;
2560 
2561  /* native crashes if (assuming all other parameters correct):
2562  * - peUse is NULL
2563  * - Sid is NULL and cbSid is > 0
2564  * - cbSid or cchReferencedDomainName are NULL
2565  * - ReferencedDomainName is NULL and cchReferencedDomainName is the correct size
2566  */
2567 
2568  user_size = UNLEN + 1;
2569  SetLastError(0xdeadbeef);
2570  ret = GetUserNameA(user_name, &user_size);
2571  ok(ret, "Failed to get user name : %d\n", GetLastError());
2572 
2573  /* get sizes */
2574  sid_size = 0;
2575  domain_size = 0;
2576  sid_use = 0xcafebabe;
2577  SetLastError(0xdeadbeef);
2578  ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, NULL, &domain_size, &sid_use);
2580  {
2581  win_skip("LookupAccountNameA is not implemented\n");
2582  return;
2583  }
2584  ok(!ret, "Expected 0, got %d\n", ret);
2586  "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2587  ok(sid_size != 0, "Expected non-zero sid size\n");
2588  ok(domain_size != 0, "Expected non-zero domain size\n");
2589  ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
2590 
2591  sid_save = sid_size;
2592  domain_save = domain_size;
2593 
2594  psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
2595  domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
2596 
2597  /* try valid account name */
2598  ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, domain, &domain_size, &sid_use);
2599  get_sid_info(psid, &account, &sid_dom);
2600  ok(ret, "Failed to lookup account name\n");
2601  ok(sid_size == GetLengthSid(psid), "Expected %d, got %d\n", GetLengthSid(psid), sid_size);
2602  ok(!lstrcmpA(account, user_name), "Expected %s, got %s\n", user_name, account);
2603  ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain);
2604  ok(domain_size == domain_save - 1, "Expected %d, got %d\n", domain_save - 1, domain_size);
2605  ok(strlen(domain) == domain_size, "Expected %d, got %d\n", lstrlenA(domain), domain_size);
2606  ok(sid_use == SidTypeUser, "Expected SidTypeUser (%d), got %d\n", SidTypeUser, sid_use);
2607  domain_size = domain_save;
2608  sid_size = sid_save;
2609 
2611  {
2612  skip("Non-English locale (test with hardcoded 'Everyone')\n");
2613  }
2614  else
2615  {
2616  ret = LookupAccountNameA(NULL, "Everyone", psid, &sid_size, domain, &domain_size, &sid_use);
2617  get_sid_info(psid, &account, &sid_dom);
2618  ok(ret, "Failed to lookup account name\n");
2619  ok(sid_size != 0, "sid_size was zero\n");
2620  ok(!lstrcmpA(account, "Everyone"), "Expected Everyone, got %s\n", account);
2621  ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain);
2622  ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
2623  ok(strlen(domain) == domain_size, "Expected %d, got %d\n", lstrlenA(domain), domain_size);
2624  ok(sid_use == SidTypeWellKnownGroup, "Expected SidTypeWellKnownGroup (%d), got %d\n", SidTypeWellKnownGroup, sid_use);
2625  domain_size = domain_save;
2626  }
2627 
2628  /* NULL Sid with zero sid size */
2629  SetLastError(0xdeadbeef);
2630  sid_size = 0;
2631  ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use);
2632  ok(!ret, "Expected 0, got %d\n", ret);
2634  "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2635  ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size);
2636  ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size);
2637 
2638  /* try cchReferencedDomainName - 1 */
2639  SetLastError(0xdeadbeef);
2640  domain_size--;
2641  ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use);
2642  ok(!ret, "Expected 0, got %d\n", ret);
2644  "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2645  ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size);
2646  ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size);
2647 
2648  /* NULL ReferencedDomainName with zero domain name size */
2649  SetLastError(0xdeadbeef);
2650  domain_size = 0;
2651  ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, NULL, &domain_size, &sid_use);
2652  ok(!ret, "Expected 0, got %d\n", ret);
2654  "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2655  ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size);
2656  ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size);
2657 
2658  HeapFree(GetProcessHeap(), 0, psid);
2659  HeapFree(GetProcessHeap(), 0, domain);
2660 
2661  /* get sizes for NULL account name */
2662  sid_size = 0;
2663  domain_size = 0;
2664  sid_use = 0xcafebabe;
2665  SetLastError(0xdeadbeef);
2666  ret = LookupAccountNameA(NULL, NULL, NULL, &sid_size, NULL, &domain_size, &sid_use);
2667  if (!ret && GetLastError() == ERROR_NONE_MAPPED)
2668  win_skip("NULL account name doesn't work on NT4\n");
2669  else
2670  {
2671  ok(!ret, "Expected 0, got %d\n", ret);
2673  "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2674  ok(sid_size != 0, "Expected non-zero sid size\n");
2675  ok(domain_size != 0, "Expected non-zero domain size\n");
2676  ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
2677 
2678  psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
2679  domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
2680 
2681  /* try NULL account name */
2682  ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain, &domain_size, &sid_use);
2683  get_sid_info(psid, &account, &sid_dom);
2684  ok(ret, "Failed to lookup account name\n");
2685  /* Using a fixed string will not work on different locales */
2686  ok(!lstrcmpiA(account, domain),
2687  "Got %s for account and %s for domain, these should be the same\n", account, domain);
2688  ok(sid_use == SidTypeDomain, "Expected SidTypeDomain (%d), got %d\n", SidTypeDomain, sid_use);
2689 
2690  HeapFree(GetProcessHeap(), 0, psid);
2691  HeapFree(GetProcessHeap(), 0, domain);
2692  }
2693 
2694  /* try an invalid account name */
2695  SetLastError(0xdeadbeef);
2696  sid_size = 0;
2697  domain_size = 0;
2698  ret = LookupAccountNameA(NULL, "oogabooga", NULL, &sid_size, NULL, &domain_size, &sid_use);
2699  ok(!ret, "Expected 0, got %d\n", ret);
2702  "Expected ERROR_NONE_MAPPED, got %d\n", GetLastError());
2703  ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
2704  ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
2705 
2706  /* try an invalid system name */
2707  SetLastError(0xdeadbeef);
2708  sid_size = 0;
2709  domain_size = 0;
2710  ret = LookupAccountNameA("deepthought", NULL, NULL, &sid_size, NULL, &domain_size, &sid_use);
2711  ok(!ret, "Expected 0, got %d\n", ret);
2713  "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
2714  ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
2715  ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
2716 
2717  /* try with the computer name as the account name */
2718  domain_size = sizeof(computer_name);
2719  GetComputerNameA(computer_name, &domain_size);
2720  sid_size = 0;
2721  domain_size = 0;
2722  ret = LookupAccountNameA(NULL, computer_name, NULL, &sid_size, NULL, &domain_size, &sid_use);
2724  GetLastError() == ERROR_NONE_MAPPED /* in a domain */ ||
2727  "LookupAccountNameA failed: %d\n", GetLastError());
2729  {
2730  psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
2731  domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
2732  ret = LookupAccountNameA(NULL, computer_name, psid, &sid_size, domain, &domain_size, &sid_use);
2733  ok(ret, "LookupAccountNameA failed: %d\n", GetLastError());
2734  ok(sid_use == SidTypeDomain ||
2735  (sid_use == SidTypeUser && ! strcmp(computer_name, user_name)), "expected SidTypeDomain for %s, got %d\n", computer_name, sid_use);
2736  HeapFree(GetProcessHeap(), 0, domain);
2737  HeapFree(GetProcessHeap(), 0, psid);
2738  }
2739 
2740  /* Well Known names */
2741  if (!pCreateWellKnownSid)
2742  {
2743  win_skip("CreateWellKnownSid not available\n");
2744  return;
2745  }
2746 
2748  {
2749  skip("Non-English locale (skipping well known name creation tests)\n");
2750  return;
2751  }
2752 
2753  check_wellknown_name("LocalService", WinLocalServiceSid);
2754  check_wellknown_name("Local Service", WinLocalServiceSid);
2755  /* 2 spaces */
2756  check_wellknown_name("Local Service", 0);
2757  check_wellknown_name("NetworkService", WinNetworkServiceSid);
2758  check_wellknown_name("Network Service", WinNetworkServiceSid);
2759 
2760  /* example of some names where the spaces are not optional */
2761  check_wellknown_name("Terminal Server User", WinTerminalServerSid);
2762  check_wellknown_name("TerminalServer User", 0);
2763  check_wellknown_name("TerminalServerUser", 0);
2764  check_wellknown_name("Terminal ServerUser", 0);
2765 
2766  check_wellknown_name("enterprise domain controllers",WinEnterpriseControllersSid);
2767  check_wellknown_name("enterprisedomain controllers", 0);
2768  check_wellknown_name("enterprise domaincontrollers", 0);
2769  check_wellknown_name("enterprisedomaincontrollers", 0);
2770 
2771  /* case insensitivity */
2772  check_wellknown_name("lOCAlServICE", WinLocalServiceSid);
2773 
2774  /* fully qualified account names */
2775  check_wellknown_name("NT AUTHORITY\\LocalService", WinLocalServiceSid);
2776  check_wellknown_name("nt authority\\Network Service", WinNetworkServiceSid);
2777  check_wellknown_name("nt authority test\\Network Service", 0);
2778  check_wellknown_name("Dummy\\Network Service", 0);
2779  check_wellknown_name("ntauthority\\Network Service", 0);
2780 }
2781 
2782 static void test_security_descriptor(void)
2783 {
2784  SECURITY_DESCRIPTOR sd, *sd_rel, *sd_rel2, *sd_abs;
2785  char buf[8192];
2786  DWORD size, size_dacl, size_sacl, size_owner, size_group;
2787  BOOL isDefault, isPresent, ret;
2788  PACL pacl, dacl, sacl;
2789  PSID psid, owner, group;
2790 
2791  SetLastError(0xdeadbeef);
2794  {
2795  win_skip("InitializeSecurityDescriptor is not implemented\n");
2796  return;
2797  }
2798 
2799  ok(GetSecurityDescriptorOwner(&sd, &psid, &isDefault), "GetSecurityDescriptorOwner failed\n");
2800  expect_eq(psid, NULL, PSID, "%p");
2801  expect_eq(isDefault, FALSE, BOOL, "%d");
2802  sd.Control |= SE_DACL_PRESENT | SE_SACL_PRESENT;
2803 
2804  SetLastError(0xdeadbeef);
2805  size = 5;
2808  ok(size > 5, "Size not increased\n");
2809  if (size <= 8192)
2810  {
2812  ok(GetSecurityDescriptorOwner(&sd, &psid, &isDefault), "GetSecurityDescriptorOwner failed\n");
2813  expect_eq(psid, NULL, PSID, "%p");
2814  expect_eq(isDefault, FALSE, BOOL, "%d");
2815  ok(GetSecurityDescriptorGroup(&sd, &psid, &isDefault), "GetSecurityDescriptorGroup failed\n");
2816  expect_eq(psid, NULL, PSID, "%p");
2817  expect_eq(isDefault, FALSE, BOOL, "%d");
2818  ok(GetSecurityDescriptorDacl(&sd, &isPresent, &pacl, &isDefault), "GetSecurityDescriptorDacl failed\n");
2819  expect_eq(isPresent, TRUE, BOOL, "%d");
2820  expect_eq(psid, NULL, PSID, "%p");
2821  expect_eq(isDefault, FALSE, BOOL, "%d");
2822  ok(GetSecurityDescriptorSacl(&sd, &isPresent, &pacl, &isDefault), "GetSecurityDescriptorSacl failed\n");
2823  expect_eq(isPresent, TRUE, BOOL, "%d");
2824  expect_eq(psid, NULL, PSID, "%p");
2825  expect_eq(isDefault, FALSE, BOOL, "%d");
2826  }
2827 
2828  ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
2829  "O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"
2830  "(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)"
2831  "(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, (void **)&sd_rel, NULL);
2832  ok(ret, "got %u\n", GetLastError());
2833 
2834  size = 0;
2835  ret = MakeSelfRelativeSD(sd_rel, NULL, &size);
2837 
2838  /* convert to absolute form */
2839  size = size_dacl = size_sacl = size_owner = size_group = 0;
2840  ret = MakeAbsoluteSD(sd_rel, NULL, &size, NULL, &size_dacl, NULL, &size_sacl, NULL, &size_owner, NULL,
2841  &size_group);
2842  ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2843 
2844  sd_abs = HeapAlloc(GetProcessHeap(), 0, size + size_dacl + size_sacl + size_owner + size_group);
2845  dacl = (PACL)(sd_abs + 1);
2846  sacl = (PACL)((char *)dacl + size_dacl);
2847  owner = (PSID)((char *)sacl + size_sacl);
2848  group = (PSID)((char *)owner + size_owner);
2849  ret = MakeAbsoluteSD(sd_rel, sd_abs, &size, dacl, &size_dacl, sacl, &size_sacl, owner, &size_owner,
2850  group, &size_group);
2851  ok(ret, "got %u\n", GetLastError());
2852 
2853  size = 0;
2854  ret = MakeSelfRelativeSD(sd_abs, NULL, &size);
2855  ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2856  ok(size == 184, "got %u\n", size);
2857 
2858  size += 4;
2859  sd_rel2 = HeapAlloc(GetProcessHeap(), 0, size);
2860  ret = MakeSelfRelativeSD(sd_abs, sd_rel2, &size);
2861  ok(ret, "got %u\n", GetLastError());
2862  ok(size == 188, "got %u\n", size);
2863 
2864  HeapFree(GetProcessHeap(), 0, sd_abs);
2865  HeapFree(GetProcessHeap(), 0, sd_rel2);
2866  LocalFree(sd_rel);
2867 }
2868 
2869 #define TEST_GRANTED_ACCESS(a,b) test_granted_access(a,b,0,__LINE__)
2870 #define TEST_GRANTED_ACCESS2(a,b,c) test_granted_access(a,b,c,__LINE__)
2872  ACCESS_MASK alt, int line)
2873 {
2874  OBJECT_BASIC_INFORMATION obj_info;
2875  NTSTATUS status;
2876 
2877  if (!pNtQueryObject)
2878  {
2879  skip_(__FILE__, line)("Not NT platform - skipping tests\n");
2880  return;
2881  }
2882 
2883  status = pNtQueryObject( handle, ObjectBasicInformation, &obj_info,
2884  sizeof(obj_info), NULL );
2885  ok_(__FILE__, line)(!status, "NtQueryObject with err: %08x\n", status);
2886  if (alt)
2887  ok_(__FILE__, line)(obj_info.GrantedAccess == access ||
2888  obj_info.GrantedAccess == alt, "Granted access should be 0x%08x "
2889  "or 0x%08x, instead of 0x%08x\n", access, alt, obj_info.GrantedAccess);
2890  else
2891  ok_(__FILE__, line)(obj_info.GrantedAccess == access, "Granted access should "
2892  "be 0x%08x, instead of 0x%08x\n", access, obj_info.GrantedAccess);
2893 }
2894 
2895 #define CHECK_SET_SECURITY(o,i,e) \
2896  do{ \
2897  BOOL res_; \
2898  DWORD err; \
2899  SetLastError( 0xdeadbeef ); \
2900  res_ = SetKernelObjectSecurity( o, i, SecurityDescriptor ); \
2901  err = GetLastError(); \
2902  if (e == ERROR_SUCCESS) \
2903  ok(res_, "SetKernelObjectSecurity failed with %d\n", err); \
2904  else \
2905  ok(!res_ && err == e, "SetKernelObjectSecurity should have failed " \
2906  "with %s, instead of %d\n", #e, err); \
2907  }while(0)
2908 
2909 static void test_process_security(void)
2910 {
2911  BOOL res;
2912  PTOKEN_USER user;
2913  PTOKEN_OWNER owner;
2915  PSID AdminSid = NULL, UsersSid = NULL, UserSid = NULL;
2916  PACL Acl = NULL, ThreadAcl = NULL;
2917  SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL;
2918  char buffer[MAX_PATH], account[MAX_PATH], domain[MAX_PATH];
2921  SECURITY_ATTRIBUTES psa, tsa;
2922  HANDLE token, event;
2923  DWORD size, acc_size, dom_size, ret;
2925  PSID EveryoneSid = NULL;
2926  SID_NAME_USE use;
2927 
2928  Acl = HeapAlloc(GetProcessHeap(), 0, 256);
2929  res = InitializeAcl(Acl, 256, ACL_REVISION);
2931  {
2932  win_skip("ACLs not implemented - skipping tests\n");
2933  HeapFree(GetProcessHeap(), 0, Acl);
2934  return;
2935  }
2936  ok(res, "InitializeAcl failed with error %d\n", GetLastError());
2937 
2938  res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
2939  ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
2940 
2941  /* get owner from the token we might be running as a user not admin */
2943  ok(res, "OpenProcessToken failed with error %d\n", GetLastError());
2944  if (!res)
2945  {
2946  HeapFree(GetProcessHeap(), 0, Acl);
2947  return;
2948  }
2949 
2951  ok(!res, "Expected failure, got %d\n", res);
2953  "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2954 
2955  owner = HeapAlloc(GetProcessHeap(), 0, size);
2956  res = GetTokenInformation( token, TokenOwner, owner, size, &size );
2957  ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
2958  AdminSid = owner->Owner;
2960 
2962  ok(!res, "Expected failure, got %d\n", res);
2964  "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2965 
2968  ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
2969  UsersSid = group->PrimaryGroup;
2970  test_sid_str(UsersSid);
2971 
2972  acc_size = sizeof(account);
2973  dom_size = sizeof(domain);
2974  ret = LookupAccountSidA( NULL, UsersSid, account, &acc_size, domain, &dom_size, &use );
2975  ok(ret, "LookupAccountSid failed with %d\n", ret);
2976  ok(use == SidTypeGroup, "expect SidTypeGroup, got %d\n", use);
2977  ok(!strcmp(account, "None"), "expect None, got %s\n", account);
2978 
2980  ok(!res, "Expected failure, got %d\n", res);
2982  "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2983 
2984  user = HeapAlloc(GetProcessHeap(), 0, size);
2986  ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
2987  UserSid = user->User.Sid;
2988  test_sid_str(UserSid);
2989  ok(EqualPrefixSid(UsersSid, UserSid), "TokenPrimaryGroup Sid and TokenUser Sid don't match.\n");
2990 
2991  CloseHandle( token );
2992  if (!res)
2993  {
2994  HeapFree(GetProcessHeap(), 0, group);
2995  HeapFree(GetProcessHeap(), 0, owner);
2996  HeapFree(GetProcessHeap(), 0, user);
2997  HeapFree(GetProcessHeap(), 0, Acl);
2998  return;
2999  }
3000 
3002  ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError());
3004  ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
3005 
3008  ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError());
3009 
3010  event = CreateEventA( NULL, TRUE, TRUE, "test_event" );
3011  ok(event != NULL, "CreateEvent %d\n", GetLastError());
3012 
3013  SecurityDescriptor->Revision = 0;
3016 
3021  /* NULL DACL is valid and means that everyone has access */
3022  SecurityDescriptor->Control |= SE_DACL_PRESENT;
3024 
3025  /* Set owner and group and dacl */
3027  ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError());
3029  test_owner_equal( event, AdminSid, __LINE__ );
3030 
3032  ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
3034  test_group_equal( event, EveryoneSid, __LINE__ );
3035 
3037  ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
3039  /* setting a dacl should not change the owner or group */
3040  test_owner_equal( event, AdminSid, __LINE__ );
3041  test_group_equal( event, EveryoneSid, __LINE__ );
3042 
3043  /* Test again with a different SID in case the previous SID also happens to
3044  * be the one that is incorrectly replacing the group. */
3046  ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
3048  test_group_equal( event, UsersSid, __LINE__ );
3049 
3051  ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
3053  test_group_equal( event, UsersSid, __LINE__ );
3054 
3055  sprintf(buffer, "%s tests/security.c test", myARGV[0]);
3056  memset(&startup, 0, sizeof(startup));
3057  startup.cb = sizeof(startup);
3058  startup.dwFlags = STARTF_USESHOWWINDOW;
3059  startup.wShowWindow = SW_SHOWNORMAL;
3060 
3061  psa.nLength = sizeof(psa);
3062  psa.lpSecurityDescriptor = SecurityDescriptor;
3063  psa.bInheritHandle = TRUE;
3064 
3065  ThreadSecurityDescriptor = HeapAlloc( GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH );
3066  res = InitializeSecurityDescriptor( ThreadSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
3067  ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError());
3068 
3069  ThreadAcl = HeapAlloc( GetProcessHeap(), 0, 256 );
3070  res = InitializeAcl( ThreadAcl, 256, ACL_REVISION );
3071  ok(res, "InitializeAcl failed with error %d\n", GetLastError());
3073  ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError() );
3075  ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
3076 
3077  res = SetSecurityDescriptorOwner( ThreadSecurityDescriptor, AdminSid, FALSE );
3078  ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError());
3079  res = SetSecurityDescriptorGroup( ThreadSecurityDescriptor, UsersSid, FALSE );
3080  ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
3081  res = SetSecurityDescriptorDacl( ThreadSecurityDescriptor, TRUE, ThreadAcl, FALSE );
3082  ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
3083 
3084  tsa.nLength = sizeof(tsa);
3085  tsa.lpSecurityDescriptor = ThreadSecurityDescriptor;
3086  tsa.bInheritHandle = TRUE;
3087 
3088  /* Doesn't matter what ACL say we should get full access for ourselves */
3089  res = CreateProcessA( NULL, buffer, &psa, &tsa, FALSE, 0, NULL, NULL, &startup, &info );
3090  ok(res, "CreateProcess with err:%d\n", GetLastError());
3095  winetest_wait_child_process( info.hProcess );
3096 
3097  FreeSid(EveryoneSid);
3098  CloseHandle( info.hProcess );
3099  CloseHandle( info.hThread );
3100  CloseHandle( event );
3101  HeapFree(GetProcessHeap(), 0, group);
3102  HeapFree(GetProcessHeap(), 0, owner);
3103  HeapFree(GetProcessHeap(), 0, user);
3104  HeapFree(GetProcessHeap(), 0, Acl);
3106  HeapFree(GetProcessHeap(), 0, ThreadAcl);
3107  HeapFree(GetProcessHeap(), 0, ThreadSecurityDescriptor);
3108 }
3109 
3111 {
3112  HANDLE handle, handle1;
3113  BOOL ret;
3114  DWORD err;
3115 
3117  ok(handle != NULL, "OpenProcess(PROCESS_TERMINATE) with err:%d\n", GetLastError());
3119 
3121  &handle1, 0, TRUE, DUPLICATE_SAME_ACCESS );
3122  ok(ret, "duplicating handle err:%d\n", GetLastError());
3124 
3125  CloseHandle( handle1 );
3126 
3127  SetLastError( 0xdeadbeef );
3129  &handle1, PROCESS_ALL_ACCESS, TRUE, 0 );
3130  err = GetLastError();
3131  ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed "
3132  "with STATUS_ACCESS_DENIED, instead of err:%d\n", err);
3133 
3134  CloseHandle( handle );
3135 
3136  /* These two should fail - they are denied by ACL */
3138  ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n");
3140  ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n");
3141 
3142  /* Documented privilege elevation */
3145  ok(ret, "duplicating handle err:%d\n", GetLastError());
3148 
3149  CloseHandle( handle );
3150 
3151  /* Same only explicitly asking for all access rights */
3153  &handle, PROCESS_ALL_ACCESS, TRUE, 0 );
3154  ok(ret, "duplicating handle err:%d\n", GetLastError());
3158  &handle1, PROCESS_VM_READ, TRUE, 0 );
3159  ok(ret, "duplicating handle err:%d\n", GetLastError());
3161  CloseHandle( handle1 );
3162  CloseHandle( handle );
3163 
3164  /* Test thread security */
3166  ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%d\n", GetLastError());
3168  CloseHandle( handle );
3169 
3171  ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n");
3172 }
3173 
3174 static void test_impersonation_level(void)
3175 {
3176  HANDLE Token, ProcessToken;
3177  HANDLE Token2;
3178  DWORD Size;
3180  TOKEN_USER *User;
3181  PRIVILEGE_SET *PrivilegeSet;
3183  BOOL ret;
3184  HKEY hkey;
3185  DWORD error;
3186 
3187  if( !pDuplicateTokenEx ) {
3188  win_skip("DuplicateTokenEx is not available\n");
3189  return;
3190  }
3191  SetLastError(0xdeadbeef);
3194  {
3195  win_skip("ImpersonateSelf is not implemented\n");
3196  return;
3197  }
3198  ok(ret, "ImpersonateSelf(SecurityAnonymous) failed with error %d\n", GetLastError());
3200  ok(!ret, "OpenThreadToken should have failed\n");
3201  error = GetLastError();
3202  ok(error == ERROR_CANT_OPEN_ANONYMOUS, "OpenThreadToken on anonymous token should have returned ERROR_CANT_OPEN_ANONYMOUS instead of %d\n", error);
3203  /* can't perform access check when opening object against an anonymous impersonation token */
3204  todo_wine {
3205  error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3207  "RegOpenKeyEx failed with %d\n", error);
3208  }
3209  RevertToSelf();
3210 
3212  ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
3213 
3214  ret = pDuplicateTokenEx(ProcessToken,
3217  ok(ret, "DuplicateTokenEx failed with error %d\n", GetLastError());
3218  /* can't increase the impersonation level */
3220  error = GetLastError();
3222  "Duplicating a token and increasing the impersonation level should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error);
3223  /* we can query anything from an anonymous token, including the user */
3225  error = GetLastError();
3226  ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error);
3227  User = HeapAlloc(GetProcessHeap(), 0, Size);
3229  ok(ret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
3230  HeapFree(GetProcessHeap(), 0, User);
3231 
3232  /* PrivilegeCheck fails with SecurityAnonymous level */
3234  error = GetLastError();
3235  ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error);
3238  ok(ret, "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError());
3239 
3240  PrivilegeSet = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PRIVILEGE_SET, Privilege[Privileges->PrivilegeCount]));
3241  PrivilegeSet->PrivilegeCount = Privileges->PrivilegeCount;
3242  memcpy(PrivilegeSet->Privilege, Privileges->Privileges, PrivilegeSet->PrivilegeCount * sizeof(PrivilegeSet->Privilege[0]));
3243  PrivilegeSet->Control = PRIVILEGE_SET_ALL_NECESSARY;
3245 
3246  ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3247  error = GetLastError();
3248  ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, "PrivilegeCheck for SecurityAnonymous token should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error);
3249 
3250  CloseHandle(Token);
3251 
3253  ok(ret, "ImpersonateSelf(SecurityIdentification) failed with error %d\n", GetLastError());
3255  ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
3256 
3257  /* can't perform access check when opening object against an identification impersonation token */
3258  error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3259  todo_wine {
3261  "RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE or ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error);
3262  }
3263  ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3264  ok(ret, "PrivilegeCheck for SecurityIdentification failed with error %d\n", GetLastError());
3265  CloseHandle(Token);
3266  RevertToSelf();
3267 
3269  ok(ret, "ImpersonateSelf(SecurityImpersonation) failed with error %d\n", GetLastError());
3271  ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
3272  error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3273  ok(error == ERROR_SUCCESS, "RegOpenKeyEx should have succeeded instead of failing with %d\n", error);
3274  RegCloseKey(hkey);
3275  ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3276  ok(ret, "PrivilegeCheck for SecurityImpersonation failed with error %d\n", GetLastError());
3277  RevertToSelf();
3278 
3279  CloseHandle(Token);
3280  CloseHandle(ProcessToken);
3281 
3282  HeapFree(GetProcessHeap(), 0, PrivilegeSet);
3283 }
3284 
3285 static void test_SetEntriesInAclW(void)
3286 {
3287  DWORD res;
3288  PSID EveryoneSid = NULL, UsersSid = NULL;
3289  PACL OldAcl = NULL, NewAcl;
3292  EXPLICIT_ACCESSW ExplicitAccess;
3293  static const WCHAR wszEveryone[] = {'E','v','e','r','y','o','n','e',0};
3294  static const WCHAR wszCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'};
3295 
3296  if (!pSetEntriesInAclW)
3297  {
3298