ReactOS 0.4.16-dev-456-ga97fcf1
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
70static BOOL (WINAPI *pAddAccessAllowedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
71static BOOL (WINAPI *pAddAccessDeniedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
72static BOOL (WINAPI *pAddAuditAccessAceEx)(PACL, DWORD, DWORD, DWORD, PSID, BOOL, BOOL);
73static BOOL (WINAPI *pAddMandatoryAce)(PACL,DWORD,DWORD,DWORD,PSID);
74static VOID (WINAPI *pBuildTrusteeWithSidA)( PTRUSTEEA pTrustee, PSID pSid );
75static VOID (WINAPI *pBuildTrusteeWithNameA)( PTRUSTEEA pTrustee, LPSTR pName );
76static VOID (WINAPI *pBuildTrusteeWithObjectsAndNameA)( PTRUSTEEA pTrustee,
82static VOID (WINAPI *pBuildTrusteeWithObjectsAndSidA)( PTRUSTEEA pTrustee,
86 PSID pSid );
87static LPSTR (WINAPI *pGetTrusteeNameA)( PTRUSTEEA pTrustee );
88static BOOL (WINAPI *pMakeSelfRelativeSD)( PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, LPDWORD );
89static BOOL (WINAPI *pConvertStringSidToSidA)( LPCSTR str, PSID pSid );
90static BOOL (WINAPI *pCheckTokenMembership)(HANDLE, PSID, PBOOL);
91static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR, DWORD,
93static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorW)(LPCWSTR, DWORD,
95static BOOL (WINAPI *pConvertSecurityDescriptorToStringSecurityDescriptorA)(PSECURITY_DESCRIPTOR, DWORD,
97static BOOL (WINAPI *pGetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
99static BOOL (WINAPI *pSetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
101static DWORD (WINAPI *pGetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
102 PSID*, PSID*, PACL*, PACL*,
104static DWORD (WINAPI *pSetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
106static PDWORD (WINAPI *pGetSidSubAuthority)(PSID, DWORD);
107static PUCHAR (WINAPI *pGetSidSubAuthorityCount)(PSID);
108static BOOL (WINAPI *pIsValidSid)(PSID);
109static DWORD (WINAPI *pRtlAdjustPrivilege)(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN);
110static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*);
111static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,
113
114static NTSTATUS (WINAPI *pLsaQueryInformationPolicy)(LSA_HANDLE,POLICY_INFORMATION_CLASS,PVOID*);
115static NTSTATUS (WINAPI *pLsaClose)(LSA_HANDLE);
116static NTSTATUS (WINAPI *pLsaFreeMemory)(PVOID);
119static DWORD (WINAPI *pSetEntriesInAclW)(ULONG, PEXPLICIT_ACCESSW, PACL, PACL*);
120static DWORD (WINAPI *pSetEntriesInAclA)(ULONG, PEXPLICIT_ACCESSA, PACL, PACL*);
121static BOOL (WINAPI *pSetSecurityDescriptorControl)(PSECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL,
123static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
125static DWORD (WINAPI *pSetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
126 PSID, PSID, PACL, PACL);
129static BOOL (WINAPI *pCreateRestrictedToken)(HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD,
131static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
132static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*);
133static NTSTATUS (WINAPI *pNtSetSecurityObject)(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
135static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*);
136static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_STRING,BOOLEAN);
137static BOOL (WINAPI *pGetWindowsAccountDomainSid)(PSID,PSID,DWORD*);
138static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ);
139static NTSTATUS (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
140static PSID_IDENTIFIER_AUTHORITY (WINAPI *pGetSidIdentifierAuthority)(PSID);
141static DWORD (WINAPI *pGetExplicitEntriesFromAclW)(PACL,PULONG,PEXPLICIT_ACCESSW*);
142
144static int myARGC;
145static char** myARGV;
146
147#define SID_SLOTS 4
148static char debugsid_str[SID_SLOTS][256];
149static int debugsid_index = 0;
150static 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
175static void init(void)
176{
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
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
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
291static 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;
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
505static 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;
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
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
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
688static 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);
712 "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %d\n",
713 GetLastError());
714}
715
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
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
863static void test_luid(void)
864{
868}
869
870static 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
991cleanup:
992 /* Remove temporary file and directory */
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
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
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
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());
1165todo_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());
1182todo_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());
1191todo_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());
1200todo_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());
1209todo_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
1225 HeapFree(GetProcessHeap(), 0, sd);
1226}
1227
1228static 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;
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());
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();
1565 ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1566 "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
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();
1580 ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1581 "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1583 ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
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());
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());
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
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
1760
1761 SetLastError(0xdeadbeef);
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)
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 */
1782static void test_token_attr(void)
1783{
1784 HANDLE Token, ImpersonationToken;
1785 DWORD Size, Size2;
1787 TOKEN_GROUPS *Groups;
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);
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;
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;
1834 ret = GetTokenInformation(Token, TokenGroups, Groups, Size2, &Size);
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
1841 HeapFree(GetProcessHeap(), 0, Groups);
1842
1843 SetLastError(0xdeadbeef);
1846 "GetTokenInformation(TokenGroups) %s with error %d\n",
1847 ret ? "succeeded" : "failed", GetLastError());
1848 Groups = HeapAlloc(GetProcessHeap(), 0, Size);
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 }
1874 HeapFree(GetProcessHeap(), 0, Groups);
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 */
1893 todo_wine win_skip("TokenLogonSid not supported. Skipping tests\n");
1894 else
1895 {
1897 "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError());
1898 Groups = HeapAlloc(GetProcessHeap(), 0, Size);
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
1917 HeapFree(GetProcessHeap(), 0, Groups);
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
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
1995}
1996
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
2019}
2020
2021typedef union _MAX_SID
2022{
2026
2027static 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 {
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
2049static const struct well_known_sid_value
2050{
2052 const char *sid_string;
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"},
2088
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
2118 ret = pCreateWellKnownSid(WinInteractiveSid, NULL, sid, &size);
2119 ok(ret, "CreateWellKnownSid failed %u\n", GetLastError());
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
2165static 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 {
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 */
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
2473static 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
2544cleanup:
2545 FreeSid(domainsid);
2546 HeapFree(GetProcessHeap(),0,psid);
2548}
2549
2550static 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];
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);
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 */
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);
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);
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
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;
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
2909static void test_process_security(void)
2910{
2911 BOOL res;
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;
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);
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
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 {
2995 HeapFree(GetProcessHeap(), 0, owner);
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 */
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());
3096
3097 FreeSid(EveryoneSid);
3098 CloseHandle( info.hProcess );
3099 CloseHandle( info.hThread );
3100 CloseHandle( event );
3102 HeapFree(GetProcessHeap(), 0, owner);
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 );