1c2c66affSColin Finck /*
2c2c66affSColin Finck * Unit tests for security functions
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright (c) 2004 Mike McCormack
5c2c66affSColin Finck * Copyright (c) 2011,2013,2014,2016 Dmitry Timoshkov
6c2c66affSColin Finck *
7c2c66affSColin Finck * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck * License as published by the Free Software Foundation; either
10c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck *
12c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15c2c66affSColin Finck * Lesser General Public License for more details.
16c2c66affSColin Finck *
17c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck */
21c2c66affSColin Finck
22*3c1b7834SAmine Khaldi #include <stdarg.h>
23*3c1b7834SAmine Khaldi #include <stdio.h>
24*3c1b7834SAmine Khaldi
25*3c1b7834SAmine Khaldi #include "ntstatus.h"
26*3c1b7834SAmine Khaldi #define WIN32_NO_STATUS
27*3c1b7834SAmine Khaldi #include "windef.h"
28*3c1b7834SAmine Khaldi #include "winbase.h"
29*3c1b7834SAmine Khaldi #include "winerror.h"
30*3c1b7834SAmine Khaldi #include "winternl.h"
31*3c1b7834SAmine Khaldi #include "aclapi.h"
32*3c1b7834SAmine Khaldi #include "winnt.h"
33*3c1b7834SAmine Khaldi #include "sddl.h"
34*3c1b7834SAmine Khaldi #include "ntsecapi.h"
35*3c1b7834SAmine Khaldi #include "lmcons.h"
36*3c1b7834SAmine Khaldi
37*3c1b7834SAmine Khaldi #include "wine/test.h"
38c2c66affSColin Finck
39c2c66affSColin Finck /* FIXME: Inspect */
40c2c66affSColin Finck #define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3)
41c2c66affSColin Finck #define GetCurrentThreadToken() ((HANDLE)~(ULONG_PTR)4)
42c2c66affSColin Finck #define GetCurrentThreadEffectiveToken() ((HANDLE)~(ULONG_PTR)5)
43c2c66affSColin Finck
44c2c66affSColin Finck #ifndef PROCESS_QUERY_LIMITED_INFORMATION
45c2c66affSColin Finck #define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
46c2c66affSColin Finck #endif
47c2c66affSColin Finck
48c2c66affSColin Finck /* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
49c2c66affSColin Finck #define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000)
50c2c66affSColin Finck #define PROCESS_ALL_ACCESS_VISTA (PROCESS_ALL_ACCESS | 0xf000)
51c2c66affSColin Finck
52c2c66affSColin Finck #ifndef EVENT_QUERY_STATE
53c2c66affSColin Finck #define EVENT_QUERY_STATE 0x0001
54c2c66affSColin Finck #endif
55c2c66affSColin Finck
56c2c66affSColin Finck #ifndef SEMAPHORE_QUERY_STATE
57c2c66affSColin Finck #define SEMAPHORE_QUERY_STATE 0x0001
58c2c66affSColin Finck #endif
59c2c66affSColin Finck
60c2c66affSColin Finck #ifndef THREAD_SET_LIMITED_INFORMATION
61c2c66affSColin Finck #define THREAD_SET_LIMITED_INFORMATION 0x0400
62c2c66affSColin Finck #define THREAD_QUERY_LIMITED_INFORMATION 0x0800
63c2c66affSColin Finck #endif
64c2c66affSColin Finck
65c2c66affSColin Finck #define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
66c2c66affSColin Finck #define THREAD_ALL_ACCESS_VISTA (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff)
67c2c66affSColin Finck
68c2c66affSColin Finck #define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_, #expr " expected " format " got " format "\n", (value), (ret_)); }
69c2c66affSColin Finck
70c2c66affSColin Finck static BOOL (WINAPI *pAddAccessAllowedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
71c2c66affSColin Finck static BOOL (WINAPI *pAddAccessDeniedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
72c2c66affSColin Finck static BOOL (WINAPI *pAddAuditAccessAceEx)(PACL, DWORD, DWORD, DWORD, PSID, BOOL, BOOL);
73c2c66affSColin Finck static BOOL (WINAPI *pAddMandatoryAce)(PACL,DWORD,DWORD,DWORD,PSID);
74c2c66affSColin Finck static VOID (WINAPI *pBuildTrusteeWithSidA)( PTRUSTEEA pTrustee, PSID pSid );
75c2c66affSColin Finck static VOID (WINAPI *pBuildTrusteeWithNameA)( PTRUSTEEA pTrustee, LPSTR pName );
76c2c66affSColin Finck static VOID (WINAPI *pBuildTrusteeWithObjectsAndNameA)( PTRUSTEEA pTrustee,
77c2c66affSColin Finck POBJECTS_AND_NAME_A pObjName,
78c2c66affSColin Finck SE_OBJECT_TYPE ObjectType,
79c2c66affSColin Finck LPSTR ObjectTypeName,
80c2c66affSColin Finck LPSTR InheritedObjectTypeName,
81c2c66affSColin Finck LPSTR Name );
82c2c66affSColin Finck static VOID (WINAPI *pBuildTrusteeWithObjectsAndSidA)( PTRUSTEEA pTrustee,
83c2c66affSColin Finck POBJECTS_AND_SID pObjSid,
84c2c66affSColin Finck GUID* pObjectGuid,
85c2c66affSColin Finck GUID* pInheritedObjectGuid,
86c2c66affSColin Finck PSID pSid );
87c2c66affSColin Finck static LPSTR (WINAPI *pGetTrusteeNameA)( PTRUSTEEA pTrustee );
88c2c66affSColin Finck static BOOL (WINAPI *pMakeSelfRelativeSD)( PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, LPDWORD );
89c2c66affSColin Finck static BOOL (WINAPI *pConvertStringSidToSidA)( LPCSTR str, PSID pSid );
90c2c66affSColin Finck static BOOL (WINAPI *pCheckTokenMembership)(HANDLE, PSID, PBOOL);
91c2c66affSColin Finck static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR, DWORD,
92c2c66affSColin Finck PSECURITY_DESCRIPTOR*, PULONG );
93c2c66affSColin Finck static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorW)(LPCWSTR, DWORD,
94c2c66affSColin Finck PSECURITY_DESCRIPTOR*, PULONG );
95c2c66affSColin Finck static BOOL (WINAPI *pConvertSecurityDescriptorToStringSecurityDescriptorA)(PSECURITY_DESCRIPTOR, DWORD,
96c2c66affSColin Finck SECURITY_INFORMATION, LPSTR *, PULONG );
97c2c66affSColin Finck static BOOL (WINAPI *pGetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
98c2c66affSColin Finck PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
99c2c66affSColin Finck static BOOL (WINAPI *pSetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
100c2c66affSColin Finck PSECURITY_DESCRIPTOR);
101c2c66affSColin Finck static DWORD (WINAPI *pGetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
102c2c66affSColin Finck PSID*, PSID*, PACL*, PACL*,
103c2c66affSColin Finck PSECURITY_DESCRIPTOR*);
104c2c66affSColin Finck static DWORD (WINAPI *pSetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
105c2c66affSColin Finck PSID, PSID, PACL, PACL);
106c2c66affSColin Finck static PDWORD (WINAPI *pGetSidSubAuthority)(PSID, DWORD);
107c2c66affSColin Finck static PUCHAR (WINAPI *pGetSidSubAuthorityCount)(PSID);
108c2c66affSColin Finck static BOOL (WINAPI *pIsValidSid)(PSID);
109c2c66affSColin Finck static DWORD (WINAPI *pRtlAdjustPrivilege)(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN);
110c2c66affSColin Finck static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*);
111c2c66affSColin Finck static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,
112c2c66affSColin Finck SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE);
113c2c66affSColin Finck
114c2c66affSColin Finck static NTSTATUS (WINAPI *pLsaQueryInformationPolicy)(LSA_HANDLE,POLICY_INFORMATION_CLASS,PVOID*);
115c2c66affSColin Finck static NTSTATUS (WINAPI *pLsaClose)(LSA_HANDLE);
116c2c66affSColin Finck static NTSTATUS (WINAPI *pLsaFreeMemory)(PVOID);
117c2c66affSColin Finck static NTSTATUS (WINAPI *pLsaOpenPolicy)(PLSA_UNICODE_STRING,PLSA_OBJECT_ATTRIBUTES,ACCESS_MASK,PLSA_HANDLE);
118c2c66affSColin Finck static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
119c2c66affSColin Finck static DWORD (WINAPI *pSetEntriesInAclW)(ULONG, PEXPLICIT_ACCESSW, PACL, PACL*);
120c2c66affSColin Finck static DWORD (WINAPI *pSetEntriesInAclA)(ULONG, PEXPLICIT_ACCESSA, PACL, PACL*);
121c2c66affSColin Finck static BOOL (WINAPI *pSetSecurityDescriptorControl)(PSECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL,
122c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL);
123c2c66affSColin Finck static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
124c2c66affSColin Finck PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);
125c2c66affSColin Finck static DWORD (WINAPI *pSetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
126c2c66affSColin Finck PSID, PSID, PACL, PACL);
127c2c66affSColin Finck static NTSTATUS (WINAPI *pNtAccessCheck)(PSECURITY_DESCRIPTOR, HANDLE, ACCESS_MASK, PGENERIC_MAPPING,
128c2c66affSColin Finck PPRIVILEGE_SET, PULONG, PULONG, NTSTATUS*);
129c2c66affSColin Finck static BOOL (WINAPI *pCreateRestrictedToken)(HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD,
130c2c66affSColin Finck PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
131c2c66affSColin Finck static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
132c2c66affSColin Finck static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*);
133c2c66affSColin Finck static NTSTATUS (WINAPI *pNtSetSecurityObject)(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
134c2c66affSColin Finck static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG);
135c2c66affSColin Finck static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*);
136c2c66affSColin Finck static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_STRING,BOOLEAN);
137c2c66affSColin Finck static BOOL (WINAPI *pGetWindowsAccountDomainSid)(PSID,PSID,DWORD*);
138c2c66affSColin Finck static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ);
139c2c66affSColin Finck static NTSTATUS (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
140c2c66affSColin Finck static PSID_IDENTIFIER_AUTHORITY (WINAPI *pGetSidIdentifierAuthority)(PSID);
141c2c66affSColin Finck static DWORD (WINAPI *pGetExplicitEntriesFromAclW)(PACL,PULONG,PEXPLICIT_ACCESSW*);
142c2c66affSColin Finck
143c2c66affSColin Finck static HMODULE hmod;
144c2c66affSColin Finck static int myARGC;
145c2c66affSColin Finck static char** myARGV;
146c2c66affSColin Finck
147c2c66affSColin Finck #define SID_SLOTS 4
148c2c66affSColin Finck static char debugsid_str[SID_SLOTS][256];
149c2c66affSColin Finck static int debugsid_index = 0;
debugstr_sid(PSID sid)150c2c66affSColin Finck static const char* debugstr_sid(PSID sid)
151c2c66affSColin Finck {
152c2c66affSColin Finck LPSTR sidstr;
153c2c66affSColin Finck DWORD le = GetLastError();
154c2c66affSColin Finck char* res = debugsid_str[debugsid_index];
155c2c66affSColin Finck debugsid_index = (debugsid_index + 1) % SID_SLOTS;
156561bed7bSAmine Khaldi
157561bed7bSAmine Khaldi if (!ConvertSidToStringSidA(sid, &sidstr))
158c2c66affSColin Finck sprintf(res, "ConvertSidToStringSidA failed le=%u", GetLastError());
159c2c66affSColin Finck else if (strlen(sidstr) > sizeof(*debugsid_str) - 1)
160c2c66affSColin Finck {
161c2c66affSColin Finck memcpy(res, sidstr, sizeof(*debugsid_str) - 4);
162c2c66affSColin Finck strcpy(res + sizeof(*debugsid_str) - 4, "...");
163c2c66affSColin Finck LocalFree(sidstr);
164c2c66affSColin Finck }
165c2c66affSColin Finck else
166c2c66affSColin Finck {
167c2c66affSColin Finck strcpy(res, sidstr);
168c2c66affSColin Finck LocalFree(sidstr);
169c2c66affSColin Finck }
170c2c66affSColin Finck /* Restore the last error in case ConvertSidToStringSidA() modified it */
171c2c66affSColin Finck SetLastError(le);
172c2c66affSColin Finck return res;
173c2c66affSColin Finck }
174c2c66affSColin Finck
init(void)175c2c66affSColin Finck static void init(void)
176c2c66affSColin Finck {
177c2c66affSColin Finck HMODULE hntdll;
178c2c66affSColin Finck
179c2c66affSColin Finck hntdll = GetModuleHandleA("ntdll.dll");
180c2c66affSColin Finck pNtQueryObject = (void *)GetProcAddress( hntdll, "NtQueryObject" );
181c2c66affSColin Finck pNtAccessCheck = (void *)GetProcAddress( hntdll, "NtAccessCheck" );
182c2c66affSColin Finck pNtSetSecurityObject = (void *)GetProcAddress(hntdll, "NtSetSecurityObject");
183c2c66affSColin Finck pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
184c2c66affSColin Finck pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
185c2c66affSColin Finck pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");
186c2c66affSColin Finck pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString");
187c2c66affSColin Finck pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
188c2c66affSColin Finck
189c2c66affSColin Finck hmod = GetModuleHandleA("advapi32.dll");
190c2c66affSColin Finck pAddAccessAllowedAceEx = (void *)GetProcAddress(hmod, "AddAccessAllowedAceEx");
191c2c66affSColin Finck pAddAccessDeniedAceEx = (void *)GetProcAddress(hmod, "AddAccessDeniedAceEx");
192c2c66affSColin Finck pAddAuditAccessAceEx = (void *)GetProcAddress(hmod, "AddAuditAccessAceEx");
193c2c66affSColin Finck pAddMandatoryAce = (void *)GetProcAddress(hmod, "AddMandatoryAce");
194c2c66affSColin Finck pCheckTokenMembership = (void *)GetProcAddress(hmod, "CheckTokenMembership");
195c2c66affSColin Finck pConvertStringSecurityDescriptorToSecurityDescriptorA =
196c2c66affSColin Finck (void *)GetProcAddress(hmod, "ConvertStringSecurityDescriptorToSecurityDescriptorA" );
197c2c66affSColin Finck pConvertStringSecurityDescriptorToSecurityDescriptorW =
198c2c66affSColin Finck (void *)GetProcAddress(hmod, "ConvertStringSecurityDescriptorToSecurityDescriptorW" );
199c2c66affSColin Finck pConvertSecurityDescriptorToStringSecurityDescriptorA =
200c2c66affSColin Finck (void *)GetProcAddress(hmod, "ConvertSecurityDescriptorToStringSecurityDescriptorA" );
201c2c66affSColin Finck pGetFileSecurityA = (void *)GetProcAddress(hmod, "GetFileSecurityA" );
202c2c66affSColin Finck pSetFileSecurityA = (void *)GetProcAddress(hmod, "SetFileSecurityA" );
203c2c66affSColin Finck pCreateWellKnownSid = (void *)GetProcAddress( hmod, "CreateWellKnownSid" );
204c2c66affSColin Finck pGetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "GetNamedSecurityInfoA");
205c2c66affSColin Finck pSetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "SetNamedSecurityInfoA");
206c2c66affSColin Finck pGetSidSubAuthority = (void *)GetProcAddress(hmod, "GetSidSubAuthority");
207c2c66affSColin Finck pGetSidSubAuthorityCount = (void *)GetProcAddress(hmod, "GetSidSubAuthorityCount");
208c2c66affSColin Finck pIsValidSid = (void *)GetProcAddress(hmod, "IsValidSid");
209c2c66affSColin Finck pMakeSelfRelativeSD = (void *)GetProcAddress(hmod, "MakeSelfRelativeSD");
210c2c66affSColin Finck pSetEntriesInAclW = (void *)GetProcAddress(hmod, "SetEntriesInAclW");
211c2c66affSColin Finck pSetEntriesInAclA = (void *)GetProcAddress(hmod, "SetEntriesInAclA");
212c2c66affSColin Finck pSetSecurityDescriptorControl = (void *)GetProcAddress(hmod, "SetSecurityDescriptorControl");
213c2c66affSColin Finck pGetSecurityInfo = (void *)GetProcAddress(hmod, "GetSecurityInfo");
214c2c66affSColin Finck pSetSecurityInfo = (void *)GetProcAddress(hmod, "SetSecurityInfo");
215c2c66affSColin Finck pCreateRestrictedToken = (void *)GetProcAddress(hmod, "CreateRestrictedToken");
216c2c66affSColin Finck pConvertStringSidToSidA = (void *)GetProcAddress(hmod, "ConvertStringSidToSidA");
217c2c66affSColin Finck pGetAclInformation = (void *)GetProcAddress(hmod, "GetAclInformation");
218c2c66affSColin Finck pGetAce = (void *)GetProcAddress(hmod, "GetAce");
219c2c66affSColin Finck pGetWindowsAccountDomainSid = (void *)GetProcAddress(hmod, "GetWindowsAccountDomainSid");
220c2c66affSColin Finck pGetSidIdentifierAuthority = (void *)GetProcAddress(hmod, "GetSidIdentifierAuthority");
221c2c66affSColin Finck pDuplicateTokenEx = (void *)GetProcAddress(hmod, "DuplicateTokenEx");
222561bed7bSAmine Khaldi pGetExplicitEntriesFromAclW = (void *)GetProcAddress(hmod, "GetExplicitEntriesFromAclW");
223c2c66affSColin Finck
224c2c66affSColin Finck myARGC = winetest_get_mainargs( &myARGV );
225c2c66affSColin Finck }
226c2c66affSColin Finck
test_get_security_descriptor(HANDLE handle,int line)227c2c66affSColin Finck static SECURITY_DESCRIPTOR* test_get_security_descriptor(HANDLE handle, int line)
228c2c66affSColin Finck {
229c2c66affSColin Finck /* use HeapFree(GetProcessHeap(), 0, sd); when done */
230c2c66affSColin Finck DWORD ret, length, needed;
231c2c66affSColin Finck SECURITY_DESCRIPTOR *sd;
232c2c66affSColin Finck
233c2c66affSColin Finck needed = 0xdeadbeef;
234c2c66affSColin Finck SetLastError(0xdeadbeef);
235c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
236c2c66affSColin Finck NULL, 0, &needed);
237c2c66affSColin Finck ok_(__FILE__, line)(!ret, "GetKernelObjectSecurity should fail\n");
238c2c66affSColin Finck ok_(__FILE__, line)(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
239c2c66affSColin Finck ok_(__FILE__, line)(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n");
240c2c66affSColin Finck
241c2c66affSColin Finck length = needed;
242c2c66affSColin Finck sd = HeapAlloc(GetProcessHeap(), 0, length);
243c2c66affSColin Finck
244c2c66affSColin Finck needed = 0xdeadbeef;
245c2c66affSColin Finck SetLastError(0xdeadbeef);
246c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
247c2c66affSColin Finck sd, length, &needed);
248c2c66affSColin Finck ok_(__FILE__, line)(ret, "GetKernelObjectSecurity error %d\n", GetLastError());
249c2c66affSColin Finck ok_(__FILE__, line)(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed);
250c2c66affSColin Finck return sd;
251c2c66affSColin Finck }
252c2c66affSColin Finck
test_owner_equal(HANDLE Handle,PSID expected,int line)253c2c66affSColin Finck static void test_owner_equal(HANDLE Handle, PSID expected, int line)
254c2c66affSColin Finck {
255c2c66affSColin Finck BOOL res;
256c2c66affSColin Finck SECURITY_DESCRIPTOR *queriedSD = NULL;
257c2c66affSColin Finck PSID owner;
258c2c66affSColin Finck BOOL owner_defaulted;
259c2c66affSColin Finck
260c2c66affSColin Finck queriedSD = test_get_security_descriptor( Handle, line );
261c2c66affSColin Finck
262c2c66affSColin Finck res = GetSecurityDescriptorOwner(queriedSD, &owner, &owner_defaulted);
263c2c66affSColin Finck ok_(__FILE__, line)(res, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
264c2c66affSColin Finck
265c2c66affSColin Finck ok_(__FILE__, line)(EqualSid(owner, expected), "Owner SIDs are not equal %s != %s\n",
266c2c66affSColin Finck debugstr_sid(owner), debugstr_sid(expected));
267c2c66affSColin Finck ok_(__FILE__, line)(!owner_defaulted, "Defaulted is true\n");
268c2c66affSColin Finck
269c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, queriedSD);
270c2c66affSColin Finck }
271c2c66affSColin Finck
test_group_equal(HANDLE Handle,PSID expected,int line)272c2c66affSColin Finck static void test_group_equal(HANDLE Handle, PSID expected, int line)
273c2c66affSColin Finck {
274c2c66affSColin Finck BOOL res;
275c2c66affSColin Finck SECURITY_DESCRIPTOR *queriedSD = NULL;
276c2c66affSColin Finck PSID group;
277c2c66affSColin Finck BOOL group_defaulted;
278c2c66affSColin Finck
279c2c66affSColin Finck queriedSD = test_get_security_descriptor( Handle, line );
280c2c66affSColin Finck
281c2c66affSColin Finck res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted);
282c2c66affSColin Finck ok_(__FILE__, line)(res, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
283c2c66affSColin Finck
284c2c66affSColin Finck ok_(__FILE__, line)(EqualSid(group, expected), "Group SIDs are not equal %s != %s\n",
285c2c66affSColin Finck debugstr_sid(group), debugstr_sid(expected));
286c2c66affSColin Finck ok_(__FILE__, line)(!group_defaulted, "Defaulted is true\n");
287c2c66affSColin Finck
288c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, queriedSD);
289c2c66affSColin Finck }
290c2c66affSColin Finck
test_sid(void)291c2c66affSColin Finck static void test_sid(void)
292c2c66affSColin Finck {
293c2c66affSColin Finck static struct
294c2c66affSColin Finck {
295c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY auth;
296c2c66affSColin Finck const char *refStr;
297c2c66affSColin Finck } refs[] = {
298c2c66affSColin Finck { { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" },
299c2c66affSColin Finck { { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1" },
300c2c66affSColin Finck { { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1" },
301c2c66affSColin Finck { { {0x00,0x00,0x00,0x00,0x01,0x02} }, "S-1-258-1" },
302c2c66affSColin Finck { { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" },
303c2c66affSColin Finck { { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" },
304c2c66affSColin Finck };
305c2c66affSColin Finck static const struct
306c2c66affSColin Finck {
307c2c66affSColin Finck const char *str;
308c2c66affSColin Finck WELL_KNOWN_SID_TYPE sid_type;
309c2c66affSColin Finck BOOL optional;
310c2c66affSColin Finck } strsid_table[] = {
311c2c66affSColin Finck /* Please keep the list sorted. */
312c2c66affSColin Finck { "AC", WinBuiltinAnyPackageSid, TRUE },
313c2c66affSColin Finck { "AN", WinAnonymousSid },
314c2c66affSColin Finck { "AO", WinBuiltinAccountOperatorsSid },
315c2c66affSColin Finck { "AU", WinAuthenticatedUserSid },
316c2c66affSColin Finck { "BA", WinBuiltinAdministratorsSid },
317c2c66affSColin Finck { "BG", WinBuiltinGuestsSid },
318c2c66affSColin Finck { "BO", WinBuiltinBackupOperatorsSid },
319c2c66affSColin Finck { "BU", WinBuiltinUsersSid },
320c2c66affSColin Finck { "CA", WinAccountCertAdminsSid, TRUE},
321c2c66affSColin Finck { "CG", WinCreatorGroupSid },
322c2c66affSColin Finck { "CO", WinCreatorOwnerSid },
323c2c66affSColin Finck { "DA", WinAccountDomainAdminsSid, TRUE},
324c2c66affSColin Finck { "DC", WinAccountComputersSid, TRUE},
325c2c66affSColin Finck { "DD", WinAccountControllersSid, TRUE},
326c2c66affSColin Finck { "DG", WinAccountDomainGuestsSid, TRUE},
327c2c66affSColin Finck { "DU", WinAccountDomainUsersSid, TRUE},
328c2c66affSColin Finck { "EA", WinAccountEnterpriseAdminsSid, TRUE},
329c2c66affSColin Finck { "ED", WinEnterpriseControllersSid },
330c2c66affSColin Finck { "IU", WinInteractiveSid },
331c2c66affSColin Finck { "LA", WinAccountAdministratorSid },
332c2c66affSColin Finck { "LG", WinAccountGuestSid },
333c2c66affSColin Finck { "LS", WinLocalServiceSid },
334c2c66affSColin Finck { "NO", WinBuiltinNetworkConfigurationOperatorsSid },
335c2c66affSColin Finck { "NS", WinNetworkServiceSid },
336c2c66affSColin Finck { "NU", WinNetworkSid },
337c2c66affSColin Finck { "PA", WinAccountPolicyAdminsSid, TRUE},
338c2c66affSColin Finck { "PO", WinBuiltinPrintOperatorsSid },
339c2c66affSColin Finck { "PS", WinSelfSid },
340c2c66affSColin Finck { "PU", WinBuiltinPowerUsersSid },
341c2c66affSColin Finck { "RC", WinRestrictedCodeSid },
342c2c66affSColin Finck { "RD", WinBuiltinRemoteDesktopUsersSid },
343c2c66affSColin Finck { "RE", WinBuiltinReplicatorSid },
344c2c66affSColin Finck { "RS", WinAccountRasAndIasServersSid, TRUE },
345c2c66affSColin Finck { "RU", WinBuiltinPreWindows2000CompatibleAccessSid },
346c2c66affSColin Finck { "SA", WinAccountSchemaAdminsSid, TRUE },
347c2c66affSColin Finck { "SO", WinBuiltinSystemOperatorsSid },
348c2c66affSColin Finck { "SU", WinServiceSid },
349c2c66affSColin Finck { "SY", WinLocalSystemSid },
350c2c66affSColin Finck { "WD", WinWorldSid },
351c2c66affSColin Finck };
352c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
353c2c66affSColin Finck const char noSubAuthStr[] = "S-1-5";
354c2c66affSColin Finck unsigned int i;
355c2c66affSColin Finck PSID psid, domain_sid;
356c2c66affSColin Finck SID *pisid;
357c2c66affSColin Finck BOOL r;
358c2c66affSColin Finck LPSTR str;
359c2c66affSColin Finck
360561bed7bSAmine Khaldi if( !pConvertStringSidToSidA )
361c2c66affSColin Finck {
362c2c66affSColin Finck win_skip("ConvertSidToStringSidA or ConvertStringSidToSidA not available\n");
363c2c66affSColin Finck return;
364c2c66affSColin Finck }
365c2c66affSColin Finck
366c2c66affSColin Finck r = pConvertStringSidToSidA( NULL, NULL );
367c2c66affSColin Finck ok( !r, "expected failure with NULL parameters\n" );
368c2c66affSColin Finck if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )
369c2c66affSColin Finck return;
370c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_PARAMETER,
371c2c66affSColin Finck "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n",
372c2c66affSColin Finck GetLastError() );
373c2c66affSColin Finck
374c2c66affSColin Finck r = pConvertStringSidToSidA( refs[0].refStr, NULL );
375c2c66affSColin Finck ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
376c2c66affSColin Finck "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n",
377c2c66affSColin Finck GetLastError() );
378c2c66affSColin Finck
379c2c66affSColin Finck r = pConvertStringSidToSidA( NULL, &str );
380c2c66affSColin Finck ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
381c2c66affSColin Finck "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n",
382c2c66affSColin Finck GetLastError() );
383c2c66affSColin Finck
384c2c66affSColin Finck r = pConvertStringSidToSidA( noSubAuthStr, &psid );
385c2c66affSColin Finck ok( !r,
386c2c66affSColin Finck "expected failure with no sub authorities\n" );
387c2c66affSColin Finck ok( GetLastError() == ERROR_INVALID_SID,
388c2c66affSColin Finck "expected GetLastError() is ERROR_INVALID_SID, got %d\n",
389c2c66affSColin Finck GetLastError() );
390c2c66affSColin Finck
391c2c66affSColin Finck ok(pConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid), "ConvertStringSidToSidA failed\n");
392c2c66affSColin Finck pisid = psid;
393c2c66affSColin Finck ok(pisid->SubAuthorityCount == 4, "Invalid sub authority count - expected 4, got %d\n", pisid->SubAuthorityCount);
394c2c66affSColin Finck ok(pisid->SubAuthority[0] == 21, "Invalid subauthority 0 - expected 21, got %d\n", pisid->SubAuthority[0]);
395c2c66affSColin Finck ok(pisid->SubAuthority[3] == 4576, "Invalid subauthority 0 - expected 4576, got %d\n", pisid->SubAuthority[3]);
396c2c66affSColin Finck LocalFree(str);
397c2c66affSColin Finck LocalFree(psid);
398c2c66affSColin Finck
399c2c66affSColin Finck for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
400c2c66affSColin Finck {
401c2c66affSColin Finck r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
402c2c66affSColin Finck &psid );
403c2c66affSColin Finck ok( r, "failed to allocate sid\n" );
404561bed7bSAmine Khaldi r = ConvertSidToStringSidA( psid, &str );
405c2c66affSColin Finck ok( r, "failed to convert sid\n" );
406c2c66affSColin Finck if (r)
407c2c66affSColin Finck {
408c2c66affSColin Finck ok( !strcmp( str, refs[i].refStr ),
409c2c66affSColin Finck "incorrect sid, expected %s, got %s\n", refs[i].refStr, str );
410c2c66affSColin Finck LocalFree( str );
411c2c66affSColin Finck }
412c2c66affSColin Finck if( psid )
413c2c66affSColin Finck FreeSid( psid );
414c2c66affSColin Finck
415c2c66affSColin Finck r = pConvertStringSidToSidA( refs[i].refStr, &psid );
416c2c66affSColin Finck ok( r, "failed to parse sid string\n" );
417c2c66affSColin Finck pisid = psid;
418c2c66affSColin Finck ok( pisid &&
419c2c66affSColin Finck !memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value,
420c2c66affSColin Finck sizeof(refs[i].auth) ),
421c2c66affSColin Finck "string sid %s didn't parse to expected value\n"
422c2c66affSColin Finck "(got 0x%04x%08x, expected 0x%04x%08x)\n",
423c2c66affSColin Finck refs[i].refStr,
424c2c66affSColin Finck MAKEWORD( pisid->IdentifierAuthority.Value[1],
425c2c66affSColin Finck pisid->IdentifierAuthority.Value[0] ),
426c2c66affSColin Finck MAKELONG( MAKEWORD( pisid->IdentifierAuthority.Value[5],
427c2c66affSColin Finck pisid->IdentifierAuthority.Value[4] ),
428c2c66affSColin Finck MAKEWORD( pisid->IdentifierAuthority.Value[3],
429c2c66affSColin Finck pisid->IdentifierAuthority.Value[2] ) ),
430c2c66affSColin Finck MAKEWORD( refs[i].auth.Value[1], refs[i].auth.Value[0] ),
431c2c66affSColin Finck MAKELONG( MAKEWORD( refs[i].auth.Value[5], refs[i].auth.Value[4] ),
432c2c66affSColin Finck MAKEWORD( refs[i].auth.Value[3], refs[i].auth.Value[2] ) ) );
433c2c66affSColin Finck if( psid )
434c2c66affSColin Finck LocalFree( psid );
435c2c66affSColin Finck }
436c2c66affSColin Finck
437c2c66affSColin Finck /* string constant format not supported before XP */
438c2c66affSColin Finck r = pConvertStringSidToSidA("AN", &psid);
439c2c66affSColin Finck if(!r)
440c2c66affSColin Finck {
441c2c66affSColin Finck win_skip("String constant format not supported\n");
442c2c66affSColin Finck return;
443c2c66affSColin Finck }
444c2c66affSColin Finck LocalFree(psid);
445c2c66affSColin Finck
446c2c66affSColin Finck AllocateAndInitializeSid(&domain_ident, 4, SECURITY_NT_NON_UNIQUE, 0, 0, 0, 0, 0, 0, 0, &domain_sid);
447c2c66affSColin Finck
448c2c66affSColin Finck for(i = 0; i < sizeof(strsid_table) / sizeof(strsid_table[0]); i++)
449c2c66affSColin Finck {
450c2c66affSColin Finck SetLastError(0xdeadbeef);
451c2c66affSColin Finck r = pConvertStringSidToSidA(strsid_table[i].str, &psid);
452c2c66affSColin Finck
453c2c66affSColin Finck if (!(strsid_table[i].optional))
454c2c66affSColin Finck {
455c2c66affSColin Finck ok(r, "%s: got %u\n", strsid_table[i].str, GetLastError());
456c2c66affSColin Finck }
457c2c66affSColin Finck
458c2c66affSColin Finck if (r)
459c2c66affSColin Finck {
460c2c66affSColin Finck char buf[SECURITY_MAX_SID_SIZE];
461c2c66affSColin Finck char *sid_string, *well_known_sid_string;
462c2c66affSColin Finck DWORD n, size;
463c2c66affSColin Finck
464c2c66affSColin Finck /* zero out domain id before comparison to simplify things */
465c2c66affSColin Finck if (strsid_table[i].sid_type == WinAccountAdministratorSid ||
466c2c66affSColin Finck strsid_table[i].sid_type == WinAccountGuestSid)
467c2c66affSColin Finck {
468c2c66affSColin Finck for (n = 1; n <= 3; n++)
469c2c66affSColin Finck *GetSidSubAuthority(psid, n) = 0;
470c2c66affSColin Finck }
471c2c66affSColin Finck
472561bed7bSAmine Khaldi r = ConvertSidToStringSidA(psid, &sid_string);
473c2c66affSColin Finck ok(r, "%s: ConvertSidToStringSid error %u\n", strsid_table[i].str, GetLastError());
474c2c66affSColin Finck if (winetest_debug > 1)
475c2c66affSColin Finck trace("%s => %s\n", strsid_table[i].str, sid_string);
476c2c66affSColin Finck
477c2c66affSColin Finck size = sizeof(buf);
478c2c66affSColin Finck r = pCreateWellKnownSid(strsid_table[i].sid_type, domain_sid, buf, &size);
479c2c66affSColin Finck ok(r, "%u: CreateWellKnownSid(%u) error %u\n", i, strsid_table[i].sid_type, GetLastError());
480c2c66affSColin Finck
481561bed7bSAmine Khaldi r = ConvertSidToStringSidA(buf, &well_known_sid_string);
482c2c66affSColin Finck ok(r, "%u: ConvertSidToStringSi(%u) error %u\n", i, strsid_table[i].sid_type, GetLastError());
483c2c66affSColin Finck if (winetest_debug > 1)
484c2c66affSColin Finck trace("%u => %s\n", strsid_table[i].sid_type, well_known_sid_string);
485c2c66affSColin Finck
486c2c66affSColin Finck ok(strcmp(sid_string, well_known_sid_string) == 0,
487c2c66affSColin Finck "%u: (%u) expected %s, got %s\n", i, strsid_table[i].sid_type, well_known_sid_string, sid_string);
488c2c66affSColin Finck
489c2c66affSColin Finck LocalFree(well_known_sid_string);
490c2c66affSColin Finck LocalFree(sid_string);
491c2c66affSColin Finck LocalFree(psid);
492c2c66affSColin Finck }
493c2c66affSColin Finck else
494c2c66affSColin Finck {
495c2c66affSColin Finck if (GetLastError() != ERROR_INVALID_SID)
496c2c66affSColin Finck trace(" %s: couldn't be converted, returned %d\n", strsid_table[i].str, GetLastError());
497c2c66affSColin Finck else
498c2c66affSColin Finck trace(" %s: couldn't be converted\n", strsid_table[i].str);
499c2c66affSColin Finck }
500c2c66affSColin Finck }
501c2c66affSColin Finck
502c2c66affSColin Finck LocalFree(domain_sid);
503c2c66affSColin Finck }
504c2c66affSColin Finck
test_trustee(void)505c2c66affSColin Finck static void test_trustee(void)
506c2c66affSColin Finck {
507c2c66affSColin Finck GUID ObjectType = {0x12345678, 0x1234, 0x5678, {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}};
508c2c66affSColin Finck GUID InheritedObjectType = {0x23456789, 0x2345, 0x6786, {0x2, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}};
509c2c66affSColin Finck GUID ZeroGuid;
510c2c66affSColin Finck OBJECTS_AND_NAME_A oan;
511c2c66affSColin Finck OBJECTS_AND_SID oas;
512c2c66affSColin Finck TRUSTEEA trustee;
513c2c66affSColin Finck PSID psid;
514c2c66affSColin Finck char szObjectTypeName[] = "ObjectTypeName";
515c2c66affSColin Finck char szInheritedObjectTypeName[] = "InheritedObjectTypeName";
516c2c66affSColin Finck char szTrusteeName[] = "szTrusteeName";
517c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} };
518c2c66affSColin Finck
519c2c66affSColin Finck memset( &ZeroGuid, 0x00, sizeof (ZeroGuid) );
520c2c66affSColin Finck
521c2c66affSColin Finck pBuildTrusteeWithSidA = (void *)GetProcAddress( hmod, "BuildTrusteeWithSidA" );
522c2c66affSColin Finck pBuildTrusteeWithNameA = (void *)GetProcAddress( hmod, "BuildTrusteeWithNameA" );
523c2c66affSColin Finck pBuildTrusteeWithObjectsAndNameA = (void *)GetProcAddress (hmod, "BuildTrusteeWithObjectsAndNameA" );
524c2c66affSColin Finck pBuildTrusteeWithObjectsAndSidA = (void *)GetProcAddress (hmod, "BuildTrusteeWithObjectsAndSidA" );
525c2c66affSColin Finck pGetTrusteeNameA = (void *)GetProcAddress (hmod, "GetTrusteeNameA" );
526c2c66affSColin Finck if( !pBuildTrusteeWithSidA || !pBuildTrusteeWithNameA ||
527c2c66affSColin Finck !pBuildTrusteeWithObjectsAndNameA || !pBuildTrusteeWithObjectsAndSidA ||
528c2c66affSColin Finck !pGetTrusteeNameA )
529c2c66affSColin Finck return;
530c2c66affSColin Finck
531c2c66affSColin Finck if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )
532c2c66affSColin Finck {
533c2c66affSColin Finck trace( "failed to init SID\n" );
534c2c66affSColin Finck return;
535c2c66affSColin Finck }
536c2c66affSColin Finck
537c2c66affSColin Finck /* test BuildTrusteeWithSidA */
538c2c66affSColin Finck memset( &trustee, 0xff, sizeof trustee );
539c2c66affSColin Finck pBuildTrusteeWithSidA( &trustee, psid );
540c2c66affSColin Finck
541c2c66affSColin Finck ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
542c2c66affSColin Finck ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
543c2c66affSColin Finck "MultipleTrusteeOperation wrong\n");
544c2c66affSColin Finck ok( trustee.TrusteeForm == TRUSTEE_IS_SID, "TrusteeForm wrong\n");
545c2c66affSColin Finck ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
546c2c66affSColin Finck ok( trustee.ptstrName == psid, "ptstrName wrong\n" );
547c2c66affSColin Finck
548c2c66affSColin Finck /* test BuildTrusteeWithObjectsAndSidA (test 1) */
549c2c66affSColin Finck memset( &trustee, 0xff, sizeof trustee );
550c2c66affSColin Finck memset( &oas, 0xff, sizeof(oas) );
551c2c66affSColin Finck pBuildTrusteeWithObjectsAndSidA(&trustee, &oas, &ObjectType,
552c2c66affSColin Finck &InheritedObjectType, psid);
553c2c66affSColin Finck
554c2c66affSColin Finck ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
555c2c66affSColin Finck ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
556c2c66affSColin Finck ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_SID, "TrusteeForm wrong\n");
557c2c66affSColin Finck ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
558c2c66affSColin Finck ok(trustee.ptstrName == (LPSTR)&oas, "ptstrName wrong\n");
559c2c66affSColin Finck
560c2c66affSColin Finck ok(oas.ObjectsPresent == (ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT), "ObjectsPresent wrong\n");
561c2c66affSColin Finck ok(!memcmp(&oas.ObjectTypeGuid, &ObjectType, sizeof(GUID)), "ObjectTypeGuid wrong\n");
562c2c66affSColin Finck ok(!memcmp(&oas.InheritedObjectTypeGuid, &InheritedObjectType, sizeof(GUID)), "InheritedObjectTypeGuid wrong\n");
563c2c66affSColin Finck ok(oas.pSid == psid, "pSid wrong\n");
564c2c66affSColin Finck
565c2c66affSColin Finck /* test GetTrusteeNameA */
566c2c66affSColin Finck ok(pGetTrusteeNameA(&trustee) == (LPSTR)&oas, "GetTrusteeName returned wrong value\n");
567c2c66affSColin Finck
568c2c66affSColin Finck /* test BuildTrusteeWithObjectsAndSidA (test 2) */
569c2c66affSColin Finck memset( &trustee, 0xff, sizeof trustee );
570c2c66affSColin Finck memset( &oas, 0xff, sizeof(oas) );
571c2c66affSColin Finck pBuildTrusteeWithObjectsAndSidA(&trustee, &oas, NULL,
572c2c66affSColin Finck &InheritedObjectType, psid);
573c2c66affSColin Finck
574c2c66affSColin Finck ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
575c2c66affSColin Finck ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
576c2c66affSColin Finck ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_SID, "TrusteeForm wrong\n");
577c2c66affSColin Finck ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
578c2c66affSColin Finck ok(trustee.ptstrName == (LPSTR)&oas, "ptstrName wrong\n");
579c2c66affSColin Finck
580c2c66affSColin Finck ok(oas.ObjectsPresent == ACE_INHERITED_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n");
581c2c66affSColin Finck ok(!memcmp(&oas.ObjectTypeGuid, &ZeroGuid, sizeof(GUID)), "ObjectTypeGuid wrong\n");
582c2c66affSColin Finck ok(!memcmp(&oas.InheritedObjectTypeGuid, &InheritedObjectType, sizeof(GUID)), "InheritedObjectTypeGuid wrong\n");
583c2c66affSColin Finck ok(oas.pSid == psid, "pSid wrong\n");
584c2c66affSColin Finck
585c2c66affSColin Finck FreeSid( psid );
586c2c66affSColin Finck
587c2c66affSColin Finck /* test BuildTrusteeWithNameA */
588c2c66affSColin Finck memset( &trustee, 0xff, sizeof trustee );
589c2c66affSColin Finck pBuildTrusteeWithNameA( &trustee, szTrusteeName );
590c2c66affSColin Finck
591c2c66affSColin Finck ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
592c2c66affSColin Finck ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
593c2c66affSColin Finck "MultipleTrusteeOperation wrong\n");
594c2c66affSColin Finck ok( trustee.TrusteeForm == TRUSTEE_IS_NAME, "TrusteeForm wrong\n");
595c2c66affSColin Finck ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
596c2c66affSColin Finck ok( trustee.ptstrName == szTrusteeName, "ptstrName wrong\n" );
597c2c66affSColin Finck
598c2c66affSColin Finck /* test BuildTrusteeWithObjectsAndNameA (test 1) */
599c2c66affSColin Finck memset( &trustee, 0xff, sizeof trustee );
600c2c66affSColin Finck memset( &oan, 0xff, sizeof(oan) );
601c2c66affSColin Finck pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, szObjectTypeName,
602c2c66affSColin Finck szInheritedObjectTypeName, szTrusteeName);
603c2c66affSColin Finck
604c2c66affSColin Finck ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
605c2c66affSColin Finck ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
606c2c66affSColin Finck ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n");
607c2c66affSColin Finck ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
608c2c66affSColin Finck ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n");
609c2c66affSColin Finck
610c2c66affSColin Finck ok(oan.ObjectsPresent == (ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT), "ObjectsPresent wrong\n");
611c2c66affSColin Finck ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n");
612c2c66affSColin Finck ok(oan.InheritedObjectTypeName == szInheritedObjectTypeName, "InheritedObjectTypeName wrong\n");
613c2c66affSColin Finck ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n");
614c2c66affSColin Finck
615c2c66affSColin Finck /* test GetTrusteeNameA */
616c2c66affSColin Finck ok(pGetTrusteeNameA(&trustee) == (LPSTR)&oan, "GetTrusteeName returned wrong value\n");
617c2c66affSColin Finck
618c2c66affSColin Finck /* test BuildTrusteeWithObjectsAndNameA (test 2) */
619c2c66affSColin Finck memset( &trustee, 0xff, sizeof trustee );
620c2c66affSColin Finck memset( &oan, 0xff, sizeof(oan) );
621c2c66affSColin Finck pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, NULL,
622c2c66affSColin Finck szInheritedObjectTypeName, szTrusteeName);
623c2c66affSColin Finck
624c2c66affSColin Finck ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
625c2c66affSColin Finck ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
626c2c66affSColin Finck ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n");
627c2c66affSColin Finck ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
628c2c66affSColin Finck ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n");
629c2c66affSColin Finck
630c2c66affSColin Finck ok(oan.ObjectsPresent == ACE_INHERITED_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n");
631c2c66affSColin Finck ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n");
632c2c66affSColin Finck ok(oan.InheritedObjectTypeName == szInheritedObjectTypeName, "InheritedObjectTypeName wrong\n");
633c2c66affSColin Finck ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n");
634c2c66affSColin Finck
635c2c66affSColin Finck /* test BuildTrusteeWithObjectsAndNameA (test 3) */
636c2c66affSColin Finck memset( &trustee, 0xff, sizeof trustee );
637c2c66affSColin Finck memset( &oan, 0xff, sizeof(oan) );
638c2c66affSColin Finck pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, szObjectTypeName,
639c2c66affSColin Finck NULL, szTrusteeName);
640c2c66affSColin Finck
641c2c66affSColin Finck ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
642c2c66affSColin Finck ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
643c2c66affSColin Finck ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n");
644c2c66affSColin Finck ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
645c2c66affSColin Finck ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n");
646c2c66affSColin Finck
647c2c66affSColin Finck ok(oan.ObjectsPresent == ACE_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n");
648c2c66affSColin Finck ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n");
649c2c66affSColin Finck ok(oan.InheritedObjectTypeName == NULL, "InheritedObjectTypeName wrong\n");
650c2c66affSColin Finck ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n");
651c2c66affSColin Finck }
652c2c66affSColin Finck
653c2c66affSColin Finck /* If the first isn't defined, assume none is */
654c2c66affSColin Finck #ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
655c2c66affSColin Finck #define SE_MIN_WELL_KNOWN_PRIVILEGE 2L
656c2c66affSColin Finck #define SE_CREATE_TOKEN_PRIVILEGE 2L
657c2c66affSColin Finck #define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L
658c2c66affSColin Finck #define SE_LOCK_MEMORY_PRIVILEGE 4L
659c2c66affSColin Finck #define SE_INCREASE_QUOTA_PRIVILEGE 5L
660c2c66affSColin Finck #define SE_MACHINE_ACCOUNT_PRIVILEGE 6L
661c2c66affSColin Finck #define SE_TCB_PRIVILEGE 7L
662c2c66affSColin Finck #define SE_SECURITY_PRIVILEGE 8L
663c2c66affSColin Finck #define SE_TAKE_OWNERSHIP_PRIVILEGE 9L
664c2c66affSColin Finck #define SE_LOAD_DRIVER_PRIVILEGE 10L
665c2c66affSColin Finck #define SE_SYSTEM_PROFILE_PRIVILEGE 11L
666c2c66affSColin Finck #define SE_SYSTEMTIME_PRIVILEGE 12L
667c2c66affSColin Finck #define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
668c2c66affSColin Finck #define SE_INC_BASE_PRIORITY_PRIVILEGE 14L
669c2c66affSColin Finck #define SE_CREATE_PAGEFILE_PRIVILEGE 15L
670c2c66affSColin Finck #define SE_CREATE_PERMANENT_PRIVILEGE 16L
671c2c66affSColin Finck #define SE_BACKUP_PRIVILEGE 17L
672c2c66affSColin Finck #define SE_RESTORE_PRIVILEGE 18L
673c2c66affSColin Finck #define SE_SHUTDOWN_PRIVILEGE 19L
674c2c66affSColin Finck #define SE_DEBUG_PRIVILEGE 20L
675c2c66affSColin Finck #define SE_AUDIT_PRIVILEGE 21L
676c2c66affSColin Finck #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
677c2c66affSColin Finck #define SE_CHANGE_NOTIFY_PRIVILEGE 23L
678c2c66affSColin Finck #define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
679c2c66affSColin Finck #define SE_UNDOCK_PRIVILEGE 25L
680c2c66affSColin Finck #define SE_SYNC_AGENT_PRIVILEGE 26L
681c2c66affSColin Finck #define SE_ENABLE_DELEGATION_PRIVILEGE 27L
682c2c66affSColin Finck #define SE_MANAGE_VOLUME_PRIVILEGE 28L
683c2c66affSColin Finck #define SE_IMPERSONATE_PRIVILEGE 29L
684c2c66affSColin Finck #define SE_CREATE_GLOBAL_PRIVILEGE 30L
685c2c66affSColin Finck #define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE
686c2c66affSColin Finck #endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
687c2c66affSColin Finck
test_allocateLuid(void)688c2c66affSColin Finck static void test_allocateLuid(void)
689c2c66affSColin Finck {
690c2c66affSColin Finck BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);
691c2c66affSColin Finck LUID luid1, luid2;
692c2c66affSColin Finck BOOL ret;
693c2c66affSColin Finck
694c2c66affSColin Finck pAllocateLocallyUniqueId = (void*)GetProcAddress(hmod, "AllocateLocallyUniqueId");
695c2c66affSColin Finck if (!pAllocateLocallyUniqueId) return;
696c2c66affSColin Finck
697c2c66affSColin Finck ret = pAllocateLocallyUniqueId(&luid1);
698c2c66affSColin Finck if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
699c2c66affSColin Finck return;
700c2c66affSColin Finck
701c2c66affSColin Finck ok(ret,
702c2c66affSColin Finck "AllocateLocallyUniqueId failed: %d\n", GetLastError());
703c2c66affSColin Finck ret = pAllocateLocallyUniqueId(&luid2);
704c2c66affSColin Finck ok( ret,
705c2c66affSColin Finck "AllocateLocallyUniqueId failed: %d\n", GetLastError());
706c2c66affSColin Finck ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0,
707c2c66affSColin Finck "AllocateLocallyUniqueId returned a well-known LUID\n");
708c2c66affSColin Finck ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart,
709c2c66affSColin Finck "AllocateLocallyUniqueId returned non-unique LUIDs\n");
710c2c66affSColin Finck ret = pAllocateLocallyUniqueId(NULL);
711c2c66affSColin Finck ok( !ret && GetLastError() == ERROR_NOACCESS,
712c2c66affSColin Finck "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %d\n",
713c2c66affSColin Finck GetLastError());
714c2c66affSColin Finck }
715c2c66affSColin Finck
test_lookupPrivilegeName(void)716c2c66affSColin Finck static void test_lookupPrivilegeName(void)
717c2c66affSColin Finck {
718c2c66affSColin Finck BOOL (WINAPI *pLookupPrivilegeNameA)(LPCSTR, PLUID, LPSTR, LPDWORD);
719c2c66affSColin Finck char buf[MAX_PATH]; /* arbitrary, seems long enough */
720c2c66affSColin Finck DWORD cchName = sizeof(buf);
721c2c66affSColin Finck LUID luid = { 0, 0 };
722c2c66affSColin Finck LONG i;
723c2c66affSColin Finck BOOL ret;
724c2c66affSColin Finck
725c2c66affSColin Finck /* check whether it's available first */
726c2c66affSColin Finck pLookupPrivilegeNameA = (void*)GetProcAddress(hmod, "LookupPrivilegeNameA");
727c2c66affSColin Finck if (!pLookupPrivilegeNameA) return;
728c2c66affSColin Finck luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
729c2c66affSColin Finck ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
730c2c66affSColin Finck if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
731c2c66affSColin Finck return;
732c2c66affSColin Finck
733c2c66affSColin Finck /* check with a short buffer */
734c2c66affSColin Finck cchName = 0;
735c2c66affSColin Finck luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
736c2c66affSColin Finck ret = pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName);
737c2c66affSColin Finck ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
738c2c66affSColin Finck "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %d\n",
739c2c66affSColin Finck GetLastError());
740c2c66affSColin Finck ok(cchName == strlen("SeCreateTokenPrivilege") + 1,
741c2c66affSColin Finck "LookupPrivilegeNameA returned an incorrect required length for\n"
742c2c66affSColin Finck "SeCreateTokenPrivilege (got %d, expected %d)\n", cchName,
743c2c66affSColin Finck lstrlenA("SeCreateTokenPrivilege") + 1);
744c2c66affSColin Finck /* check a known value and its returned length on success */
745c2c66affSColin Finck cchName = sizeof(buf);
746c2c66affSColin Finck ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
747c2c66affSColin Finck cchName == strlen("SeCreateTokenPrivilege"),
748c2c66affSColin Finck "LookupPrivilegeNameA returned an incorrect output length for\n"
749c2c66affSColin Finck "SeCreateTokenPrivilege (got %d, expected %d)\n", cchName,
750c2c66affSColin Finck (int)strlen("SeCreateTokenPrivilege"));
751c2c66affSColin Finck /* check known values */
752c2c66affSColin Finck for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i <= SE_MAX_WELL_KNOWN_PRIVILEGE; i++)
753c2c66affSColin Finck {
754c2c66affSColin Finck luid.LowPart = i;
755c2c66affSColin Finck cchName = sizeof(buf);
756c2c66affSColin Finck ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
757c2c66affSColin Finck ok( ret || GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
758c2c66affSColin Finck "LookupPrivilegeNameA(0.%d) failed: %d\n", i, GetLastError());
759c2c66affSColin Finck }
760c2c66affSColin Finck /* check a bogus LUID */
761c2c66affSColin Finck luid.LowPart = 0xdeadbeef;
762c2c66affSColin Finck cchName = sizeof(buf);
763c2c66affSColin Finck ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
764c2c66affSColin Finck ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
765c2c66affSColin Finck "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n",
766c2c66affSColin Finck GetLastError());
767c2c66affSColin Finck /* check on a bogus system */
768c2c66affSColin Finck luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
769c2c66affSColin Finck cchName = sizeof(buf);
770c2c66affSColin Finck ret = pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName);
771c2c66affSColin Finck ok( !ret && (GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
772c2c66affSColin Finck GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */,
773c2c66affSColin Finck "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d\n",
774c2c66affSColin Finck GetLastError());
775c2c66affSColin Finck }
776c2c66affSColin Finck
777c2c66affSColin Finck struct NameToLUID
778c2c66affSColin Finck {
779c2c66affSColin Finck const char *name;
780c2c66affSColin Finck DWORD lowPart;
781c2c66affSColin Finck };
782c2c66affSColin Finck
test_lookupPrivilegeValue(void)783c2c66affSColin Finck static void test_lookupPrivilegeValue(void)
784c2c66affSColin Finck {
785c2c66affSColin Finck static const struct NameToLUID privs[] = {
786c2c66affSColin Finck { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE },
787c2c66affSColin Finck { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE },
788c2c66affSColin Finck { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE },
789c2c66affSColin Finck { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE },
790c2c66affSColin Finck { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE },
791c2c66affSColin Finck { "SeTcbPrivilege", SE_TCB_PRIVILEGE },
792c2c66affSColin Finck { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE },
793c2c66affSColin Finck { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE },
794c2c66affSColin Finck { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE },
795c2c66affSColin Finck { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE },
796c2c66affSColin Finck { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE },
797c2c66affSColin Finck { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE },
798c2c66affSColin Finck { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE },
799c2c66affSColin Finck { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE },
800c2c66affSColin Finck { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE },
801c2c66affSColin Finck { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE },
802c2c66affSColin Finck { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE },
803c2c66affSColin Finck { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE },
804c2c66affSColin Finck { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },
805c2c66affSColin Finck { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },
806c2c66affSColin Finck { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },
807c2c66affSColin Finck { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILEGE },
808c2c66affSColin Finck { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },
809c2c66affSColin Finck { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },
810c2c66affSColin Finck { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },
811c2c66affSColin Finck { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE },
812c2c66affSColin Finck { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE },
813c2c66affSColin Finck { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE },
814c2c66affSColin Finck { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },
815c2c66affSColin Finck };
816c2c66affSColin Finck BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
817c2c66affSColin Finck unsigned int i;
818c2c66affSColin Finck LUID luid;
819c2c66affSColin Finck BOOL ret;
820c2c66affSColin Finck
821c2c66affSColin Finck /* check whether it's available first */
822c2c66affSColin Finck pLookupPrivilegeValueA = (void*)GetProcAddress(hmod, "LookupPrivilegeValueA");
823c2c66affSColin Finck if (!pLookupPrivilegeValueA) return;
824c2c66affSColin Finck ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid);
825c2c66affSColin Finck if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
826c2c66affSColin Finck return;
827c2c66affSColin Finck
828c2c66affSColin Finck /* check a bogus system name */
829c2c66affSColin Finck ret = pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid);
830c2c66affSColin Finck ok( !ret && (GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
831c2c66affSColin Finck GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */,
832c2c66affSColin Finck "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d\n",
833c2c66affSColin Finck GetLastError());
834c2c66affSColin Finck /* check a NULL string */
835c2c66affSColin Finck ret = pLookupPrivilegeValueA(NULL, 0, &luid);
836c2c66affSColin Finck ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
837c2c66affSColin Finck "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n",
838c2c66affSColin Finck GetLastError());
839c2c66affSColin Finck /* check a bogus privilege name */
840c2c66affSColin Finck ret = pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid);
841c2c66affSColin Finck ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
842c2c66affSColin Finck "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n",
843c2c66affSColin Finck GetLastError());
844c2c66affSColin Finck /* check case insensitive */
845c2c66affSColin Finck ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid);
846c2c66affSColin Finck ok( ret,
847c2c66affSColin Finck "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %d\n",
848c2c66affSColin Finck GetLastError());
849c2c66affSColin Finck for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++)
850c2c66affSColin Finck {
851c2c66affSColin Finck /* Not all privileges are implemented on all Windows versions, so
852c2c66affSColin Finck * don't worry if the call fails
853c2c66affSColin Finck */
854c2c66affSColin Finck if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))
855c2c66affSColin Finck {
856c2c66affSColin Finck ok(luid.LowPart == privs[i].lowPart,
857c2c66affSColin Finck "LookupPrivilegeValueA returned an invalid LUID for %s\n",
858c2c66affSColin Finck privs[i].name);
859c2c66affSColin Finck }
860c2c66affSColin Finck }
861c2c66affSColin Finck }
862c2c66affSColin Finck
test_luid(void)863c2c66affSColin Finck static void test_luid(void)
864c2c66affSColin Finck {
865c2c66affSColin Finck test_allocateLuid();
866c2c66affSColin Finck test_lookupPrivilegeName();
867c2c66affSColin Finck test_lookupPrivilegeValue();
868c2c66affSColin Finck }
869c2c66affSColin Finck
test_FileSecurity(void)870c2c66affSColin Finck static void test_FileSecurity(void)
871c2c66affSColin Finck {
872c2c66affSColin Finck char wintmpdir [MAX_PATH];
873c2c66affSColin Finck char path [MAX_PATH];
874c2c66affSColin Finck char file [MAX_PATH];
875c2c66affSColin Finck HANDLE fh, token;
876c2c66affSColin Finck DWORD sdSize, retSize, rc, granted, priv_set_len;
877c2c66affSColin Finck PRIVILEGE_SET priv_set;
878c2c66affSColin Finck BOOL status;
879c2c66affSColin Finck BYTE *sd;
880c2c66affSColin Finck GENERIC_MAPPING mapping = { FILE_READ_DATA, FILE_WRITE_DATA, FILE_EXECUTE, FILE_ALL_ACCESS };
881c2c66affSColin Finck const SECURITY_INFORMATION request = OWNER_SECURITY_INFORMATION
882c2c66affSColin Finck | GROUP_SECURITY_INFORMATION
883c2c66affSColin Finck | DACL_SECURITY_INFORMATION;
884c2c66affSColin Finck
885c2c66affSColin Finck if (!pGetFileSecurityA) {
886c2c66affSColin Finck win_skip ("GetFileSecurity is not available\n");
887c2c66affSColin Finck return;
888c2c66affSColin Finck }
889c2c66affSColin Finck
890c2c66affSColin Finck if (!pSetFileSecurityA) {
891c2c66affSColin Finck win_skip ("SetFileSecurity is not available\n");
892c2c66affSColin Finck return;
893c2c66affSColin Finck }
894c2c66affSColin Finck
895c2c66affSColin Finck if (!GetTempPathA (sizeof (wintmpdir), wintmpdir)) {
896c2c66affSColin Finck win_skip ("GetTempPathA failed\n");
897c2c66affSColin Finck return;
898c2c66affSColin Finck }
899c2c66affSColin Finck
900c2c66affSColin Finck /* Create a temporary directory and in it a temporary file */
901c2c66affSColin Finck strcat (strcpy (path, wintmpdir), "rary");
902c2c66affSColin Finck SetLastError(0xdeadbeef);
903c2c66affSColin Finck rc = CreateDirectoryA (path, NULL);
904c2c66affSColin Finck ok (rc || GetLastError() == ERROR_ALREADY_EXISTS, "CreateDirectoryA "
905c2c66affSColin Finck "failed for '%s' with %d\n", path, GetLastError());
906c2c66affSColin Finck
907c2c66affSColin Finck strcat (strcpy (file, path), "\\ess");
908c2c66affSColin Finck SetLastError(0xdeadbeef);
909c2c66affSColin Finck fh = CreateFileA (file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
910c2c66affSColin Finck ok (fh != INVALID_HANDLE_VALUE, "CreateFileA "
911c2c66affSColin Finck "failed for '%s' with %d\n", file, GetLastError());
912c2c66affSColin Finck CloseHandle (fh);
913c2c66affSColin Finck
914c2c66affSColin Finck /* For the temporary file ... */
915c2c66affSColin Finck
916c2c66affSColin Finck /* Get size needed */
917c2c66affSColin Finck retSize = 0;
918c2c66affSColin Finck SetLastError(0xdeadbeef);
919c2c66affSColin Finck rc = pGetFileSecurityA (file, request, NULL, 0, &retSize);
920c2c66affSColin Finck if (!rc && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
921c2c66affSColin Finck win_skip("GetFileSecurityA is not implemented\n");
922c2c66affSColin Finck goto cleanup;
923c2c66affSColin Finck }
924c2c66affSColin Finck ok (!rc, "GetFileSecurityA "
925c2c66affSColin Finck "was expected to fail for '%s'\n", file);
926c2c66affSColin Finck ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
927c2c66affSColin Finck "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
928c2c66affSColin Finck ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize);
929c2c66affSColin Finck
930c2c66affSColin Finck sdSize = retSize;
931c2c66affSColin Finck sd = HeapAlloc (GetProcessHeap (), 0, sdSize);
932c2c66affSColin Finck
933c2c66affSColin Finck /* Get security descriptor for real */
934c2c66affSColin Finck retSize = -1;
935c2c66affSColin Finck SetLastError(0xdeadbeef);
936c2c66affSColin Finck rc = pGetFileSecurityA (file, request, sd, sdSize, &retSize);
937c2c66affSColin Finck ok (rc, "GetFileSecurityA "
938c2c66affSColin Finck "was not expected to fail '%s': %d\n", file, GetLastError());
939c2c66affSColin Finck ok (retSize == sdSize ||
940c2c66affSColin Finck broken(retSize == 0), /* NT4 */
941c2c66affSColin Finck "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize);
942c2c66affSColin Finck
943c2c66affSColin Finck /* Use it to set security descriptor */
944c2c66affSColin Finck SetLastError(0xdeadbeef);
945c2c66affSColin Finck rc = pSetFileSecurityA (file, request, sd);
946c2c66affSColin Finck ok (rc, "SetFileSecurityA "
947c2c66affSColin Finck "was not expected to fail '%s': %d\n", file, GetLastError());
948c2c66affSColin Finck
949c2c66affSColin Finck HeapFree (GetProcessHeap (), 0, sd);
950c2c66affSColin Finck
951c2c66affSColin Finck /* Repeat for the temporary directory ... */
952c2c66affSColin Finck
953c2c66affSColin Finck /* Get size needed */
954c2c66affSColin Finck retSize = 0;
955c2c66affSColin Finck SetLastError(0xdeadbeef);
956c2c66affSColin Finck rc = pGetFileSecurityA (path, request, NULL, 0, &retSize);
957c2c66affSColin Finck ok (!rc, "GetFileSecurityA "
958c2c66affSColin Finck "was expected to fail for '%s'\n", path);
959c2c66affSColin Finck ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
960c2c66affSColin Finck "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
961c2c66affSColin Finck ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize);
962c2c66affSColin Finck
963c2c66affSColin Finck sdSize = retSize;
964c2c66affSColin Finck sd = HeapAlloc (GetProcessHeap (), 0, sdSize);
965c2c66affSColin Finck
966c2c66affSColin Finck /* Get security descriptor for real */
967c2c66affSColin Finck retSize = -1;
968c2c66affSColin Finck SetLastError(0xdeadbeef);
969c2c66affSColin Finck rc = pGetFileSecurityA (path, request, sd, sdSize, &retSize);
970c2c66affSColin Finck ok (rc, "GetFileSecurityA "
971c2c66affSColin Finck "was not expected to fail '%s': %d\n", path, GetLastError());
972c2c66affSColin Finck ok (retSize == sdSize ||
973c2c66affSColin Finck broken(retSize == 0), /* NT4 */
974c2c66affSColin Finck "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize);
975c2c66affSColin Finck
976c2c66affSColin Finck /* Use it to set security descriptor */
977c2c66affSColin Finck SetLastError(0xdeadbeef);
978c2c66affSColin Finck rc = pSetFileSecurityA (path, request, sd);
979c2c66affSColin Finck ok (rc, "SetFileSecurityA "
980c2c66affSColin Finck "was not expected to fail '%s': %d\n", path, GetLastError());
981c2c66affSColin Finck HeapFree (GetProcessHeap (), 0, sd);
982c2c66affSColin Finck
983c2c66affSColin Finck /* Old test */
984c2c66affSColin Finck strcpy (wintmpdir, "\\Should not exist");
985c2c66affSColin Finck SetLastError(0xdeadbeef);
986c2c66affSColin Finck rc = pGetFileSecurityA (wintmpdir, OWNER_SECURITY_INFORMATION, NULL, 0, &sdSize);
987c2c66affSColin Finck ok (!rc, "GetFileSecurityA should fail for not existing directories/files\n");
988c2c66affSColin Finck ok (GetLastError() == ERROR_FILE_NOT_FOUND,
989c2c66affSColin Finck "last error ERROR_FILE_NOT_FOUND expected, got %d\n", GetLastError());
990c2c66affSColin Finck
991c2c66affSColin Finck cleanup:
992c2c66affSColin Finck /* Remove temporary file and directory */
993c2c66affSColin Finck DeleteFileA(file);
994c2c66affSColin Finck RemoveDirectoryA(path);
995c2c66affSColin Finck
996c2c66affSColin Finck /* Test file access permissions for a file with FILE_ATTRIBUTE_ARCHIVE */
997c2c66affSColin Finck SetLastError(0xdeadbeef);
998c2c66affSColin Finck rc = GetTempPathA(sizeof(wintmpdir), wintmpdir);
999c2c66affSColin Finck ok(rc, "GetTempPath error %d\n", GetLastError());
1000c2c66affSColin Finck
1001c2c66affSColin Finck SetLastError(0xdeadbeef);
1002c2c66affSColin Finck rc = GetTempFileNameA(wintmpdir, "tmp", 0, file);
1003c2c66affSColin Finck ok(rc, "GetTempFileName error %d\n", GetLastError());
1004c2c66affSColin Finck
1005c2c66affSColin Finck rc = GetFileAttributesA(file);
1006c2c66affSColin Finck rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED);
1007c2c66affSColin Finck ok(rc == FILE_ATTRIBUTE_ARCHIVE, "expected FILE_ATTRIBUTE_ARCHIVE got %#x\n", rc);
1008c2c66affSColin Finck
1009c2c66affSColin Finck rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
1010c2c66affSColin Finck NULL, 0, &sdSize);
1011c2c66affSColin Finck ok(!rc, "GetFileSecurity should fail\n");
1012c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1013c2c66affSColin Finck "expected ERROR_INSUFFICIENT_BUFFER got %d\n", GetLastError());
1014c2c66affSColin Finck ok(sdSize > sizeof(SECURITY_DESCRIPTOR), "got sd size %d\n", sdSize);
1015c2c66affSColin Finck
1016c2c66affSColin Finck sd = HeapAlloc(GetProcessHeap (), 0, sdSize);
1017c2c66affSColin Finck retSize = 0xdeadbeef;
1018c2c66affSColin Finck SetLastError(0xdeadbeef);
1019c2c66affSColin Finck rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
1020c2c66affSColin Finck sd, sdSize, &retSize);
1021c2c66affSColin Finck ok(rc, "GetFileSecurity error %d\n", GetLastError());
1022c2c66affSColin Finck ok(retSize == sdSize || broken(retSize == 0) /* NT4 */, "expected %d, got %d\n", sdSize, retSize);
1023c2c66affSColin Finck
1024c2c66affSColin Finck SetLastError(0xdeadbeef);
1025c2c66affSColin Finck rc = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token);
1026c2c66affSColin Finck ok(!rc, "OpenThreadToken should fail\n");
1027c2c66affSColin Finck ok(GetLastError() == ERROR_NO_TOKEN, "expected ERROR_NO_TOKEN, got %d\n", GetLastError());
1028c2c66affSColin Finck
1029c2c66affSColin Finck SetLastError(0xdeadbeef);
1030c2c66affSColin Finck rc = ImpersonateSelf(SecurityIdentification);
1031c2c66affSColin Finck ok(rc, "ImpersonateSelf error %d\n", GetLastError());
1032c2c66affSColin Finck
1033c2c66affSColin Finck SetLastError(0xdeadbeef);
1034c2c66affSColin Finck rc = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token);
1035c2c66affSColin Finck ok(rc, "OpenThreadToken error %d\n", GetLastError());
1036c2c66affSColin Finck
1037c2c66affSColin Finck SetLastError(0xdeadbeef);
1038c2c66affSColin Finck rc = RevertToSelf();
1039c2c66affSColin Finck ok(rc, "RevertToSelf error %d\n", GetLastError());
1040c2c66affSColin Finck
1041c2c66affSColin Finck priv_set_len = sizeof(priv_set);
1042c2c66affSColin Finck granted = 0xdeadbeef;
1043c2c66affSColin Finck status = 0xdeadbeef;
1044c2c66affSColin Finck SetLastError(0xdeadbeef);
1045c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1046c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1047c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1048c2c66affSColin Finck ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#x\n", granted);
1049c2c66affSColin Finck
1050c2c66affSColin Finck granted = 0xdeadbeef;
1051c2c66affSColin Finck status = 0xdeadbeef;
1052c2c66affSColin Finck SetLastError(0xdeadbeef);
1053c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1054c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1055c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1056c2c66affSColin Finck ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#x\n", granted);
1057c2c66affSColin Finck
1058c2c66affSColin Finck granted = 0xdeadbeef;
1059c2c66affSColin Finck status = 0xdeadbeef;
1060c2c66affSColin Finck SetLastError(0xdeadbeef);
1061c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1062c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1063c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1064c2c66affSColin Finck ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#x\n", granted);
1065c2c66affSColin Finck
1066c2c66affSColin Finck granted = 0xdeadbeef;
1067c2c66affSColin Finck status = 0xdeadbeef;
1068c2c66affSColin Finck SetLastError(0xdeadbeef);
1069c2c66affSColin Finck rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1070c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1071c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1072c2c66affSColin Finck ok(granted == DELETE, "expected DELETE, got %#x\n", granted);
1073c2c66affSColin Finck
1074c2c66affSColin Finck granted = 0xdeadbeef;
1075c2c66affSColin Finck status = 0xdeadbeef;
1076c2c66affSColin Finck SetLastError(0xdeadbeef);
1077c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status);
1078c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1079c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1080c2c66affSColin Finck ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#x\n", granted);
1081c2c66affSColin Finck
1082c2c66affSColin Finck granted = 0xdeadbeef;
1083c2c66affSColin Finck status = 0xdeadbeef;
1084c2c66affSColin Finck SetLastError(0xdeadbeef);
1085c2c66affSColin Finck rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status);
1086c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1087c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1088c2c66affSColin Finck ok(granted == 0x1ff, "expected 0x1ff, got %#x\n", granted);
1089c2c66affSColin Finck
1090c2c66affSColin Finck granted = 0xdeadbeef;
1091c2c66affSColin Finck status = 0xdeadbeef;
1092c2c66affSColin Finck SetLastError(0xdeadbeef);
1093c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status);
1094c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1095c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1096c2c66affSColin Finck ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", granted);
1097c2c66affSColin Finck
1098c2c66affSColin Finck SetLastError(0xdeadbeef);
1099c2c66affSColin Finck rc = AccessCheck(sd, token, 0xffffffff, &mapping, &priv_set, &priv_set_len, &granted, &status);
1100c2c66affSColin Finck ok(!rc, "AccessCheck should fail\n");
1101c2c66affSColin Finck ok(GetLastError() == ERROR_GENERIC_NOT_MAPPED, "expected ERROR_GENERIC_NOT_MAPPED, got %d\n", GetLastError());
1102c2c66affSColin Finck
1103c2c66affSColin Finck /* Test file access permissions for a file with FILE_ATTRIBUTE_READONLY */
1104c2c66affSColin Finck SetLastError(0xdeadbeef);
1105c2c66affSColin Finck fh = CreateFileA(file, FILE_READ_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0);
1106c2c66affSColin Finck ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
1107c2c66affSColin Finck retSize = 0xdeadbeef;
1108c2c66affSColin Finck SetLastError(0xdeadbeef);
1109c2c66affSColin Finck rc = WriteFile(fh, "1", 1, &retSize, NULL);
1110c2c66affSColin Finck ok(!rc, "WriteFile should fail\n");
1111c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1112c2c66affSColin Finck ok(retSize == 0, "expected 0, got %d\n", retSize);
1113c2c66affSColin Finck CloseHandle(fh);
1114c2c66affSColin Finck
1115c2c66affSColin Finck rc = GetFileAttributesA(file);
1116c2c66affSColin Finck rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED);
1117c2c66affSColin Finck todo_wine
1118c2c66affSColin Finck ok(rc == (FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY),
1119c2c66affSColin Finck "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#x\n", rc);
1120c2c66affSColin Finck
1121c2c66affSColin Finck SetLastError(0xdeadbeef);
1122c2c66affSColin Finck rc = SetFileAttributesA(file, FILE_ATTRIBUTE_ARCHIVE);
1123c2c66affSColin Finck ok(rc, "SetFileAttributes error %d\n", GetLastError());
1124c2c66affSColin Finck SetLastError(0xdeadbeef);
1125c2c66affSColin Finck rc = DeleteFileA(file);
1126c2c66affSColin Finck ok(rc, "DeleteFile error %d\n", GetLastError());
1127c2c66affSColin Finck
1128c2c66affSColin Finck SetLastError(0xdeadbeef);
1129c2c66affSColin Finck fh = CreateFileA(file, FILE_READ_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0);
1130c2c66affSColin Finck ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
1131c2c66affSColin Finck retSize = 0xdeadbeef;
1132c2c66affSColin Finck SetLastError(0xdeadbeef);
1133c2c66affSColin Finck rc = WriteFile(fh, "1", 1, &retSize, NULL);
1134c2c66affSColin Finck ok(!rc, "WriteFile should fail\n");
1135c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1136c2c66affSColin Finck ok(retSize == 0, "expected 0, got %d\n", retSize);
1137c2c66affSColin Finck CloseHandle(fh);
1138c2c66affSColin Finck
1139c2c66affSColin Finck rc = GetFileAttributesA(file);
1140c2c66affSColin Finck rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED);
1141c2c66affSColin Finck ok(rc == (FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY),
1142c2c66affSColin Finck "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#x\n", rc);
1143c2c66affSColin Finck
1144c2c66affSColin Finck retSize = 0xdeadbeef;
1145c2c66affSColin Finck SetLastError(0xdeadbeef);
1146c2c66affSColin Finck rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
1147c2c66affSColin Finck sd, sdSize, &retSize);
1148c2c66affSColin Finck ok(rc, "GetFileSecurity error %d\n", GetLastError());
1149c2c66affSColin Finck ok(retSize == sdSize || broken(retSize == 0) /* NT4 */, "expected %d, got %d\n", sdSize, retSize);
1150c2c66affSColin Finck
1151c2c66affSColin Finck priv_set_len = sizeof(priv_set);
1152c2c66affSColin Finck granted = 0xdeadbeef;
1153c2c66affSColin Finck status = 0xdeadbeef;
1154c2c66affSColin Finck SetLastError(0xdeadbeef);
1155c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1156c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1157c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1158c2c66affSColin Finck ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#x\n", granted);
1159c2c66affSColin Finck
1160c2c66affSColin Finck granted = 0xdeadbeef;
1161c2c66affSColin Finck status = 0xdeadbeef;
1162c2c66affSColin Finck SetLastError(0xdeadbeef);
1163c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1164c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1165c2c66affSColin Finck todo_wine {
1166c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1167c2c66affSColin Finck ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#x\n", granted);
1168c2c66affSColin Finck }
1169c2c66affSColin Finck granted = 0xdeadbeef;
1170c2c66affSColin Finck status = 0xdeadbeef;
1171c2c66affSColin Finck SetLastError(0xdeadbeef);
1172c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1173c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1174c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1175c2c66affSColin Finck ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#x\n", granted);
1176c2c66affSColin Finck
1177c2c66affSColin Finck granted = 0xdeadbeef;
1178c2c66affSColin Finck status = 0xdeadbeef;
1179c2c66affSColin Finck SetLastError(0xdeadbeef);
1180c2c66affSColin Finck rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1181c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1182c2c66affSColin Finck todo_wine {
1183c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1184c2c66affSColin Finck ok(granted == DELETE, "expected DELETE, got %#x\n", granted);
1185c2c66affSColin Finck }
1186c2c66affSColin Finck granted = 0xdeadbeef;
1187c2c66affSColin Finck status = 0xdeadbeef;
1188c2c66affSColin Finck SetLastError(0xdeadbeef);
1189c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status);
1190c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1191c2c66affSColin Finck todo_wine {
1192c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1193c2c66affSColin Finck ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#x\n", granted);
1194c2c66affSColin Finck }
1195c2c66affSColin Finck granted = 0xdeadbeef;
1196c2c66affSColin Finck status = 0xdeadbeef;
1197c2c66affSColin Finck SetLastError(0xdeadbeef);
1198c2c66affSColin Finck rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status);
1199c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1200c2c66affSColin Finck todo_wine {
1201c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1202c2c66affSColin Finck ok(granted == 0x1ff, "expected 0x1ff, got %#x\n", granted);
1203c2c66affSColin Finck }
1204c2c66affSColin Finck granted = 0xdeadbeef;
1205c2c66affSColin Finck status = 0xdeadbeef;
1206c2c66affSColin Finck SetLastError(0xdeadbeef);
1207c2c66affSColin Finck rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status);
1208c2c66affSColin Finck ok(rc, "AccessCheck error %d\n", GetLastError());
1209c2c66affSColin Finck todo_wine {
1210c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
1211c2c66affSColin Finck ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", granted);
1212c2c66affSColin Finck }
1213c2c66affSColin Finck SetLastError(0xdeadbeef);
1214c2c66affSColin Finck rc = DeleteFileA(file);
1215c2c66affSColin Finck ok(!rc, "DeleteFile should fail\n");
1216c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1217c2c66affSColin Finck SetLastError(0xdeadbeef);
1218c2c66affSColin Finck rc = SetFileAttributesA(file, FILE_ATTRIBUTE_ARCHIVE);
1219c2c66affSColin Finck ok(rc, "SetFileAttributes error %d\n", GetLastError());
1220c2c66affSColin Finck SetLastError(0xdeadbeef);
1221c2c66affSColin Finck rc = DeleteFileA(file);
1222c2c66affSColin Finck ok(rc, "DeleteFile error %d\n", GetLastError());
1223c2c66affSColin Finck
1224c2c66affSColin Finck CloseHandle(token);
1225c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sd);
1226c2c66affSColin Finck }
1227c2c66affSColin Finck
test_AccessCheck(void)1228c2c66affSColin Finck static void test_AccessCheck(void)
1229c2c66affSColin Finck {
1230c2c66affSColin Finck PSID EveryoneSid = NULL, AdminSid = NULL, UsersSid = NULL;
1231c2c66affSColin Finck PACL Acl = NULL;
1232c2c66affSColin Finck SECURITY_DESCRIPTOR *SecurityDescriptor = NULL;
1233c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
1234c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
1235c2c66affSColin Finck GENERIC_MAPPING Mapping = { KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS };
1236c2c66affSColin Finck ACCESS_MASK Access;
1237c2c66affSColin Finck BOOL AccessStatus;
1238c2c66affSColin Finck HANDLE Token;
1239c2c66affSColin Finck HANDLE ProcessToken;
1240c2c66affSColin Finck BOOL ret;
1241c2c66affSColin Finck DWORD PrivSetLen;
1242c2c66affSColin Finck PRIVILEGE_SET *PrivSet;
1243c2c66affSColin Finck BOOL res;
1244c2c66affSColin Finck HMODULE NtDllModule;
1245c2c66affSColin Finck BOOLEAN Enabled;
1246c2c66affSColin Finck DWORD err;
1247c2c66affSColin Finck NTSTATUS ntret, ntAccessStatus;
1248c2c66affSColin Finck
1249c2c66affSColin Finck NtDllModule = GetModuleHandleA("ntdll.dll");
1250c2c66affSColin Finck if (!NtDllModule)
1251c2c66affSColin Finck {
1252c2c66affSColin Finck skip("not running on NT, skipping test\n");
1253c2c66affSColin Finck return;
1254c2c66affSColin Finck }
1255c2c66affSColin Finck pRtlAdjustPrivilege = (void *)GetProcAddress(NtDllModule, "RtlAdjustPrivilege");
1256c2c66affSColin Finck if (!pRtlAdjustPrivilege)
1257c2c66affSColin Finck {
1258c2c66affSColin Finck win_skip("missing RtlAdjustPrivilege, skipping test\n");
1259c2c66affSColin Finck return;
1260c2c66affSColin Finck }
1261c2c66affSColin Finck
1262c2c66affSColin Finck Acl = HeapAlloc(GetProcessHeap(), 0, 256);
1263c2c66affSColin Finck res = InitializeAcl(Acl, 256, ACL_REVISION);
1264c2c66affSColin Finck if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1265c2c66affSColin Finck {
1266c2c66affSColin Finck skip("ACLs not implemented - skipping tests\n");
1267c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Acl);
1268c2c66affSColin Finck return;
1269c2c66affSColin Finck }
1270c2c66affSColin Finck ok(res, "InitializeAcl failed with error %d\n", GetLastError());
1271c2c66affSColin Finck
1272c2c66affSColin Finck res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
1273c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
1274c2c66affSColin Finck
1275c2c66affSColin Finck res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
1276c2c66affSColin Finck DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdminSid);
1277c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
1278c2c66affSColin Finck
1279c2c66affSColin Finck res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
1280c2c66affSColin Finck DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
1281c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
1282c2c66affSColin Finck
1283c2c66affSColin Finck SecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
1284c2c66affSColin Finck
1285c2c66affSColin Finck res = InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
1286c2c66affSColin Finck ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError());
1287c2c66affSColin Finck
1288c2c66affSColin Finck res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
1289c2c66affSColin Finck ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
1290c2c66affSColin Finck
1291c2c66affSColin Finck PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1292c2c66affSColin Finck PrivSet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, PrivSetLen);
1293c2c66affSColin Finck PrivSet->PrivilegeCount = 16;
1294c2c66affSColin Finck
1295c2c66affSColin Finck res = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &ProcessToken);
1296c2c66affSColin Finck ok(res, "OpenProcessToken failed with error %d\n", GetLastError());
1297c2c66affSColin Finck
1298c2c66affSColin Finck pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, FALSE, TRUE, &Enabled);
1299c2c66affSColin Finck
1300c2c66affSColin Finck res = DuplicateToken(ProcessToken, SecurityImpersonation, &Token);
1301c2c66affSColin Finck ok(res, "DuplicateToken failed with error %d\n", GetLastError());
1302c2c66affSColin Finck
1303c2c66affSColin Finck /* SD without owner/group */
1304c2c66affSColin Finck SetLastError(0xdeadbeef);
1305c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1306c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_QUERY_VALUE, &Mapping,
1307c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1308c2c66affSColin Finck err = GetLastError();
1309c2c66affSColin Finck ok(!ret && err == ERROR_INVALID_SECURITY_DESCR, "AccessCheck should have "
1310c2c66affSColin Finck "failed with ERROR_INVALID_SECURITY_DESCR, instead of %d\n", err);
1311c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1312c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1313c2c66affSColin Finck
1314c2c66affSColin Finck /* Set owner and group */
1315c2c66affSColin Finck res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE);
1316c2c66affSColin Finck ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError());
1317c2c66affSColin Finck res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, TRUE);
1318c2c66affSColin Finck ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
1319c2c66affSColin Finck
1320c2c66affSColin Finck /* Generic access mask */
1321c2c66affSColin Finck SetLastError(0xdeadbeef);
1322c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1323c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1324c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1325c2c66affSColin Finck err = GetLastError();
1326c2c66affSColin Finck ok(!ret && err == ERROR_GENERIC_NOT_MAPPED, "AccessCheck should have failed "
1327c2c66affSColin Finck "with ERROR_GENERIC_NOT_MAPPED, instead of %d\n", err);
1328c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1329c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1330c2c66affSColin Finck
1331c2c66affSColin Finck /* Generic access mask - no privilegeset buffer */
1332c2c66affSColin Finck SetLastError(0xdeadbeef);
1333c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1334c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1335c2c66affSColin Finck NULL, &PrivSetLen, &Access, &AccessStatus);
1336c2c66affSColin Finck err = GetLastError();
1337c2c66affSColin Finck ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1338c2c66affSColin Finck "with ERROR_NOACCESS, instead of %d\n", err);
1339c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1340c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1341c2c66affSColin Finck
1342c2c66affSColin Finck /* Generic access mask - no returnlength */
1343c2c66affSColin Finck SetLastError(0xdeadbeef);
1344c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1345c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1346c2c66affSColin Finck PrivSet, NULL, &Access, &AccessStatus);
1347c2c66affSColin Finck err = GetLastError();
1348c2c66affSColin Finck ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1349c2c66affSColin Finck "with ERROR_NOACCESS, instead of %d\n", err);
1350c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1351c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1352c2c66affSColin Finck
1353c2c66affSColin Finck /* Generic access mask - no privilegeset buffer, no returnlength */
1354c2c66affSColin Finck SetLastError(0xdeadbeef);
1355c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1356c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1357c2c66affSColin Finck NULL, NULL, &Access, &AccessStatus);
1358c2c66affSColin Finck err = GetLastError();
1359c2c66affSColin Finck ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1360c2c66affSColin Finck "with ERROR_NOACCESS, instead of %d\n", err);
1361c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1362c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1363c2c66affSColin Finck
1364c2c66affSColin Finck /* sd with no dacl present */
1365c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1366c2c66affSColin Finck ret = SetSecurityDescriptorDacl(SecurityDescriptor, FALSE, NULL, FALSE);
1367c2c66affSColin Finck ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
1368c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1369c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1370c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1371c2c66affSColin Finck ok(AccessStatus && (Access == KEY_READ),
1372c2c66affSColin Finck "AccessCheck failed to grant access with error %d\n",
1373c2c66affSColin Finck GetLastError());
1374c2c66affSColin Finck
1375c2c66affSColin Finck /* sd with no dacl present - no privilegeset buffer */
1376c2c66affSColin Finck SetLastError(0xdeadbeef);
1377c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1378c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1379c2c66affSColin Finck NULL, &PrivSetLen, &Access, &AccessStatus);
1380c2c66affSColin Finck err = GetLastError();
1381c2c66affSColin Finck ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1382c2c66affSColin Finck "with ERROR_NOACCESS, instead of %d\n", err);
1383c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1384c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1385c2c66affSColin Finck
1386c2c66affSColin Finck if(pNtAccessCheck)
1387c2c66affSColin Finck {
1388c2c66affSColin Finck /* Generic access mask - no privilegeset buffer */
1389c2c66affSColin Finck SetLastError(0xdeadbeef);
1390c2c66affSColin Finck Access = ntAccessStatus = 0x1abe11ed;
1391c2c66affSColin Finck ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1392c2c66affSColin Finck NULL, &PrivSetLen, &Access, &ntAccessStatus);
1393c2c66affSColin Finck err = GetLastError();
1394c2c66affSColin Finck ok(ntret == STATUS_ACCESS_VIOLATION,
1395c2c66affSColin Finck "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret);
1396c2c66affSColin Finck ok(err == 0xdeadbeef,
1397c2c66affSColin Finck "NtAccessCheck shouldn't set last error, got %d\n", err);
1398c2c66affSColin Finck ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1399c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1400c2c66affSColin Finck
1401c2c66affSColin Finck /* Generic access mask - no returnlength */
1402c2c66affSColin Finck SetLastError(0xdeadbeef);
1403c2c66affSColin Finck Access = ntAccessStatus = 0x1abe11ed;
1404c2c66affSColin Finck ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1405c2c66affSColin Finck PrivSet, NULL, &Access, &ntAccessStatus);
1406c2c66affSColin Finck err = GetLastError();
1407c2c66affSColin Finck ok(ntret == STATUS_ACCESS_VIOLATION,
1408c2c66affSColin Finck "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret);
1409c2c66affSColin Finck ok(err == 0xdeadbeef,
1410c2c66affSColin Finck "NtAccessCheck shouldn't set last error, got %d\n", err);
1411c2c66affSColin Finck ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1412c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1413c2c66affSColin Finck
1414c2c66affSColin Finck /* Generic access mask - no privilegeset buffer, no returnlength */
1415c2c66affSColin Finck SetLastError(0xdeadbeef);
1416c2c66affSColin Finck Access = ntAccessStatus = 0x1abe11ed;
1417c2c66affSColin Finck ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1418c2c66affSColin Finck NULL, NULL, &Access, &ntAccessStatus);
1419c2c66affSColin Finck err = GetLastError();
1420c2c66affSColin Finck ok(ntret == STATUS_ACCESS_VIOLATION,
1421c2c66affSColin Finck "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret);
1422c2c66affSColin Finck ok(err == 0xdeadbeef,
1423c2c66affSColin Finck "NtAccessCheck shouldn't set last error, got %d\n", err);
1424c2c66affSColin Finck ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1425c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1426c2c66affSColin Finck }
1427c2c66affSColin Finck else
1428c2c66affSColin Finck win_skip("NtAccessCheck unavailable. Skipping.\n");
1429c2c66affSColin Finck
1430c2c66affSColin Finck /* sd with NULL dacl */
1431c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1432c2c66affSColin Finck ret = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, NULL, FALSE);
1433c2c66affSColin Finck ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
1434c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1435c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1436c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1437c2c66affSColin Finck ok(AccessStatus && (Access == KEY_READ),
1438c2c66affSColin Finck "AccessCheck failed to grant access with error %d\n",
1439c2c66affSColin Finck GetLastError());
1440c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping,
1441c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1442c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1443c2c66affSColin Finck ok(AccessStatus && (Access == KEY_ALL_ACCESS),
1444c2c66affSColin Finck "AccessCheck failed to grant access with error %d\n",
1445c2c66affSColin Finck GetLastError());
1446c2c66affSColin Finck
1447c2c66affSColin Finck /* sd with blank dacl */
1448c2c66affSColin Finck ret = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
1449c2c66affSColin Finck ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
1450c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1451c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1452c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1453c2c66affSColin Finck err = GetLastError();
1454c2c66affSColin Finck ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed "
1455c2c66affSColin Finck "with ERROR_ACCESS_DENIED, instead of %d\n", err);
1456c2c66affSColin Finck ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access);
1457c2c66affSColin Finck
1458c2c66affSColin Finck res = AddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, EveryoneSid);
1459c2c66affSColin Finck ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
1460c2c66affSColin Finck
1461c2c66affSColin Finck res = AddAccessDeniedAce(Acl, ACL_REVISION, KEY_SET_VALUE, AdminSid);
1462c2c66affSColin Finck ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError());
1463c2c66affSColin Finck
1464c2c66affSColin Finck /* sd with dacl */
1465c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1466c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1467c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1468c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1469c2c66affSColin Finck ok(AccessStatus && (Access == KEY_READ),
1470c2c66affSColin Finck "AccessCheck failed to grant access with error %d\n",
1471c2c66affSColin Finck GetLastError());
1472c2c66affSColin Finck
1473c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping,
1474c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1475c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1476c2c66affSColin Finck ok(AccessStatus,
1477c2c66affSColin Finck "AccessCheck failed to grant any access with error %d\n",
1478c2c66affSColin Finck GetLastError());
1479c2c66affSColin Finck trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08x\n", Access);
1480c2c66affSColin Finck
1481c2c66affSColin Finck /* Null PrivSet with null PrivSetLen pointer */
1482c2c66affSColin Finck SetLastError(0xdeadbeef);
1483c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1484c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1485c2c66affSColin Finck NULL, NULL, &Access, &AccessStatus);
1486c2c66affSColin Finck err = GetLastError();
1487c2c66affSColin Finck ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1488c2c66affSColin Finck "failed with ERROR_NOACCESS, instead of %d\n", err);
1489c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1490c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1491c2c66affSColin Finck
1492c2c66affSColin Finck /* Null PrivSet with zero PrivSetLen */
1493c2c66affSColin Finck SetLastError(0xdeadbeef);
1494c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1495c2c66affSColin Finck PrivSetLen = 0;
1496c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1497c2c66affSColin Finck 0, &PrivSetLen, &Access, &AccessStatus);
1498c2c66affSColin Finck err = GetLastError();
1499c2c66affSColin Finck ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1500c2c66affSColin Finck "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1501c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1502c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1503c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1504c2c66affSColin Finck
1505c2c66affSColin Finck /* Null PrivSet with insufficient PrivSetLen */
1506c2c66affSColin Finck SetLastError(0xdeadbeef);
1507c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1508c2c66affSColin Finck PrivSetLen = 1;
1509c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1510c2c66affSColin Finck 0, &PrivSetLen, &Access, &AccessStatus);
1511c2c66affSColin Finck err = GetLastError();
1512c2c66affSColin Finck ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1513c2c66affSColin Finck "failed with ERROR_NOACCESS, instead of %d\n", err);
1514c2c66affSColin Finck ok(PrivSetLen == 1, "PrivSetLen returns %d\n", PrivSetLen);
1515c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1516c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1517c2c66affSColin Finck
1518c2c66affSColin Finck /* Null PrivSet with insufficient PrivSetLen */
1519c2c66affSColin Finck SetLastError(0xdeadbeef);
1520c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1521c2c66affSColin Finck PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
1522c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1523c2c66affSColin Finck 0, &PrivSetLen, &Access, &AccessStatus);
1524c2c66affSColin Finck err = GetLastError();
1525c2c66affSColin Finck ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1526c2c66affSColin Finck "failed with ERROR_NOACCESS, instead of %d\n", err);
1527c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET) - 1, "PrivSetLen returns %d\n", PrivSetLen);
1528c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1529c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1530c2c66affSColin Finck
1531c2c66affSColin Finck /* Null PrivSet with minimal sufficient PrivSetLen */
1532c2c66affSColin Finck SetLastError(0xdeadbeef);
1533c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1534c2c66affSColin Finck PrivSetLen = sizeof(PRIVILEGE_SET);
1535c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1536c2c66affSColin Finck 0, &PrivSetLen, &Access, &AccessStatus);
1537c2c66affSColin Finck err = GetLastError();
1538c2c66affSColin Finck ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1539c2c66affSColin Finck "failed with ERROR_NOACCESS, instead of %d\n", err);
1540c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1541c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1542c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1543c2c66affSColin Finck
1544c2c66affSColin Finck /* Valid PrivSet with zero PrivSetLen */
1545c2c66affSColin Finck SetLastError(0xdeadbeef);
1546c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1547c2c66affSColin Finck PrivSetLen = 0;
1548c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1549c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1550c2c66affSColin Finck err = GetLastError();
1551c2c66affSColin Finck ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1552c2c66affSColin Finck "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1553c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1554c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1555c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1556c2c66affSColin Finck
1557c2c66affSColin Finck /* Valid PrivSet with insufficient PrivSetLen */
1558c2c66affSColin Finck SetLastError(0xdeadbeef);
1559c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1560c2c66affSColin Finck PrivSetLen = 1;
1561c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1562c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1563c2c66affSColin Finck err = GetLastError();
1564c2c66affSColin Finck todo_wine
1565c2c66affSColin Finck ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1566c2c66affSColin Finck "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1567c2c66affSColin Finck todo_wine
1568c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1569c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1570c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1571c2c66affSColin Finck
1572c2c66affSColin Finck /* Valid PrivSet with insufficient PrivSetLen */
1573c2c66affSColin Finck SetLastError(0xdeadbeef);
1574c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1575c2c66affSColin Finck PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
1576c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1577c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1578c2c66affSColin Finck err = GetLastError();
1579c2c66affSColin Finck todo_wine
1580c2c66affSColin Finck ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1581c2c66affSColin Finck "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1582c2c66affSColin Finck todo_wine
1583c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1584c2c66affSColin Finck todo_wine
1585c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1586c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1587c2c66affSColin Finck
1588c2c66affSColin Finck /* Valid PrivSet with minimal sufficient PrivSetLen */
1589c2c66affSColin Finck SetLastError(0xdeadbeef);
1590c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1591c2c66affSColin Finck PrivSetLen = sizeof(PRIVILEGE_SET);
1592c2c66affSColin Finck memset(PrivSet, 0xcc, PrivSetLen);
1593c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1594c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1595c2c66affSColin Finck err = GetLastError();
1596c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1597c2c66affSColin Finck todo_wine
1598c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1599c2c66affSColin Finck ok(AccessStatus && (Access == KEY_READ),
1600c2c66affSColin Finck "AccessCheck failed to grant access with error %d\n", GetLastError());
1601c2c66affSColin Finck ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n",
1602c2c66affSColin Finck PrivSet->PrivilegeCount);
1603c2c66affSColin Finck
1604c2c66affSColin Finck /* Valid PrivSet with sufficient PrivSetLen */
1605c2c66affSColin Finck SetLastError(0xdeadbeef);
1606c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1607c2c66affSColin Finck PrivSetLen = sizeof(PRIVILEGE_SET) + 1;
1608c2c66affSColin Finck memset(PrivSet, 0xcc, PrivSetLen);
1609c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1610c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1611c2c66affSColin Finck err = GetLastError();
1612c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1613c2c66affSColin Finck todo_wine
1614c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET) + 1, "PrivSetLen returns %d\n", PrivSetLen);
1615c2c66affSColin Finck ok(AccessStatus && (Access == KEY_READ),
1616c2c66affSColin Finck "AccessCheck failed to grant access with error %d\n", GetLastError());
1617c2c66affSColin Finck ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n",
1618c2c66affSColin Finck PrivSet->PrivilegeCount);
1619c2c66affSColin Finck
1620c2c66affSColin Finck PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1621c2c66affSColin Finck
1622c2c66affSColin Finck /* Null PrivSet with valid PrivSetLen */
1623c2c66affSColin Finck SetLastError(0xdeadbeef);
1624c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1625c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1626c2c66affSColin Finck 0, &PrivSetLen, &Access, &AccessStatus);
1627c2c66affSColin Finck err = GetLastError();
1628c2c66affSColin Finck ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1629c2c66affSColin Finck "failed with ERROR_NOACCESS, instead of %d\n", err);
1630c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1631c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1632c2c66affSColin Finck
1633c2c66affSColin Finck /* Access denied by SD */
1634c2c66affSColin Finck SetLastError(0xdeadbeef);
1635c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1636c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_WRITE, &Mapping,
1637c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1638c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1639c2c66affSColin Finck err = GetLastError();
1640c2c66affSColin Finck ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed "
1641c2c66affSColin Finck "with ERROR_ACCESS_DENIED, instead of %d\n", err);
1642c2c66affSColin Finck ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access);
1643c2c66affSColin Finck
1644c2c66affSColin Finck SetLastError(0xdeadbeef);
1645c2c66affSColin Finck PrivSet->PrivilegeCount = 16;
1646c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
1647c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1648c2c66affSColin Finck ok(ret && !AccessStatus && GetLastError() == ERROR_PRIVILEGE_NOT_HELD,
1649c2c66affSColin Finck "AccessCheck should have failed with ERROR_PRIVILEGE_NOT_HELD, instead of %d\n",
1650c2c66affSColin Finck GetLastError());
1651c2c66affSColin Finck
1652c2c66affSColin Finck ret = ImpersonateLoggedOnUser(Token);
1653c2c66affSColin Finck ok(ret, "ImpersonateLoggedOnUser failed with error %d\n", GetLastError());
1654c2c66affSColin Finck ret = pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, TRUE, TRUE, &Enabled);
1655c2c66affSColin Finck if (!ret)
1656c2c66affSColin Finck {
1657c2c66affSColin Finck /* Valid PrivSet with zero PrivSetLen */
1658c2c66affSColin Finck SetLastError(0xdeadbeef);
1659c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1660c2c66affSColin Finck PrivSetLen = 0;
1661c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1662c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1663c2c66affSColin Finck err = GetLastError();
1664c2c66affSColin Finck ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1665c2c66affSColin Finck "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1666c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1667c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1668c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1669c2c66affSColin Finck
1670c2c66affSColin Finck /* Valid PrivSet with insufficient PrivSetLen */
1671c2c66affSColin Finck SetLastError(0xdeadbeef);
1672c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1673c2c66affSColin Finck PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
1674c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1675c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1676c2c66affSColin Finck err = GetLastError();
1677c2c66affSColin Finck todo_wine
1678c2c66affSColin Finck ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1679c2c66affSColin Finck "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
1680c2c66affSColin Finck todo_wine
1681c2c66affSColin Finck ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
1682c2c66affSColin Finck todo_wine
1683c2c66affSColin Finck ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1684c2c66affSColin Finck "Access and/or AccessStatus were changed!\n");
1685c2c66affSColin Finck
1686c2c66affSColin Finck /* Valid PrivSet with minimal sufficient PrivSetLen */
1687c2c66affSColin Finck SetLastError(0xdeadbeef);
1688c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1689c2c66affSColin Finck PrivSetLen = sizeof(PRIVILEGE_SET);
1690c2c66affSColin Finck memset(PrivSet, 0xcc, PrivSetLen);
1691c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
1692c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1693c2c66affSColin Finck ok(ret && AccessStatus && GetLastError() == 0xdeadbeef,
1694c2c66affSColin Finck "AccessCheck should have succeeded, error %d\n",
1695c2c66affSColin Finck GetLastError());
1696c2c66affSColin Finck ok(Access == ACCESS_SYSTEM_SECURITY,
1697c2c66affSColin Finck "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n",
1698c2c66affSColin Finck Access);
1699c2c66affSColin Finck ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n",
1700c2c66affSColin Finck PrivSet->PrivilegeCount);
1701c2c66affSColin Finck
1702c2c66affSColin Finck /* Valid PrivSet with large PrivSetLen */
1703c2c66affSColin Finck SetLastError(0xdeadbeef);
1704c2c66affSColin Finck Access = AccessStatus = 0x1abe11ed;
1705c2c66affSColin Finck PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1706c2c66affSColin Finck memset(PrivSet, 0xcc, PrivSetLen);
1707c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
1708c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1709c2c66affSColin Finck ok(ret && AccessStatus && GetLastError() == 0xdeadbeef,
1710c2c66affSColin Finck "AccessCheck should have succeeded, error %d\n",
1711c2c66affSColin Finck GetLastError());
1712c2c66affSColin Finck ok(Access == ACCESS_SYSTEM_SECURITY,
1713c2c66affSColin Finck "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n",
1714c2c66affSColin Finck Access);
1715c2c66affSColin Finck ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n",
1716c2c66affSColin Finck PrivSet->PrivilegeCount);
1717c2c66affSColin Finck }
1718c2c66affSColin Finck else
1719c2c66affSColin Finck trace("Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test\n",
1720c2c66affSColin Finck ret);
1721c2c66affSColin Finck ret = RevertToSelf();
1722c2c66affSColin Finck ok(ret, "RevertToSelf failed with error %d\n", GetLastError());
1723c2c66affSColin Finck
1724c2c66affSColin Finck /* test INHERIT_ONLY_ACE */
1725c2c66affSColin Finck ret = InitializeAcl(Acl, 256, ACL_REVISION);
1726c2c66affSColin Finck ok(ret, "InitializeAcl failed with error %d\n", GetLastError());
1727c2c66affSColin Finck
1728c2c66affSColin Finck /* NT doesn't have AddAccessAllowedAceEx. Skipping this call/test doesn't influence
1729c2c66affSColin Finck * the next ones.
1730c2c66affSColin Finck */
1731c2c66affSColin Finck if (pAddAccessAllowedAceEx)
1732c2c66affSColin Finck {
1733c2c66affSColin Finck ret = pAddAccessAllowedAceEx(Acl, ACL_REVISION, INHERIT_ONLY_ACE, KEY_READ, EveryoneSid);
1734c2c66affSColin Finck ok(ret, "AddAccessAllowedAceEx failed with error %d\n", GetLastError());
1735c2c66affSColin Finck }
1736c2c66affSColin Finck else
1737c2c66affSColin Finck win_skip("AddAccessAllowedAceEx is not available\n");
1738c2c66affSColin Finck
1739c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1740c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1741c2c66affSColin Finck ok(ret, "AccessCheck failed with error %d\n", GetLastError());
1742c2c66affSColin Finck err = GetLastError();
1743c2c66affSColin Finck ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed "
1744c2c66affSColin Finck "with ERROR_ACCESS_DENIED, instead of %d\n", err);
1745c2c66affSColin Finck ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access);
1746c2c66affSColin Finck
1747c2c66affSColin Finck CloseHandle(Token);
1748c2c66affSColin Finck
1749c2c66affSColin Finck res = DuplicateToken(ProcessToken, SecurityAnonymous, &Token);
1750c2c66affSColin Finck ok(res, "DuplicateToken failed with error %d\n", GetLastError());
1751c2c66affSColin Finck
1752c2c66affSColin Finck SetLastError(0xdeadbeef);
1753c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping,
1754c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1755c2c66affSColin Finck err = GetLastError();
1756c2c66affSColin Finck ok(!ret && err == ERROR_BAD_IMPERSONATION_LEVEL, "AccessCheck should have failed "
1757c2c66affSColin Finck "with ERROR_BAD_IMPERSONATION_LEVEL, instead of %d\n", err);
1758c2c66affSColin Finck
1759c2c66affSColin Finck CloseHandle(Token);
1760c2c66affSColin Finck
1761c2c66affSColin Finck SetLastError(0xdeadbeef);
1762c2c66affSColin Finck ret = AccessCheck(SecurityDescriptor, ProcessToken, KEY_READ, &Mapping,
1763c2c66affSColin Finck PrivSet, &PrivSetLen, &Access, &AccessStatus);
1764c2c66affSColin Finck err = GetLastError();
1765c2c66affSColin Finck ok(!ret && err == ERROR_NO_IMPERSONATION_TOKEN, "AccessCheck should have failed "
1766c2c66affSColin Finck "with ERROR_NO_IMPERSONATION_TOKEN, instead of %d\n", err);
1767c2c66affSColin Finck
1768c2c66affSColin Finck CloseHandle(ProcessToken);
1769c2c66affSColin Finck
1770c2c66affSColin Finck if (EveryoneSid)
1771c2c66affSColin Finck FreeSid(EveryoneSid);
1772c2c66affSColin Finck if (AdminSid)
1773c2c66affSColin Finck FreeSid(AdminSid);
1774c2c66affSColin Finck if (UsersSid)
1775c2c66affSColin Finck FreeSid(UsersSid);
1776c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Acl);
1777c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, SecurityDescriptor);
1778c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, PrivSet);
1779c2c66affSColin Finck }
1780c2c66affSColin Finck
1781c2c66affSColin Finck /* test GetTokenInformation for the various attributes */
test_token_attr(void)1782c2c66affSColin Finck static void test_token_attr(void)
1783c2c66affSColin Finck {
1784c2c66affSColin Finck HANDLE Token, ImpersonationToken;
1785c2c66affSColin Finck DWORD Size, Size2;
1786c2c66affSColin Finck TOKEN_PRIVILEGES *Privileges;
1787c2c66affSColin Finck TOKEN_GROUPS *Groups;
1788c2c66affSColin Finck TOKEN_USER *User;
1789c2c66affSColin Finck TOKEN_DEFAULT_DACL *Dacl;
1790c2c66affSColin Finck BOOL ret;
1791c2c66affSColin Finck DWORD i, GLE;
1792c2c66affSColin Finck LPSTR SidString;
1793c2c66affSColin Finck SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
1794c2c66affSColin Finck ACL *acl;
1795c2c66affSColin Finck
1796c2c66affSColin Finck /* cygwin-like use case */
1797c2c66affSColin Finck SetLastError(0xdeadbeef);
1798c2c66affSColin Finck ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &Token);
1799c2c66affSColin Finck if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1800c2c66affSColin Finck {
1801c2c66affSColin Finck win_skip("OpenProcessToken is not implemented\n");
1802c2c66affSColin Finck return;
1803c2c66affSColin Finck }
1804c2c66affSColin Finck ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1805c2c66affSColin Finck if (ret)
1806c2c66affSColin Finck {
1807c2c66affSColin Finck DWORD buf[256]; /* GetTokenInformation wants a dword-aligned buffer */
1808c2c66affSColin Finck Size = sizeof(buf);
1809c2c66affSColin Finck ret = GetTokenInformation(Token, TokenUser,(void*)buf, Size, &Size);
1810c2c66affSColin Finck ok(ret, "GetTokenInformation failed with error %d\n", GetLastError());
1811c2c66affSColin Finck Size = sizeof(ImpersonationLevel);
1812c2c66affSColin Finck ret = GetTokenInformation(Token, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size);
1813c2c66affSColin Finck GLE = GetLastError();
1814c2c66affSColin Finck ok(!ret && (GLE == ERROR_INVALID_PARAMETER), "GetTokenInformation(TokenImpersonationLevel) on primary token should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GLE);
1815c2c66affSColin Finck CloseHandle(Token);
1816c2c66affSColin Finck }
1817c2c66affSColin Finck
1818c2c66affSColin Finck SetLastError(0xdeadbeef);
1819c2c66affSColin Finck ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &Token);
1820c2c66affSColin Finck ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1821c2c66affSColin Finck
1822c2c66affSColin Finck /* groups */
1823c2c66affSColin Finck /* insufficient buffer length */
1824c2c66affSColin Finck SetLastError(0xdeadbeef);
1825c2c66affSColin Finck Size2 = 0;
1826c2c66affSColin Finck ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size2);
1827c2c66affSColin Finck ok(Size2 > 1, "got %d\n", Size2);
1828c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1829c2c66affSColin Finck "%d with error %d\n", ret, GetLastError());
1830c2c66affSColin Finck Size2 -= 1;
1831c2c66affSColin Finck Groups = HeapAlloc(GetProcessHeap(), 0, Size2);
1832c2c66affSColin Finck memset(Groups, 0xcc, Size2);
1833c2c66affSColin Finck Size = 0;
1834c2c66affSColin Finck ret = GetTokenInformation(Token, TokenGroups, Groups, Size2, &Size);
1835c2c66affSColin Finck ok(Size > 1, "got %d\n", Size);
1836c2c66affSColin Finck ok((!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) || broken(ret) /* wow64 */,
1837c2c66affSColin Finck "%d with error %d\n", ret, GetLastError());
1838c2c66affSColin Finck if(!ret)
1839c2c66affSColin Finck ok(*((BYTE*)Groups) == 0xcc, "buffer altered\n");
1840c2c66affSColin Finck
1841c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Groups);
1842c2c66affSColin Finck
1843c2c66affSColin Finck SetLastError(0xdeadbeef);
1844c2c66affSColin Finck ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size);
1845c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1846c2c66affSColin Finck "GetTokenInformation(TokenGroups) %s with error %d\n",
1847c2c66affSColin Finck ret ? "succeeded" : "failed", GetLastError());
1848c2c66affSColin Finck Groups = HeapAlloc(GetProcessHeap(), 0, Size);
1849c2c66affSColin Finck SetLastError(0xdeadbeef);
1850c2c66affSColin Finck ret = GetTokenInformation(Token, TokenGroups, Groups, Size, &Size);
1851c2c66affSColin Finck ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n", GetLastError());
1852c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef,
1853c2c66affSColin Finck "GetTokenInformation shouldn't have set last error to %d\n",
1854c2c66affSColin Finck GetLastError());
1855c2c66affSColin Finck trace("TokenGroups:\n");
1856c2c66affSColin Finck for (i = 0; i < Groups->GroupCount; i++)
1857c2c66affSColin Finck {
1858c2c66affSColin Finck DWORD NameLength = 255;
1859c2c66affSColin Finck CHAR Name[255];
1860c2c66affSColin Finck DWORD DomainLength = 255;
1861c2c66affSColin Finck CHAR Domain[255];
1862c2c66affSColin Finck SID_NAME_USE SidNameUse;
1863c2c66affSColin Finck Name[0] = '\0';
1864c2c66affSColin Finck Domain[0] = '\0';
1865c2c66affSColin Finck ret = LookupAccountSidA(NULL, Groups->Groups[i].Sid, Name, &NameLength, Domain, &DomainLength, &SidNameUse);
1866c2c66affSColin Finck if (ret)
1867c2c66affSColin Finck {
1868561bed7bSAmine Khaldi ConvertSidToStringSidA(Groups->Groups[i].Sid, &SidString);
1869c2c66affSColin Finck trace("%s, %s\\%s use: %d attr: 0x%08x\n", SidString, Domain, Name, SidNameUse, Groups->Groups[i].Attributes);
1870c2c66affSColin Finck LocalFree(SidString);
1871c2c66affSColin Finck }
1872c2c66affSColin Finck else trace("attr: 0x%08x LookupAccountSid failed with error %d\n", Groups->Groups[i].Attributes, GetLastError());
1873c2c66affSColin Finck }
1874c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Groups);
1875c2c66affSColin Finck
1876c2c66affSColin Finck /* user */
1877c2c66affSColin Finck ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size);
1878c2c66affSColin Finck ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1879c2c66affSColin Finck "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
1880c2c66affSColin Finck User = HeapAlloc(GetProcessHeap(), 0, Size);
1881c2c66affSColin Finck ret = GetTokenInformation(Token, TokenUser, User, Size, &Size);
1882c2c66affSColin Finck ok(ret,
1883c2c66affSColin Finck "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
1884c2c66affSColin Finck
1885561bed7bSAmine Khaldi ConvertSidToStringSidA(User->User.Sid, &SidString);
1886c2c66affSColin Finck trace("TokenUser: %s attr: 0x%08x\n", SidString, User->User.Attributes);
1887c2c66affSColin Finck LocalFree(SidString);
1888c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, User);
1889c2c66affSColin Finck
1890*3c1b7834SAmine Khaldi /* logon */
1891*3c1b7834SAmine Khaldi ret = GetTokenInformation(Token, TokenLogonSid, NULL, 0, &Size);
1892*3c1b7834SAmine Khaldi if (!ret && (GetLastError() == ERROR_INVALID_PARAMETER))
1893*3c1b7834SAmine Khaldi todo_wine win_skip("TokenLogonSid not supported. Skipping tests\n");
1894*3c1b7834SAmine Khaldi else
1895*3c1b7834SAmine Khaldi {
1896*3c1b7834SAmine Khaldi ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1897*3c1b7834SAmine Khaldi "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError());
1898*3c1b7834SAmine Khaldi Groups = HeapAlloc(GetProcessHeap(), 0, Size);
1899*3c1b7834SAmine Khaldi ret = GetTokenInformation(Token, TokenLogonSid, Groups, Size, &Size);
1900*3c1b7834SAmine Khaldi ok(ret,
1901*3c1b7834SAmine Khaldi "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError());
1902*3c1b7834SAmine Khaldi if (ret)
1903*3c1b7834SAmine Khaldi {
1904*3c1b7834SAmine Khaldi ok(Groups->GroupCount == 1, "got %d\n", Groups->GroupCount);
1905*3c1b7834SAmine Khaldi if(Groups->GroupCount == 1)
1906*3c1b7834SAmine Khaldi {
1907*3c1b7834SAmine Khaldi ConvertSidToStringSidA(Groups->Groups[0].Sid, &SidString);
1908*3c1b7834SAmine Khaldi trace("TokenLogon: %s\n", SidString);
1909*3c1b7834SAmine Khaldi LocalFree(SidString);
1910*3c1b7834SAmine Khaldi
1911*3c1b7834SAmine Khaldi /* S-1-5-5-0-XXXXXX */
1912*3c1b7834SAmine Khaldi ret = IsWellKnownSid(Groups->Groups[0].Sid, WinLogonIdsSid);
1913*3c1b7834SAmine Khaldi ok(ret, "Unknown SID\n");
1914*3c1b7834SAmine Khaldi }
1915*3c1b7834SAmine Khaldi }
1916*3c1b7834SAmine Khaldi
1917*3c1b7834SAmine Khaldi HeapFree(GetProcessHeap(), 0, Groups);
1918*3c1b7834SAmine Khaldi }
1919*3c1b7834SAmine Khaldi
1920c2c66affSColin Finck /* privileges */
1921c2c66affSColin Finck ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size);
1922c2c66affSColin Finck ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1923c2c66affSColin Finck "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError());
1924c2c66affSColin Finck Privileges = HeapAlloc(GetProcessHeap(), 0, Size);
1925c2c66affSColin Finck ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size);
1926c2c66affSColin Finck ok(ret,
1927c2c66affSColin Finck "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError());
1928c2c66affSColin Finck trace("TokenPrivileges:\n");
1929c2c66affSColin Finck for (i = 0; i < Privileges->PrivilegeCount; i++)
1930c2c66affSColin Finck {
1931c2c66affSColin Finck CHAR Name[256];
1932c2c66affSColin Finck DWORD NameLen = sizeof(Name)/sizeof(Name[0]);
1933c2c66affSColin Finck LookupPrivilegeNameA(NULL, &Privileges->Privileges[i].Luid, Name, &NameLen);
1934c2c66affSColin Finck trace("\t%s, 0x%x\n", Name, Privileges->Privileges[i].Attributes);
1935c2c66affSColin Finck }
1936c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Privileges);
1937c2c66affSColin Finck
1938c2c66affSColin Finck ret = DuplicateToken(Token, SecurityAnonymous, &ImpersonationToken);
1939c2c66affSColin Finck ok(ret, "DuplicateToken failed with error %d\n", GetLastError());
1940c2c66affSColin Finck
1941c2c66affSColin Finck Size = sizeof(ImpersonationLevel);
1942c2c66affSColin Finck ret = GetTokenInformation(ImpersonationToken, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size);
1943c2c66affSColin Finck ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
1944c2c66affSColin Finck ok(ImpersonationLevel == SecurityAnonymous, "ImpersonationLevel should have been SecurityAnonymous instead of %d\n", ImpersonationLevel);
1945c2c66affSColin Finck
1946c2c66affSColin Finck CloseHandle(ImpersonationToken);
1947c2c66affSColin Finck
1948c2c66affSColin Finck /* default dacl */
1949c2c66affSColin Finck ret = GetTokenInformation(Token, TokenDefaultDacl, NULL, 0, &Size);
1950c2c66affSColin Finck ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1951c2c66affSColin Finck "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1952c2c66affSColin Finck
1953c2c66affSColin Finck Dacl = HeapAlloc(GetProcessHeap(), 0, Size);
1954c2c66affSColin Finck ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size);
1955c2c66affSColin Finck ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1956c2c66affSColin Finck
1957c2c66affSColin Finck SetLastError(0xdeadbeef);
1958c2c66affSColin Finck ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, 0);
1959c2c66affSColin Finck GLE = GetLastError();
1960c2c66affSColin Finck ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n");
1961c2c66affSColin Finck ok(GLE == ERROR_BAD_LENGTH, "expected ERROR_BAD_LENGTH got %u\n", GLE);
1962c2c66affSColin Finck
1963c2c66affSColin Finck SetLastError(0xdeadbeef);
1964c2c66affSColin Finck ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, Size);
1965c2c66affSColin Finck GLE = GetLastError();
1966c2c66affSColin Finck ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n");
1967c2c66affSColin Finck ok(GLE == ERROR_NOACCESS, "expected ERROR_NOACCESS got %u\n", GLE);
1968c2c66affSColin Finck
1969c2c66affSColin Finck acl = Dacl->DefaultDacl;
1970c2c66affSColin Finck Dacl->DefaultDacl = NULL;
1971c2c66affSColin Finck
1972c2c66affSColin Finck ret = SetTokenInformation(Token, TokenDefaultDacl, Dacl, Size);
1973c2c66affSColin Finck ok(ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n");
1974c2c66affSColin Finck
1975c2c66affSColin Finck Size2 = 0;
1976c2c66affSColin Finck Dacl->DefaultDacl = (ACL *)0xdeadbeef;
1977c2c66affSColin Finck ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2);
1978c2c66affSColin Finck ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1979c2c66affSColin Finck ok(Dacl->DefaultDacl == NULL, "expected NULL, got %p\n", Dacl->DefaultDacl);
1980c2c66affSColin Finck ok(Size2 == sizeof(TOKEN_DEFAULT_DACL) || broken(Size2 == 2*sizeof(TOKEN_DEFAULT_DACL)), /* WoW64 */
1981c2c66affSColin Finck "got %u expected sizeof(TOKEN_DEFAULT_DACL)\n", Size2);
1982c2c66affSColin Finck
1983c2c66affSColin Finck Dacl->DefaultDacl = acl;
1984c2c66affSColin Finck ret = SetTokenInformation(Token, TokenDefaultDacl, Dacl, Size);
1985c2c66affSColin Finck ok(ret, "SetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1986c2c66affSColin Finck
1987c2c66affSColin Finck if (Size2 == sizeof(TOKEN_DEFAULT_DACL)) {
1988c2c66affSColin Finck ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2);
1989c2c66affSColin Finck ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError());
1990c2c66affSColin Finck } else
1991c2c66affSColin Finck win_skip("TOKEN_DEFAULT_DACL size too small on WoW64\n");
1992c2c66affSColin Finck
1993c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Dacl);
1994c2c66affSColin Finck CloseHandle(Token);
1995c2c66affSColin Finck }
1996c2c66affSColin Finck
test_GetTokenInformation(void)1997c2c66affSColin Finck static void test_GetTokenInformation(void)
1998c2c66affSColin Finck {
1999c2c66affSColin Finck DWORD is_app_container, size;
2000c2c66affSColin Finck HANDLE token;
2001c2c66affSColin Finck BOOL ret;
2002c2c66affSColin Finck
2003c2c66affSColin Finck ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
2004c2c66affSColin Finck ok(ret, "OpenProcessToken failed: %u\n", GetLastError());
2005c2c66affSColin Finck
2006c2c66affSColin Finck size = 0;
2007c2c66affSColin Finck is_app_container = 0xdeadbeef;
2008c2c66affSColin Finck ret = GetTokenInformation(token, TokenIsAppContainer, &is_app_container,
2009c2c66affSColin Finck sizeof(is_app_container), &size);
2010c2c66affSColin Finck ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER ||
2011c2c66affSColin Finck GetLastError() == ERROR_INVALID_FUNCTION), /* pre-win8 */
2012c2c66affSColin Finck "GetTokenInformation failed: %u\n", GetLastError());
2013c2c66affSColin Finck if(ret) {
2014c2c66affSColin Finck ok(size == sizeof(is_app_container), "size = %u\n", size);
2015c2c66affSColin Finck ok(!is_app_container, "is_app_container = %x\n", is_app_container);
2016c2c66affSColin Finck }
2017c2c66affSColin Finck
2018c2c66affSColin Finck CloseHandle(token);
2019c2c66affSColin Finck }
2020c2c66affSColin Finck
2021c2c66affSColin Finck typedef union _MAX_SID
2022c2c66affSColin Finck {
2023c2c66affSColin Finck SID sid;
2024c2c66affSColin Finck char max[SECURITY_MAX_SID_SIZE];
2025c2c66affSColin Finck } MAX_SID;
2026c2c66affSColin Finck
test_sid_str(PSID * sid)2027c2c66affSColin Finck static void test_sid_str(PSID * sid)
2028c2c66affSColin Finck {
2029c2c66affSColin Finck char *str_sid;
2030561bed7bSAmine Khaldi BOOL ret = ConvertSidToStringSidA(sid, &str_sid);
2031c2c66affSColin Finck ok(ret, "ConvertSidToStringSidA() failed: %d\n", GetLastError());
2032c2c66affSColin Finck if (ret)
2033c2c66affSColin Finck {
2034c2c66affSColin Finck char account[MAX_PATH], domain[MAX_PATH];
2035c2c66affSColin Finck SID_NAME_USE use;
2036c2c66affSColin Finck DWORD acc_size = MAX_PATH;
2037c2c66affSColin Finck DWORD dom_size = MAX_PATH;
2038c2c66affSColin Finck ret = LookupAccountSidA (NULL, sid, account, &acc_size, domain, &dom_size, &use);
2039c2c66affSColin Finck ok(ret || GetLastError() == ERROR_NONE_MAPPED,
2040c2c66affSColin Finck "LookupAccountSid(%s) failed: %d\n", str_sid, GetLastError());
2041c2c66affSColin Finck if (ret)
2042c2c66affSColin Finck trace(" %s %s\\%s %d\n", str_sid, domain, account, use);
2043c2c66affSColin Finck else if (GetLastError() == ERROR_NONE_MAPPED)
2044c2c66affSColin Finck trace(" %s couldn't be mapped\n", str_sid);
2045c2c66affSColin Finck LocalFree(str_sid);
2046c2c66affSColin Finck }
2047c2c66affSColin Finck }
2048c2c66affSColin Finck
2049c2c66affSColin Finck static const struct well_known_sid_value
2050c2c66affSColin Finck {
2051c2c66affSColin Finck BOOL without_domain;
2052c2c66affSColin Finck const char *sid_string;
2053c2c66affSColin Finck } well_known_sid_values[] = {
2054c2c66affSColin Finck /* 0 */ {TRUE, "S-1-0-0"}, {TRUE, "S-1-1-0"}, {TRUE, "S-1-2-0"}, {TRUE, "S-1-3-0"},
2055c2c66affSColin Finck /* 4 */ {TRUE, "S-1-3-1"}, {TRUE, "S-1-3-2"}, {TRUE, "S-1-3-3"}, {TRUE, "S-1-5"},
2056c2c66affSColin Finck /* 8 */ {FALSE, "S-1-5-1"}, {TRUE, "S-1-5-2"}, {TRUE, "S-1-5-3"}, {TRUE, "S-1-5-4"},
2057c2c66affSColin Finck /* 12 */ {TRUE, "S-1-5-6"}, {TRUE, "S-1-5-7"}, {TRUE, "S-1-5-8"}, {TRUE, "S-1-5-9"},
2058c2c66affSColin Finck /* 16 */ {TRUE, "S-1-5-10"}, {TRUE, "S-1-5-11"}, {TRUE, "S-1-5-12"}, {TRUE, "S-1-5-13"},
2059c2c66affSColin Finck /* 20 */ {TRUE, "S-1-5-14"}, {FALSE, NULL}, {TRUE, "S-1-5-18"}, {TRUE, "S-1-5-19"},
2060c2c66affSColin Finck /* 24 */ {TRUE, "S-1-5-20"}, {TRUE, "S-1-5-32"},
2061c2c66affSColin Finck /* 26 */ {FALSE, "S-1-5-32-544"}, {TRUE, "S-1-5-32-545"}, {TRUE, "S-1-5-32-546"},
2062c2c66affSColin Finck /* 29 */ {TRUE, "S-1-5-32-547"}, {TRUE, "S-1-5-32-548"}, {TRUE, "S-1-5-32-549"},
2063c2c66affSColin Finck /* 32 */ {TRUE, "S-1-5-32-550"}, {TRUE, "S-1-5-32-551"}, {TRUE, "S-1-5-32-552"},
2064c2c66affSColin Finck /* 35 */ {TRUE, "S-1-5-32-554"}, {TRUE, "S-1-5-32-555"}, {TRUE, "S-1-5-32-556"},
2065c2c66affSColin Finck /* 38 */ {FALSE, "S-1-5-21-12-23-34-45-56-500"}, {FALSE, "S-1-5-21-12-23-34-45-56-501"},
2066c2c66affSColin Finck /* 40 */ {FALSE, "S-1-5-21-12-23-34-45-56-502"}, {FALSE, "S-1-5-21-12-23-34-45-56-512"},
2067c2c66affSColin Finck /* 42 */ {FALSE, "S-1-5-21-12-23-34-45-56-513"}, {FALSE, "S-1-5-21-12-23-34-45-56-514"},
2068c2c66affSColin Finck /* 44 */ {FALSE, "S-1-5-21-12-23-34-45-56-515"}, {FALSE, "S-1-5-21-12-23-34-45-56-516"},
2069c2c66affSColin Finck /* 46 */ {FALSE, "S-1-5-21-12-23-34-45-56-517"}, {FALSE, "S-1-5-21-12-23-34-45-56-518"},
2070c2c66affSColin Finck /* 48 */ {FALSE, "S-1-5-21-12-23-34-45-56-519"}, {FALSE, "S-1-5-21-12-23-34-45-56-520"},
2071c2c66affSColin Finck /* 50 */ {FALSE, "S-1-5-21-12-23-34-45-56-553"},
2072c2c66affSColin Finck /* Added in Windows Server 2003 */
2073c2c66affSColin Finck /* 51 */ {TRUE, "S-1-5-64-10"}, {TRUE, "S-1-5-64-21"}, {TRUE, "S-1-5-64-14"},
2074c2c66affSColin Finck /* 54 */ {TRUE, "S-1-5-15"}, {TRUE, "S-1-5-1000"}, {FALSE, "S-1-5-32-557"},
2075c2c66affSColin Finck /* 57 */ {TRUE, "S-1-5-32-558"}, {TRUE, "S-1-5-32-559"}, {TRUE, "S-1-5-32-560"},
2076c2c66affSColin Finck /* 60 */ {TRUE, "S-1-5-32-561"}, {TRUE, "S-1-5-32-562"},
2077c2c66affSColin Finck /* Added in Windows Vista: */
2078c2c66affSColin Finck /* 62 */ {TRUE, "S-1-5-32-568"},
2079c2c66affSColin Finck /* 63 */ {TRUE, "S-1-5-17"}, {FALSE, "S-1-5-32-569"}, {TRUE, "S-1-16-0"},
2080c2c66affSColin Finck /* 66 */ {TRUE, "S-1-16-4096"}, {TRUE, "S-1-16-8192"}, {TRUE, "S-1-16-12288"},
2081c2c66affSColin Finck /* 69 */ {TRUE, "S-1-16-16384"}, {TRUE, "S-1-5-33"}, {TRUE, "S-1-3-4"},
2082c2c66affSColin Finck /* 72 */ {FALSE, "S-1-5-21-12-23-34-45-56-571"}, {FALSE, "S-1-5-21-12-23-34-45-56-572"},
2083c2c66affSColin Finck /* 74 */ {TRUE, "S-1-5-22"}, {FALSE, "S-1-5-21-12-23-34-45-56-521"}, {TRUE, "S-1-5-32-573"},
2084c2c66affSColin Finck /* 77 */ {FALSE, "S-1-5-21-12-23-34-45-56-498"}, {TRUE, "S-1-5-32-574"}, {TRUE, "S-1-16-8448"},
2085c2c66affSColin Finck /* 80 */ {FALSE, NULL}, {TRUE, "S-1-2-1"}, {TRUE, "S-1-5-65-1"}, {FALSE, NULL},
2086c2c66affSColin Finck /* 84 */ {TRUE, "S-1-15-2-1"},
2087c2c66affSColin Finck };
2088c2c66affSColin Finck
test_CreateWellKnownSid(void)2089c2c66affSColin Finck static void test_CreateWellKnownSid(void)
2090c2c66affSColin Finck {
2091c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY };
2092c2c66affSColin Finck PSID domainsid, sid;
2093c2c66affSColin Finck DWORD size, error;
2094c2c66affSColin Finck BOOL ret;
2095c2c66affSColin Finck unsigned int i;
2096c2c66affSColin Finck
2097c2c66affSColin Finck if (!pCreateWellKnownSid)
2098c2c66affSColin Finck {
2099c2c66affSColin Finck win_skip("CreateWellKnownSid not available\n");
2100c2c66affSColin Finck return;
2101c2c66affSColin Finck }
2102c2c66affSColin Finck
2103c2c66affSColin Finck size = 0;
2104c2c66affSColin Finck SetLastError(0xdeadbeef);
2105c2c66affSColin Finck ret = pCreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size);
2106c2c66affSColin Finck error = GetLastError();
2107c2c66affSColin Finck ok(!ret, "CreateWellKnownSid succeeded\n");
2108c2c66affSColin Finck ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
2109c2c66affSColin Finck ok(size, "expected size > 0\n");
2110c2c66affSColin Finck
2111c2c66affSColin Finck SetLastError(0xdeadbeef);
2112c2c66affSColin Finck ret = pCreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size);
2113c2c66affSColin Finck error = GetLastError();
2114c2c66affSColin Finck ok(!ret, "CreateWellKnownSid succeeded\n");
2115c2c66affSColin Finck ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2116c2c66affSColin Finck
2117c2c66affSColin Finck sid = HeapAlloc(GetProcessHeap(), 0, size);
2118c2c66affSColin Finck ret = pCreateWellKnownSid(WinInteractiveSid, NULL, sid, &size);
2119c2c66affSColin Finck ok(ret, "CreateWellKnownSid failed %u\n", GetLastError());
2120c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sid);
2121c2c66affSColin Finck
2122c2c66affSColin Finck /* a domain sid usually have three subauthorities but we test that CreateWellKnownSid doesn't check it */
2123c2c66affSColin Finck AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid);
2124c2c66affSColin Finck
2125c2c66affSColin Finck for (i = 0; i < sizeof(well_known_sid_values)/sizeof(well_known_sid_values[0]); i++)
2126c2c66affSColin Finck {
2127c2c66affSColin Finck const struct well_known_sid_value *value = &well_known_sid_values[i];
2128c2c66affSColin Finck char sid_buffer[SECURITY_MAX_SID_SIZE];
2129c2c66affSColin Finck LPSTR str;
2130c2c66affSColin Finck DWORD cb;
2131c2c66affSColin Finck
2132c2c66affSColin Finck if (value->sid_string == NULL)
2133c2c66affSColin Finck continue;
2134c2c66affSColin Finck
2135c2c66affSColin Finck /* some SIDs aren't implemented by all Windows versions - detect it */
2136c2c66affSColin Finck cb = sizeof(sid_buffer);
2137c2c66affSColin Finck if (!pCreateWellKnownSid(i, NULL, sid_buffer, &cb))
2138c2c66affSColin Finck {
2139c2c66affSColin Finck skip("Well known SID %u not implemented\n", i);
2140c2c66affSColin Finck continue;
2141c2c66affSColin Finck }
2142c2c66affSColin Finck
2143c2c66affSColin Finck cb = sizeof(sid_buffer);
2144c2c66affSColin Finck ok(pCreateWellKnownSid(i, value->without_domain ? NULL : domainsid, sid_buffer, &cb), "Couldn't create well known sid %u\n", i);
2145c2c66affSColin Finck expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%d");
2146c2c66affSColin Finck ok(IsValidSid(sid_buffer), "The sid is not valid\n");
2147561bed7bSAmine Khaldi ok(ConvertSidToStringSidA(sid_buffer, &str), "Couldn't convert SID to string\n");
2148c2c66affSColin Finck ok(strcmp(str, value->sid_string) == 0, "%d: SID mismatch - expected %s, got %s\n", i,
2149c2c66affSColin Finck value->sid_string, str);
2150c2c66affSColin Finck LocalFree(str);
2151c2c66affSColin Finck
2152c2c66affSColin Finck if (value->without_domain)
2153c2c66affSColin Finck {
2154c2c66affSColin Finck char buf2[SECURITY_MAX_SID_SIZE];
2155c2c66affSColin Finck cb = sizeof(buf2);
2156c2c66affSColin Finck ok(pCreateWellKnownSid(i, domainsid, buf2, &cb), "Couldn't create well known sid %u with optional domain\n", i);
2157c2c66affSColin Finck expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%d");
2158c2c66affSColin Finck ok(memcmp(buf2, sid_buffer, cb) == 0, "SID create with domain is different than without (%u)\n", i);
2159c2c66affSColin Finck }
2160c2c66affSColin Finck }
2161c2c66affSColin Finck
2162c2c66affSColin Finck FreeSid(domainsid);
2163c2c66affSColin Finck }
2164c2c66affSColin Finck
test_LookupAccountSid(void)2165c2c66affSColin Finck static void test_LookupAccountSid(void)
2166c2c66affSColin Finck {
2167c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
2168c2c66affSColin Finck CHAR accountA[MAX_PATH], domainA[MAX_PATH], usernameA[MAX_PATH];
2169c2c66affSColin Finck DWORD acc_sizeA, dom_sizeA, user_sizeA;
2170c2c66affSColin Finck DWORD real_acc_sizeA, real_dom_sizeA;
2171c2c66affSColin Finck WCHAR accountW[MAX_PATH], domainW[MAX_PATH];
2172c2c66affSColin Finck DWORD acc_sizeW, dom_sizeW;
2173c2c66affSColin Finck DWORD real_acc_sizeW, real_dom_sizeW;
2174c2c66affSColin Finck PSID pUsersSid = NULL;
2175c2c66affSColin Finck SID_NAME_USE use;
2176c2c66affSColin Finck BOOL ret;
2177c2c66affSColin Finck DWORD error, size, cbti = 0;
2178c2c66affSColin Finck MAX_SID max_sid;
2179c2c66affSColin Finck CHAR *str_sidA;
2180c2c66affSColin Finck int i;
2181c2c66affSColin Finck HANDLE hToken;
2182c2c66affSColin Finck PTOKEN_USER ptiUser = NULL;
2183c2c66affSColin Finck
2184c2c66affSColin Finck /* native windows crashes if account size, domain size, or name use is NULL */
2185c2c66affSColin Finck
2186c2c66affSColin Finck ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
2187c2c66affSColin Finck DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pUsersSid);
2188c2c66affSColin Finck ok(ret || (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED),
2189c2c66affSColin Finck "AllocateAndInitializeSid failed with error %d\n", GetLastError());
2190c2c66affSColin Finck
2191c2c66affSColin Finck /* not running on NT so give up */
2192c2c66affSColin Finck if (!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2193c2c66affSColin Finck return;
2194c2c66affSColin Finck
2195c2c66affSColin Finck real_acc_sizeA = MAX_PATH;
2196c2c66affSColin Finck real_dom_sizeA = MAX_PATH;
2197c2c66affSColin Finck ret = LookupAccountSidA(NULL, pUsersSid, accountA, &real_acc_sizeA, domainA, &real_dom_sizeA, &use);
2198c2c66affSColin Finck ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2199c2c66affSColin Finck
2200c2c66affSColin Finck /* try NULL account */
2201c2c66affSColin Finck acc_sizeA = MAX_PATH;
2202c2c66affSColin Finck dom_sizeA = MAX_PATH;
2203c2c66affSColin Finck ret = LookupAccountSidA(NULL, pUsersSid, NULL, &acc_sizeA, domainA, &dom_sizeA, &use);
2204c2c66affSColin Finck ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2205c2c66affSColin Finck
2206c2c66affSColin Finck /* try NULL domain */
2207c2c66affSColin Finck acc_sizeA = MAX_PATH;
2208c2c66affSColin Finck dom_sizeA = MAX_PATH;
2209c2c66affSColin Finck ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, NULL, &dom_sizeA, &use);
2210c2c66affSColin Finck ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2211c2c66affSColin Finck
2212c2c66affSColin Finck /* try a small account buffer */
2213c2c66affSColin Finck acc_sizeA = 1;
2214c2c66affSColin Finck dom_sizeA = MAX_PATH;
2215c2c66affSColin Finck accountA[0] = 0;
2216c2c66affSColin Finck ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2217c2c66affSColin Finck ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
2218c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2219c2c66affSColin Finck "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
2220c2c66affSColin Finck
2221c2c66affSColin Finck /* try a 0 sized account buffer */
2222c2c66affSColin Finck acc_sizeA = 0;
2223c2c66affSColin Finck dom_sizeA = MAX_PATH;
2224c2c66affSColin Finck accountA[0] = 0;
2225c2c66affSColin Finck LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2226c2c66affSColin Finck /* this can fail or succeed depending on OS version but the size will always be returned */
2227c2c66affSColin Finck ok(acc_sizeA == real_acc_sizeA + 1,
2228c2c66affSColin Finck "LookupAccountSidA() Expected acc_size = %u, got %u\n",
2229c2c66affSColin Finck real_acc_sizeA + 1, acc_sizeA);
2230c2c66affSColin Finck
2231c2c66affSColin Finck /* try a 0 sized account buffer */
2232c2c66affSColin Finck acc_sizeA = 0;
2233c2c66affSColin Finck dom_sizeA = MAX_PATH;
2234c2c66affSColin Finck LookupAccountSidA(NULL, pUsersSid, NULL, &acc_sizeA, domainA, &dom_sizeA, &use);
2235c2c66affSColin Finck /* this can fail or succeed depending on OS version but the size will always be returned */
2236c2c66affSColin Finck ok(acc_sizeA == real_acc_sizeA + 1,
2237c2c66affSColin Finck "LookupAccountSid() Expected acc_size = %u, got %u\n",
2238c2c66affSColin Finck real_acc_sizeA + 1, acc_sizeA);
2239c2c66affSColin Finck
2240c2c66affSColin Finck /* try a small domain buffer */
2241c2c66affSColin Finck dom_sizeA = 1;
2242c2c66affSColin Finck acc_sizeA = MAX_PATH;
2243c2c66affSColin Finck accountA[0] = 0;
2244c2c66affSColin Finck ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2245c2c66affSColin Finck ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
2246c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2247c2c66affSColin Finck "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
2248c2c66affSColin Finck
2249c2c66affSColin Finck /* try a 0 sized domain buffer */
2250c2c66affSColin Finck dom_sizeA = 0;
2251c2c66affSColin Finck acc_sizeA = MAX_PATH;
2252c2c66affSColin Finck accountA[0] = 0;
2253c2c66affSColin Finck LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2254c2c66affSColin Finck /* this can fail or succeed depending on OS version but the size will always be returned */
2255c2c66affSColin Finck ok(dom_sizeA == real_dom_sizeA + 1,
2256c2c66affSColin Finck "LookupAccountSidA() Expected dom_size = %u, got %u\n",
2257c2c66affSColin Finck real_dom_sizeA + 1, dom_sizeA);
2258c2c66affSColin Finck
2259c2c66affSColin Finck /* try a 0 sized domain buffer */
2260c2c66affSColin Finck dom_sizeA = 0;
2261c2c66affSColin Finck acc_sizeA = MAX_PATH;
2262c2c66affSColin Finck LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, NULL, &dom_sizeA, &use);
2263c2c66affSColin Finck /* this can fail or succeed depending on OS version but the size will always be returned */
2264c2c66affSColin Finck ok(dom_sizeA == real_dom_sizeA + 1,
2265c2c66affSColin Finck "LookupAccountSidA() Expected dom_size = %u, got %u\n",
2266c2c66affSColin Finck real_dom_sizeA + 1, dom_sizeA);
2267c2c66affSColin Finck
2268c2c66affSColin Finck real_acc_sizeW = MAX_PATH;
2269c2c66affSColin Finck real_dom_sizeW = MAX_PATH;
2270c2c66affSColin Finck ret = LookupAccountSidW(NULL, pUsersSid, accountW, &real_acc_sizeW, domainW, &real_dom_sizeW, &use);
2271c2c66affSColin Finck ok(ret, "LookupAccountSidW() Expected TRUE, got FALSE\n");
2272c2c66affSColin Finck
2273c2c66affSColin Finck /* try an invalid system name */
2274c2c66affSColin Finck real_acc_sizeA = MAX_PATH;
2275c2c66affSColin Finck real_dom_sizeA = MAX_PATH;
2276c2c66affSColin Finck ret = LookupAccountSidA("deepthought", pUsersSid, accountA, &real_acc_sizeA, domainA, &real_dom_sizeA, &use);
2277c2c66affSColin Finck ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
2278c2c66affSColin Finck ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* Vista */,
2279c2c66affSColin Finck "LookupAccountSidA() Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %u\n", GetLastError());
2280c2c66affSColin Finck
2281c2c66affSColin Finck /* native windows crashes if domainW or accountW is NULL */
2282c2c66affSColin Finck
2283c2c66affSColin Finck /* try a small account buffer */
2284c2c66affSColin Finck acc_sizeW = 1;
2285c2c66affSColin Finck dom_sizeW = MAX_PATH;
2286c2c66affSColin Finck accountW[0] = 0;
2287c2c66affSColin Finck ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2288c2c66affSColin Finck ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n");
2289c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2290c2c66affSColin Finck "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
2291c2c66affSColin Finck
2292c2c66affSColin Finck /* try a 0 sized account buffer */
2293c2c66affSColin Finck acc_sizeW = 0;
2294c2c66affSColin Finck dom_sizeW = MAX_PATH;
2295c2c66affSColin Finck accountW[0] = 0;
2296c2c66affSColin Finck LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2297c2c66affSColin Finck /* this can fail or succeed depending on OS version but the size will always be returned */
2298c2c66affSColin Finck ok(acc_sizeW == real_acc_sizeW + 1,
2299c2c66affSColin Finck "LookupAccountSidW() Expected acc_size = %u, got %u\n",
2300c2c66affSColin Finck real_acc_sizeW + 1, acc_sizeW);
2301c2c66affSColin Finck
2302c2c66affSColin Finck /* try a 0 sized account buffer */
2303c2c66affSColin Finck acc_sizeW = 0;
2304c2c66affSColin Finck dom_sizeW = MAX_PATH;
2305c2c66affSColin Finck LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, domainW, &dom_sizeW, &use);
2306c2c66affSColin Finck /* this can fail or succeed depending on OS version but the size will always be returned */
2307c2c66affSColin Finck ok(acc_sizeW == real_acc_sizeW + 1,
2308c2c66affSColin Finck "LookupAccountSidW() Expected acc_size = %u, got %u\n",
2309c2c66affSColin Finck real_acc_sizeW + 1, acc_sizeW);
2310c2c66affSColin Finck
2311c2c66affSColin Finck /* try a small domain buffer */
2312c2c66affSColin Finck dom_sizeW = 1;
2313c2c66affSColin Finck acc_sizeW = MAX_PATH;
2314c2c66affSColin Finck accountW[0] = 0;
2315c2c66affSColin Finck ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2316c2c66affSColin Finck ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n");
2317c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2318c2c66affSColin Finck "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
2319c2c66affSColin Finck
2320c2c66affSColin Finck /* try a 0 sized domain buffer */
2321c2c66affSColin Finck dom_sizeW = 0;
2322c2c66affSColin Finck acc_sizeW = MAX_PATH;
2323c2c66affSColin Finck accountW[0] = 0;
2324c2c66affSColin Finck LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2325c2c66affSColin Finck /* this can fail or succeed depending on OS version but the size will always be returned */
2326c2c66affSColin Finck ok(dom_sizeW == real_dom_sizeW + 1,
2327c2c66affSColin Finck "LookupAccountSidW() Expected dom_size = %u, got %u\n",
2328c2c66affSColin Finck real_dom_sizeW + 1, dom_sizeW);
2329c2c66affSColin Finck
2330c2c66affSColin Finck /* try a 0 sized domain buffer */
2331c2c66affSColin Finck dom_sizeW = 0;
2332c2c66affSColin Finck acc_sizeW = MAX_PATH;
2333c2c66affSColin Finck LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, NULL, &dom_sizeW, &use);
2334c2c66affSColin Finck /* this can fail or succeed depending on OS version but the size will always be returned */
2335c2c66affSColin Finck ok(dom_sizeW == real_dom_sizeW + 1,
2336c2c66affSColin Finck "LookupAccountSidW() Expected dom_size = %u, got %u\n",
2337c2c66affSColin Finck real_dom_sizeW + 1, dom_sizeW);
2338c2c66affSColin Finck
2339c2c66affSColin Finck acc_sizeW = dom_sizeW = use = 0;
2340c2c66affSColin Finck SetLastError(0xdeadbeef);
2341c2c66affSColin Finck ret = LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, NULL, &dom_sizeW, &use);
2342c2c66affSColin Finck error = GetLastError();
2343c2c66affSColin Finck ok(!ret, "LookupAccountSidW failed %u\n", GetLastError());
2344c2c66affSColin Finck ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
2345c2c66affSColin Finck ok(acc_sizeW, "expected non-zero account size\n");
2346c2c66affSColin Finck ok(dom_sizeW, "expected non-zero domain size\n");
2347c2c66affSColin Finck ok(!use, "expected zero use %u\n", use);
2348c2c66affSColin Finck
2349c2c66affSColin Finck FreeSid(pUsersSid);
2350c2c66affSColin Finck
2351c2c66affSColin Finck /* Test LookupAccountSid with Sid retrieved from token information.
2352c2c66affSColin Finck This assumes this process is running under the account of the current user.*/
2353c2c66affSColin Finck ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &hToken);
2354c2c66affSColin Finck ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
2355c2c66affSColin Finck ret = GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti);
2356c2c66affSColin Finck ok(!ret, "GetTokenInformation failed with error %d\n", GetLastError());
2357c2c66affSColin Finck ptiUser = HeapAlloc(GetProcessHeap(), 0, cbti);
2358c2c66affSColin Finck if (GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti))
2359c2c66affSColin Finck {
2360c2c66affSColin Finck acc_sizeA = dom_sizeA = MAX_PATH;
2361c2c66affSColin Finck ret = LookupAccountSidA(NULL, ptiUser->User.Sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2362c2c66affSColin Finck ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2363c2c66affSColin Finck user_sizeA = MAX_PATH;
2364c2c66affSColin Finck ret = GetUserNameA(usernameA , &user_sizeA);
2365c2c66affSColin Finck ok(ret, "GetUserNameA() Expected TRUE, got FALSE\n");
2366c2c66affSColin Finck ok(lstrcmpA(usernameA, accountA) == 0, "LookupAccountSidA() Expected account name: %s got: %s\n", usernameA, accountA );
2367c2c66affSColin Finck }
2368c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, ptiUser);
2369c2c66affSColin Finck
2370561bed7bSAmine Khaldi if (pCreateWellKnownSid)
2371c2c66affSColin Finck {
2372c2c66affSColin Finck trace("Well Known SIDs:\n");
2373c2c66affSColin Finck for (i = 0; i <= 84; i++)
2374c2c66affSColin Finck {
2375c2c66affSColin Finck size = SECURITY_MAX_SID_SIZE;
2376c2c66affSColin Finck if (pCreateWellKnownSid(i, NULL, &max_sid.sid, &size))
2377c2c66affSColin Finck {
2378561bed7bSAmine Khaldi if (ConvertSidToStringSidA(&max_sid.sid, &str_sidA))
2379c2c66affSColin Finck {
2380c2c66affSColin Finck acc_sizeA = MAX_PATH;
2381c2c66affSColin Finck dom_sizeA = MAX_PATH;
2382c2c66affSColin Finck if (LookupAccountSidA(NULL, &max_sid.sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use))
2383c2c66affSColin Finck trace(" %d: %s %s\\%s %d\n", i, str_sidA, domainA, accountA, use);
2384c2c66affSColin Finck LocalFree(str_sidA);
2385c2c66affSColin Finck }
2386c2c66affSColin Finck }
2387c2c66affSColin Finck else
2388c2c66affSColin Finck {
2389c2c66affSColin Finck if (GetLastError() != ERROR_INVALID_PARAMETER)
2390c2c66affSColin Finck trace(" CreateWellKnownSid(%d) failed: %d\n", i, GetLastError());
2391c2c66affSColin Finck else
2392c2c66affSColin Finck trace(" %d: not supported\n", i);
2393c2c66affSColin Finck }
2394c2c66affSColin Finck }
2395c2c66affSColin Finck
2396c2c66affSColin Finck pLsaQueryInformationPolicy = (void *)GetProcAddress( hmod, "LsaQueryInformationPolicy");
2397c2c66affSColin Finck pLsaOpenPolicy = (void *)GetProcAddress( hmod, "LsaOpenPolicy");
2398c2c66affSColin Finck pLsaFreeMemory = (void *)GetProcAddress( hmod, "LsaFreeMemory");
2399c2c66affSColin Finck pLsaClose = (void *)GetProcAddress( hmod, "LsaClose");
2400c2c66affSColin Finck
2401c2c66affSColin Finck if (pLsaQueryInformationPolicy && pLsaOpenPolicy && pLsaFreeMemory && pLsaClose)
2402c2c66affSColin Finck {
2403c2c66affSColin Finck NTSTATUS status;
2404c2c66affSColin Finck LSA_HANDLE handle;
2405c2c66affSColin Finck LSA_OBJECT_ATTRIBUTES object_attributes;
2406c2c66affSColin Finck
2407c2c66affSColin Finck ZeroMemory(&object_attributes, sizeof(object_attributes));
2408c2c66affSColin Finck object_attributes.Length = sizeof(object_attributes);
2409c2c66affSColin Finck
2410c2c66affSColin Finck status = pLsaOpenPolicy( NULL, &object_attributes, POLICY_ALL_ACCESS, &handle);
2411c2c66affSColin Finck ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED,
2412c2c66affSColin Finck "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x\n", status);
2413c2c66affSColin Finck
2414c2c66affSColin Finck /* try a more restricted access mask if necessary */
2415c2c66affSColin Finck if (status == STATUS_ACCESS_DENIED) {
2416c2c66affSColin Finck trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n");
2417c2c66affSColin Finck status = pLsaOpenPolicy( NULL, &object_attributes, POLICY_VIEW_LOCAL_INFORMATION, &handle);
2418c2c66affSColin Finck ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x\n", status);
2419c2c66affSColin Finck }
2420c2c66affSColin Finck
2421c2c66affSColin Finck if (status == STATUS_SUCCESS)
2422c2c66affSColin Finck {
2423c2c66affSColin Finck PPOLICY_ACCOUNT_DOMAIN_INFO info;
2424c2c66affSColin Finck status = pLsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (PVOID*)&info);
2425c2c66affSColin Finck ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy() failed, returned 0x%08x\n", status);
2426c2c66affSColin Finck if (status == STATUS_SUCCESS)
2427c2c66affSColin Finck {
2428c2c66affSColin Finck ok(info->DomainSid!=0, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) missing SID\n");
2429c2c66affSColin Finck if (info->DomainSid)
2430c2c66affSColin Finck {
2431c2c66affSColin Finck int count = *GetSidSubAuthorityCount(info->DomainSid);
2432c2c66affSColin Finck CopySid(GetSidLengthRequired(count), &max_sid, info->DomainSid);
2433c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2434c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_ADMIN;
2435c2c66affSColin Finck max_sid.sid.SubAuthorityCount = count + 1;
2436c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2437c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_GUEST;
2438c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2439c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ADMINS;
2440c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2441c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_USERS;
2442c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2443c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_GUESTS;
2444c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2445c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_COMPUTERS;
2446c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2447c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CONTROLLERS;
2448c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2449c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CERT_ADMINS;
2450c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2451c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_SCHEMA_ADMINS;
2452c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2453c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ENTERPRISE_ADMINS;
2454c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2455c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_POLICY_ADMINS;
2456c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2457c2c66affSColin Finck max_sid.sid.SubAuthority[count] = DOMAIN_ALIAS_RID_RAS_SERVERS;
2458c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2459c2c66affSColin Finck max_sid.sid.SubAuthority[count] = 1000; /* first user account */
2460c2c66affSColin Finck test_sid_str((PSID)&max_sid.sid);
2461c2c66affSColin Finck }
2462c2c66affSColin Finck
2463c2c66affSColin Finck pLsaFreeMemory((LPVOID)info);
2464c2c66affSColin Finck }
2465c2c66affSColin Finck
2466c2c66affSColin Finck status = pLsaClose(handle);
2467c2c66affSColin Finck ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status);
2468c2c66affSColin Finck }
2469c2c66affSColin Finck }
2470c2c66affSColin Finck }
2471c2c66affSColin Finck }
2472c2c66affSColin Finck
get_sid_info(PSID psid,LPSTR * user,LPSTR * dom)2473c2c66affSColin Finck static BOOL get_sid_info(PSID psid, LPSTR *user, LPSTR *dom)
2474c2c66affSColin Finck {
2475c2c66affSColin Finck static CHAR account[UNLEN + 1];
2476c2c66affSColin Finck static CHAR domain[UNLEN + 1];
2477c2c66affSColin Finck DWORD size, dom_size;
2478c2c66affSColin Finck SID_NAME_USE use;
2479c2c66affSColin Finck
2480c2c66affSColin Finck *user = account;
2481c2c66affSColin Finck *dom = domain;
2482c2c66affSColin Finck
2483c2c66affSColin Finck size = dom_size = UNLEN + 1;
2484c2c66affSColin Finck account[0] = '\0';
2485c2c66affSColin Finck domain[0] = '\0';
2486c2c66affSColin Finck SetLastError(0xdeadbeef);
2487c2c66affSColin Finck return LookupAccountSidA(NULL, psid, account, &size, domain, &dom_size, &use);
2488c2c66affSColin Finck }
2489c2c66affSColin Finck
check_wellknown_name(const char * name,WELL_KNOWN_SID_TYPE result)2490c2c66affSColin Finck static void check_wellknown_name(const char* name, WELL_KNOWN_SID_TYPE result)
2491c2c66affSColin Finck {
2492c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY };
2493c2c66affSColin Finck PSID domainsid = NULL;
2494c2c66affSColin Finck char wk_sid[SECURITY_MAX_SID_SIZE];
2495c2c66affSColin Finck DWORD cb;
2496c2c66affSColin Finck
2497c2c66affSColin Finck DWORD sid_size, domain_size;
2498c2c66affSColin Finck SID_NAME_USE sid_use;
2499c2c66affSColin Finck LPSTR domain, account, sid_domain, wk_domain, wk_account;
2500c2c66affSColin Finck PSID psid;
2501c2c66affSColin Finck BOOL ret ,ret2;
2502c2c66affSColin Finck
2503c2c66affSColin Finck sid_size = 0;
2504c2c66affSColin Finck domain_size = 0;
2505c2c66affSColin Finck ret = LookupAccountNameA(NULL, name, NULL, &sid_size, NULL, &domain_size, &sid_use);
2506c2c66affSColin Finck ok(!ret, " %s Should have failed to lookup account name\n", name);
2507c2c66affSColin Finck psid = HeapAlloc(GetProcessHeap(),0,sid_size);
2508c2c66affSColin Finck domain = HeapAlloc(GetProcessHeap(),0,domain_size);
2509c2c66affSColin Finck ret = LookupAccountNameA(NULL, name, psid, &sid_size, domain, &domain_size, &sid_use);
2510c2c66affSColin Finck
2511c2c66affSColin Finck if (!result)
2512c2c66affSColin Finck {
2513c2c66affSColin Finck ok(!ret, " %s Should have failed to lookup account name\n",name);
2514c2c66affSColin Finck goto cleanup;
2515c2c66affSColin Finck }
2516c2c66affSColin Finck
2517c2c66affSColin Finck AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid);
2518c2c66affSColin Finck cb = sizeof(wk_sid);
2519c2c66affSColin Finck if (!pCreateWellKnownSid(result, domainsid, wk_sid, &cb))
2520c2c66affSColin Finck {
2521c2c66affSColin Finck win_skip("SID %i is not available on the system\n",result);
2522c2c66affSColin Finck goto cleanup;
2523c2c66affSColin Finck }
2524c2c66affSColin Finck
2525c2c66affSColin Finck ret2 = get_sid_info(wk_sid, &wk_account, &wk_domain);
2526c2c66affSColin Finck if (!ret2 && GetLastError() == ERROR_NONE_MAPPED)
2527c2c66affSColin Finck {
2528c2c66affSColin Finck win_skip("CreateWellKnownSid() succeeded but the account '%s' is not present (W2K)\n", name);
2529c2c66affSColin Finck goto cleanup;
2530c2c66affSColin Finck }
2531c2c66affSColin Finck
2532c2c66affSColin Finck get_sid_info(psid, &account, &sid_domain);
2533c2c66affSColin Finck
2534c2c66affSColin Finck ok(ret, "Failed to lookup account name %s\n",name);
2535c2c66affSColin Finck ok(sid_size != 0, "sid_size was zero\n");
2536c2c66affSColin Finck
2537c2c66affSColin Finck ok(EqualSid(psid,wk_sid),"%s Sid %s fails to match well known sid %s!\n",
2538c2c66affSColin Finck name, debugstr_sid(psid), debugstr_sid(wk_sid));
2539c2c66affSColin Finck
2540c2c66affSColin Finck ok(!lstrcmpA(account, wk_account), "Expected %s , got %s\n", account, wk_account);
2541c2c66affSColin Finck ok(!lstrcmpA(domain, wk_domain), "Expected %s, got %s\n", wk_domain, domain);
2542c2c66affSColin Finck ok(sid_use == SidTypeWellKnownGroup , "Expected Use (5), got %d\n", sid_use);
2543c2c66affSColin Finck
2544c2c66affSColin Finck cleanup:
2545c2c66affSColin Finck FreeSid(domainsid);
2546c2c66affSColin Finck HeapFree(GetProcessHeap(),0,psid);
2547c2c66affSColin Finck HeapFree(GetProcessHeap(),0,domain);
2548c2c66affSColin Finck }
2549c2c66affSColin Finck
test_LookupAccountName(void)2550c2c66affSColin Finck static void test_LookupAccountName(void)
2551c2c66affSColin Finck {
2552c2c66affSColin Finck DWORD sid_size, domain_size, user_size;
2553c2c66affSColin Finck DWORD sid_save, domain_save;
2554c2c66affSColin Finck CHAR user_name[UNLEN + 1];
2555c2c66affSColin Finck CHAR computer_name[UNLEN + 1];
2556c2c66affSColin Finck SID_NAME_USE sid_use;
2557c2c66affSColin Finck LPSTR domain, account, sid_dom;
2558c2c66affSColin Finck PSID psid;
2559c2c66affSColin Finck BOOL ret;
2560c2c66affSColin Finck
2561c2c66affSColin Finck /* native crashes if (assuming all other parameters correct):
2562c2c66affSColin Finck * - peUse is NULL
2563c2c66affSColin Finck * - Sid is NULL and cbSid is > 0
2564c2c66affSColin Finck * - cbSid or cchReferencedDomainName are NULL
2565c2c66affSColin Finck * - ReferencedDomainName is NULL and cchReferencedDomainName is the correct size
2566c2c66affSColin Finck */
2567c2c66affSColin Finck
2568c2c66affSColin Finck user_size = UNLEN + 1;
2569c2c66affSColin Finck SetLastError(0xdeadbeef);
2570c2c66affSColin Finck ret = GetUserNameA(user_name, &user_size);
2571c2c66affSColin Finck ok(ret, "Failed to get user name : %d\n", GetLastError());
2572c2c66affSColin Finck
2573c2c66affSColin Finck /* get sizes */
2574c2c66affSColin Finck sid_size = 0;
2575c2c66affSColin Finck domain_size = 0;
2576c2c66affSColin Finck sid_use = 0xcafebabe;
2577c2c66affSColin Finck SetLastError(0xdeadbeef);
2578c2c66affSColin Finck ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, NULL, &domain_size, &sid_use);
2579c2c66affSColin Finck if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2580c2c66affSColin Finck {
2581c2c66affSColin Finck win_skip("LookupAccountNameA is not implemented\n");
2582c2c66affSColin Finck return;
2583c2c66affSColin Finck }
2584c2c66affSColin Finck ok(!ret, "Expected 0, got %d\n", ret);
2585c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2586c2c66affSColin Finck "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2587c2c66affSColin Finck ok(sid_size != 0, "Expected non-zero sid size\n");
2588c2c66affSColin Finck ok(domain_size != 0, "Expected non-zero domain size\n");
2589*3c1b7834SAmine Khaldi ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
2590c2c66affSColin Finck
2591c2c66affSColin Finck sid_save = sid_size;
2592c2c66affSColin Finck domain_save = domain_size;
2593c2c66affSColin Finck
2594c2c66affSColin Finck psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
2595c2c66affSColin Finck domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
2596c2c66affSColin Finck
2597c2c66affSColin Finck /* try valid account name */
2598c2c66affSColin Finck ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, domain, &domain_size, &sid_use);
2599c2c66affSColin Finck get_sid_info(psid, &account, &sid_dom);
2600c2c66affSColin Finck ok(ret, "Failed to lookup account name\n");
2601c2c66affSColin Finck ok(sid_size == GetLengthSid(psid), "Expected %d, got %d\n", GetLengthSid(psid), sid_size);
2602c2c66affSColin Finck ok(!lstrcmpA(account, user_name), "Expected %s, got %s\n", user_name, account);
2603c2c66affSColin Finck ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain);
2604c2c66affSColin Finck ok(domain_size == domain_save - 1, "Expected %d, got %d\n", domain_save - 1, domain_size);
2605c2c66affSColin Finck ok(strlen(domain) == domain_size, "Expected %d, got %d\n", lstrlenA(domain), domain_size);
2606c2c66affSColin Finck ok(sid_use == SidTypeUser, "Expected SidTypeUser (%d), got %d\n", SidTypeUser, sid_use);
2607c2c66affSColin Finck domain_size = domain_save;
2608c2c66affSColin Finck sid_size = sid_save;
2609c2c66affSColin Finck
2610c2c66affSColin Finck if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
2611c2c66affSColin Finck {
2612c2c66affSColin Finck skip("Non-English locale (test with hardcoded 'Everyone')\n");
2613c2c66affSColin Finck }
2614c2c66affSColin Finck else
2615c2c66affSColin Finck {
2616c2c66affSColin Finck ret = LookupAccountNameA(NULL, "Everyone", psid, &sid_size, domain, &domain_size, &sid_use);
2617c2c66affSColin Finck get_sid_info(psid, &account, &sid_dom);
2618c2c66affSColin Finck ok(ret, "Failed to lookup account name\n");
2619c2c66affSColin Finck ok(sid_size != 0, "sid_size was zero\n");
2620c2c66affSColin Finck ok(!lstrcmpA(account, "Everyone"), "Expected Everyone, got %s\n", account);
2621c2c66affSColin Finck ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain);
2622c2c66affSColin Finck ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
2623c2c66affSColin Finck ok(strlen(domain) == domain_size, "Expected %d, got %d\n", lstrlenA(domain), domain_size);
2624c2c66affSColin Finck ok(sid_use == SidTypeWellKnownGroup, "Expected SidTypeWellKnownGroup (%d), got %d\n", SidTypeWellKnownGroup, sid_use);
2625c2c66affSColin Finck domain_size = domain_save;
2626c2c66affSColin Finck }
2627c2c66affSColin Finck
2628c2c66affSColin Finck /* NULL Sid with zero sid size */
2629c2c66affSColin Finck SetLastError(0xdeadbeef);
2630c2c66affSColin Finck sid_size = 0;
2631c2c66affSColin Finck ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use);
2632c2c66affSColin Finck ok(!ret, "Expected 0, got %d\n", ret);
2633c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2634c2c66affSColin Finck "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2635c2c66affSColin Finck ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size);
2636c2c66affSColin Finck ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size);
2637c2c66affSColin Finck
2638c2c66affSColin Finck /* try cchReferencedDomainName - 1 */
2639c2c66affSColin Finck SetLastError(0xdeadbeef);
2640c2c66affSColin Finck domain_size--;
2641c2c66affSColin Finck ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use);
2642c2c66affSColin Finck ok(!ret, "Expected 0, got %d\n", ret);
2643c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2644c2c66affSColin Finck "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2645c2c66affSColin Finck ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size);
2646c2c66affSColin Finck ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size);
2647c2c66affSColin Finck
2648c2c66affSColin Finck /* NULL ReferencedDomainName with zero domain name size */
2649c2c66affSColin Finck SetLastError(0xdeadbeef);
2650c2c66affSColin Finck domain_size = 0;
2651c2c66affSColin Finck ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, NULL, &domain_size, &sid_use);
2652c2c66affSColin Finck ok(!ret, "Expected 0, got %d\n", ret);
2653c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2654c2c66affSColin Finck "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2655c2c66affSColin Finck ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size);
2656c2c66affSColin Finck ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size);
2657c2c66affSColin Finck
2658c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, psid);
2659c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, domain);
2660c2c66affSColin Finck
2661c2c66affSColin Finck /* get sizes for NULL account name */
2662c2c66affSColin Finck sid_size = 0;
2663c2c66affSColin Finck domain_size = 0;
2664c2c66affSColin Finck sid_use = 0xcafebabe;
2665c2c66affSColin Finck SetLastError(0xdeadbeef);
2666c2c66affSColin Finck ret = LookupAccountNameA(NULL, NULL, NULL, &sid_size, NULL, &domain_size, &sid_use);
2667c2c66affSColin Finck if (!ret && GetLastError() == ERROR_NONE_MAPPED)
2668c2c66affSColin Finck win_skip("NULL account name doesn't work on NT4\n");
2669c2c66affSColin Finck else
2670c2c66affSColin Finck {
2671c2c66affSColin Finck ok(!ret, "Expected 0, got %d\n", ret);
2672c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2673c2c66affSColin Finck "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2674c2c66affSColin Finck ok(sid_size != 0, "Expected non-zero sid size\n");
2675c2c66affSColin Finck ok(domain_size != 0, "Expected non-zero domain size\n");
2676*3c1b7834SAmine Khaldi ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
2677c2c66affSColin Finck
2678c2c66affSColin Finck psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
2679c2c66affSColin Finck domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
2680c2c66affSColin Finck
2681c2c66affSColin Finck /* try NULL account name */
2682c2c66affSColin Finck ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain, &domain_size, &sid_use);
2683c2c66affSColin Finck get_sid_info(psid, &account, &sid_dom);
2684c2c66affSColin Finck ok(ret, "Failed to lookup account name\n");
2685c2c66affSColin Finck /* Using a fixed string will not work on different locales */
2686c2c66affSColin Finck ok(!lstrcmpiA(account, domain),
2687c2c66affSColin Finck "Got %s for account and %s for domain, these should be the same\n", account, domain);
2688c2c66affSColin Finck ok(sid_use == SidTypeDomain, "Expected SidTypeDomain (%d), got %d\n", SidTypeDomain, sid_use);
2689c2c66affSColin Finck
2690c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, psid);
2691c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, domain);
2692c2c66affSColin Finck }
2693c2c66affSColin Finck
2694c2c66affSColin Finck /* try an invalid account name */
2695c2c66affSColin Finck SetLastError(0xdeadbeef);
2696c2c66affSColin Finck sid_size = 0;
2697c2c66affSColin Finck domain_size = 0;
2698c2c66affSColin Finck ret = LookupAccountNameA(NULL, "oogabooga", NULL, &sid_size, NULL, &domain_size, &sid_use);
2699c2c66affSColin Finck ok(!ret, "Expected 0, got %d\n", ret);
2700c2c66affSColin Finck ok(GetLastError() == ERROR_NONE_MAPPED ||
2701c2c66affSColin Finck broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE),
2702c2c66affSColin Finck "Expected ERROR_NONE_MAPPED, got %d\n", GetLastError());
2703c2c66affSColin Finck ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
2704c2c66affSColin Finck ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
2705c2c66affSColin Finck
2706c2c66affSColin Finck /* try an invalid system name */
2707c2c66affSColin Finck SetLastError(0xdeadbeef);
2708c2c66affSColin Finck sid_size = 0;
2709c2c66affSColin Finck domain_size = 0;
2710c2c66affSColin Finck ret = LookupAccountNameA("deepthought", NULL, NULL, &sid_size, NULL, &domain_size, &sid_use);
2711c2c66affSColin Finck ok(!ret, "Expected 0, got %d\n", ret);
2712c2c66affSColin Finck ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* Vista */,
2713c2c66affSColin Finck "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
2714c2c66affSColin Finck ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
2715c2c66affSColin Finck ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
2716c2c66affSColin Finck
2717c2c66affSColin Finck /* try with the computer name as the account name */
2718c2c66affSColin Finck domain_size = sizeof(computer_name);
2719c2c66affSColin Finck GetComputerNameA(computer_name, &domain_size);
2720c2c66affSColin Finck sid_size = 0;
2721c2c66affSColin Finck domain_size = 0;
2722c2c66affSColin Finck ret = LookupAccountNameA(NULL, computer_name, NULL, &sid_size, NULL, &domain_size, &sid_use);
2723c2c66affSColin Finck ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
2724c2c66affSColin Finck GetLastError() == ERROR_NONE_MAPPED /* in a domain */ ||
2725c2c66affSColin Finck broken(GetLastError() == ERROR_TRUSTED_DOMAIN_FAILURE) ||
2726c2c66affSColin Finck broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE)),
2727c2c66affSColin Finck "LookupAccountNameA failed: %d\n", GetLastError());
2728c2c66affSColin Finck if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2729c2c66affSColin Finck {
2730c2c66affSColin Finck psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
2731c2c66affSColin Finck domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
2732c2c66affSColin Finck ret = LookupAccountNameA(NULL, computer_name, psid, &sid_size, domain, &domain_size, &sid_use);
2733c2c66affSColin Finck ok(ret, "LookupAccountNameA failed: %d\n", GetLastError());
2734c2c66affSColin Finck ok(sid_use == SidTypeDomain ||
2735c2c66affSColin Finck (sid_use == SidTypeUser && ! strcmp(computer_name, user_name)), "expected SidTypeDomain for %s, got %d\n", computer_name, sid_use);
2736c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, domain);
2737c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, psid);
2738c2c66affSColin Finck }
2739c2c66affSColin Finck
2740c2c66affSColin Finck /* Well Known names */
2741c2c66affSColin Finck if (!pCreateWellKnownSid)
2742c2c66affSColin Finck {
2743c2c66affSColin Finck win_skip("CreateWellKnownSid not available\n");
2744c2c66affSColin Finck return;
2745c2c66affSColin Finck }
2746c2c66affSColin Finck
2747c2c66affSColin Finck if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
2748c2c66affSColin Finck {
2749c2c66affSColin Finck skip("Non-English locale (skipping well known name creation tests)\n");
2750c2c66affSColin Finck return;
2751c2c66affSColin Finck }
2752c2c66affSColin Finck
2753c2c66affSColin Finck check_wellknown_name("LocalService", WinLocalServiceSid);
2754c2c66affSColin Finck check_wellknown_name("Local Service", WinLocalServiceSid);
2755c2c66affSColin Finck /* 2 spaces */
2756c2c66affSColin Finck check_wellknown_name("Local Service", 0);
2757c2c66affSColin Finck check_wellknown_name("NetworkService", WinNetworkServiceSid);
2758c2c66affSColin Finck check_wellknown_name("Network Service", WinNetworkServiceSid);
2759c2c66affSColin Finck
2760c2c66affSColin Finck /* example of some names where the spaces are not optional */
2761c2c66affSColin Finck check_wellknown_name("Terminal Server User", WinTerminalServerSid);
2762c2c66affSColin Finck check_wellknown_name("TerminalServer User", 0);
2763c2c66affSColin Finck check_wellknown_name("TerminalServerUser", 0);
2764c2c66affSColin Finck check_wellknown_name("Terminal ServerUser", 0);
2765c2c66affSColin Finck
2766c2c66affSColin Finck check_wellknown_name("enterprise domain controllers",WinEnterpriseControllersSid);
2767c2c66affSColin Finck check_wellknown_name("enterprisedomain controllers", 0);
2768c2c66affSColin Finck check_wellknown_name("enterprise domaincontrollers", 0);
2769c2c66affSColin Finck check_wellknown_name("enterprisedomaincontrollers", 0);
2770c2c66affSColin Finck
2771c2c66affSColin Finck /* case insensitivity */
2772c2c66affSColin Finck check_wellknown_name("lOCAlServICE", WinLocalServiceSid);
2773c2c66affSColin Finck
2774c2c66affSColin Finck /* fully qualified account names */
2775c2c66affSColin Finck check_wellknown_name("NT AUTHORITY\\LocalService", WinLocalServiceSid);
2776c2c66affSColin Finck check_wellknown_name("nt authority\\Network Service", WinNetworkServiceSid);
2777c2c66affSColin Finck check_wellknown_name("nt authority test\\Network Service", 0);
2778c2c66affSColin Finck check_wellknown_name("Dummy\\Network Service", 0);
2779c2c66affSColin Finck check_wellknown_name("ntauthority\\Network Service", 0);
2780c2c66affSColin Finck }
2781c2c66affSColin Finck
test_security_descriptor(void)2782c2c66affSColin Finck static void test_security_descriptor(void)
2783c2c66affSColin Finck {
2784*3c1b7834SAmine Khaldi SECURITY_DESCRIPTOR sd, *sd_rel, *sd_rel2, *sd_abs;
2785c2c66affSColin Finck char buf[8192];
2786*3c1b7834SAmine Khaldi DWORD size, size_dacl, size_sacl, size_owner, size_group;
2787c2c66affSColin Finck BOOL isDefault, isPresent, ret;
2788*3c1b7834SAmine Khaldi PACL pacl, dacl, sacl;
2789*3c1b7834SAmine Khaldi PSID psid, owner, group;
2790c2c66affSColin Finck
2791c2c66affSColin Finck SetLastError(0xdeadbeef);
2792c2c66affSColin Finck ret = InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
2793c2c66affSColin Finck if (ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2794c2c66affSColin Finck {
2795c2c66affSColin Finck win_skip("InitializeSecurityDescriptor is not implemented\n");
2796c2c66affSColin Finck return;
2797c2c66affSColin Finck }
2798c2c66affSColin Finck
2799c2c66affSColin Finck ok(GetSecurityDescriptorOwner(&sd, &psid, &isDefault), "GetSecurityDescriptorOwner failed\n");
2800c2c66affSColin Finck expect_eq(psid, NULL, PSID, "%p");
2801c2c66affSColin Finck expect_eq(isDefault, FALSE, BOOL, "%d");
2802c2c66affSColin Finck sd.Control |= SE_DACL_PRESENT | SE_SACL_PRESENT;
2803c2c66affSColin Finck
2804c2c66affSColin Finck SetLastError(0xdeadbeef);
2805c2c66affSColin Finck size = 5;
2806c2c66affSColin Finck expect_eq(MakeSelfRelativeSD(&sd, buf, &size), FALSE, BOOL, "%d");
2807c2c66affSColin Finck expect_eq(GetLastError(), ERROR_INSUFFICIENT_BUFFER, DWORD, "%u");
2808c2c66affSColin Finck ok(size > 5, "Size not increased\n");
2809c2c66affSColin Finck if (size <= 8192)
2810c2c66affSColin Finck {
2811c2c66affSColin Finck expect_eq(MakeSelfRelativeSD(&sd, buf, &size), TRUE, BOOL, "%d");
2812c2c66affSColin Finck ok(GetSecurityDescriptorOwner(&sd, &psid, &isDefault), "GetSecurityDescriptorOwner failed\n");
2813c2c66affSColin Finck expect_eq(psid, NULL, PSID, "%p");
2814c2c66affSColin Finck expect_eq(isDefault, FALSE, BOOL, "%d");
2815c2c66affSColin Finck ok(GetSecurityDescriptorGroup(&sd, &psid, &isDefault), "GetSecurityDescriptorGroup failed\n");
2816c2c66affSColin Finck expect_eq(psid, NULL, PSID, "%p");
2817c2c66affSColin Finck expect_eq(isDefault, FALSE, BOOL, "%d");
2818c2c66affSColin Finck ok(GetSecurityDescriptorDacl(&sd, &isPresent, &pacl, &isDefault), "GetSecurityDescriptorDacl failed\n");
2819c2c66affSColin Finck expect_eq(isPresent, TRUE, BOOL, "%d");
2820c2c66affSColin Finck expect_eq(psid, NULL, PSID, "%p");
2821c2c66affSColin Finck expect_eq(isDefault, FALSE, BOOL, "%d");
2822c2c66affSColin Finck ok(GetSecurityDescriptorSacl(&sd, &isPresent, &pacl, &isDefault), "GetSecurityDescriptorSacl failed\n");
2823c2c66affSColin Finck expect_eq(isPresent, TRUE, BOOL, "%d");
2824c2c66affSColin Finck expect_eq(psid, NULL, PSID, "%p");
2825c2c66affSColin Finck expect_eq(isDefault, FALSE, BOOL, "%d");
2826c2c66affSColin Finck }
2827*3c1b7834SAmine Khaldi
2828*3c1b7834SAmine Khaldi ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
2829*3c1b7834SAmine Khaldi "O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"
2830*3c1b7834SAmine Khaldi "(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)"
2831*3c1b7834SAmine Khaldi "(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, (void **)&sd_rel, NULL);
2832*3c1b7834SAmine Khaldi ok(ret, "got %u\n", GetLastError());
2833*3c1b7834SAmine Khaldi
2834*3c1b7834SAmine Khaldi size = 0;
2835*3c1b7834SAmine Khaldi ret = MakeSelfRelativeSD(sd_rel, NULL, &size);
2836*3c1b7834SAmine Khaldi todo_wine ok(!ret && GetLastError() == ERROR_BAD_DESCRIPTOR_FORMAT, "got %u\n", GetLastError());
2837*3c1b7834SAmine Khaldi
2838*3c1b7834SAmine Khaldi /* convert to absolute form */
2839*3c1b7834SAmine Khaldi size = size_dacl = size_sacl = size_owner = size_group = 0;
2840*3c1b7834SAmine Khaldi ret = MakeAbsoluteSD(sd_rel, NULL, &size, NULL, &size_dacl, NULL, &size_sacl, NULL, &size_owner, NULL,
2841*3c1b7834SAmine Khaldi &size_group);
2842*3c1b7834SAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2843*3c1b7834SAmine Khaldi
2844*3c1b7834SAmine Khaldi sd_abs = HeapAlloc(GetProcessHeap(), 0, size + size_dacl + size_sacl + size_owner + size_group);
2845*3c1b7834SAmine Khaldi dacl = (PACL)(sd_abs + 1);
2846*3c1b7834SAmine Khaldi sacl = (PACL)((char *)dacl + size_dacl);
2847*3c1b7834SAmine Khaldi owner = (PSID)((char *)sacl + size_sacl);
2848*3c1b7834SAmine Khaldi group = (PSID)((char *)owner + size_owner);
2849*3c1b7834SAmine Khaldi ret = MakeAbsoluteSD(sd_rel, sd_abs, &size, dacl, &size_dacl, sacl, &size_sacl, owner, &size_owner,
2850*3c1b7834SAmine Khaldi group, &size_group);
2851*3c1b7834SAmine Khaldi ok(ret, "got %u\n", GetLastError());
2852*3c1b7834SAmine Khaldi
2853*3c1b7834SAmine Khaldi size = 0;
2854*3c1b7834SAmine Khaldi ret = MakeSelfRelativeSD(sd_abs, NULL, &size);
2855*3c1b7834SAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
2856*3c1b7834SAmine Khaldi ok(size == 184, "got %u\n", size);
2857*3c1b7834SAmine Khaldi
2858*3c1b7834SAmine Khaldi size += 4;
2859*3c1b7834SAmine Khaldi sd_rel2 = HeapAlloc(GetProcessHeap(), 0, size);
2860*3c1b7834SAmine Khaldi ret = MakeSelfRelativeSD(sd_abs, sd_rel2, &size);
2861*3c1b7834SAmine Khaldi ok(ret, "got %u\n", GetLastError());
2862*3c1b7834SAmine Khaldi ok(size == 188, "got %u\n", size);
2863*3c1b7834SAmine Khaldi
2864*3c1b7834SAmine Khaldi HeapFree(GetProcessHeap(), 0, sd_abs);
2865*3c1b7834SAmine Khaldi HeapFree(GetProcessHeap(), 0, sd_rel2);
2866*3c1b7834SAmine Khaldi LocalFree(sd_rel);
2867c2c66affSColin Finck }
2868c2c66affSColin Finck
2869c2c66affSColin Finck #define TEST_GRANTED_ACCESS(a,b) test_granted_access(a,b,0,__LINE__)
2870c2c66affSColin Finck #define TEST_GRANTED_ACCESS2(a,b,c) test_granted_access(a,b,c,__LINE__)
test_granted_access(HANDLE handle,ACCESS_MASK access,ACCESS_MASK alt,int line)2871c2c66affSColin Finck static void test_granted_access(HANDLE handle, ACCESS_MASK access,
2872c2c66affSColin Finck ACCESS_MASK alt, int line)
2873c2c66affSColin Finck {
2874c2c66affSColin Finck OBJECT_BASIC_INFORMATION obj_info;
2875c2c66affSColin Finck NTSTATUS status;
2876c2c66affSColin Finck
2877c2c66affSColin Finck if (!pNtQueryObject)
2878c2c66affSColin Finck {
2879c2c66affSColin Finck skip_(__FILE__, line)("Not NT platform - skipping tests\n");
2880c2c66affSColin Finck return;
2881c2c66affSColin Finck }
2882c2c66affSColin Finck
2883c2c66affSColin Finck status = pNtQueryObject( handle, ObjectBasicInformation, &obj_info,
2884c2c66affSColin Finck sizeof(obj_info), NULL );
2885c2c66affSColin Finck ok_(__FILE__, line)(!status, "NtQueryObject with err: %08x\n", status);
2886c2c66affSColin Finck if (alt)
2887c2c66affSColin Finck ok_(__FILE__, line)(obj_info.GrantedAccess == access ||
2888c2c66affSColin Finck obj_info.GrantedAccess == alt, "Granted access should be 0x%08x "
2889c2c66affSColin Finck "or 0x%08x, instead of 0x%08x\n", access, alt, obj_info.GrantedAccess);
2890c2c66affSColin Finck else
2891c2c66affSColin Finck ok_(__FILE__, line)(obj_info.GrantedAccess == access, "Granted access should "
2892c2c66affSColin Finck "be 0x%08x, instead of 0x%08x\n", access, obj_info.GrantedAccess);
2893c2c66affSColin Finck }
2894c2c66affSColin Finck
2895c2c66affSColin Finck #define CHECK_SET_SECURITY(o,i,e) \
2896c2c66affSColin Finck do{ \
2897c2c66affSColin Finck BOOL res_; \
2898c2c66affSColin Finck DWORD err; \
2899c2c66affSColin Finck SetLastError( 0xdeadbeef ); \
2900c2c66affSColin Finck res_ = SetKernelObjectSecurity( o, i, SecurityDescriptor ); \
2901c2c66affSColin Finck err = GetLastError(); \
2902c2c66affSColin Finck if (e == ERROR_SUCCESS) \
2903c2c66affSColin Finck ok(res_, "SetKernelObjectSecurity failed with %d\n", err); \
2904c2c66affSColin Finck else \
2905c2c66affSColin Finck ok(!res_ && err == e, "SetKernelObjectSecurity should have failed " \
2906c2c66affSColin Finck "with %s, instead of %d\n", #e, err); \
2907c2c66affSColin Finck }while(0)
2908c2c66affSColin Finck
test_process_security(void)2909c2c66affSColin Finck static void test_process_security(void)
2910c2c66affSColin Finck {
2911c2c66affSColin Finck BOOL res;
2912c2c66affSColin Finck PTOKEN_USER user;
2913c2c66affSColin Finck PTOKEN_OWNER owner;
2914c2c66affSColin Finck PTOKEN_PRIMARY_GROUP group;
2915c2c66affSColin Finck PSID AdminSid = NULL, UsersSid = NULL, UserSid = NULL;
2916c2c66affSColin Finck PACL Acl = NULL, ThreadAcl = NULL;
2917c2c66affSColin Finck SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL;
2918c2c66affSColin Finck char buffer[MAX_PATH], account[MAX_PATH], domain[MAX_PATH];
2919c2c66affSColin Finck PROCESS_INFORMATION info;
2920c2c66affSColin Finck STARTUPINFOA startup;
2921c2c66affSColin Finck SECURITY_ATTRIBUTES psa, tsa;
2922c2c66affSColin Finck HANDLE token, event;
2923c2c66affSColin Finck DWORD size, acc_size, dom_size, ret;
2924c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
2925c2c66affSColin Finck PSID EveryoneSid = NULL;
2926c2c66affSColin Finck SID_NAME_USE use;
2927c2c66affSColin Finck
2928c2c66affSColin Finck Acl = HeapAlloc(GetProcessHeap(), 0, 256);
2929c2c66affSColin Finck res = InitializeAcl(Acl, 256, ACL_REVISION);
2930c2c66affSColin Finck if (!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2931c2c66affSColin Finck {
2932c2c66affSColin Finck win_skip("ACLs not implemented - skipping tests\n");
2933c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Acl);
2934c2c66affSColin Finck return;
2935c2c66affSColin Finck }
2936c2c66affSColin Finck ok(res, "InitializeAcl failed with error %d\n", GetLastError());
2937c2c66affSColin Finck
2938c2c66affSColin Finck res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
2939c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
2940c2c66affSColin Finck
2941c2c66affSColin Finck /* get owner from the token we might be running as a user not admin */
2942c2c66affSColin Finck res = OpenProcessToken( GetCurrentProcess(), MAXIMUM_ALLOWED, &token );
2943c2c66affSColin Finck ok(res, "OpenProcessToken failed with error %d\n", GetLastError());
2944c2c66affSColin Finck if (!res)
2945c2c66affSColin Finck {
2946c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Acl);
2947c2c66affSColin Finck return;
2948c2c66affSColin Finck }
2949c2c66affSColin Finck
2950c2c66affSColin Finck res = GetTokenInformation( token, TokenOwner, NULL, 0, &size );
2951c2c66affSColin Finck ok(!res, "Expected failure, got %d\n", res);
2952c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2953c2c66affSColin Finck "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2954c2c66affSColin Finck
2955c2c66affSColin Finck owner = HeapAlloc(GetProcessHeap(), 0, size);
2956c2c66affSColin Finck res = GetTokenInformation( token, TokenOwner, owner, size, &size );
2957c2c66affSColin Finck ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
2958c2c66affSColin Finck AdminSid = owner->Owner;
2959c2c66affSColin Finck test_sid_str(AdminSid);
2960c2c66affSColin Finck
2961c2c66affSColin Finck res = GetTokenInformation( token, TokenPrimaryGroup, NULL, 0, &size );
2962c2c66affSColin Finck ok(!res, "Expected failure, got %d\n", res);
2963c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2964c2c66affSColin Finck "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2965c2c66affSColin Finck
2966c2c66affSColin Finck group = HeapAlloc(GetProcessHeap(), 0, size);
2967c2c66affSColin Finck res = GetTokenInformation( token, TokenPrimaryGroup, group, size, &size );
2968c2c66affSColin Finck ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
2969c2c66affSColin Finck UsersSid = group->PrimaryGroup;
2970c2c66affSColin Finck test_sid_str(UsersSid);
2971c2c66affSColin Finck
2972c2c66affSColin Finck acc_size = sizeof(account);
2973c2c66affSColin Finck dom_size = sizeof(domain);
2974c2c66affSColin Finck ret = LookupAccountSidA( NULL, UsersSid, account, &acc_size, domain, &dom_size, &use );
2975c2c66affSColin Finck ok(ret, "LookupAccountSid failed with %d\n", ret);
2976c2c66affSColin Finck ok(use == SidTypeGroup, "expect SidTypeGroup, got %d\n", use);
2977c2c66affSColin Finck ok(!strcmp(account, "None"), "expect None, got %s\n", account);
2978c2c66affSColin Finck
2979c2c66affSColin Finck res = GetTokenInformation( token, TokenUser, NULL, 0, &size );
2980c2c66affSColin Finck ok(!res, "Expected failure, got %d\n", res);
2981c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2982c2c66affSColin Finck "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2983c2c66affSColin Finck
2984c2c66affSColin Finck user = HeapAlloc(GetProcessHeap(), 0, size);
2985c2c66affSColin Finck res = GetTokenInformation( token, TokenUser, user, size, &size );
2986c2c66affSColin Finck ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
2987c2c66affSColin Finck UserSid = user->User.Sid;
2988c2c66affSColin Finck test_sid_str(UserSid);
2989c2c66affSColin Finck ok(EqualPrefixSid(UsersSid, UserSid), "TokenPrimaryGroup Sid and TokenUser Sid don't match.\n");
2990c2c66affSColin Finck
2991c2c66affSColin Finck CloseHandle( token );
2992c2c66affSColin Finck if (!res)
2993c2c66affSColin Finck {
2994c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, group);
2995c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, owner);
2996c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, user);
2997c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Acl);
2998c2c66affSColin Finck return;
2999c2c66affSColin Finck }
3000c2c66affSColin Finck
3001c2c66affSColin Finck res = AddAccessDeniedAce(Acl, ACL_REVISION, PROCESS_VM_READ, AdminSid);
3002c2c66affSColin Finck ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError());
3003c2c66affSColin Finck res = AddAccessAllowedAce(Acl, ACL_REVISION, PROCESS_ALL_ACCESS, AdminSid);
3004c2c66affSColin Finck ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
3005c2c66affSColin Finck
3006c2c66affSColin Finck SecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
3007c2c66affSColin Finck res = InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
3008c2c66affSColin Finck ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError());
3009c2c66affSColin Finck
3010c2c66affSColin Finck event = CreateEventA( NULL, TRUE, TRUE, "test_event" );
3011c2c66affSColin Finck ok(event != NULL, "CreateEvent %d\n", GetLastError());
3012c2c66affSColin Finck
3013c2c66affSColin Finck SecurityDescriptor->Revision = 0;
3014c2c66affSColin Finck CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_UNKNOWN_REVISION );
3015c2c66affSColin Finck SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION;
3016c2c66affSColin Finck
3017c2c66affSColin Finck CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_INVALID_SECURITY_DESCR );
3018c2c66affSColin Finck CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_INVALID_SECURITY_DESCR );
3019c2c66affSColin Finck CHECK_SET_SECURITY( event, SACL_SECURITY_INFORMATION, ERROR_ACCESS_DENIED );
3020c2c66affSColin Finck CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
3021c2c66affSColin Finck /* NULL DACL is valid and means that everyone has access */
3022c2c66affSColin Finck SecurityDescriptor->Control |= SE_DACL_PRESENT;
3023c2c66affSColin Finck CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
3024c2c66affSColin Finck
3025c2c66affSColin Finck /* Set owner and group and dacl */
3026c2c66affSColin Finck res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE);
3027c2c66affSColin Finck ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError());
3028c2c66affSColin Finck CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_SUCCESS );
3029c2c66affSColin Finck test_owner_equal( event, AdminSid, __LINE__ );
3030c2c66affSColin Finck
3031c2c66affSColin Finck res = SetSecurityDescriptorGroup(SecurityDescriptor, EveryoneSid, FALSE);
3032c2c66affSColin Finck ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
3033c2c66affSColin Finck CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS );
3034c2c66affSColin Finck test_group_equal( event, EveryoneSid, __LINE__ );
3035c2c66affSColin Finck
3036c2c66affSColin Finck res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
3037c2c66affSColin Finck ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
3038c2c66affSColin Finck CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
3039c2c66affSColin Finck /* setting a dacl should not change the owner or group */
3040c2c66affSColin Finck test_owner_equal( event, AdminSid, __LINE__ );
3041c2c66affSColin Finck test_group_equal( event, EveryoneSid, __LINE__ );
3042c2c66affSColin Finck
3043c2c66affSColin Finck /* Test again with a different SID in case the previous SID also happens to
3044c2c66affSColin Finck * be the one that is incorrectly replacing the group. */
3045c2c66affSColin Finck res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, FALSE);
3046c2c66affSColin Finck ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
3047c2c66affSColin Finck CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS );
3048c2c66affSColin Finck test_group_equal( event, UsersSid, __LINE__ );
3049c2c66affSColin Finck
3050c2c66affSColin Finck res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
3051c2c66affSColin Finck ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
3052c2c66affSColin Finck CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
3053c2c66affSColin Finck test_group_equal( event, UsersSid, __LINE__ );
3054c2c66affSColin Finck
3055c2c66affSColin Finck sprintf(buffer, "%s tests/security.c test", myARGV[0]);
3056c2c66affSColin Finck memset(&startup, 0, sizeof(startup));
3057c2c66affSColin Finck startup.cb = sizeof(startup);
3058c2c66affSColin Finck startup.dwFlags = STARTF_USESHOWWINDOW;
3059c2c66affSColin Finck startup.wShowWindow = SW_SHOWNORMAL;
3060c2c66affSColin Finck
3061c2c66affSColin Finck psa.nLength = sizeof(psa);
3062c2c66affSColin Finck psa.lpSecurityDescriptor = SecurityDescriptor;
3063c2c66affSColin Finck psa.bInheritHandle = TRUE;
3064c2c66affSColin Finck
3065c2c66affSColin Finck ThreadSecurityDescriptor = HeapAlloc( GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH );
3066c2c66affSColin Finck res = InitializeSecurityDescriptor( ThreadSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
3067c2c66affSColin Finck ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError());
3068c2c66affSColin Finck
3069c2c66affSColin Finck ThreadAcl = HeapAlloc( GetProcessHeap(), 0, 256 );
3070c2c66affSColin Finck res = InitializeAcl( ThreadAcl, 256, ACL_REVISION );
3071c2c66affSColin Finck ok(res, "InitializeAcl failed with error %d\n", GetLastError());
3072c2c66affSColin Finck res = AddAccessDeniedAce( ThreadAcl, ACL_REVISION, THREAD_SET_THREAD_TOKEN, AdminSid );
3073c2c66affSColin Finck ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError() );
3074c2c66affSColin Finck res = AddAccessAllowedAce( ThreadAcl, ACL_REVISION, THREAD_ALL_ACCESS, AdminSid );
3075c2c66affSColin Finck ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
3076c2c66affSColin Finck
3077c2c66affSColin Finck res = SetSecurityDescriptorOwner( ThreadSecurityDescriptor, AdminSid, FALSE );
3078c2c66affSColin Finck ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError());
3079c2c66affSColin Finck res = SetSecurityDescriptorGroup( ThreadSecurityDescriptor, UsersSid, FALSE );
3080c2c66affSColin Finck ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
3081c2c66affSColin Finck res = SetSecurityDescriptorDacl( ThreadSecurityDescriptor, TRUE, ThreadAcl, FALSE );
3082c2c66affSColin Finck ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
3083c2c66affSColin Finck
3084c2c66affSColin Finck tsa.nLength = sizeof(tsa);
3085c2c66affSColin Finck tsa.lpSecurityDescriptor = ThreadSecurityDescriptor;
3086c2c66affSColin Finck tsa.bInheritHandle = TRUE;
3087c2c66affSColin Finck
3088c2c66affSColin Finck /* Doesn't matter what ACL say we should get full access for ourselves */
3089c2c66affSColin Finck res = CreateProcessA( NULL, buffer, &psa, &tsa, FALSE, 0, NULL, NULL, &startup, &info );
3090c2c66affSColin Finck ok(res, "CreateProcess with err:%d\n", GetLastError());
3091c2c66affSColin Finck TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4,
3092c2c66affSColin Finck STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
3093c2c66affSColin Finck TEST_GRANTED_ACCESS2( info.hThread, THREAD_ALL_ACCESS_NT4,
3094c2c66affSColin Finck STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
3095c2c66affSColin Finck winetest_wait_child_process( info.hProcess );
3096c2c66affSColin Finck
3097c2c66affSColin Finck FreeSid(EveryoneSid);
3098c2c66affSColin Finck CloseHandle( info.hProcess );
3099c2c66affSColin Finck CloseHandle( info.hThread );
3100c2c66affSColin Finck CloseHandle( event );
3101c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, group);
3102c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, owner);
3103c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, user);
3104c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Acl);
3105c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, SecurityDescriptor);
3106c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, ThreadAcl);
3107c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, ThreadSecurityDescriptor);
3108c2c66affSColin Finck }
3109c2c66affSColin Finck
test_process_security_child(void)3110c2c66affSColin Finck static void test_process_security_child(void)
3111c2c66affSColin Finck {
3112c2c66affSColin Finck HANDLE handle, handle1;
3113c2c66affSColin Finck BOOL ret;
3114c2c66affSColin Finck DWORD err;
3115c2c66affSColin Finck
3116c2c66affSColin Finck handle = OpenProcess( PROCESS_TERMINATE, FALSE, GetCurrentProcessId() );
3117c2c66affSColin Finck ok(handle != NULL, "OpenProcess(PROCESS_TERMINATE) with err:%d\n", GetLastError());
3118c2c66affSColin Finck TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE );
3119c2c66affSColin Finck
3120c2c66affSColin Finck ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
3121c2c66affSColin Finck &handle1, 0, TRUE, DUPLICATE_SAME_ACCESS );
3122c2c66affSColin Finck ok(ret, "duplicating handle err:%d\n", GetLastError());
3123c2c66affSColin Finck TEST_GRANTED_ACCESS( handle1, PROCESS_TERMINATE );
3124c2c66affSColin Finck
3125c2c66affSColin Finck CloseHandle( handle1 );
3126c2c66affSColin Finck
3127c2c66affSColin Finck SetLastError( 0xdeadbeef );
3128c2c66affSColin Finck ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
3129c2c66affSColin Finck &handle1, PROCESS_ALL_ACCESS, TRUE, 0 );
3130c2c66affSColin Finck err = GetLastError();
3131c2c66affSColin Finck ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed "
3132c2c66affSColin Finck "with STATUS_ACCESS_DENIED, instead of err:%d\n", err);
3133c2c66affSColin Finck
3134c2c66affSColin Finck CloseHandle( handle );
3135c2c66affSColin Finck
3136c2c66affSColin Finck /* These two should fail - they are denied by ACL */
3137c2c66affSColin Finck handle = OpenProcess( PROCESS_VM_READ, FALSE, GetCurrentProcessId() );
3138c2c66affSColin Finck ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n");
3139c2c66affSColin Finck handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() );
3140c2c66affSColin Finck ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n");
3141c2c66affSColin Finck
3142c2c66affSColin Finck /* Documented privilege elevation */
3143c2c66affSColin Finck ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
3144c2c66affSColin Finck &handle, 0, TRUE, DUPLICATE_SAME_ACCESS );
3145c2c66affSColin Finck ok(ret, "duplicating handle err:%d\n", GetLastError());
3146c2c66affSColin Finck TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
3147c2c66affSColin Finck STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
3148c2c66affSColin Finck
3149c2c66affSColin Finck CloseHandle( handle );
3150c2c66affSColin Finck
3151c2c66affSColin Finck /* Same only explicitly asking for all access rights */
3152c2c66affSColin Finck ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
3153c2c66affSColin Finck &handle, PROCESS_ALL_ACCESS, TRUE, 0 );
3154c2c66affSColin Finck ok(ret, "duplicating handle err:%d\n", GetLastError());
3155c2c66affSColin Finck TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
3156c2c66affSColin Finck PROCESS_ALL_ACCESS | PROCESS_QUERY_LIMITED_INFORMATION );
3157c2c66affSColin Finck ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
3158c2c66affSColin Finck &handle1, PROCESS_VM_READ, TRUE, 0 );
3159c2c66affSColin Finck ok(ret, "duplicating handle err:%d\n", GetLastError());
3160c2c66affSColin Finck TEST_GRANTED_ACCESS( handle1, PROCESS_VM_READ );
3161c2c66affSColin Finck CloseHandle( handle1 );
3162c2c66affSColin Finck CloseHandle( handle );
3163c2c66affSColin Finck
3164c2c66affSColin Finck /* Test thread security */
3165c2c66affSColin Finck handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() );
3166c2c66affSColin Finck ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%d\n", GetLastError());
3167c2c66affSColin Finck TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE );
3168c2c66affSColin Finck CloseHandle( handle );
3169c2c66affSColin Finck
3170c2c66affSColin Finck handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() );
3171c2c66affSColin Finck ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n");
3172c2c66affSColin Finck }
3173c2c66affSColin Finck
test_impersonation_level(void)3174c2c66affSColin Finck static void test_impersonation_level(void)
3175c2c66affSColin Finck {
3176c2c66affSColin Finck HANDLE Token, ProcessToken;
3177c2c66affSColin Finck HANDLE Token2;
3178c2c66affSColin Finck DWORD Size;
3179c2c66affSColin Finck TOKEN_PRIVILEGES *Privileges;
3180c2c66affSColin Finck TOKEN_USER *User;
3181c2c66affSColin Finck PRIVILEGE_SET *PrivilegeSet;
3182c2c66affSColin Finck BOOL AccessGranted;
3183c2c66affSColin Finck BOOL ret;
3184c2c66affSColin Finck HKEY hkey;
3185c2c66affSColin Finck DWORD error;
3186c2c66affSColin Finck
3187c2c66affSColin Finck if( !pDuplicateTokenEx ) {
3188c2c66affSColin Finck win_skip("DuplicateTokenEx is not available\n");
3189c2c66affSColin Finck return;
3190c2c66affSColin Finck }
3191c2c66affSColin Finck SetLastError(0xdeadbeef);
3192c2c66affSColin Finck ret = ImpersonateSelf(SecurityAnonymous);
3193c2c66affSColin Finck if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3194c2c66affSColin Finck {
3195c2c66affSColin Finck win_skip("ImpersonateSelf is not implemented\n");
3196c2c66affSColin Finck return;
3197c2c66affSColin Finck }
3198c2c66affSColin Finck ok(ret, "ImpersonateSelf(SecurityAnonymous) failed with error %d\n", GetLastError());
3199c2c66affSColin Finck ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
3200c2c66affSColin Finck ok(!ret, "OpenThreadToken should have failed\n");
3201c2c66affSColin Finck error = GetLastError();
3202c2c66affSColin Finck ok(error == ERROR_CANT_OPEN_ANONYMOUS, "OpenThreadToken on anonymous token should have returned ERROR_CANT_OPEN_ANONYMOUS instead of %d\n", error);
3203c2c66affSColin Finck /* can't perform access check when opening object against an anonymous impersonation token */
3204c2c66affSColin Finck todo_wine {
3205c2c66affSColin Finck error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3206c2c66affSColin Finck ok(error == ERROR_INVALID_HANDLE || error == ERROR_CANT_OPEN_ANONYMOUS || error == ERROR_BAD_IMPERSONATION_LEVEL,
3207c2c66affSColin Finck "RegOpenKeyEx failed with %d\n", error);
3208c2c66affSColin Finck }
3209c2c66affSColin Finck RevertToSelf();
3210c2c66affSColin Finck
3211c2c66affSColin Finck ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken);
3212c2c66affSColin Finck ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
3213c2c66affSColin Finck
3214c2c66affSColin Finck ret = pDuplicateTokenEx(ProcessToken,
3215c2c66affSColin Finck TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, NULL,
3216c2c66affSColin Finck SecurityAnonymous, TokenImpersonation, &Token);
3217c2c66affSColin Finck ok(ret, "DuplicateTokenEx failed with error %d\n", GetLastError());
3218c2c66affSColin Finck /* can't increase the impersonation level */
3219c2c66affSColin Finck ret = DuplicateToken(Token, SecurityIdentification, &Token2);
3220c2c66affSColin Finck error = GetLastError();
3221c2c66affSColin Finck ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL,
3222c2c66affSColin Finck "Duplicating a token and increasing the impersonation level should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error);
3223c2c66affSColin Finck /* we can query anything from an anonymous token, including the user */
3224c2c66affSColin Finck ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size);
3225c2c66affSColin Finck error = GetLastError();
3226c2c66affSColin Finck ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error);
3227c2c66affSColin Finck User = HeapAlloc(GetProcessHeap(), 0, Size);
3228c2c66affSColin Finck ret = GetTokenInformation(Token, TokenUser, User, Size, &Size);
3229c2c66affSColin Finck ok(ret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
3230c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, User);
3231c2c66affSColin Finck
3232c2c66affSColin Finck /* PrivilegeCheck fails with SecurityAnonymous level */
3233c2c66affSColin Finck ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size);
3234c2c66affSColin Finck error = GetLastError();
3235c2c66affSColin Finck ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error);
3236c2c66affSColin Finck Privileges = HeapAlloc(GetProcessHeap(), 0, Size);
3237c2c66affSColin Finck ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size);
3238c2c66affSColin Finck ok(ret, "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError());
3239c2c66affSColin Finck
3240c2c66affSColin Finck PrivilegeSet = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PRIVILEGE_SET, Privilege[Privileges->PrivilegeCount]));
3241c2c66affSColin Finck PrivilegeSet->PrivilegeCount = Privileges->PrivilegeCount;
3242c2c66affSColin Finck memcpy(PrivilegeSet->Privilege, Privileges->Privileges, PrivilegeSet->PrivilegeCount * sizeof(PrivilegeSet->Privilege[0]));
3243c2c66affSColin Finck PrivilegeSet->Control = PRIVILEGE_SET_ALL_NECESSARY;
3244c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Privileges);
3245c2c66affSColin Finck
3246c2c66affSColin Finck ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3247c2c66affSColin Finck error = GetLastError();
3248c2c66affSColin Finck ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, "PrivilegeCheck for SecurityAnonymous token should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error);
3249c2c66affSColin Finck
3250c2c66affSColin Finck CloseHandle(Token);
3251c2c66affSColin Finck
3252c2c66affSColin Finck ret = ImpersonateSelf(SecurityIdentification);
3253c2c66affSColin Finck ok(ret, "ImpersonateSelf(SecurityIdentification) failed with error %d\n", GetLastError());
3254c2c66affSColin Finck ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
3255c2c66affSColin Finck ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
3256c2c66affSColin Finck
3257c2c66affSColin Finck /* can't perform access check when opening object against an identification impersonation token */
3258c2c66affSColin Finck error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3259c2c66affSColin Finck todo_wine {
3260c2c66affSColin Finck ok(error == ERROR_INVALID_HANDLE || error == ERROR_BAD_IMPERSONATION_LEVEL,
3261c2c66affSColin Finck "RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE or ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error);
3262c2c66affSColin Finck }
3263c2c66affSColin Finck ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3264c2c66affSColin Finck ok(ret, "PrivilegeCheck for SecurityIdentification failed with error %d\n", GetLastError());
3265c2c66affSColin Finck CloseHandle(Token);
3266c2c66affSColin Finck RevertToSelf();
3267c2c66affSColin Finck
3268c2c66affSColin Finck ret = ImpersonateSelf(SecurityImpersonation);
3269c2c66affSColin Finck ok(ret, "ImpersonateSelf(SecurityImpersonation) failed with error %d\n", GetLastError());
3270c2c66affSColin Finck ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
3271c2c66affSColin Finck ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
3272c2c66affSColin Finck error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3273c2c66affSColin Finck ok(error == ERROR_SUCCESS, "RegOpenKeyEx should have succeeded instead of failing with %d\n", error);
3274c2c66affSColin Finck RegCloseKey(hkey);
3275c2c66affSColin Finck ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3276c2c66affSColin Finck ok(ret, "PrivilegeCheck for SecurityImpersonation failed with error %d\n", GetLastError());
3277c2c66affSColin Finck RevertToSelf();
3278c2c66affSColin Finck
3279c2c66affSColin Finck CloseHandle(Token);
3280c2c66affSColin Finck CloseHandle(ProcessToken);
3281c2c66affSColin Finck
3282c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, PrivilegeSet);
3283c2c66affSColin Finck }
3284c2c66affSColin Finck
test_SetEntriesInAclW(void)3285c2c66affSColin Finck static void test_SetEntriesInAclW(void)
3286c2c66affSColin Finck {
3287c2c66affSColin Finck DWORD res;
3288c2c66affSColin Finck PSID EveryoneSid = NULL, UsersSid = NULL;
3289c2c66affSColin Finck PACL OldAcl = NULL, NewAcl;
3290c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
3291c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
3292c2c66affSColin Finck EXPLICIT_ACCESSW ExplicitAccess;
3293c2c66affSColin Finck static const WCHAR wszEveryone[] = {'E','v','e','r','y','o','n','e',0};
3294c2c66affSColin Finck static const WCHAR wszCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'};
3295c2c66affSColin Finck
3296c2c66affSColin Finck if (!pSetEntriesInAclW)
3297c2c66affSColin Finck {
3298c2c66affSColin Finck win_skip("SetEntriesInAclW is not available\n");
3299c2c66affSColin Finck return;
3300c2c66affSColin Finck }
3301c2c66affSColin Finck
3302c2c66affSColin Finck NewAcl = (PACL)0xdeadbeef;
3303c2c66affSColin Finck res = pSetEntriesInAclW(0, NULL, NULL, &NewAcl);
3304c2c66affSColin Finck if(res == ERROR_CALL_NOT_IMPLEMENTED)
3305c2c66affSColin Finck {
3306c2c66affSColin Finck win_skip("SetEntriesInAclW is not implemented\n");
3307c2c66affSColin Finck return;
3308c2c66affSColin Finck }
3309c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
3310c2c66affSColin Finck ok(NewAcl == NULL ||
3311c2c66affSColin Finck broken(NewAcl != NULL), /* NT4 */
3312c2c66affSColin Finck "NewAcl=%p, expected NULL\n", NewAcl);
3313c2c66affSColin Finck LocalFree(NewAcl);
3314c2c66affSColin Finck
3315c2c66affSColin Finck OldAcl = HeapAlloc(GetProcessHeap(), 0, 256);
3316c2c66affSColin Finck res = InitializeAcl(OldAcl, 256, ACL_REVISION);
3317c2c66affSColin Finck if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3318c2c66affSColin Finck {
3319c2c66affSColin Finck win_skip("ACLs not implemented - skipping tests\n");
3320c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, OldAcl);
3321c2c66affSColin Finck return;
3322c2c66affSColin Finck }
3323c2c66affSColin Finck ok(res, "InitializeAcl failed with error %d\n", GetLastError());
3324c2c66affSColin Finck
3325c2c66affSColin Finck res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
3326c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
3327c2c66affSColin Finck
3328c2c66affSColin Finck res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
3329c2c66affSColin Finck DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
3330c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
3331c2c66affSColin Finck
3332c2c66affSColin Finck res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid);
3333c2c66affSColin Finck ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
3334c2c66affSColin Finck
3335c2c66affSColin Finck ExplicitAccess.grfAccessPermissions = KEY_WRITE;
3336c2c66affSColin Finck ExplicitAccess.grfAccessMode = GRANT_ACCESS;
3337c2c66affSColin Finck ExplicitAccess.grfInheritance = NO_INHERITANCE;
3338c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
3339c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3340c2c66affSColin Finck ExplicitAccess.Trustee.ptstrName = EveryoneSid;
3341c2c66affSColin Finck ExplicitAccess.Trustee.MultipleTrusteeOperation = 0xDEADBEEF;
3342c2c66affSColin Finck ExplicitAccess.Trustee.pMultipleTrustee = (PVOID)0xDEADBEEF;
3343c2c66affSColin Finck res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3344c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
3345c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3346c2c66affSColin Finck LocalFree(NewAcl);
3347c2c66affSColin Finck
3348c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3349c2c66affSColin Finck ExplicitAccess.Trustee.pMultipleTrustee = NULL;
3350c2c66affSColin Finck ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3351c2c66affSColin Finck res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3352c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
3353c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3354c2c66affSColin Finck LocalFree(NewAcl);
3355c2c66affSColin Finck
3356c2c66affSColin Finck if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
3357c2c66affSColin Finck {
3358c2c66affSColin Finck skip("Non-English locale (test with hardcoded 'Everyone')\n");
3359c2c66affSColin Finck }
3360c2c66affSColin Finck else
3361c2c66affSColin Finck {
3362c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3363c2c66affSColin Finck ExplicitAccess.Trustee.ptstrName = (LPWSTR)wszEveryone;
3364c2c66affSColin Finck res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3365c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
3366c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3367c2c66affSColin Finck LocalFree(NewAcl);
3368c2c66affSColin Finck
3369c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM;
3370c2c66affSColin Finck res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3371c2c66affSColin Finck ok(res == ERROR_INVALID_PARAMETER ||
3372c2c66affSColin Finck broken(res == ERROR_NOT_SUPPORTED), /* NT4 */
3373c2c66affSColin Finck "SetEntriesInAclW failed: %u\n", res);
3374c2c66affSColin Finck ok(NewAcl == NULL ||
3375c2c66affSColin Finck broken(NewAcl != NULL), /* NT4 */
3376c2c66affSColin Finck "returned acl wasn't NULL: %p\n", NewAcl);
3377c2c66affSColin Finck
3378c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3379c2c66affSColin Finck ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE;
3380c2c66affSColin Finck res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3381c2c66affSColin Finck ok(res == ERROR_INVALID_PARAMETER ||
3382c2c66affSColin Finck broken(res == ERROR_NOT_SUPPORTED), /* NT4 */
3383c2c66affSColin Finck "SetEntriesInAclW failed: %u\n", res);
3384c2c66affSColin Finck ok(NewAcl == NULL ||
3385c2c66affSColin Finck broken(NewAcl != NULL), /* NT4 */
3386c2c66affSColin Finck "returned acl wasn't NULL: %p\n", NewAcl);
3387c2c66affSColin Finck
3388c2c66affSColin Finck ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3389c2c66affSColin Finck ExplicitAccess.grfAccessMode = SET_ACCESS;
3390c2c66affSColin Finck res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3391c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
3392c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3393c2c66affSColin Finck LocalFree(NewAcl);
3394c2c66affSColin Finck }
3395c2c66affSColin Finck
3396c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3397c2c66affSColin Finck ExplicitAccess.Trustee.ptstrName = (LPWSTR)wszCurrentUser;
3398c2c66affSColin Finck res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3399c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
3400c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3401c2c66affSColin Finck LocalFree(NewAcl);
3402c2c66affSColin Finck
3403c2c66affSColin Finck ExplicitAccess.grfAccessMode = REVOKE_ACCESS;
3404c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3405c2c66affSColin Finck ExplicitAccess.Trustee.ptstrName = UsersSid;
3406c2c66affSColin Finck res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3407c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
3408c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3409c2c66affSColin Finck LocalFree(NewAcl);
3410c2c66affSColin Finck
3411c2c66affSColin Finck FreeSid(UsersSid);
3412c2c66affSColin Finck FreeSid(EveryoneSid);
3413c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, OldAcl);
3414c2c66affSColin Finck }
3415c2c66affSColin Finck
test_SetEntriesInAclA(void)3416c2c66affSColin Finck static void test_SetEntriesInAclA(void)
3417c2c66affSColin Finck {
3418c2c66affSColin Finck DWORD res;
3419c2c66affSColin Finck PSID EveryoneSid = NULL, UsersSid = NULL;
3420c2c66affSColin Finck PACL OldAcl = NULL, NewAcl;
3421c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
3422c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
3423c2c66affSColin Finck EXPLICIT_ACCESSA ExplicitAccess;
3424c2c66affSColin Finck static const CHAR szEveryone[] = {'E','v','e','r','y','o','n','e',0};
3425c2c66affSColin Finck static const CHAR szCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'};
3426c2c66affSColin Finck
3427c2c66affSColin Finck if (!pSetEntriesInAclA)
3428c2c66affSColin Finck {
3429c2c66affSColin Finck win_skip("SetEntriesInAclA is not available\n");
3430c2c66affSColin Finck return;
3431c2c66affSColin Finck }
3432c2c66affSColin Finck
3433c2c66affSColin Finck NewAcl = (PACL)0xdeadbeef;
3434c2c66affSColin Finck res = pSetEntriesInAclA(0, NULL, NULL, &NewAcl);
3435c2c66affSColin Finck if(res == ERROR_CALL_NOT_IMPLEMENTED)
3436c2c66affSColin Finck {
3437c2c66affSColin Finck win_skip("SetEntriesInAclA is not implemented\n");
3438c2c66affSColin Finck return;
3439c2c66affSColin Finck }
3440c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
3441c2c66affSColin Finck ok(NewAcl == NULL ||
3442c2c66affSColin Finck broken(NewAcl != NULL), /* NT4 */
3443c2c66affSColin Finck "NewAcl=%p, expected NULL\n", NewAcl);
3444c2c66affSColin Finck LocalFree(NewAcl);
3445c2c66affSColin Finck
3446c2c66affSColin Finck OldAcl = HeapAlloc(GetProcessHeap(), 0, 256);
3447c2c66affSColin Finck res = InitializeAcl(OldAcl, 256, ACL_REVISION);
3448c2c66affSColin Finck if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3449c2c66affSColin Finck {
3450c2c66affSColin Finck win_skip("ACLs not implemented - skipping tests\n");
3451c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, OldAcl);
3452c2c66affSColin Finck return;
3453c2c66affSColin Finck }
3454c2c66affSColin Finck ok(res, "InitializeAcl failed with error %d\n", GetLastError());
3455c2c66affSColin Finck
3456c2c66affSColin Finck res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
3457c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
3458c2c66affSColin Finck
3459c2c66affSColin Finck res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
3460c2c66affSColin Finck DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
3461c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
3462c2c66affSColin Finck
3463c2c66affSColin Finck res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid);
3464c2c66affSColin Finck ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
3465c2c66affSColin Finck
3466c2c66affSColin Finck ExplicitAccess.grfAccessPermissions = KEY_WRITE;
3467c2c66affSColin Finck ExplicitAccess.grfAccessMode = GRANT_ACCESS;
3468c2c66affSColin Finck ExplicitAccess.grfInheritance = NO_INHERITANCE;
3469c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
3470c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3471c2c66affSColin Finck ExplicitAccess.Trustee.ptstrName = EveryoneSid;
3472c2c66affSColin Finck ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3473c2c66affSColin Finck ExplicitAccess.Trustee.pMultipleTrustee = NULL;
3474c2c66affSColin Finck res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3475c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
3476c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3477c2c66affSColin Finck LocalFree(NewAcl);
3478c2c66affSColin Finck
3479c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3480c2c66affSColin Finck ExplicitAccess.Trustee.pMultipleTrustee = NULL;
3481c2c66affSColin Finck ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3482c2c66affSColin Finck res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3483c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
3484c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3485c2c66affSColin Finck LocalFree(NewAcl);
3486c2c66affSColin Finck
3487c2c66affSColin Finck if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
3488c2c66affSColin Finck {
3489c2c66affSColin Finck skip("Non-English locale (test with hardcoded 'Everyone')\n");
3490c2c66affSColin Finck }
3491c2c66affSColin Finck else
3492c2c66affSColin Finck {
3493c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3494c2c66affSColin Finck ExplicitAccess.Trustee.ptstrName = (LPSTR)szEveryone;
3495c2c66affSColin Finck res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3496c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
3497c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3498c2c66affSColin Finck LocalFree(NewAcl);
3499c2c66affSColin Finck
3500c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM;
3501c2c66affSColin Finck res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3502c2c66affSColin Finck ok(res == ERROR_INVALID_PARAMETER ||
3503c2c66affSColin Finck broken(res == ERROR_NOT_SUPPORTED), /* NT4 */
3504c2c66affSColin Finck "SetEntriesInAclA failed: %u\n", res);
3505c2c66affSColin Finck ok(NewAcl == NULL ||
3506c2c66affSColin Finck broken(NewAcl != NULL), /* NT4 */
3507c2c66affSColin Finck "returned acl wasn't NULL: %p\n", NewAcl);
3508c2c66affSColin Finck
3509c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3510c2c66affSColin Finck ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE;
3511c2c66affSColin Finck res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3512c2c66affSColin Finck ok(res == ERROR_INVALID_PARAMETER ||
3513c2c66affSColin Finck broken(res == ERROR_NOT_SUPPORTED), /* NT4 */
3514c2c66affSColin Finck "SetEntriesInAclA failed: %u\n", res);
3515c2c66affSColin Finck ok(NewAcl == NULL ||
3516c2c66affSColin Finck broken(NewAcl != NULL), /* NT4 */
3517c2c66affSColin Finck "returned acl wasn't NULL: %p\n", NewAcl);
3518c2c66affSColin Finck
3519c2c66affSColin Finck ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3520c2c66affSColin Finck ExplicitAccess.grfAccessMode = SET_ACCESS;
3521c2c66affSColin Finck res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3522c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
3523c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3524c2c66affSColin Finck LocalFree(NewAcl);
3525c2c66affSColin Finck }
3526c2c66affSColin Finck
3527c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3528c2c66affSColin Finck ExplicitAccess.Trustee.ptstrName = (LPSTR)szCurrentUser;
3529c2c66affSColin Finck res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3530c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
3531c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3532c2c66affSColin Finck LocalFree(NewAcl);
3533c2c66affSColin Finck
3534c2c66affSColin Finck ExplicitAccess.grfAccessMode = REVOKE_ACCESS;
3535c2c66affSColin Finck ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3536c2c66affSColin Finck ExplicitAccess.Trustee.ptstrName = UsersSid;
3537c2c66affSColin Finck res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3538c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
3539c2c66affSColin Finck ok(NewAcl != NULL, "returned acl was NULL\n");
3540c2c66affSColin Finck LocalFree(NewAcl);
3541c2c66affSColin Finck
3542c2c66affSColin Finck FreeSid(UsersSid);
3543c2c66affSColin Finck FreeSid(EveryoneSid);
3544c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, OldAcl);
3545c2c66affSColin Finck }
3546c2c66affSColin Finck
3547c2c66affSColin Finck /* helper function for test_CreateDirectoryA */
get_nt_pathW(const char * name,UNICODE_STRING * nameW)3548c2c66affSColin Finck static void get_nt_pathW(const char *name, UNICODE_STRING *nameW)
3549c2c66affSColin Finck {
3550c2c66affSColin Finck UNICODE_STRING strW;
3551c2c66affSColin Finck ANSI_STRING str;
3552c2c66affSColin Finck NTSTATUS status;
3553c2c66affSColin Finck BOOLEAN ret;
3554c2c66affSColin Finck
3555c2c66affSColin Finck pRtlInitAnsiString(&str, name);
3556c2c66affSColin Finck
3557c2c66affSColin Finck status = pRtlAnsiStringToUnicodeString(&strW, &str, TRUE);
3558c2c66affSColin Finck ok(!status, "RtlAnsiStringToUnicodeString failed with %08x\n", status);
3559c2c66affSColin Finck
3560c2c66affSColin Finck ret = pRtlDosPathNameToNtPathName_U(strW.Buffer, nameW, NULL, NULL);
3561c2c66affSColin Finck ok(ret, "RtlDosPathNameToNtPathName_U failed\n");
3562c2c66affSColin Finck
3563c2c66affSColin Finck pRtlFreeUnicodeString(&strW);
3564c2c66affSColin Finck }
3565c2c66affSColin Finck
test_inherited_dacl(PACL dacl,PSID admin_sid,PSID user_sid,DWORD flags,DWORD mask,BOOL todo_count,BOOL todo_sid,BOOL todo_flags,int line)3566c2c66affSColin Finck static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD flags, DWORD mask,
3567c2c66affSColin Finck BOOL todo_count, BOOL todo_sid, BOOL todo_flags, int line)
3568c2c66affSColin Finck {
3569c2c66affSColin Finck ACL_SIZE_INFORMATION acl_size;
3570c2c66affSColin Finck ACCESS_ALLOWED_ACE *ace;
3571c2c66affSColin Finck BOOL bret;
3572c2c66affSColin Finck
3573c2c66affSColin Finck bret = pGetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3574c2c66affSColin Finck ok_(__FILE__, line)(bret, "GetAclInformation failed\n");
3575c2c66affSColin Finck
3576c2c66affSColin Finck todo_wine_if (todo_count)
3577c2c66affSColin Finck ok_(__FILE__, line)(acl_size.AceCount == 2,
3578c2c66affSColin Finck "GetAclInformation returned unexpected entry count (%d != 2)\n",
3579c2c66affSColin Finck acl_size.AceCount);
3580c2c66affSColin Finck
3581c2c66affSColin Finck if (acl_size.AceCount > 0)
3582c2c66affSColin Finck {
3583c2c66affSColin Finck bret = pGetAce(dacl, 0, (VOID **)&ace);
3584c2c66affSColin Finck ok_(__FILE__, line)(bret, "Failed to get Current User ACE\n");
3585c2c66affSColin Finck
3586c2c66affSColin Finck bret = EqualSid(&ace->SidStart, user_sid);
3587c2c66affSColin Finck todo_wine_if (todo_sid)
3588c2c66affSColin Finck ok_(__FILE__, line)(bret, "Current User ACE (%s) != Current User SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
3589c2c66affSColin Finck
3590c2c66affSColin Finck todo_wine_if (todo_flags)
3591c2c66affSColin Finck ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
3592c2c66affSColin Finck "Current User ACE has unexpected flags (0x%x != 0x%x)\n",
3593c2c66affSColin Finck ((ACE_HEADER *)ace)->AceFlags, flags);
3594c2c66affSColin Finck
3595c2c66affSColin Finck ok_(__FILE__, line)(ace->Mask == mask,
3596c2c66affSColin Finck "Current User ACE has unexpected mask (0x%x != 0x%x)\n",
3597c2c66affSColin Finck ace->Mask, mask);
3598c2c66affSColin Finck }
3599c2c66affSColin Finck if (acl_size.AceCount > 1)
3600c2c66affSColin Finck {
3601c2c66affSColin Finck bret = pGetAce(dacl, 1, (VOID **)&ace);
3602c2c66affSColin Finck ok_(__FILE__, line)(bret, "Failed to get Administators Group ACE\n");
3603c2c66affSColin Finck
3604c2c66affSColin Finck bret = EqualSid(&ace->SidStart, admin_sid);
3605c2c66affSColin Finck todo_wine_if (todo_sid)
3606c2c66affSColin Finck ok_(__FILE__, line)(bret, "Administators Group ACE (%s) != Administators Group SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
3607c2c66affSColin Finck
3608c2c66affSColin Finck todo_wine_if (todo_flags)
3609c2c66affSColin Finck ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
3610c2c66affSColin Finck "Administators Group ACE has unexpected flags (0x%x != 0x%x)\n",
3611c2c66affSColin Finck ((ACE_HEADER *)ace)->AceFlags, flags);
3612c2c66affSColin Finck
3613c2c66affSColin Finck ok_(__FILE__, line)(ace->Mask == mask,
3614c2c66affSColin Finck "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n",
3615c2c66affSColin Finck ace->Mask, mask);
3616c2c66affSColin Finck }
3617c2c66affSColin Finck }
3618c2c66affSColin Finck
test_CreateDirectoryA(void)3619c2c66affSColin Finck static void test_CreateDirectoryA(void)
3620c2c66affSColin Finck {
3621c2c66affSColin Finck char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
3622c2c66affSColin Finck DWORD sid_size = sizeof(admin_ptr), user_size;
3623c2c66affSColin Finck PSID admin_sid = (PSID) admin_ptr, user_sid;
3624c2c66affSColin Finck char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
3625c2c66affSColin Finck PSECURITY_DESCRIPTOR pSD = &sd;
3626c2c66affSColin Finck ACL_SIZE_INFORMATION acl_size;
3627c2c66affSColin Finck UNICODE_STRING tmpfileW;
3628c2c66affSColin Finck SECURITY_ATTRIBUTES sa;
3629c2c66affSColin Finck OBJECT_ATTRIBUTES attr;
3630c2c66affSColin Finck char tmpfile[MAX_PATH];
3631c2c66affSColin Finck char tmpdir[MAX_PATH];
3632c2c66affSColin Finck HANDLE token, hTemp;
3633c2c66affSColin Finck IO_STATUS_BLOCK io;
3634c2c66affSColin Finck struct _SID *owner;
3635c2c66affSColin Finck BOOL bret = TRUE;
3636c2c66affSColin Finck NTSTATUS status;
3637c2c66affSColin Finck DWORD error;
3638c2c66affSColin Finck PACL pDacl;
3639c2c66affSColin Finck
3640c2c66affSColin Finck if (!pGetSecurityInfo || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
3641c2c66affSColin Finck {
3642c2c66affSColin Finck win_skip("Required functions are not available\n");
3643c2c66affSColin Finck return;
3644c2c66affSColin Finck }
3645c2c66affSColin Finck
3646c2c66affSColin Finck if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
3647c2c66affSColin Finck {
3648c2c66affSColin Finck if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
3649c2c66affSColin Finck else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
3650c2c66affSColin Finck }
3651c2c66affSColin Finck if (!bret)
3652c2c66affSColin Finck {
3653c2c66affSColin Finck win_skip("Failed to get current user token\n");
3654c2c66affSColin Finck return;
3655c2c66affSColin Finck }
3656c2c66affSColin Finck bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size);
3657c2c66affSColin Finck ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
3658c2c66affSColin Finck "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
3659c2c66affSColin Finck user = HeapAlloc(GetProcessHeap(), 0, user_size);
3660c2c66affSColin Finck bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size);
3661c2c66affSColin Finck ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
3662c2c66affSColin Finck CloseHandle( token );
3663c2c66affSColin Finck user_sid = ((TOKEN_USER *)user)->User.Sid;
3664c2c66affSColin Finck
3665c2c66affSColin Finck sa.nLength = sizeof(sa);
3666c2c66affSColin Finck sa.lpSecurityDescriptor = pSD;
3667c2c66affSColin Finck sa.bInheritHandle = TRUE;
3668c2c66affSColin Finck InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3669c2c66affSColin Finck pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
3670*3c1b7834SAmine Khaldi pDacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
3671c2c66affSColin Finck bret = InitializeAcl(pDacl, 100, ACL_REVISION);
3672c2c66affSColin Finck ok(bret, "Failed to initialize ACL.\n");
3673c2c66affSColin Finck bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
3674c2c66affSColin Finck GENERIC_ALL, user_sid);
3675c2c66affSColin Finck ok(bret, "Failed to add Current User to ACL.\n");
3676c2c66affSColin Finck bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
3677c2c66affSColin Finck GENERIC_ALL, admin_sid);
3678c2c66affSColin Finck ok(bret, "Failed to add Administrator Group to ACL.\n");
3679c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3680c2c66affSColin Finck ok(bret, "Failed to add ACL to security descriptor.\n");
3681c2c66affSColin Finck
3682c2c66affSColin Finck GetTempPathA(MAX_PATH, tmpdir);
3683c2c66affSColin Finck lstrcatA(tmpdir, "Please Remove Me");
3684c2c66affSColin Finck bret = CreateDirectoryA(tmpdir, &sa);
3685c2c66affSColin Finck ok(bret == TRUE, "CreateDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
3686c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDacl);
3687c2c66affSColin Finck
3688c2c66affSColin Finck SetLastError(0xdeadbeef);
3689c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpdir, SE_FILE_OBJECT,
3690c2c66affSColin Finck OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner,
3691c2c66affSColin Finck NULL, &pDacl, NULL, &pSD);
3692c2c66affSColin Finck if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3693c2c66affSColin Finck {
3694c2c66affSColin Finck win_skip("GetNamedSecurityInfoA is not implemented\n");
3695c2c66affSColin Finck goto done;
3696c2c66affSColin Finck }
3697c2c66affSColin Finck ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
3698c2c66affSColin Finck test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
3699c2c66affSColin Finck 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
3700c2c66affSColin Finck LocalFree(pSD);
3701c2c66affSColin Finck
3702c2c66affSColin Finck /* Test inheritance of ACLs in CreateFile without security descriptor */
3703c2c66affSColin Finck strcpy(tmpfile, tmpdir);
3704c2c66affSColin Finck lstrcatA(tmpfile, "/tmpfile");
3705c2c66affSColin Finck
3706c2c66affSColin Finck hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
3707c2c66affSColin Finck CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
3708c2c66affSColin Finck ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError());
3709c2c66affSColin Finck
3710c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3711c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3712c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3713c2c66affSColin Finck ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
3714c2c66affSColin Finck test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
3715c2c66affSColin Finck 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
3716c2c66affSColin Finck LocalFree(pSD);
3717c2c66affSColin Finck CloseHandle(hTemp);
3718c2c66affSColin Finck
3719c2c66affSColin Finck /* Test inheritance of ACLs in CreateFile with security descriptor -
3720c2c66affSColin Finck * When a security descriptor is set, then inheritance doesn't take effect */
3721c2c66affSColin Finck pSD = &sd;
3722c2c66affSColin Finck InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3723c2c66affSColin Finck pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
3724c2c66affSColin Finck bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3725c2c66affSColin Finck ok(bret, "Failed to initialize ACL\n");
3726c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3727c2c66affSColin Finck ok(bret, "Failed to add ACL to security descriptor\n");
3728c2c66affSColin Finck
3729c2c66affSColin Finck strcpy(tmpfile, tmpdir);
3730c2c66affSColin Finck lstrcatA(tmpfile, "/tmpfile");
3731c2c66affSColin Finck
3732c2c66affSColin Finck sa.nLength = sizeof(sa);
3733c2c66affSColin Finck sa.lpSecurityDescriptor = pSD;
3734c2c66affSColin Finck sa.bInheritHandle = TRUE;
3735c2c66affSColin Finck hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, &sa,
3736c2c66affSColin Finck CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
3737c2c66affSColin Finck ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError());
3738c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDacl);
3739c2c66affSColin Finck
3740c2c66affSColin Finck error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
3741c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3742c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3743c2c66affSColin Finck ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
3744c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3745c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
3746c2c66affSColin Finck ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
3747c2c66affSColin Finck acl_size.AceCount);
3748c2c66affSColin Finck LocalFree(pSD);
3749c2c66affSColin Finck
3750c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3751c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3752c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3753c2c66affSColin Finck ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
3754c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3755c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
3756c2c66affSColin Finck ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
3757c2c66affSColin Finck acl_size.AceCount);
3758c2c66affSColin Finck LocalFree(pSD);
3759c2c66affSColin Finck CloseHandle(hTemp);
3760c2c66affSColin Finck
3761c2c66affSColin Finck /* Test inheritance of ACLs in NtCreateFile without security descriptor */
3762c2c66affSColin Finck strcpy(tmpfile, tmpdir);
3763c2c66affSColin Finck lstrcatA(tmpfile, "/tmpfile");
3764c2c66affSColin Finck get_nt_pathW(tmpfile, &tmpfileW);
3765c2c66affSColin Finck
3766c2c66affSColin Finck attr.Length = sizeof(attr);
3767c2c66affSColin Finck attr.RootDirectory = 0;
3768c2c66affSColin Finck attr.ObjectName = &tmpfileW;
3769c2c66affSColin Finck attr.Attributes = OBJ_CASE_INSENSITIVE;
3770c2c66affSColin Finck attr.SecurityDescriptor = NULL;
3771c2c66affSColin Finck attr.SecurityQualityOfService = NULL;
3772c2c66affSColin Finck
3773c2c66affSColin Finck status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0,
3774c2c66affSColin Finck FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
3775c2c66affSColin Finck ok(!status, "NtCreateFile failed with %08x\n", status);
3776c2c66affSColin Finck pRtlFreeUnicodeString(&tmpfileW);
3777c2c66affSColin Finck
3778c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3779c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3780c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3781c2c66affSColin Finck ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
3782c2c66affSColin Finck test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
3783c2c66affSColin Finck 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
3784c2c66affSColin Finck LocalFree(pSD);
3785c2c66affSColin Finck CloseHandle(hTemp);
3786c2c66affSColin Finck
3787c2c66affSColin Finck /* Test inheritance of ACLs in NtCreateFile with security descriptor -
3788c2c66affSColin Finck * When a security descriptor is set, then inheritance doesn't take effect */
3789c2c66affSColin Finck pSD = &sd;
3790c2c66affSColin Finck InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3791c2c66affSColin Finck pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
3792c2c66affSColin Finck bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3793c2c66affSColin Finck ok(bret, "Failed to initialize ACL\n");
3794c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3795c2c66affSColin Finck ok(bret, "Failed to add ACL to security descriptor\n");
3796c2c66affSColin Finck
3797c2c66affSColin Finck strcpy(tmpfile, tmpdir);
3798c2c66affSColin Finck lstrcatA(tmpfile, "/tmpfile");
3799c2c66affSColin Finck get_nt_pathW(tmpfile, &tmpfileW);
3800c2c66affSColin Finck
3801c2c66affSColin Finck attr.Length = sizeof(attr);
3802c2c66affSColin Finck attr.RootDirectory = 0;
3803c2c66affSColin Finck attr.ObjectName = &tmpfileW;
3804c2c66affSColin Finck attr.Attributes = OBJ_CASE_INSENSITIVE;
3805c2c66affSColin Finck attr.SecurityDescriptor = pSD;
3806c2c66affSColin Finck attr.SecurityQualityOfService = NULL;
3807c2c66affSColin Finck
3808c2c66affSColin Finck status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0,
3809c2c66affSColin Finck FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
3810c2c66affSColin Finck ok(!status, "NtCreateFile failed with %08x\n", status);
3811c2c66affSColin Finck pRtlFreeUnicodeString(&tmpfileW);
3812c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDacl);
3813c2c66affSColin Finck
3814c2c66affSColin Finck error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
3815c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3816c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3817c2c66affSColin Finck ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
3818c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3819c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
3820c2c66affSColin Finck ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
3821c2c66affSColin Finck acl_size.AceCount);
3822c2c66affSColin Finck LocalFree(pSD);
3823c2c66affSColin Finck
3824c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3825c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3826c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3827c2c66affSColin Finck ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
3828c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3829c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
3830*3c1b7834SAmine Khaldi todo_wine
3831c2c66affSColin Finck ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
3832c2c66affSColin Finck acl_size.AceCount);
3833c2c66affSColin Finck LocalFree(pSD);
3834c2c66affSColin Finck CloseHandle(hTemp);
3835c2c66affSColin Finck
3836c2c66affSColin Finck /* Test inheritance of ACLs in CreateDirectory without security descriptor */
3837c2c66affSColin Finck strcpy(tmpfile, tmpdir);
3838c2c66affSColin Finck lstrcatA(tmpfile, "/tmpdir");
3839c2c66affSColin Finck bret = CreateDirectoryA(tmpfile, NULL);
3840c2c66affSColin Finck ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError());
3841c2c66affSColin Finck
3842c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3843c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3844c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3845c2c66affSColin Finck ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
3846c2c66affSColin Finck test_inherited_dacl(pDacl, admin_sid, user_sid,
3847c2c66affSColin Finck OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
3848c2c66affSColin Finck 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
3849c2c66affSColin Finck LocalFree(pSD);
3850c2c66affSColin Finck bret = RemoveDirectoryA(tmpfile);
3851c2c66affSColin Finck ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError());
3852c2c66affSColin Finck
3853c2c66affSColin Finck /* Test inheritance of ACLs in CreateDirectory with security descriptor */
3854c2c66affSColin Finck pSD = &sd;
3855c2c66affSColin Finck InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3856c2c66affSColin Finck pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
3857c2c66affSColin Finck bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3858c2c66affSColin Finck ok(bret, "Failed to initialize ACL\n");
3859c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3860c2c66affSColin Finck ok(bret, "Failed to add ACL to security desciptor\n");
3861c2c66affSColin Finck
3862c2c66affSColin Finck strcpy(tmpfile, tmpdir);
3863c2c66affSColin Finck lstrcatA(tmpfile, "/tmpdir1");
3864c2c66affSColin Finck
3865c2c66affSColin Finck sa.nLength = sizeof(sa);
3866c2c66affSColin Finck sa.lpSecurityDescriptor = pSD;
3867c2c66affSColin Finck sa.bInheritHandle = TRUE;
3868c2c66affSColin Finck bret = CreateDirectoryA(tmpfile, &sa);
3869c2c66affSColin Finck ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError());
3870c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDacl);
3871c2c66affSColin Finck
3872c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3873c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3874c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3875c2c66affSColin Finck ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
3876c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3877c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
3878c2c66affSColin Finck todo_wine
3879c2c66affSColin Finck ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
3880c2c66affSColin Finck acl_size.AceCount);
3881c2c66affSColin Finck LocalFree(pSD);
3882c2c66affSColin Finck
3883c2c66affSColin Finck SetLastError(0xdeadbeef);
3884c2c66affSColin Finck bret = RemoveDirectoryA(tmpfile);
3885c2c66affSColin Finck error = GetLastError();
3886c2c66affSColin Finck ok(bret == FALSE, "RemoveDirectoryA unexpected succeeded\n");
3887c2c66affSColin Finck ok(error == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %u\n", error);
3888c2c66affSColin Finck
3889c2c66affSColin Finck pSD = &sd;
3890c2c66affSColin Finck InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3891c2c66affSColin Finck pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
3892c2c66affSColin Finck bret = InitializeAcl(pDacl, 100, ACL_REVISION);
3893c2c66affSColin Finck ok(bret, "Failed to initialize ACL.\n");
3894c2c66affSColin Finck bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
3895c2c66affSColin Finck ok(bret, "Failed to add Current User to ACL.\n");
3896c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3897c2c66affSColin Finck ok(bret, "Failed to add ACL to security desciptor.\n");
3898c2c66affSColin Finck error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
3899c2c66affSColin Finck NULL, pDacl, NULL);
3900c2c66affSColin Finck ok(error == ERROR_SUCCESS, "SetNamedSecurityInfoA failed with error %u\n", error);
3901c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDacl);
3902c2c66affSColin Finck
3903c2c66affSColin Finck bret = RemoveDirectoryA(tmpfile);
3904c2c66affSColin Finck ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError());
3905c2c66affSColin Finck
3906c2c66affSColin Finck /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) without security descriptor */
3907c2c66affSColin Finck strcpy(tmpfile, tmpdir);
3908c2c66affSColin Finck lstrcatA(tmpfile, "/tmpdir");
3909c2c66affSColin Finck get_nt_pathW(tmpfile, &tmpfileW);
3910c2c66affSColin Finck
3911c2c66affSColin Finck attr.Length = sizeof(attr);
3912c2c66affSColin Finck attr.RootDirectory = 0;
3913c2c66affSColin Finck attr.ObjectName = &tmpfileW;
3914c2c66affSColin Finck attr.Attributes = OBJ_CASE_INSENSITIVE;
3915c2c66affSColin Finck attr.SecurityDescriptor = NULL;
3916c2c66affSColin Finck attr.SecurityQualityOfService = NULL;
3917c2c66affSColin Finck
3918c2c66affSColin Finck status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL,
3919c2c66affSColin Finck FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0);
3920c2c66affSColin Finck ok(!status, "NtCreateFile failed with %08x\n", status);
3921c2c66affSColin Finck RtlFreeUnicodeString(&tmpfileW);
3922c2c66affSColin Finck
3923c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3924c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3925c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3926c2c66affSColin Finck ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
3927c2c66affSColin Finck test_inherited_dacl(pDacl, admin_sid, user_sid,
3928c2c66affSColin Finck OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
3929c2c66affSColin Finck 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
3930c2c66affSColin Finck LocalFree(pSD);
3931c2c66affSColin Finck CloseHandle(hTemp);
3932c2c66affSColin Finck
3933c2c66affSColin Finck /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) with security descriptor */
3934c2c66affSColin Finck pSD = &sd;
3935c2c66affSColin Finck InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3936c2c66affSColin Finck pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
3937c2c66affSColin Finck bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3938c2c66affSColin Finck ok(bret, "Failed to initialize ACL\n");
3939c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3940c2c66affSColin Finck ok(bret, "Failed to add ACL to security desciptor\n");
3941c2c66affSColin Finck
3942c2c66affSColin Finck strcpy(tmpfile, tmpdir);
3943c2c66affSColin Finck lstrcatA(tmpfile, "/tmpdir2");
3944c2c66affSColin Finck get_nt_pathW(tmpfile, &tmpfileW);
3945c2c66affSColin Finck
3946c2c66affSColin Finck attr.Length = sizeof(attr);
3947c2c66affSColin Finck attr.RootDirectory = 0;
3948c2c66affSColin Finck attr.ObjectName = &tmpfileW;
3949c2c66affSColin Finck attr.Attributes = OBJ_CASE_INSENSITIVE;
3950c2c66affSColin Finck attr.SecurityDescriptor = pSD;
3951c2c66affSColin Finck attr.SecurityQualityOfService = NULL;
3952c2c66affSColin Finck
3953c2c66affSColin Finck status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL,
3954c2c66affSColin Finck FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0);
3955c2c66affSColin Finck ok(!status, "NtCreateFile failed with %08x\n", status);
3956c2c66affSColin Finck RtlFreeUnicodeString(&tmpfileW);
3957c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDacl);
3958c2c66affSColin Finck
3959c2c66affSColin Finck error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
3960c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3961c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3962c2c66affSColin Finck ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
3963c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3964c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
3965561bed7bSAmine Khaldi todo_wine
3966c2c66affSColin Finck ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
3967c2c66affSColin Finck acl_size.AceCount);
3968c2c66affSColin Finck LocalFree(pSD);
3969c2c66affSColin Finck
3970c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3971c2c66affSColin Finck OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3972c2c66affSColin Finck (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3973c2c66affSColin Finck ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
3974c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3975c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
3976c2c66affSColin Finck todo_wine
3977c2c66affSColin Finck ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
3978c2c66affSColin Finck acl_size.AceCount);
3979c2c66affSColin Finck LocalFree(pSD);
3980c2c66affSColin Finck CloseHandle(hTemp);
3981c2c66affSColin Finck
3982c2c66affSColin Finck done:
3983c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, user);
3984c2c66affSColin Finck bret = RemoveDirectoryA(tmpdir);
3985c2c66affSColin Finck ok(bret == TRUE, "RemoveDirectoryA should always succeed\n");
3986c2c66affSColin Finck }
3987c2c66affSColin Finck
test_GetNamedSecurityInfoA(void)3988c2c66affSColin Finck static void test_GetNamedSecurityInfoA(void)
3989c2c66affSColin Finck {
3990c2c66affSColin Finck char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
3991c2c66affSColin Finck char system_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES];
3992c2c66affSColin Finck char users_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES];
3993c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
3994c2c66affSColin Finck PSID admin_sid = (PSID) admin_ptr, users_sid = (PSID) users_ptr;
3995c2c66affSColin Finck PSID system_sid = (PSID) system_ptr, user_sid, localsys_sid;
3996c2c66affSColin Finck DWORD sid_size = sizeof(admin_ptr), user_size;
3997c2c66affSColin Finck char invalid_path[] = "/an invalid file path";
3998c2c66affSColin Finck int users_ace_id = -1, admins_ace_id = -1, i;
3999c2c66affSColin Finck char software_key[] = "MACHINE\\Software";
4000c2c66affSColin Finck char sd[SECURITY_DESCRIPTOR_MIN_LENGTH+sizeof(void*)];
4001c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL control;
4002c2c66affSColin Finck ACL_SIZE_INFORMATION acl_size;
4003c2c66affSColin Finck CHAR windows_dir[MAX_PATH];
4004c2c66affSColin Finck PSECURITY_DESCRIPTOR pSD;
4005c2c66affSColin Finck ACCESS_ALLOWED_ACE *ace;
4006c2c66affSColin Finck BOOL bret = TRUE, isNT4;
4007c2c66affSColin Finck char tmpfile[MAX_PATH];
4008c2c66affSColin Finck DWORD error, revision;
4009c2c66affSColin Finck BOOL owner_defaulted;
4010c2c66affSColin Finck BOOL group_defaulted;
4011c2c66affSColin Finck BOOL dacl_defaulted;
4012c2c66affSColin Finck HANDLE token, hTemp, h;
4013c2c66affSColin Finck PSID owner, group;
4014c2c66affSColin Finck BOOL dacl_present;
4015c2c66affSColin Finck PACL pDacl;
4016c2c66affSColin Finck BYTE flags;
4017c2c66affSColin Finck NTSTATUS status;
4018c2c66affSColin Finck
4019c2c66affSColin Finck if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
4020c2c66affSColin Finck {
4021c2c66affSColin Finck win_skip("Required functions are not available\n");
4022c2c66affSColin Finck return;
4023c2c66affSColin Finck }
4024c2c66affSColin Finck
4025c2c66affSColin Finck if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
4026c2c66affSColin Finck {
4027c2c66affSColin Finck if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
4028c2c66affSColin Finck else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
4029c2c66affSColin Finck }
4030c2c66affSColin Finck if (!bret)
4031c2c66affSColin Finck {
4032c2c66affSColin Finck win_skip("Failed to get current user token\n");
4033c2c66affSColin Finck return;
4034c2c66affSColin Finck }
4035c2c66affSColin Finck bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size);
4036c2c66affSColin Finck ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
4037c2c66affSColin Finck "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
4038c2c66affSColin Finck user = HeapAlloc(GetProcessHeap(), 0, user_size);
4039c2c66affSColin Finck bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size);
4040c2c66affSColin Finck ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
4041c2c66affSColin Finck CloseHandle( token );
4042c2c66affSColin Finck user_sid = ((TOKEN_USER *)user)->User.Sid;
4043c2c66affSColin Finck
4044c2c66affSColin Finck bret = GetWindowsDirectoryA(windows_dir, MAX_PATH);
4045c2c66affSColin Finck ok(bret, "GetWindowsDirectory failed with error %d\n", GetLastError());
4046c2c66affSColin Finck
4047c2c66affSColin Finck SetLastError(0xdeadbeef);
4048c2c66affSColin Finck error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,
4049c2c66affSColin Finck OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
4050c2c66affSColin Finck NULL, NULL, NULL, NULL, &pSD);
4051c2c66affSColin Finck if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
4052c2c66affSColin Finck {
4053c2c66affSColin Finck win_skip("GetNamedSecurityInfoA is not implemented\n");
4054c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, user);
4055c2c66affSColin Finck return;
4056c2c66affSColin Finck }
4057c2c66affSColin Finck ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
4058c2c66affSColin Finck
4059c2c66affSColin Finck bret = GetSecurityDescriptorControl(pSD, &control, &revision);
4060c2c66affSColin Finck ok(bret, "GetSecurityDescriptorControl failed with error %d\n", GetLastError());
4061c2c66affSColin Finck ok((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == (SE_SELF_RELATIVE|SE_DACL_PRESENT) ||
4062c2c66affSColin Finck broken((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT), /* NT4 */
4063c2c66affSColin Finck "control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set\n", control);
4064c2c66affSColin Finck ok(revision == SECURITY_DESCRIPTOR_REVISION1, "revision was %d instead of 1\n", revision);
4065c2c66affSColin Finck
4066c2c66affSColin Finck isNT4 = (control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT;
4067c2c66affSColin Finck
4068c2c66affSColin Finck bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
4069c2c66affSColin Finck ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
4070c2c66affSColin Finck ok(owner != NULL, "owner should not be NULL\n");
4071c2c66affSColin Finck
4072c2c66affSColin Finck bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
4073c2c66affSColin Finck ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
4074c2c66affSColin Finck ok(group != NULL, "group should not be NULL\n");
4075c2c66affSColin Finck LocalFree(pSD);
4076c2c66affSColin Finck
4077c2c66affSColin Finck
4078c2c66affSColin Finck /* NULL descriptor tests */
4079c2c66affSColin Finck if(isNT4)
4080c2c66affSColin Finck {
4081c2c66affSColin Finck win_skip("NT4 does not support GetNamedSecutityInfo with a NULL descriptor\n");
4082c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, user);
4083c2c66affSColin Finck return;
4084c2c66affSColin Finck }
4085c2c66affSColin Finck
4086c2c66affSColin Finck error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
4087c2c66affSColin Finck NULL, NULL, NULL, NULL, NULL);
4088c2c66affSColin Finck ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error);
4089c2c66affSColin Finck
4090c2c66affSColin Finck pDacl = NULL;
4091c2c66affSColin Finck error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
4092c2c66affSColin Finck NULL, NULL, &pDacl, NULL, &pSD);
4093c2c66affSColin Finck ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
4094c2c66affSColin Finck ok(pDacl != NULL, "DACL should not be NULL\n");
4095c2c66affSColin Finck LocalFree(pSD);
4096c2c66affSColin Finck
4097c2c66affSColin Finck error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,
4098c2c66affSColin Finck NULL, NULL, &pDacl, NULL, NULL);
4099c2c66affSColin Finck ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error);
4100c2c66affSColin Finck
4101c2c66affSColin Finck /* Test behavior of SetNamedSecurityInfo with an invalid path */
4102c2c66affSColin Finck SetLastError(0xdeadbeef);
4103c2c66affSColin Finck error = pSetNamedSecurityInfoA(invalid_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
4104c2c66affSColin Finck NULL, NULL, NULL);
4105c2c66affSColin Finck ok(error == ERROR_FILE_NOT_FOUND, "Unexpected error returned: 0x%x\n", error);
4106c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef, "Expected last error to remain unchanged.\n");
4107c2c66affSColin Finck
4108c2c66affSColin Finck /* Create security descriptor information and test that it comes back the same */
4109c2c66affSColin Finck pSD = &sd;
4110c2c66affSColin Finck pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
4111c2c66affSColin Finck InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
4112c2c66affSColin Finck pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
4113c2c66affSColin Finck bret = InitializeAcl(pDacl, 100, ACL_REVISION);
4114c2c66affSColin Finck ok(bret, "Failed to initialize ACL.\n");
4115c2c66affSColin Finck bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4116c2c66affSColin Finck ok(bret, "Failed to add Current User to ACL.\n");
4117c2c66affSColin Finck bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
4118c2c66affSColin Finck ok(bret, "Failed to add Administrator Group to ACL.\n");
4119c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4120c2c66affSColin Finck ok(bret, "Failed to add ACL to security descriptor.\n");
4121c2c66affSColin Finck GetTempFileNameA(".", "foo", 0, tmpfile);
4122c2c66affSColin Finck hTemp = CreateFileA(tmpfile, WRITE_DAC|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ,
4123c2c66affSColin Finck NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
4124c2c66affSColin Finck SetLastError(0xdeadbeef);
4125c2c66affSColin Finck error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
4126c2c66affSColin Finck NULL, pDacl, NULL);
4127c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDacl);
4128c2c66affSColin Finck if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
4129c2c66affSColin Finck {
4130c2c66affSColin Finck win_skip("SetNamedSecurityInfoA is not implemented\n");
4131c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, user);
4132c2c66affSColin Finck CloseHandle(hTemp);
4133c2c66affSColin Finck return;
4134c2c66affSColin Finck }
4135c2c66affSColin Finck ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
4136c2c66affSColin Finck SetLastError(0xdeadbeef);
4137c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4138c2c66affSColin Finck NULL, NULL, &pDacl, NULL, &pSD);
4139c2c66affSColin Finck if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
4140c2c66affSColin Finck {
4141c2c66affSColin Finck win_skip("GetNamedSecurityInfoA is not implemented\n");
4142c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, user);
4143c2c66affSColin Finck CloseHandle(hTemp);
4144c2c66affSColin Finck return;
4145c2c66affSColin Finck }
4146c2c66affSColin Finck ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
4147c2c66affSColin Finck
4148c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4149c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
4150c2c66affSColin Finck if (acl_size.AceCount > 0)
4151c2c66affSColin Finck {
4152c2c66affSColin Finck bret = pGetAce(pDacl, 0, (VOID **)&ace);
4153c2c66affSColin Finck ok(bret, "Failed to get Current User ACE.\n");
4154c2c66affSColin Finck bret = EqualSid(&ace->SidStart, user_sid);
4155c2c66affSColin Finck ok(bret, "Current User ACE (%s) != Current User SID (%s).\n",
4156c2c66affSColin Finck debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
4157c2c66affSColin Finck ok(((ACE_HEADER *)ace)->AceFlags == 0,
4158c2c66affSColin Finck "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
4159c2c66affSColin Finck ok(ace->Mask == 0x1f01ff,
4160c2c66affSColin Finck "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
4161c2c66affSColin Finck }
4162c2c66affSColin Finck if (acl_size.AceCount > 1)
4163c2c66affSColin Finck {
4164c2c66affSColin Finck bret = pGetAce(pDacl, 1, (VOID **)&ace);
4165c2c66affSColin Finck ok(bret, "Failed to get Administators Group ACE.\n");
4166c2c66affSColin Finck bret = EqualSid(&ace->SidStart, admin_sid);
4167c2c66affSColin Finck ok(bret || broken(!bret) /* win2k */, "Administators Group ACE (%s) != Administators Group SID (%s).\n",
4168c2c66affSColin Finck debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
4169c2c66affSColin Finck ok(((ACE_HEADER *)ace)->AceFlags == 0,
4170c2c66affSColin Finck "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
4171c2c66affSColin Finck ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
4172c2c66affSColin Finck "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
4173c2c66affSColin Finck }
4174c2c66affSColin Finck LocalFree(pSD);
4175c2c66affSColin Finck
4176c2c66affSColin Finck /* show that setting empty DACL is not removing all file permissions */
4177c2c66affSColin Finck pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
4178c2c66affSColin Finck bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
4179c2c66affSColin Finck ok(bret, "Failed to initialize ACL.\n");
4180c2c66affSColin Finck error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4181c2c66affSColin Finck NULL, NULL, pDacl, NULL);
4182c2c66affSColin Finck ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
4183c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDacl);
4184c2c66affSColin Finck
4185c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4186c2c66affSColin Finck NULL, NULL, &pDacl, NULL, &pSD);
4187c2c66affSColin Finck ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
4188c2c66affSColin Finck
4189c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4190c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
4191c2c66affSColin Finck if (acl_size.AceCount > 0)
4192c2c66affSColin Finck {
4193c2c66affSColin Finck bret = pGetAce(pDacl, 0, (VOID **)&ace);
4194c2c66affSColin Finck ok(bret, "Failed to get ACE.\n");
4195c2c66affSColin Finck ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
4196c2c66affSColin Finck "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
4197c2c66affSColin Finck }
4198c2c66affSColin Finck LocalFree(pSD);
4199c2c66affSColin Finck
4200c2c66affSColin Finck h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4201c2c66affSColin Finck NULL, OPEN_EXISTING, 0, NULL);
4202c2c66affSColin Finck ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
4203c2c66affSColin Finck CloseHandle(h);
4204c2c66affSColin Finck
4205c2c66affSColin Finck /* test setting NULL DACL */
4206c2c66affSColin Finck error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
4207c2c66affSColin Finck DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL);
4208c2c66affSColin Finck ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
4209c2c66affSColin Finck
4210c2c66affSColin Finck error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4211c2c66affSColin Finck NULL, NULL, &pDacl, NULL, &pSD);
4212c2c66affSColin Finck ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
4213c2c66affSColin Finck todo_wine ok(!pDacl, "pDacl != NULL\n");
4214c2c66affSColin Finck LocalFree(pSD);
4215c2c66affSColin Finck
4216c2c66affSColin Finck h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4217c2c66affSColin Finck NULL, OPEN_EXISTING, 0, NULL);
4218c2c66affSColin Finck ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
4219c2c66affSColin Finck CloseHandle(h);
4220c2c66affSColin Finck
4221c2c66affSColin Finck /* NtSetSecurityObject doesn't inherit DACL entries */
4222c2c66affSColin Finck pSD = sd+sizeof(void*)-((ULONG_PTR)sd)%sizeof(void*);
4223c2c66affSColin Finck InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
4224c2c66affSColin Finck pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
4225c2c66affSColin Finck bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
4226c2c66affSColin Finck ok(bret, "Failed to initialize ACL.\n");
4227c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4228c2c66affSColin Finck ok(bret, "Failed to add ACL to security descriptor.\n");
4229c2c66affSColin Finck status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4230c2c66affSColin Finck ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
4231c2c66affSColin Finck
4232c2c66affSColin Finck h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4233c2c66affSColin Finck NULL, OPEN_EXISTING, 0, NULL);
4234c2c66affSColin Finck ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
4235c2c66affSColin Finck CloseHandle(h);
4236c2c66affSColin Finck
4237c2c66affSColin Finck pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ);
4238c2c66affSColin Finck status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4239c2c66affSColin Finck ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
4240c2c66affSColin Finck
4241c2c66affSColin Finck h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4242c2c66affSColin Finck NULL, OPEN_EXISTING, 0, NULL);
4243c2c66affSColin Finck ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
4244c2c66affSColin Finck CloseHandle(h);
4245c2c66affSColin Finck
4246c2c66affSColin Finck pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED,
4247c2c66affSColin Finck SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED);
4248c2c66affSColin Finck status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4249c2c66affSColin Finck ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
4250c2c66affSColin Finck
4251c2c66affSColin Finck h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4252c2c66affSColin Finck NULL, OPEN_EXISTING, 0, NULL);
4253c2c66affSColin Finck ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
4254c2c66affSColin Finck CloseHandle(h);
4255c2c66affSColin Finck
4256c2c66affSColin Finck /* test if DACL is properly mapped to permission */
4257c2c66affSColin Finck bret = InitializeAcl(pDacl, 100, ACL_REVISION);
4258c2c66affSColin Finck ok(bret, "Failed to initialize ACL.\n");
4259c2c66affSColin Finck bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4260c2c66affSColin Finck ok(bret, "Failed to add Current User to ACL.\n");
4261c2c66affSColin Finck bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4262c2c66affSColin Finck ok(bret, "Failed to add Current User to ACL.\n");
4263c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4264c2c66affSColin Finck ok(bret, "Failed to add ACL to security descriptor.\n");
4265c2c66affSColin Finck status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4266c2c66affSColin Finck ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
4267c2c66affSColin Finck
4268c2c66affSColin Finck h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4269c2c66affSColin Finck NULL, OPEN_EXISTING, 0, NULL);
4270c2c66affSColin Finck ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
4271c2c66affSColin Finck CloseHandle(h);
4272c2c66affSColin Finck
4273c2c66affSColin Finck bret = InitializeAcl(pDacl, 100, ACL_REVISION);
4274c2c66affSColin Finck ok(bret, "Failed to initialize ACL.\n");
4275c2c66affSColin Finck bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4276c2c66affSColin Finck ok(bret, "Failed to add Current User to ACL.\n");
4277c2c66affSColin Finck bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4278c2c66affSColin Finck ok(bret, "Failed to add Current User to ACL.\n");
4279c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4280c2c66affSColin Finck ok(bret, "Failed to add ACL to security descriptor.\n");
4281c2c66affSColin Finck status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4282c2c66affSColin Finck ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
4283c2c66affSColin Finck
4284c2c66affSColin Finck h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4285c2c66affSColin Finck NULL, OPEN_EXISTING, 0, NULL);
4286c2c66affSColin Finck ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
4287c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDacl);
4288c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, user);
4289c2c66affSColin Finck CloseHandle(hTemp);
4290c2c66affSColin Finck
4291c2c66affSColin Finck /* Test querying the ownership of a built-in registry key */
4292c2c66affSColin Finck sid_size = sizeof(system_ptr);
4293c2c66affSColin Finck pCreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size);
4294c2c66affSColin Finck error = pGetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY,
4295c2c66affSColin Finck OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION,
4296c2c66affSColin Finck NULL, NULL, NULL, NULL, &pSD);
4297c2c66affSColin Finck ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
4298c2c66affSColin Finck
4299c2c66affSColin Finck bret = AllocateAndInitializeSid(&SIDAuthNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &localsys_sid);
4300c2c66affSColin Finck ok(bret, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
4301c2c66affSColin Finck
4302c2c66affSColin Finck bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
4303c2c66affSColin Finck ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
4304c2c66affSColin Finck ok(owner != NULL, "owner should not be NULL\n");
4305c2c66affSColin Finck ok(EqualSid(owner, admin_sid) || EqualSid(owner, localsys_sid),
4306c2c66affSColin Finck "MACHINE\\Software owner SID (%s) != Administrators SID (%s) or Local System Sid (%s).\n",
4307c2c66affSColin Finck debugstr_sid(owner), debugstr_sid(admin_sid), debugstr_sid(localsys_sid));
4308c2c66affSColin Finck
4309c2c66affSColin Finck bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
4310c2c66affSColin Finck ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
4311c2c66affSColin Finck ok(group != NULL, "group should not be NULL\n");
4312c2c66affSColin Finck ok(EqualSid(group, admin_sid) || broken(EqualSid(group, system_sid)) /* before Win7 */
4313c2c66affSColin Finck || broken(((SID*)group)->SubAuthority[0] == SECURITY_NT_NON_UNIQUE) /* Vista */,
4314c2c66affSColin Finck "MACHINE\\Software group SID (%s) != Local System SID (%s or %s)\n",
4315c2c66affSColin Finck debugstr_sid(group), debugstr_sid(admin_sid), debugstr_sid(system_sid));
4316c2c66affSColin Finck LocalFree(pSD);
4317c2c66affSColin Finck
4318c2c66affSColin Finck /* Test querying the DACL of a built-in registry key */
4319c2c66affSColin Finck sid_size = sizeof(users_ptr);
4320c2c66affSColin Finck pCreateWellKnownSid(WinBuiltinUsersSid, NULL, users_sid, &sid_size);
4321c2c66affSColin Finck error = pGetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION,
4322c2c66affSColin Finck NULL, NULL, NULL, NULL, &pSD);
4323c2c66affSColin Finck ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
4324c2c66affSColin Finck
4325c2c66affSColin Finck bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted);
4326c2c66affSColin Finck ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError());
4327c2c66affSColin Finck ok(dacl_present, "DACL should be present\n");
4328c2c66affSColin Finck ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n");
4329c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4330c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
4331c2c66affSColin Finck ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n");
4332c2c66affSColin Finck for (i=0; i<acl_size.AceCount; i++)
4333c2c66affSColin Finck {
4334c2c66affSColin Finck bret = pGetAce(pDacl, i, (VOID **)&ace);
4335c2c66affSColin Finck ok(bret, "Failed to get ACE %d.\n", i);
4336c2c66affSColin Finck bret = EqualSid(&ace->SidStart, users_sid);
4337c2c66affSColin Finck if (bret) users_ace_id = i;
4338c2c66affSColin Finck bret = EqualSid(&ace->SidStart, admin_sid);
4339c2c66affSColin Finck if (bret) admins_ace_id = i;
4340c2c66affSColin Finck }
4341c2c66affSColin Finck ok(users_ace_id != -1 || broken(users_ace_id == -1) /* win2k */,
4342561bed7bSAmine Khaldi "Builtin Users ACE not found.\n");
4343c2c66affSColin Finck if (users_ace_id != -1)
4344c2c66affSColin Finck {
4345c2c66affSColin Finck bret = pGetAce(pDacl, users_ace_id, (VOID **)&ace);
4346c2c66affSColin Finck ok(bret, "Failed to get Builtin Users ACE.\n");
4347c2c66affSColin Finck flags = ((ACE_HEADER *)ace)->AceFlags;
4348c2c66affSColin Finck ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE)
4349c2c66affSColin Finck || broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */
4350c2c66affSColin Finck || broken(flags == (CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* win 10 wow64 */
4351c2c66affSColin Finck || broken(flags == CONTAINER_INHERIT_ACE), /* win 10 */
4352c2c66affSColin Finck "Builtin Users ACE has unexpected flags (0x%x != 0x%x)\n", flags,
4353c2c66affSColin Finck INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE);
4354c2c66affSColin Finck ok(ace->Mask == GENERIC_READ
4355c2c66affSColin Finck || broken(ace->Mask == KEY_READ), /* win 10 */
4356c2c66affSColin Finck "Builtin Users ACE has unexpected mask (0x%x != 0x%x)\n",
4357c2c66affSColin Finck ace->Mask, GENERIC_READ);
4358c2c66affSColin Finck }
4359561bed7bSAmine Khaldi ok(admins_ace_id != -1, "Builtin Admins ACE not found.\n");
4360c2c66affSColin Finck if (admins_ace_id != -1)
4361c2c66affSColin Finck {
4362c2c66affSColin Finck bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace);
4363c2c66affSColin Finck ok(bret, "Failed to get Builtin Admins ACE.\n");
4364c2c66affSColin Finck flags = ((ACE_HEADER *)ace)->AceFlags;
4365c2c66affSColin Finck ok(flags == 0x0
4366c2c66affSColin Finck || broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */
4367c2c66affSColin Finck || broken(flags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) /* win7 */
4368c2c66affSColin Finck || broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE)) /* win8+ */
4369c2c66affSColin Finck || broken(flags == (CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* win 10 wow64 */
4370c2c66affSColin Finck || broken(flags == CONTAINER_INHERIT_ACE), /* win 10 */
4371c2c66affSColin Finck "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags);
4372c2c66affSColin Finck ok(ace->Mask == KEY_ALL_ACCESS || broken(ace->Mask == GENERIC_ALL) /* w2k8 */,
4373c2c66affSColin Finck "Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, KEY_ALL_ACCESS);
4374c2c66affSColin Finck }
4375c2c66affSColin Finck
4376c2c66affSColin Finck FreeSid(localsys_sid);
4377c2c66affSColin Finck LocalFree(pSD);
4378c2c66affSColin Finck }
4379c2c66affSColin Finck
test_ConvertStringSecurityDescriptor(void)4380c2c66affSColin Finck static void test_ConvertStringSecurityDescriptor(void)
4381c2c66affSColin Finck {
4382c2c66affSColin Finck BOOL ret;
4383c2c66affSColin Finck PSECURITY_DESCRIPTOR pSD;
4384c2c66affSColin Finck static const WCHAR Blank[] = { 0 };
4385c2c66affSColin Finck unsigned int i;
4386*3c1b7834SAmine Khaldi ULONG size;
4387*3c1b7834SAmine Khaldi ACL *acl;
4388c2c66affSColin Finck static const struct
4389c2c66affSColin Finck {
4390c2c66affSColin Finck const char *sidstring;
4391c2c66affSColin Finck DWORD revision;
4392c2c66affSColin Finck BOOL ret;
4393c2c66affSColin Finck DWORD GLE;
4394c2c66affSColin Finck DWORD altGLE;
4395c2c66affSColin Finck } cssd[] =
4396c2c66affSColin Finck {
4397c2c66affSColin Finck { "D:(A;;GA;;;WD)", 0xdeadbeef, FALSE, ERROR_UNKNOWN_REVISION },
4398c2c66affSColin Finck /* test ACE string type */
4399c2c66affSColin Finck { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4400c2c66affSColin Finck { "D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4401c2c66affSColin Finck { "ERROR:(D;;GA;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_PARAMETER },
4402c2c66affSColin Finck /* test ACE string with spaces */
4403c2c66affSColin Finck { " D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4404c2c66affSColin Finck { "D: (D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4405c2c66affSColin Finck { "D:( D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4406c2c66affSColin Finck { "D:(D ;;GA;;;WD)", SDDL_REVISION_1, FALSE, RPC_S_INVALID_STRING_UUID, ERROR_INVALID_ACL }, /* Vista+ */
4407c2c66affSColin Finck { "D:(D; ;GA;;;WD)", SDDL_REVISION_1, TRUE },
4408c2c66affSColin Finck { "D:(D;; GA;;;WD)", SDDL_REVISION_1, TRUE },
4409c2c66affSColin Finck { "D:(D;;GA ;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL },
4410c2c66affSColin Finck { "D:(D;;GA; ;;WD)", SDDL_REVISION_1, TRUE },
4411c2c66affSColin Finck { "D:(D;;GA;; ;WD)", SDDL_REVISION_1, TRUE },
4412c2c66affSColin Finck { "D:(D;;GA;;; WD)", SDDL_REVISION_1, TRUE },
4413c2c66affSColin Finck { "D:(D;;GA;;;WD )", SDDL_REVISION_1, TRUE },
4414c2c66affSColin Finck /* test ACE string access rights */
4415c2c66affSColin Finck { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4416c2c66affSColin Finck { "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, TRUE },
4417c2c66affSColin Finck { "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, TRUE },
4418c2c66affSColin Finck { "D:(A;;RPWPCCDCLCSWLODTCR;;;WD)", SDDL_REVISION_1, TRUE },
4419c2c66affSColin Finck { "D:(A;;FAFRFWFX;;;WD)", SDDL_REVISION_1, TRUE },
4420c2c66affSColin Finck { "D:(A;;KAKRKWKX;;;WD)", SDDL_REVISION_1, TRUE },
4421c2c66affSColin Finck { "D:(A;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
4422c2c66affSColin Finck { "S:(AU;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
4423c2c66affSColin Finck /* test ACE string access right error case */
4424c2c66affSColin Finck { "D:(A;;ROB;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL },
4425c2c66affSColin Finck /* test behaviour with empty strings */
4426c2c66affSColin Finck { "", SDDL_REVISION_1, TRUE },
4427c2c66affSColin Finck /* test ACE string SID */
4428c2c66affSColin Finck { "D:(D;;GA;;;S-1-0-0)", SDDL_REVISION_1, TRUE },
4429c2c66affSColin Finck { "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL, ERROR_INVALID_SID } /* W2K */
4430c2c66affSColin Finck };
4431c2c66affSColin Finck
4432c2c66affSColin Finck if (!pConvertStringSecurityDescriptorToSecurityDescriptorA)
4433c2c66affSColin Finck {
4434c2c66affSColin Finck win_skip("ConvertStringSecurityDescriptorToSecurityDescriptor is not available\n");
4435c2c66affSColin Finck return;
4436c2c66affSColin Finck }
4437c2c66affSColin Finck
4438c2c66affSColin Finck for (i = 0; i < sizeof(cssd)/sizeof(cssd[0]); i++)
4439c2c66affSColin Finck {
4440c2c66affSColin Finck DWORD GLE;
4441c2c66affSColin Finck
4442c2c66affSColin Finck SetLastError(0xdeadbeef);
4443c2c66affSColin Finck ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
4444c2c66affSColin Finck cssd[i].sidstring, cssd[i].revision, &pSD, NULL);
4445c2c66affSColin Finck GLE = GetLastError();
4446c2c66affSColin Finck ok(ret == cssd[i].ret, "(%02u) Expected %s (%d)\n", i, cssd[i].ret ? "success" : "failure", GLE);
4447c2c66affSColin Finck if (!cssd[i].ret)
4448c2c66affSColin Finck ok(GLE == cssd[i].GLE ||
4449c2c66affSColin Finck (cssd[i].altGLE && GLE == cssd[i].altGLE),
4450c2c66affSColin Finck "(%02u) Unexpected last error %d\n", i, GLE);
4451c2c66affSColin Finck if (ret)
4452c2c66affSColin Finck LocalFree(pSD);
4453c2c66affSColin Finck }
4454c2c66affSColin Finck
4455c2c66affSColin Finck /* test behaviour with NULL parameters */
4456c2c66affSColin Finck SetLastError(0xdeadbeef);
4457c2c66affSColin Finck ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
4458c2c66affSColin Finck NULL, 0xdeadbeef, &pSD, NULL);
4459c2c66affSColin Finck todo_wine
4460c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4461c2c66affSColin Finck "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n",
4462c2c66affSColin Finck GetLastError());
4463c2c66affSColin Finck
4464c2c66affSColin Finck SetLastError(0xdeadbeef);
4465c2c66affSColin Finck ret = pConvertStringSecurityDescriptorToSecurityDescriptorW(
4466c2c66affSColin Finck NULL, 0xdeadbeef, &pSD, NULL);
4467c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4468c2c66affSColin Finck "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n",
4469c2c66affSColin Finck GetLastError());
4470c2c66affSColin Finck
4471c2c66affSColin Finck SetLastError(0xdeadbeef);
4472c2c66affSColin Finck ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
4473c2c66affSColin Finck "D:(A;;ROB;;;WD)", 0xdeadbeef, NULL, NULL);
4474c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4475c2c66affSColin Finck "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n",
4476c2c66affSColin Finck GetLastError());
4477c2c66affSColin Finck
4478c2c66affSColin Finck SetLastError(0xdeadbeef);
4479c2c66affSColin Finck ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
4480c2c66affSColin Finck "D:(A;;ROB;;;WD)", SDDL_REVISION_1, NULL, NULL);
4481c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4482c2c66affSColin Finck "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n",
4483c2c66affSColin Finck GetLastError());
4484c2c66affSColin Finck
4485c2c66affSColin Finck /* test behaviour with empty strings */
4486c2c66affSColin Finck SetLastError(0xdeadbeef);
4487c2c66affSColin Finck ret = pConvertStringSecurityDescriptorToSecurityDescriptorW(
4488c2c66affSColin Finck Blank, SDDL_REVISION_1, &pSD, NULL);
4489c2c66affSColin Finck ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError());
4490c2c66affSColin Finck LocalFree(pSD);
4491c2c66affSColin Finck
4492c2c66affSColin Finck SetLastError(0xdeadbeef);
4493c2c66affSColin Finck ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
4494c2c66affSColin Finck "D:P(A;;GRGW;;;BA)(A;;GRGW;;;S-1-5-21-0-0-0-1000)S:(ML;;NWNR;;;S-1-16-12288)", SDDL_REVISION_1, &pSD, NULL);
4495c2c66affSColin Finck ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_DATATYPE) /* win2k */,
4496c2c66affSColin Finck "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %u\n", GetLastError());
4497c2c66affSColin Finck if (ret) LocalFree(pSD);
4498*3c1b7834SAmine Khaldi
4499*3c1b7834SAmine Khaldi /* empty DACL */
4500*3c1b7834SAmine Khaldi size = 0;
4501*3c1b7834SAmine Khaldi SetLastError(0xdeadbeef);
4502*3c1b7834SAmine Khaldi ret = pConvertStringSecurityDescriptorToSecurityDescriptorA("D:", SDDL_REVISION_1, &pSD, &size);
4503*3c1b7834SAmine Khaldi ok(ret, "unexpected error %u\n", GetLastError());
4504*3c1b7834SAmine Khaldi ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %u\n", size);
4505*3c1b7834SAmine Khaldi acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
4506*3c1b7834SAmine Khaldi ok(acl->AclRevision == ACL_REVISION, "got %u\n", acl->AclRevision);
4507*3c1b7834SAmine Khaldi ok(!acl->Sbz1, "got %u\n", acl->Sbz1);
4508*3c1b7834SAmine Khaldi ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize);
4509*3c1b7834SAmine Khaldi ok(!acl->AceCount, "got %u\n", acl->AceCount);
4510*3c1b7834SAmine Khaldi ok(!acl->Sbz2, "got %u\n", acl->Sbz2);
4511*3c1b7834SAmine Khaldi LocalFree(pSD);
4512*3c1b7834SAmine Khaldi
4513*3c1b7834SAmine Khaldi /* empty SACL */
4514*3c1b7834SAmine Khaldi size = 0;
4515*3c1b7834SAmine Khaldi SetLastError(0xdeadbeef);
4516*3c1b7834SAmine Khaldi ret = pConvertStringSecurityDescriptorToSecurityDescriptorA("S:", SDDL_REVISION_1, &pSD, &size);
4517*3c1b7834SAmine Khaldi ok(ret, "unexpected error %u\n", GetLastError());
4518*3c1b7834SAmine Khaldi ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %u\n", size);
4519*3c1b7834SAmine Khaldi acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
4520*3c1b7834SAmine Khaldi ok(!acl->Sbz1, "got %u\n", acl->Sbz1);
4521*3c1b7834SAmine Khaldi ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize);
4522*3c1b7834SAmine Khaldi ok(!acl->AceCount, "got %u\n", acl->AceCount);
4523*3c1b7834SAmine Khaldi ok(!acl->Sbz2, "got %u\n", acl->Sbz2);
4524*3c1b7834SAmine Khaldi LocalFree(pSD);
4525c2c66affSColin Finck }
4526c2c66affSColin Finck
test_ConvertSecurityDescriptorToString(void)4527c2c66affSColin Finck static void test_ConvertSecurityDescriptorToString(void)
4528c2c66affSColin Finck {
4529c2c66affSColin Finck SECURITY_DESCRIPTOR desc;
4530c2c66affSColin Finck SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION;
4531c2c66affSColin Finck LPSTR string;
4532c2c66affSColin Finck DWORD size;
4533c2c66affSColin Finck PSID psid, psid2;
4534c2c66affSColin Finck PACL pacl;
4535c2c66affSColin Finck char sid_buf[256];
4536c2c66affSColin Finck char acl_buf[8192];
4537c2c66affSColin Finck ULONG len;
4538c2c66affSColin Finck
4539c2c66affSColin Finck if (!pConvertSecurityDescriptorToStringSecurityDescriptorA)
4540c2c66affSColin Finck {
4541c2c66affSColin Finck win_skip("ConvertSecurityDescriptorToStringSecurityDescriptor is not available\n");
4542c2c66affSColin Finck return;
4543c2c66affSColin Finck }
4544c2c66affSColin Finck if (!pCreateWellKnownSid)
4545c2c66affSColin Finck {
4546c2c66affSColin Finck win_skip("CreateWellKnownSid is not available\n");
4547c2c66affSColin Finck return;
4548c2c66affSColin Finck }
4549c2c66affSColin Finck
4550c2c66affSColin Finck /* It seems Windows XP adds an extra character to the length of the string for each ACE in an ACL. We
4551c2c66affSColin Finck * don't replicate this feature so we only test len >= strlen+1. */
4552c2c66affSColin Finck #define CHECK_RESULT_AND_FREE(exp_str) \
4553c2c66affSColin Finck ok(strcmp(string, (exp_str)) == 0, "String mismatch (expected \"%s\", got \"%s\")\n", (exp_str), string); \
4554c2c66affSColin Finck ok(len >= (strlen(exp_str) + 1), "Length mismatch (expected %d, got %d)\n", lstrlenA(exp_str) + 1, len); \
4555c2c66affSColin Finck LocalFree(string);
4556c2c66affSColin Finck
4557c2c66affSColin Finck #define CHECK_ONE_OF_AND_FREE(exp_str1, exp_str2) \
4558c2c66affSColin Finck ok(strcmp(string, (exp_str1)) == 0 || strcmp(string, (exp_str2)) == 0, "String mismatch (expected\n\"%s\" or\n\"%s\", got\n\"%s\")\n", (exp_str1), (exp_str2), string); \
4559c2c66affSColin Finck ok(len >= (strlen(exp_str1) + 1) || len >= (strlen(exp_str2) + 1), "Length mismatch (expected %d or %d, got %d)\n", lstrlenA(exp_str1) + 1, lstrlenA(exp_str2) + 1, len); \
4560c2c66affSColin Finck LocalFree(string);
4561c2c66affSColin Finck
4562c2c66affSColin Finck InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION);
4563c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4564c2c66affSColin Finck CHECK_RESULT_AND_FREE("");
4565c2c66affSColin Finck
4566c2c66affSColin Finck size = 4096;
4567c2c66affSColin Finck pCreateWellKnownSid(WinLocalSid, NULL, sid_buf, &size);
4568c2c66affSColin Finck SetSecurityDescriptorOwner(&desc, sid_buf, FALSE);
4569c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4570c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:S-1-2-0");
4571c2c66affSColin Finck
4572c2c66affSColin Finck SetSecurityDescriptorOwner(&desc, sid_buf, TRUE);
4573c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4574c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:S-1-2-0");
4575c2c66affSColin Finck
4576c2c66affSColin Finck size = sizeof(sid_buf);
4577c2c66affSColin Finck pCreateWellKnownSid(WinLocalSystemSid, NULL, sid_buf, &size);
4578c2c66affSColin Finck SetSecurityDescriptorOwner(&desc, sid_buf, TRUE);
4579c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4580c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:SY");
4581c2c66affSColin Finck
4582c2c66affSColin Finck pConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid);
4583c2c66affSColin Finck SetSecurityDescriptorGroup(&desc, psid, TRUE);
4584c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4585c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576");
4586c2c66affSColin Finck
4587c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, GROUP_SECURITY_INFORMATION, &string, &len), "Conversion failed\n");
4588c2c66affSColin Finck CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576");
4589c2c66affSColin Finck
4590c2c66affSColin Finck pacl = (PACL)acl_buf;
4591c2c66affSColin Finck InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION);
4592c2c66affSColin Finck SetSecurityDescriptorDacl(&desc, TRUE, pacl, TRUE);
4593c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4594c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:");
4595c2c66affSColin Finck
4596c2c66affSColin Finck SetSecurityDescriptorDacl(&desc, TRUE, pacl, FALSE);
4597c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4598c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:");
4599c2c66affSColin Finck
4600c2c66affSColin Finck pConvertStringSidToSidA("S-1-5-6", &psid2);
4601c2c66affSColin Finck pAddAccessAllowedAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, 0xf0000000, psid2);
4602c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4603c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)");
4604c2c66affSColin Finck
4605c2c66affSColin Finck pAddAccessAllowedAceEx(pacl, ACL_REVISION, INHERIT_ONLY_ACE|INHERITED_ACE, 0x00000003, psid2);
4606c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4607c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)");
4608c2c66affSColin Finck
4609c2c66affSColin Finck pAddAccessDeniedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 0xffffffff, psid);
4610c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4611c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)");
4612c2c66affSColin Finck
4613c2c66affSColin Finck
4614c2c66affSColin Finck pacl = (PACL)acl_buf;
4615c2c66affSColin Finck InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION);
4616c2c66affSColin Finck SetSecurityDescriptorSacl(&desc, TRUE, pacl, FALSE);
4617c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4618c2c66affSColin Finck CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:");
4619c2c66affSColin Finck
4620c2c66affSColin Finck /* fails in win2k */
4621c2c66affSColin Finck SetSecurityDescriptorDacl(&desc, TRUE, NULL, FALSE);
4622c2c66affSColin Finck pAddAuditAccessAceEx(pacl, ACL_REVISION, VALID_INHERIT_FLAGS, KEY_READ|KEY_WRITE, psid2, TRUE, TRUE);
4623c2c66affSColin Finck if (pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len))
4624c2c66affSColin Finck {
4625c2c66affSColin Finck CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)", /* XP */
4626c2c66affSColin Finck "O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)" /* Vista */);
4627c2c66affSColin Finck }
4628c2c66affSColin Finck
4629c2c66affSColin Finck /* fails in win2k */
4630c2c66affSColin Finck pAddAuditAccessAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, FILE_GENERIC_READ|FILE_GENERIC_WRITE, psid2, TRUE, FALSE);
4631c2c66affSColin Finck if (pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len))
4632c2c66affSColin Finck {
4633c2c66affSColin Finck CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", /* XP */
4634c2c66affSColin Finck "O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)" /* Vista */);
4635c2c66affSColin Finck }
4636c2c66affSColin Finck
4637c2c66affSColin Finck LocalFree(psid2);
4638c2c66affSColin Finck LocalFree(psid);
4639c2c66affSColin Finck }
4640c2c66affSColin Finck
test_SetSecurityDescriptorControl(PSECURITY_DESCRIPTOR sec)4641c2c66affSColin Finck static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec)
4642c2c66affSColin Finck {
4643c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL ref;
4644c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL test;
4645c2c66affSColin Finck
4646c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL const mutable
4647c2c66affSColin Finck = SE_DACL_AUTO_INHERIT_REQ | SE_SACL_AUTO_INHERIT_REQ
4648c2c66affSColin Finck | SE_DACL_AUTO_INHERITED | SE_SACL_AUTO_INHERITED
4649c2c66affSColin Finck | SE_DACL_PROTECTED | SE_SACL_PROTECTED
4650c2c66affSColin Finck | 0x00000040 | 0x00000080 /* not defined in winnt.h */
4651c2c66affSColin Finck ;
4652c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL const immutable
4653c2c66affSColin Finck = SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED
4654c2c66affSColin Finck | SE_DACL_PRESENT | SE_DACL_DEFAULTED
4655c2c66affSColin Finck | SE_SACL_PRESENT | SE_SACL_DEFAULTED
4656c2c66affSColin Finck | SE_RM_CONTROL_VALID | SE_SELF_RELATIVE
4657c2c66affSColin Finck ;
4658c2c66affSColin Finck
4659c2c66affSColin Finck int bit;
4660c2c66affSColin Finck DWORD dwRevision;
4661c2c66affSColin Finck LPCSTR fmt = "Expected error %s, got %u\n";
4662c2c66affSColin Finck
4663c2c66affSColin Finck GetSecurityDescriptorControl (sec, &ref, &dwRevision);
4664c2c66affSColin Finck
4665c2c66affSColin Finck /* The mutable bits are mutable regardless of the truth of
4666c2c66affSColin Finck SE_DACL_PRESENT and/or SE_SACL_PRESENT */
4667c2c66affSColin Finck
4668c2c66affSColin Finck /* Check call barfs if any bit-of-interest is immutable */
4669c2c66affSColin Finck for (bit = 0; bit < 16; ++bit)
4670c2c66affSColin Finck {
4671c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL const bitOfInterest = 1 << bit;
4672c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitOfInterest;
4673c2c66affSColin Finck
4674c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL ctrl;
4675c2c66affSColin Finck
4676c2c66affSColin Finck DWORD dwExpect = (bitOfInterest & immutable)
4677c2c66affSColin Finck ? ERROR_INVALID_PARAMETER : 0xbebecaca;
4678c2c66affSColin Finck LPCSTR strExpect = (bitOfInterest & immutable)
4679c2c66affSColin Finck ? "ERROR_INVALID_PARAMETER" : "0xbebecaca";
4680c2c66affSColin Finck
4681c2c66affSColin Finck ctrl = (bitOfInterest & mutable) ? ref + bitOfInterest : ref;
4682c2c66affSColin Finck setOrClear ^= bitOfInterest;
4683c2c66affSColin Finck SetLastError (0xbebecaca);
4684c2c66affSColin Finck pSetSecurityDescriptorControl (sec, bitOfInterest, setOrClear);
4685c2c66affSColin Finck ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4686c2c66affSColin Finck GetSecurityDescriptorControl(sec, &test, &dwRevision);
4687c2c66affSColin Finck expect_eq(test, ctrl, int, "%x");
4688c2c66affSColin Finck
4689c2c66affSColin Finck setOrClear ^= bitOfInterest;
4690c2c66affSColin Finck SetLastError (0xbebecaca);
4691c2c66affSColin Finck pSetSecurityDescriptorControl (sec, bitOfInterest, setOrClear);
4692c2c66affSColin Finck ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4693c2c66affSColin Finck GetSecurityDescriptorControl (sec, &test, &dwRevision);
4694c2c66affSColin Finck expect_eq(test, ref, int, "%x");
4695c2c66affSColin Finck }
4696c2c66affSColin Finck
4697c2c66affSColin Finck /* Check call barfs if any bit-to-set is immutable
4698c2c66affSColin Finck even when not a bit-of-interest */
4699c2c66affSColin Finck for (bit = 0; bit < 16; ++bit)
4700c2c66affSColin Finck {
4701c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL const bitsOfInterest = mutable;
4702c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitsOfInterest;
4703c2c66affSColin Finck
4704c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL ctrl;
4705c2c66affSColin Finck
4706c2c66affSColin Finck DWORD dwExpect = ((1 << bit) & immutable)
4707c2c66affSColin Finck ? ERROR_INVALID_PARAMETER : 0xbebecaca;
4708c2c66affSColin Finck LPCSTR strExpect = ((1 << bit) & immutable)
4709c2c66affSColin Finck ? "ERROR_INVALID_PARAMETER" : "0xbebecaca";
4710c2c66affSColin Finck
4711c2c66affSColin Finck ctrl = ((1 << bit) & immutable) ? test : ref | mutable;
4712c2c66affSColin Finck setOrClear ^= bitsOfInterest;
4713c2c66affSColin Finck SetLastError (0xbebecaca);
4714c2c66affSColin Finck pSetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit));
4715c2c66affSColin Finck ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4716c2c66affSColin Finck GetSecurityDescriptorControl(sec, &test, &dwRevision);
4717c2c66affSColin Finck expect_eq(test, ctrl, int, "%x");
4718c2c66affSColin Finck
4719c2c66affSColin Finck ctrl = ((1 << bit) & immutable) ? test : ref | (1 << bit);
4720c2c66affSColin Finck setOrClear ^= bitsOfInterest;
4721c2c66affSColin Finck SetLastError (0xbebecaca);
4722c2c66affSColin Finck pSetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit));
4723c2c66affSColin Finck ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4724c2c66affSColin Finck GetSecurityDescriptorControl(sec, &test, &dwRevision);
4725c2c66affSColin Finck expect_eq(test, ctrl, int, "%x");
4726c2c66affSColin Finck }
4727c2c66affSColin Finck }
4728c2c66affSColin Finck
test_PrivateObjectSecurity(void)4729c2c66affSColin Finck static void test_PrivateObjectSecurity(void)
4730c2c66affSColin Finck {
4731c2c66affSColin Finck SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION;
4732c2c66affSColin Finck SECURITY_DESCRIPTOR_CONTROL ctrl;
4733c2c66affSColin Finck PSECURITY_DESCRIPTOR sec;
4734c2c66affSColin Finck DWORD dwDescSize;
4735c2c66affSColin Finck DWORD dwRevision;
4736c2c66affSColin Finck DWORD retSize;
4737c2c66affSColin Finck LPSTR string;
4738c2c66affSColin Finck ULONG len;
4739c2c66affSColin Finck PSECURITY_DESCRIPTOR buf;
4740c2c66affSColin Finck BOOL ret;
4741c2c66affSColin Finck
4742c2c66affSColin Finck if (!pConvertStringSecurityDescriptorToSecurityDescriptorA)
4743c2c66affSColin Finck {
4744c2c66affSColin Finck win_skip("ConvertStringSecurityDescriptorToSecurityDescriptor is not available\n");
4745c2c66affSColin Finck return;
4746c2c66affSColin Finck }
4747c2c66affSColin Finck
4748c2c66affSColin Finck ok(pConvertStringSecurityDescriptorToSecurityDescriptorA(
4749c2c66affSColin Finck "O:SY"
4750c2c66affSColin Finck "G:S-1-5-21-93476-23408-4576"
4751c2c66affSColin Finck "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"
4752c2c66affSColin Finck "(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4753c2c66affSColin Finck "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)",
4754c2c66affSColin Finck SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
4755c2c66affSColin Finck
4756c2c66affSColin Finck test_SetSecurityDescriptorControl(sec);
4757c2c66affSColin Finck
4758c2c66affSColin Finck LocalFree(sec);
4759c2c66affSColin Finck
4760c2c66affSColin Finck ok(pConvertStringSecurityDescriptorToSecurityDescriptorA(
4761c2c66affSColin Finck "O:SY"
4762c2c66affSColin Finck "G:S-1-5-21-93476-23408-4576",
4763c2c66affSColin Finck SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
4764c2c66affSColin Finck
4765c2c66affSColin Finck test_SetSecurityDescriptorControl(sec);
4766c2c66affSColin Finck
4767c2c66affSColin Finck LocalFree(sec);
4768c2c66affSColin Finck
4769c2c66affSColin Finck ok(pConvertStringSecurityDescriptorToSecurityDescriptorA(
4770c2c66affSColin Finck "O:SY"
4771c2c66affSColin Finck "G:S-1-5-21-93476-23408-4576"
4772c2c66affSColin Finck "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4773c2c66affSColin Finck "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
4774c2c66affSColin Finck buf = HeapAlloc(GetProcessHeap(), 0, dwDescSize);
4775c2c66affSColin Finck pSetSecurityDescriptorControl(sec, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
4776c2c66affSColin Finck GetSecurityDescriptorControl(sec, &ctrl, &dwRevision);
4777c2c66affSColin Finck expect_eq(ctrl, 0x9014, int, "%x");
4778c2c66affSColin Finck
4779c2c66affSColin Finck ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION, buf, dwDescSize, &retSize);
4780c2c66affSColin Finck ok(ret, "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError());
4781c2c66affSColin Finck ok(retSize <= dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize);
4782c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4783c2c66affSColin Finck CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576");
4784c2c66affSColin Finck GetSecurityDescriptorControl(buf, &ctrl, &dwRevision);
4785c2c66affSColin Finck expect_eq(ctrl, 0x8000, int, "%x");
4786c2c66affSColin Finck
4787c2c66affSColin Finck ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, buf, dwDescSize, &retSize);
4788c2c66affSColin Finck ok(ret, "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError());
4789c2c66affSColin Finck ok(retSize <= dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize);
4790c2c66affSColin Finck ret = pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len);
4791c2c66affSColin Finck ok(ret, "Conversion failed err=%u\n", GetLastError());
4792c2c66affSColin Finck CHECK_ONE_OF_AND_FREE("G:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)",
4793c2c66affSColin Finck "G:S-1-5-21-93476-23408-4576D:P(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"); /* Win7 */
4794c2c66affSColin Finck GetSecurityDescriptorControl(buf, &ctrl, &dwRevision);
4795c2c66affSColin Finck expect_eq(ctrl & (~ SE_DACL_PROTECTED), 0x8004, int, "%x");
4796c2c66affSColin Finck
4797c2c66affSColin Finck ret = GetPrivateObjectSecurity(sec, sec_info, buf, dwDescSize, &retSize);
4798c2c66affSColin Finck ok(ret, "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError());
4799c2c66affSColin Finck ok(retSize == dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize);
4800c2c66affSColin Finck ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4801c2c66affSColin Finck CHECK_ONE_OF_AND_FREE("O:SY"
4802c2c66affSColin Finck "G:S-1-5-21-93476-23408-4576"
4803c2c66affSColin Finck "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4804c2c66affSColin Finck "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)",
4805c2c66affSColin Finck "O:SY"
4806c2c66affSColin Finck "G:S-1-5-21-93476-23408-4576"
4807c2c66affSColin Finck "D:P(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4808c2c66affSColin Finck "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)"); /* Win7 */
4809c2c66affSColin Finck GetSecurityDescriptorControl(buf, &ctrl, &dwRevision);
4810c2c66affSColin Finck expect_eq(ctrl & (~ SE_DACL_PROTECTED), 0x8014, int, "%x");
4811c2c66affSColin Finck
4812c2c66affSColin Finck SetLastError(0xdeadbeef);
4813c2c66affSColin Finck ok(GetPrivateObjectSecurity(sec, sec_info, buf, 5, &retSize) == FALSE, "GetPrivateObjectSecurity should have failed\n");
4814c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected error ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
4815c2c66affSColin Finck
4816c2c66affSColin Finck LocalFree(sec);
4817c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, buf);
4818c2c66affSColin Finck }
4819c2c66affSColin Finck #undef CHECK_RESULT_AND_FREE
4820c2c66affSColin Finck #undef CHECK_ONE_OF_AND_FREE
4821c2c66affSColin Finck
test_acls(void)4822c2c66affSColin Finck static void test_acls(void)
4823c2c66affSColin Finck {
4824c2c66affSColin Finck char buffer[256];
4825c2c66affSColin Finck PACL pAcl = (PACL)buffer;
4826c2c66affSColin Finck BOOL ret;
4827c2c66affSColin Finck
4828c2c66affSColin Finck SetLastError(0xdeadbeef);
4829c2c66affSColin Finck ret = InitializeAcl(pAcl, sizeof(ACL) - 1, ACL_REVISION);
4830c2c66affSColin Finck if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
4831c2c66affSColin Finck {
4832c2c66affSColin Finck win_skip("InitializeAcl is not implemented\n");
4833c2c66affSColin Finck return;
4834c2c66affSColin Finck }
4835c2c66affSColin Finck
4836c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InitializeAcl with too small a buffer should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError());
4837c2c66affSColin Finck
4838c2c66affSColin Finck SetLastError(0xdeadbeef);
4839c2c66affSColin Finck ret = InitializeAcl(pAcl, 0xffffffff, ACL_REVISION);
4840c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl with too large a buffer should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
4841c2c66affSColin Finck
4842c2c66affSColin Finck SetLastError(0xdeadbeef);
4843c2c66affSColin Finck ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION1);
4844c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(ACL_REVISION1) should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
4845c2c66affSColin Finck
4846c2c66affSColin Finck ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION2);
4847c2c66affSColin Finck ok(ret, "InitializeAcl(ACL_REVISION2) failed with error %d\n", GetLastError());
4848c2c66affSColin Finck
4849c2c66affSColin Finck ret = IsValidAcl(pAcl);
4850c2c66affSColin Finck ok(ret, "IsValidAcl failed with error %d\n", GetLastError());
4851c2c66affSColin Finck
4852c2c66affSColin Finck ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION3);
4853c2c66affSColin Finck ok(ret, "InitializeAcl(ACL_REVISION3) failed with error %d\n", GetLastError());
4854c2c66affSColin Finck
4855c2c66affSColin Finck ret = IsValidAcl(pAcl);
4856c2c66affSColin Finck ok(ret, "IsValidAcl failed with error %d\n", GetLastError());
4857c2c66affSColin Finck
4858c2c66affSColin Finck SetLastError(0xdeadbeef);
4859c2c66affSColin Finck ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION4);
4860c2c66affSColin Finck if (GetLastError() != ERROR_INVALID_PARAMETER)
4861c2c66affSColin Finck {
4862c2c66affSColin Finck ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %d\n", GetLastError());
4863c2c66affSColin Finck
4864c2c66affSColin Finck ret = IsValidAcl(pAcl);
4865c2c66affSColin Finck ok(ret, "IsValidAcl failed with error %d\n", GetLastError());
4866c2c66affSColin Finck }
4867c2c66affSColin Finck else
4868c2c66affSColin Finck win_skip("ACL_REVISION4 is not implemented on NT4\n");
4869c2c66affSColin Finck
4870c2c66affSColin Finck SetLastError(0xdeadbeef);
4871c2c66affSColin Finck ret = InitializeAcl(pAcl, sizeof(buffer), -1);
4872c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(-1) failed with error %d\n", GetLastError());
4873c2c66affSColin Finck }
4874c2c66affSColin Finck
test_GetSecurityInfo(void)4875c2c66affSColin Finck static void test_GetSecurityInfo(void)
4876c2c66affSColin Finck {
4877c2c66affSColin Finck char domain_users_ptr[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
4878c2c66affSColin Finck char b[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
4879c2c66affSColin Finck char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100];
4880c2c66affSColin Finck PSID domain_users_sid = (PSID) domain_users_ptr, domain_sid;
4881c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY sia = { SECURITY_NT_AUTHORITY };
4882c2c66affSColin Finck int domain_users_ace_id = -1, admins_ace_id = -1, i;
4883c2c66affSColin Finck DWORD sid_size = sizeof(admin_ptr), l = sizeof(b);
4884c2c66affSColin Finck PSID admin_sid = (PSID) admin_ptr, user_sid;
4885c2c66affSColin Finck char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
4886c2c66affSColin Finck BOOL owner_defaulted, group_defaulted;
4887c2c66affSColin Finck BOOL dacl_defaulted, dacl_present;
4888c2c66affSColin Finck ACL_SIZE_INFORMATION acl_size;
4889c2c66affSColin Finck PSECURITY_DESCRIPTOR pSD;
4890c2c66affSColin Finck ACCESS_ALLOWED_ACE *ace;
4891c2c66affSColin Finck HANDLE token, obj;
4892c2c66affSColin Finck PSID owner, group;
4893c2c66affSColin Finck BOOL bret = TRUE;
4894c2c66affSColin Finck PACL pDacl;
4895c2c66affSColin Finck BYTE flags;
4896c2c66affSColin Finck DWORD ret;
4897c2c66affSColin Finck
4898c2c66affSColin Finck if (!pGetSecurityInfo || !pSetSecurityInfo)
4899c2c66affSColin Finck {
4900c2c66affSColin Finck win_skip("[Get|Set]SecurityInfo is not available\n");
4901c2c66affSColin Finck return;
4902c2c66affSColin Finck }
4903c2c66affSColin Finck
4904c2c66affSColin Finck if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
4905c2c66affSColin Finck {
4906c2c66affSColin Finck if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
4907c2c66affSColin Finck else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
4908c2c66affSColin Finck }
4909c2c66affSColin Finck if (!bret)
4910c2c66affSColin Finck {
4911c2c66affSColin Finck win_skip("Failed to get current user token\n");
4912c2c66affSColin Finck return;
4913c2c66affSColin Finck }
4914c2c66affSColin Finck bret = GetTokenInformation(token, TokenUser, b, l, &l);
4915c2c66affSColin Finck ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
4916c2c66affSColin Finck CloseHandle( token );
4917c2c66affSColin Finck user_sid = ((TOKEN_USER *)b)->User.Sid;
4918c2c66affSColin Finck
4919c2c66affSColin Finck /* Create something. Files have lots of associated security info. */
4920c2c66affSColin Finck obj = CreateFileA(myARGV[0], GENERIC_READ|WRITE_DAC, FILE_SHARE_READ, NULL,
4921c2c66affSColin Finck OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
4922c2c66affSColin Finck if (obj == INVALID_HANDLE_VALUE)
4923c2c66affSColin Finck {
4924c2c66affSColin Finck skip("Couldn't create an object for GetSecurityInfo test\n");
4925c2c66affSColin Finck return;
4926c2c66affSColin Finck }
4927c2c66affSColin Finck
4928c2c66affSColin Finck ret = pGetSecurityInfo(obj, SE_FILE_OBJECT,
4929c2c66affSColin Finck OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
4930c2c66affSColin Finck &owner, &group, &pDacl, NULL, &pSD);
4931c2c66affSColin Finck if (ret == ERROR_CALL_NOT_IMPLEMENTED)
4932c2c66affSColin Finck {
4933c2c66affSColin Finck win_skip("GetSecurityInfo is not implemented\n");
4934c2c66affSColin Finck CloseHandle(obj);
4935c2c66affSColin Finck return;
4936c2c66affSColin Finck }
4937c2c66affSColin Finck ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
4938c2c66affSColin Finck ok(pSD != NULL, "GetSecurityInfo\n");
4939c2c66affSColin Finck ok(owner != NULL, "GetSecurityInfo\n");
4940c2c66affSColin Finck ok(group != NULL, "GetSecurityInfo\n");
4941c2c66affSColin Finck if (pDacl != NULL)
4942c2c66affSColin Finck ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
4943c2c66affSColin Finck else
4944c2c66affSColin Finck win_skip("No ACL information returned\n");
4945c2c66affSColin Finck
4946c2c66affSColin Finck LocalFree(pSD);
4947c2c66affSColin Finck
4948c2c66affSColin Finck if (!pCreateWellKnownSid)
4949c2c66affSColin Finck {
4950c2c66affSColin Finck win_skip("NULL parameter test would crash on NT4\n");
4951c2c66affSColin Finck CloseHandle(obj);
4952c2c66affSColin Finck return;
4953c2c66affSColin Finck }
4954c2c66affSColin Finck
4955c2c66affSColin Finck /* If we don't ask for the security descriptor, Windows will still give us
4956c2c66affSColin Finck the other stuff, leaving us no way to free it. */
4957c2c66affSColin Finck ret = pGetSecurityInfo(obj, SE_FILE_OBJECT,
4958c2c66affSColin Finck OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
4959c2c66affSColin Finck &owner, &group, &pDacl, NULL, NULL);
4960c2c66affSColin Finck ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
4961c2c66affSColin Finck ok(owner != NULL, "GetSecurityInfo\n");
4962c2c66affSColin Finck ok(group != NULL, "GetSecurityInfo\n");
4963c2c66affSColin Finck if (pDacl != NULL)
4964c2c66affSColin Finck ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
4965c2c66affSColin Finck else
4966c2c66affSColin Finck win_skip("No ACL information returned\n");
4967c2c66affSColin Finck
4968c2c66affSColin Finck /* Create security descriptor information and test that it comes back the same */
4969c2c66affSColin Finck pSD = &sd;
4970c2c66affSColin Finck pDacl = (PACL)&dacl;
4971c2c66affSColin Finck InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
4972c2c66affSColin Finck pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
4973c2c66affSColin Finck bret = InitializeAcl(pDacl, sizeof(dacl), ACL_REVISION);
4974c2c66affSColin Finck ok(bret, "Failed to initialize ACL.\n");
4975c2c66affSColin Finck bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4976c2c66affSColin Finck ok(bret, "Failed to add Current User to ACL.\n");
4977c2c66affSColin Finck bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
4978c2c66affSColin Finck ok(bret, "Failed to add Administrator Group to ACL.\n");
4979c2c66affSColin Finck bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4980c2c66affSColin Finck ok(bret, "Failed to add ACL to security descriptor.\n");
4981c2c66affSColin Finck ret = pSetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4982c2c66affSColin Finck NULL, NULL, pDacl, NULL);
4983c2c66affSColin Finck ok(ret == ERROR_SUCCESS, "SetSecurityInfo returned %d\n", ret);
4984c2c66affSColin Finck ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4985c2c66affSColin Finck NULL, NULL, &pDacl, NULL, &pSD);
4986c2c66affSColin Finck ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
4987c2c66affSColin Finck ok(pDacl && IsValidAcl(pDacl), "GetSecurityInfo returned invalid DACL.\n");
4988c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4989c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
4990c2c66affSColin Finck if (acl_size.AceCount > 0)
4991c2c66affSColin Finck {
4992c2c66affSColin Finck bret = pGetAce(pDacl, 0, (VOID **)&ace);
4993c2c66affSColin Finck ok(bret, "Failed to get Current User ACE.\n");
4994c2c66affSColin Finck bret = EqualSid(&ace->SidStart, user_sid);
4995c2c66affSColin Finck ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
4996c2c66affSColin Finck ok(((ACE_HEADER *)ace)->AceFlags == 0,
4997c2c66affSColin Finck "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
4998c2c66affSColin Finck ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
4999c2c66affSColin Finck ace->Mask);
5000c2c66affSColin Finck }
5001c2c66affSColin Finck if (acl_size.AceCount > 1)
5002c2c66affSColin Finck {
5003c2c66affSColin Finck bret = pGetAce(pDacl, 1, (VOID **)&ace);
5004c2c66affSColin Finck ok(bret, "Failed to get Administators Group ACE.\n");
5005c2c66affSColin Finck bret = EqualSid(&ace->SidStart, admin_sid);
5006c2c66affSColin Finck ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
5007c2c66affSColin Finck ok(((ACE_HEADER *)ace)->AceFlags == 0,
5008c2c66affSColin Finck "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
5009c2c66affSColin Finck ok(ace->Mask == 0x1f01ff,
5010c2c66affSColin Finck "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
5011c2c66affSColin Finck }
5012c2c66affSColin Finck LocalFree(pSD);
5013c2c66affSColin Finck CloseHandle(obj);
5014c2c66affSColin Finck
5015c2c66affSColin Finck /* Obtain the "domain users" SID from the user SID */
5016c2c66affSColin Finck if (!AllocateAndInitializeSid(&sia, 4, *GetSidSubAuthority(user_sid, 0),
5017c2c66affSColin Finck *GetSidSubAuthority(user_sid, 1),
5018c2c66affSColin Finck *GetSidSubAuthority(user_sid, 2),
5019c2c66affSColin Finck *GetSidSubAuthority(user_sid, 3), 0, 0, 0, 0, &domain_sid))
5020c2c66affSColin Finck {
5021c2c66affSColin Finck win_skip("Failed to get current domain SID\n");
5022c2c66affSColin Finck return;
5023c2c66affSColin Finck }
5024c2c66affSColin Finck sid_size = sizeof(domain_users_ptr);
5025c2c66affSColin Finck pCreateWellKnownSid(WinAccountDomainUsersSid, domain_sid, domain_users_sid, &sid_size);
5026c2c66affSColin Finck FreeSid(domain_sid);
5027c2c66affSColin Finck
5028c2c66affSColin Finck /* Test querying the ownership of a process */
5029c2c66affSColin Finck ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT,
5030c2c66affSColin Finck OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION,
5031c2c66affSColin Finck NULL, NULL, NULL, NULL, &pSD);
5032c2c66affSColin Finck ok(!ret, "GetNamedSecurityInfo failed with error %d\n", ret);
5033c2c66affSColin Finck
5034c2c66affSColin Finck bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
5035c2c66affSColin Finck ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
5036c2c66affSColin Finck ok(owner != NULL, "owner should not be NULL\n");
5037c2c66affSColin Finck ok(EqualSid(owner, admin_sid) || EqualSid(owner, user_sid),
5038c2c66affSColin Finck "Process owner SID != Administrators SID.\n");
5039c2c66affSColin Finck
5040c2c66affSColin Finck bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
5041c2c66affSColin Finck ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
5042c2c66affSColin Finck ok(group != NULL, "group should not be NULL\n");
5043c2c66affSColin Finck ok(EqualSid(group, domain_users_sid), "Process group SID != Domain Users SID.\n");
5044c2c66affSColin Finck LocalFree(pSD);
5045c2c66affSColin Finck
5046c2c66affSColin Finck /* Test querying the DACL of a process */
5047c2c66affSColin Finck ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
5048c2c66affSColin Finck NULL, NULL, NULL, NULL, &pSD);
5049c2c66affSColin Finck ok(!ret, "GetSecurityInfo failed with error %d\n", ret);
5050c2c66affSColin Finck
5051c2c66affSColin Finck bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted);
5052c2c66affSColin Finck ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError());
5053c2c66affSColin Finck ok(dacl_present, "DACL should be present\n");
5054c2c66affSColin Finck ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n");
5055c2c66affSColin Finck bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
5056c2c66affSColin Finck ok(bret, "GetAclInformation failed\n");
5057c2c66affSColin Finck ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n");
5058c2c66affSColin Finck for (i=0; i<acl_size.AceCount; i++)
5059c2c66affSColin Finck {
5060c2c66affSColin Finck bret = pGetAce(pDacl, i, (VOID **)&ace);
5061c2c66affSColin Finck ok(bret, "Failed to get ACE %d.\n", i);
5062c2c66affSColin Finck bret = EqualSid(&ace->SidStart, domain_users_sid);
5063c2c66affSColin Finck if (bret) domain_users_ace_id = i;
5064c2c66affSColin Finck bret = EqualSid(&ace->SidStart, admin_sid);
5065c2c66affSColin Finck if (bret) admins_ace_id = i;
5066c2c66affSColin Finck }
5067c2c66affSColin Finck ok(domain_users_ace_id != -1 || broken(domain_users_ace_id == -1) /* win2k */,
5068c2c66affSColin Finck "Domain Users ACE not found.\n");
5069c2c66affSColin Finck if (domain_users_ace_id != -1)
5070c2c66affSColin Finck {
5071c2c66affSColin Finck bret = pGetAce(pDacl, domain_users_ace_id, (VOID **)&ace);
5072c2c66affSColin Finck ok(bret, "Failed to get Domain Users ACE.\n");
5073c2c66affSColin Finck flags = ((ACE_HEADER *)ace)->AceFlags;
5074c2c66affSColin Finck ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE),
5075c2c66affSColin Finck "Domain Users ACE has unexpected flags (0x%x != 0x%x)\n", flags,
5076c2c66affSColin Finck INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE);
5077c2c66affSColin Finck ok(ace->Mask == GENERIC_READ, "Domain Users ACE has unexpected mask (0x%x != 0x%x)\n",
5078c2c66affSColin Finck ace->Mask, GENERIC_READ);
5079c2c66affSColin Finck }
5080c2c66affSColin Finck ok(admins_ace_id != -1 || broken(admins_ace_id == -1) /* xp */,
5081c2c66affSColin Finck "Builtin Admins ACE not found.\n");
5082c2c66affSColin Finck if (admins_ace_id != -1)
5083c2c66affSColin Finck {
5084c2c66affSColin Finck bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace);
5085c2c66affSColin Finck ok(bret, "Failed to get Builtin Admins ACE.\n");
5086c2c66affSColin Finck flags = ((ACE_HEADER *)ace)->AceFlags;
5087c2c66affSColin Finck ok(flags == 0x0, "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags);
5088c2c66affSColin Finck ok(ace->Mask == PROCESS_ALL_ACCESS || broken(ace->Mask == 0x1f0fff) /* win2k */,
5089c2c66affSColin Finck "Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, PROCESS_ALL_ACCESS);
5090c2c66affSColin Finck }
5091c2c66affSColin Finck LocalFree(pSD);
5092c2c66affSColin Finck }
5093c2c66affSColin Finck
test_GetSidSubAuthority(void)5094c2c66affSColin Finck static void test_GetSidSubAuthority(void)
5095c2c66affSColin Finck {
5096c2c66affSColin Finck PSID psid = NULL;
5097c2c66affSColin Finck
5098c2c66affSColin Finck if (!pGetSidSubAuthority || !pConvertStringSidToSidA || !pIsValidSid || !pGetSidSubAuthorityCount)
5099c2c66affSColin Finck {
5100c2c66affSColin Finck win_skip("Some functions not available\n");
5101c2c66affSColin Finck return;
5102c2c66affSColin Finck }
5103c2c66affSColin Finck /* Note: on windows passing in an invalid index like -1, lets GetSidSubAuthority return 0x05000000 but
5104c2c66affSColin Finck still GetLastError returns ERROR_SUCCESS then. We don't test these unlikely cornercases here for now */
5105c2c66affSColin Finck ok(pConvertStringSidToSidA("S-1-5-21-93476-23408-4576",&psid),"ConvertStringSidToSidA failed\n");
5106c2c66affSColin Finck ok(pIsValidSid(psid),"Sid is not valid\n");
5107c2c66affSColin Finck SetLastError(0xbebecaca);
5108c2c66affSColin Finck ok(*pGetSidSubAuthorityCount(psid) == 4,"GetSidSubAuthorityCount gave %d expected 4\n",*pGetSidSubAuthorityCount(psid));
5109c2c66affSColin Finck ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError());
5110c2c66affSColin Finck SetLastError(0xbebecaca);
5111c2c66affSColin Finck ok(*pGetSidSubAuthority(psid,0) == 21,"GetSidSubAuthority gave %d expected 21\n",*pGetSidSubAuthority(psid,0));
5112c2c66affSColin Finck ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError());
5113c2c66affSColin Finck SetLastError(0xbebecaca);
5114c2c66affSColin Finck ok(*pGetSidSubAuthority(psid,1) == 93476,"GetSidSubAuthority gave %d expected 93476\n",*pGetSidSubAuthority(psid,1));
5115c2c66affSColin Finck ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError());
5116c2c66affSColin Finck SetLastError(0xbebecaca);
5117c2c66affSColin Finck ok(pGetSidSubAuthority(psid,4) != NULL,"Expected out of bounds GetSidSubAuthority to return a non-NULL pointer\n");
5118c2c66affSColin Finck ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError());
5119c2c66affSColin Finck LocalFree(psid);
5120c2c66affSColin Finck }
5121c2c66affSColin Finck
test_CheckTokenMembership(void)5122c2c66affSColin Finck static void test_CheckTokenMembership(void)
5123c2c66affSColin Finck {
5124c2c66affSColin Finck PTOKEN_GROUPS token_groups;
5125c2c66affSColin Finck DWORD size;
5126c2c66affSColin Finck HANDLE process_token, token;
5127c2c66affSColin Finck BOOL is_member;
5128c2c66affSColin Finck BOOL ret;
5129c2c66affSColin Finck DWORD i;
5130c2c66affSColin Finck
5131c2c66affSColin Finck if (!pCheckTokenMembership)
5132c2c66affSColin Finck {
5133c2c66affSColin Finck win_skip("CheckTokenMembership is not available\n");
5134c2c66affSColin Finck return;
5135c2c66affSColin Finck }
5136c2c66affSColin Finck ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token);
5137c2c66affSColin Finck ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
5138c2c66affSColin Finck
5139c2c66affSColin Finck ret = DuplicateToken(process_token, SecurityImpersonation, &token);
5140c2c66affSColin Finck ok(ret, "DuplicateToken failed with error %d\n", GetLastError());
5141c2c66affSColin Finck
5142c2c66affSColin Finck /* groups */
5143c2c66affSColin Finck ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
5144c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
5145c2c66affSColin Finck "GetTokenInformation(TokenGroups) %s with error %d\n",
5146c2c66affSColin Finck ret ? "succeeded" : "failed", GetLastError());
5147c2c66affSColin Finck token_groups = HeapAlloc(GetProcessHeap(), 0, size);
5148c2c66affSColin Finck ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
5149c2c66affSColin Finck ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n", GetLastError());
5150c2c66affSColin Finck
5151c2c66affSColin Finck for (i = 0; i < token_groups->GroupCount; i++)
5152c2c66affSColin Finck {
5153c2c66affSColin Finck if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED)
5154c2c66affSColin Finck break;
5155c2c66affSColin Finck }
5156c2c66affSColin Finck
5157c2c66affSColin Finck if (i == token_groups->GroupCount)
5158c2c66affSColin Finck {
5159c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, token_groups);
5160c2c66affSColin Finck CloseHandle(token);
5161c2c66affSColin Finck skip("user not a member of any group\n");
5162c2c66affSColin Finck return;
5163c2c66affSColin Finck }
5164c2c66affSColin Finck
5165c2c66affSColin Finck is_member = FALSE;
5166c2c66affSColin Finck ret = pCheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member);
5167c2c66affSColin Finck ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError());
5168c2c66affSColin Finck ok(is_member, "CheckTokenMembership should have detected sid as member\n");
5169c2c66affSColin Finck
5170c2c66affSColin Finck is_member = FALSE;
5171c2c66affSColin Finck ret = pCheckTokenMembership(NULL, token_groups->Groups[i].Sid, &is_member);
5172c2c66affSColin Finck ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError());
5173c2c66affSColin Finck ok(is_member, "CheckTokenMembership should have detected sid as member\n");
5174c2c66affSColin Finck
5175c2c66affSColin Finck is_member = TRUE;
5176c2c66affSColin Finck SetLastError(0xdeadbeef);
5177c2c66affSColin Finck ret = pCheckTokenMembership(process_token, token_groups->Groups[i].Sid, &is_member);
5178c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_NO_IMPERSONATION_TOKEN,
5179c2c66affSColin Finck "CheckTokenMembership with process token %s with error %d\n",
5180c2c66affSColin Finck ret ? "succeeded" : "failed", GetLastError());
5181c2c66affSColin Finck ok(!is_member, "CheckTokenMembership should have cleared is_member\n");
5182c2c66affSColin Finck
5183c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, token_groups);
5184c2c66affSColin Finck CloseHandle(token);
5185c2c66affSColin Finck CloseHandle(process_token);
5186c2c66affSColin Finck }
5187c2c66affSColin Finck
test_EqualSid(void)5188c2c66affSColin Finck static void test_EqualSid(void)
5189c2c66affSColin Finck {
5190c2c66affSColin Finck PSID sid1, sid2;
5191c2c66affSColin Finck BOOL ret;
5192c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
5193c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
5194c2c66affSColin Finck
5195c2c66affSColin Finck SetLastError(0xdeadbeef);
5196c2c66affSColin Finck ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
5197c2c66affSColin Finck DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid1);
5198c2c66affSColin Finck if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
5199c2c66affSColin Finck {
5200c2c66affSColin Finck win_skip("AllocateAndInitializeSid is not implemented\n");
5201c2c66affSColin Finck return;
5202c2c66affSColin Finck }
5203c2c66affSColin Finck ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
5204c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef,
5205c2c66affSColin Finck "AllocateAndInitializeSid shouldn't have set last error to %d\n",
5206c2c66affSColin Finck GetLastError());
5207c2c66affSColin Finck
5208c2c66affSColin Finck ret = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID,
5209c2c66affSColin Finck 0, 0, 0, 0, 0, 0, 0, &sid2);
5210c2c66affSColin Finck ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
5211c2c66affSColin Finck
5212c2c66affSColin Finck SetLastError(0xdeadbeef);
5213c2c66affSColin Finck ret = EqualSid(sid1, sid2);
5214c2c66affSColin Finck ok(!ret, "World and domain admins sids shouldn't have been equal\n");
5215c2c66affSColin Finck ok(GetLastError() == ERROR_SUCCESS ||
5216c2c66affSColin Finck broken(GetLastError() == 0xdeadbeef), /* NT4 */
5217c2c66affSColin Finck "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n",
5218c2c66affSColin Finck GetLastError());
5219c2c66affSColin Finck
5220c2c66affSColin Finck SetLastError(0xdeadbeef);
5221c2c66affSColin Finck sid2 = FreeSid(sid2);
5222c2c66affSColin Finck ok(!sid2, "FreeSid should have returned NULL instead of %p\n", sid2);
5223c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef,
5224c2c66affSColin Finck "FreeSid shouldn't have set last error to %d\n",
5225c2c66affSColin Finck GetLastError());
5226c2c66affSColin Finck
5227c2c66affSColin Finck ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
5228c2c66affSColin Finck DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid2);
5229c2c66affSColin Finck ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
5230c2c66affSColin Finck
5231c2c66affSColin Finck SetLastError(0xdeadbeef);
5232c2c66affSColin Finck ret = EqualSid(sid1, sid2);
5233c2c66affSColin Finck ok(ret, "Same sids should have been equal %s != %s\n",
5234c2c66affSColin Finck debugstr_sid(sid1), debugstr_sid(sid2));
5235c2c66affSColin Finck ok(GetLastError() == ERROR_SUCCESS ||
5236c2c66affSColin Finck broken(GetLastError() == 0xdeadbeef), /* NT4 */
5237c2c66affSColin Finck "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n",
5238c2c66affSColin Finck GetLastError());
5239c2c66affSColin Finck
5240c2c66affSColin Finck ((SID *)sid2)->Revision = 2;
5241c2c66affSColin Finck SetLastError(0xdeadbeef);
5242c2c66affSColin Finck ret = EqualSid(sid1, sid2);
5243c2c66affSColin Finck ok(!ret, "EqualSid with invalid sid should have returned FALSE\n");
5244c2c66affSColin Finck ok(GetLastError() == ERROR_SUCCESS ||
5245c2c66affSColin Finck broken(GetLastError() == 0xdeadbeef), /* NT4 */
5246c2c66affSColin Finck "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n",
5247c2c66affSColin Finck GetLastError());
5248c2c66affSColin Finck ((SID *)sid2)->Revision = SID_REVISION;
5249c2c66affSColin Finck
5250c2c66affSColin Finck FreeSid(sid1);
5251c2c66affSColin Finck FreeSid(sid2);
5252c2c66affSColin Finck }
5253c2c66affSColin Finck
test_GetUserNameA(void)5254c2c66affSColin Finck static void test_GetUserNameA(void)
5255c2c66affSColin Finck {
5256c2c66affSColin Finck char buffer[UNLEN + 1], filler[UNLEN + 1];
5257c2c66affSColin Finck DWORD required_len, buffer_len;
5258c2c66affSColin Finck BOOL ret;
5259c2c66affSColin Finck
5260c2c66affSColin Finck /* Test crashes on Windows. */
5261c2c66affSColin Finck if (0)
5262c2c66affSColin Finck {
5263c2c66affSColin Finck SetLastError(0xdeadbeef);
5264c2c66affSColin Finck GetUserNameA(NULL, NULL);
5265c2c66affSColin Finck }
5266c2c66affSColin Finck
5267c2c66affSColin Finck SetLastError(0xdeadbeef);
5268c2c66affSColin Finck required_len = 0;
5269c2c66affSColin Finck ret = GetUserNameA(NULL, &required_len);
5270c2c66affSColin Finck ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5271c2c66affSColin Finck ok(required_len != 0, "Outputted buffer length was %u\n", required_len);
5272c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError());
5273c2c66affSColin Finck
5274c2c66affSColin Finck SetLastError(0xdeadbeef);
5275c2c66affSColin Finck required_len = 1;
5276c2c66affSColin Finck ret = GetUserNameA(NULL, &required_len);
5277c2c66affSColin Finck ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5278c2c66affSColin Finck ok(required_len != 0 && required_len != 1, "Outputted buffer length was %u\n", required_len);
5279c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError());
5280c2c66affSColin Finck
5281c2c66affSColin Finck /* Tests crashes on Windows. */
5282c2c66affSColin Finck if (0)
5283c2c66affSColin Finck {
5284c2c66affSColin Finck SetLastError(0xdeadbeef);
5285c2c66affSColin Finck required_len = UNLEN + 1;
5286c2c66affSColin Finck GetUserNameA(NULL, &required_len);
5287c2c66affSColin Finck
5288c2c66affSColin Finck SetLastError(0xdeadbeef);
5289c2c66affSColin Finck GetUserNameA(buffer, NULL);
5290c2c66affSColin Finck }
5291c2c66affSColin Finck
5292c2c66affSColin Finck memset(filler, 'x', sizeof(filler));
5293c2c66affSColin Finck
5294c2c66affSColin Finck /* Note that GetUserNameA on XP and newer outputs the number of bytes
5295c2c66affSColin Finck * required for a Unicode string, which affects a test in the next block. */
5296c2c66affSColin Finck SetLastError(0xdeadbeef);
5297c2c66affSColin Finck memcpy(buffer, filler, sizeof(filler));
5298c2c66affSColin Finck required_len = 0;
5299c2c66affSColin Finck ret = GetUserNameA(buffer, &required_len);
5300c2c66affSColin Finck ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5301c2c66affSColin Finck ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n");
5302c2c66affSColin Finck ok(required_len != 0, "Outputted buffer length was %u\n", required_len);
5303c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError());
5304c2c66affSColin Finck
5305c2c66affSColin Finck SetLastError(0xdeadbeef);
5306c2c66affSColin Finck memcpy(buffer, filler, sizeof(filler));
5307c2c66affSColin Finck buffer_len = required_len;
5308c2c66affSColin Finck ret = GetUserNameA(buffer, &buffer_len);
5309c2c66affSColin Finck ok(ret == TRUE, "GetUserNameA returned %d, last error %u\n", ret, GetLastError());
5310c2c66affSColin Finck ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n");
5311c2c66affSColin Finck ok(buffer_len == required_len ||
5312c2c66affSColin Finck broken(buffer_len == required_len / sizeof(WCHAR)), /* XP+ */
5313c2c66affSColin Finck "Outputted buffer length was %u\n", buffer_len);
5314c2c66affSColin Finck
5315c2c66affSColin Finck /* Use the reported buffer size from the last GetUserNameA call and pass
5316c2c66affSColin Finck * a length that is one less than the required value. */
5317c2c66affSColin Finck SetLastError(0xdeadbeef);
5318c2c66affSColin Finck memcpy(buffer, filler, sizeof(filler));
5319c2c66affSColin Finck buffer_len--;
5320c2c66affSColin Finck ret = GetUserNameA(buffer, &buffer_len);
5321c2c66affSColin Finck ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5322c2c66affSColin Finck ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was untouched\n");
5323c2c66affSColin Finck ok(buffer_len == required_len, "Outputted buffer length was %u\n", buffer_len);
5324c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError());
5325c2c66affSColin Finck }
5326c2c66affSColin Finck
test_GetUserNameW(void)5327c2c66affSColin Finck static void test_GetUserNameW(void)
5328c2c66affSColin Finck {
5329c2c66affSColin Finck WCHAR buffer[UNLEN + 1], filler[UNLEN + 1];
5330c2c66affSColin Finck DWORD required_len, buffer_len;
5331c2c66affSColin Finck BOOL ret;
5332c2c66affSColin Finck
5333c2c66affSColin Finck /* Test crashes on Windows. */
5334c2c66affSColin Finck if (0)
5335c2c66affSColin Finck {
5336c2c66affSColin Finck SetLastError(0xdeadbeef);
5337c2c66affSColin Finck GetUserNameW(NULL, NULL);
5338c2c66affSColin Finck }
5339c2c66affSColin Finck
5340c2c66affSColin Finck SetLastError(0xdeadbeef);
5341c2c66affSColin Finck required_len = 0;
5342c2c66affSColin Finck ret = GetUserNameW(NULL, &required_len);
5343c2c66affSColin Finck ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5344c2c66affSColin Finck ok(required_len != 0, "Outputted buffer length was %u\n", required_len);
5345c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError());
5346c2c66affSColin Finck
5347c2c66affSColin Finck SetLastError(0xdeadbeef);
5348c2c66affSColin Finck required_len = 1;
5349c2c66affSColin Finck ret = GetUserNameW(NULL, &required_len);
5350c2c66affSColin Finck ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5351c2c66affSColin Finck ok(required_len != 0 && required_len != 1, "Outputted buffer length was %u\n", required_len);
5352c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError());
5353c2c66affSColin Finck
5354c2c66affSColin Finck /* Tests crash on Windows. */
5355c2c66affSColin Finck if (0)
5356c2c66affSColin Finck {
5357c2c66affSColin Finck SetLastError(0xdeadbeef);
5358c2c66affSColin Finck required_len = UNLEN + 1;
5359c2c66affSColin Finck GetUserNameW(NULL, &required_len);
5360c2c66affSColin Finck
5361c2c66affSColin Finck SetLastError(0xdeadbeef);
5362c2c66affSColin Finck GetUserNameW(buffer, NULL);
5363c2c66affSColin Finck }
5364c2c66affSColin Finck
5365c2c66affSColin Finck memset(filler, 'x', sizeof(filler));
5366c2c66affSColin Finck
5367c2c66affSColin Finck SetLastError(0xdeadbeef);
5368c2c66affSColin Finck memcpy(buffer, filler, sizeof(filler));
5369c2c66affSColin Finck required_len = 0;
5370c2c66affSColin Finck ret = GetUserNameW(buffer, &required_len);
5371c2c66affSColin Finck ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5372c2c66affSColin Finck ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n");
5373c2c66affSColin Finck ok(required_len != 0, "Outputted buffer length was %u\n", required_len);
5374c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError());
5375c2c66affSColin Finck
5376c2c66affSColin Finck SetLastError(0xdeadbeef);
5377c2c66affSColin Finck memcpy(buffer, filler, sizeof(filler));
5378c2c66affSColin Finck buffer_len = required_len;
5379c2c66affSColin Finck ret = GetUserNameW(buffer, &buffer_len);
5380c2c66affSColin Finck ok(ret == TRUE, "GetUserNameW returned %d, last error %u\n", ret, GetLastError());
5381c2c66affSColin Finck ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n");
5382c2c66affSColin Finck ok(buffer_len == required_len, "Outputted buffer length was %u\n", buffer_len);
5383c2c66affSColin Finck
5384c2c66affSColin Finck /* GetUserNameW on XP and newer writes a truncated portion of the username string to the buffer. */
5385c2c66affSColin Finck SetLastError(0xdeadbeef);
5386c2c66affSColin Finck memcpy(buffer, filler, sizeof(filler));
5387c2c66affSColin Finck buffer_len--;
5388c2c66affSColin Finck ret = GetUserNameW(buffer, &buffer_len);
5389c2c66affSColin Finck ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5390c2c66affSColin Finck ok(!memcmp(buffer, filler, sizeof(filler)) ||
5391c2c66affSColin Finck broken(memcmp(buffer, filler, sizeof(filler)) != 0), /* XP+ */
5392c2c66affSColin Finck "Output buffer was altered\n");
5393c2c66affSColin Finck ok(buffer_len == required_len, "Outputted buffer length was %u\n", buffer_len);
5394c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError());
5395c2c66affSColin Finck }
5396c2c66affSColin Finck
test_CreateRestrictedToken(void)5397c2c66affSColin Finck static void test_CreateRestrictedToken(void)
5398c2c66affSColin Finck {
5399561bed7bSAmine Khaldi TOKEN_PRIMARY_GROUP *primary_group, *primary_group2;
5400c2c66affSColin Finck HANDLE process_token, token, r_token;
5401c2c66affSColin Finck PTOKEN_GROUPS token_groups, groups2;
5402c2c66affSColin Finck SID_AND_ATTRIBUTES sattr;
5403c2c66affSColin Finck SECURITY_IMPERSONATION_LEVEL level;
5404561bed7bSAmine Khaldi TOKEN_PRIVILEGES *privs;
5405561bed7bSAmine Khaldi PRIVILEGE_SET privset;
5406c2c66affSColin Finck TOKEN_TYPE type;
5407c2c66affSColin Finck BOOL is_member;
5408c2c66affSColin Finck DWORD size;
5409c2c66affSColin Finck BOOL ret;
5410c2c66affSColin Finck DWORD i, j;
5411c2c66affSColin Finck
5412c2c66affSColin Finck if (!pCreateRestrictedToken)
5413c2c66affSColin Finck {
5414c2c66affSColin Finck win_skip("CreateRestrictedToken is not available\n");
5415c2c66affSColin Finck return;
5416c2c66affSColin Finck }
5417c2c66affSColin Finck
5418c2c66affSColin Finck ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token);
5419c2c66affSColin Finck ok(ret, "got error %d\n", GetLastError());
5420c2c66affSColin Finck
5421561bed7bSAmine Khaldi ret = DuplicateTokenEx(process_token, TOKEN_DUPLICATE|TOKEN_ADJUST_GROUPS|TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
5422c2c66affSColin Finck NULL, SecurityImpersonation, TokenImpersonation, &token);
5423c2c66affSColin Finck ok(ret, "got error %d\n", GetLastError());
5424c2c66affSColin Finck
5425c2c66affSColin Finck /* groups */
5426c2c66affSColin Finck ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
5427c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
5428c2c66affSColin Finck "got %d with error %d\n", ret, GetLastError());
5429c2c66affSColin Finck token_groups = HeapAlloc(GetProcessHeap(), 0, size);
5430c2c66affSColin Finck ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
5431c2c66affSColin Finck ok(ret, "got error %d\n", GetLastError());
5432c2c66affSColin Finck
5433c2c66affSColin Finck for (i = 0; i < token_groups->GroupCount; i++)
5434c2c66affSColin Finck {
5435c2c66affSColin Finck if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED)
5436c2c66affSColin Finck break;
5437c2c66affSColin Finck }
5438c2c66affSColin Finck
5439c2c66affSColin Finck if (i == token_groups->GroupCount)
5440c2c66affSColin Finck {
5441c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, token_groups);
5442c2c66affSColin Finck CloseHandle(token);
5443c2c66affSColin Finck skip("User not a member of any group\n");
5444c2c66affSColin Finck return;
5445c2c66affSColin Finck }
5446c2c66affSColin Finck
5447c2c66affSColin Finck is_member = FALSE;
5448c2c66affSColin Finck ret = pCheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member);
5449c2c66affSColin Finck ok(ret, "got error %d\n", GetLastError());
5450c2c66affSColin Finck ok(is_member, "not a member\n");
5451c2c66affSColin Finck
5452561bed7bSAmine Khaldi privset.PrivilegeCount = 1;
5453561bed7bSAmine Khaldi privset.Control = PRIVILEGE_SET_ALL_NECESSARY;
5454561bed7bSAmine Khaldi ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privset.Privilege[0].Luid);
5455561bed7bSAmine Khaldi ok(ret, "got error %d\n", GetLastError());
5456561bed7bSAmine Khaldi
5457561bed7bSAmine Khaldi is_member = FALSE;
5458561bed7bSAmine Khaldi ret = PrivilegeCheck(token, &privset, &is_member);
5459561bed7bSAmine Khaldi ok(ret, "got error %d\n", GetLastError());
5460561bed7bSAmine Khaldi ok(is_member, "Expected SeChangeNotifyPrivilege to be enabled\n");
5461561bed7bSAmine Khaldi
5462561bed7bSAmine Khaldi /* disable a SID and a privilege in new token */
5463c2c66affSColin Finck sattr.Sid = token_groups->Groups[i].Sid;
5464c2c66affSColin Finck sattr.Attributes = 0;
5465c2c66affSColin Finck r_token = NULL;
5466561bed7bSAmine Khaldi ret = pCreateRestrictedToken(token, 0, 1, &sattr, 1, &privset.Privilege[0], 0, NULL, &r_token);
5467c2c66affSColin Finck ok(ret, "got error %d\n", GetLastError());
5468c2c66affSColin Finck
5469c2c66affSColin Finck if (ret)
5470c2c66affSColin Finck {
5471c2c66affSColin Finck /* check if a SID is enabled */
5472c2c66affSColin Finck is_member = TRUE;
5473c2c66affSColin Finck ret = pCheckTokenMembership(r_token, token_groups->Groups[i].Sid, &is_member);
5474c2c66affSColin Finck ok(ret, "got error %d\n", GetLastError());
5475561bed7bSAmine Khaldi ok(!is_member, "not a member\n");
5476c2c66affSColin Finck
5477c2c66affSColin Finck ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size);
5478c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
5479c2c66affSColin Finck ret, GetLastError());
5480c2c66affSColin Finck groups2 = HeapAlloc(GetProcessHeap(), 0, size);
5481c2c66affSColin Finck ret = GetTokenInformation(r_token, TokenGroups, groups2, size, &size);
5482c2c66affSColin Finck ok(ret, "got error %d\n", GetLastError());
5483c2c66affSColin Finck
5484c2c66affSColin Finck for (j = 0; j < groups2->GroupCount; j++)
5485c2c66affSColin Finck {
5486c2c66affSColin Finck if (EqualSid(groups2->Groups[j].Sid, token_groups->Groups[i].Sid))
5487c2c66affSColin Finck break;
5488c2c66affSColin Finck }
5489c2c66affSColin Finck
5490561bed7bSAmine Khaldi ok(groups2->Groups[j].Attributes & SE_GROUP_USE_FOR_DENY_ONLY,
5491c2c66affSColin Finck "got wrong attributes\n");
5492561bed7bSAmine Khaldi ok((groups2->Groups[j].Attributes & SE_GROUP_ENABLED) == 0,
5493c2c66affSColin Finck "got wrong attributes\n");
5494c2c66affSColin Finck
5495c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, groups2);
5496c2c66affSColin Finck
5497c2c66affSColin Finck size = sizeof(type);
5498c2c66affSColin Finck ret = GetTokenInformation(r_token, TokenType, &type, size, &size);
5499c2c66affSColin Finck ok(ret, "got error %d\n", GetLastError());
5500c2c66affSColin Finck ok(type == TokenImpersonation, "got type %u\n", type);
5501c2c66affSColin Finck
5502c2c66affSColin Finck size = sizeof(level);
5503c2c66affSColin Finck ret = GetTokenInformation(r_token, TokenImpersonationLevel, &level, size, &size);
5504c2c66affSColin Finck ok(ret, "got error %d\n", GetLastError());
5505c2c66affSColin Finck ok(level == SecurityImpersonation, "got level %u\n", type);
5506561bed7bSAmine Khaldi
5507561bed7bSAmine Khaldi is_member = TRUE;
5508561bed7bSAmine Khaldi ret = PrivilegeCheck(r_token, &privset, &is_member);
5509561bed7bSAmine Khaldi ok(ret, "got error %d\n", GetLastError());
5510561bed7bSAmine Khaldi ok(!is_member, "Expected SeChangeNotifyPrivilege not to be enabled\n");
5511561bed7bSAmine Khaldi
5512561bed7bSAmine Khaldi ret = GetTokenInformation(r_token, TokenPrivileges, NULL, 0, &size);
5513561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
5514561bed7bSAmine Khaldi ret, GetLastError());
5515561bed7bSAmine Khaldi privs = HeapAlloc(GetProcessHeap(), 0, size);
5516561bed7bSAmine Khaldi ret = GetTokenInformation(r_token, TokenPrivileges, privs, size, &size);
5517561bed7bSAmine Khaldi ok(ret, "got error %d\n", GetLastError());
5518561bed7bSAmine Khaldi
5519561bed7bSAmine Khaldi is_member = FALSE;
5520561bed7bSAmine Khaldi for (j = 0; j < privs->PrivilegeCount; j++)
5521561bed7bSAmine Khaldi {
5522561bed7bSAmine Khaldi if (RtlEqualLuid(&privs->Privileges[j].Luid, &privset.Privilege[0].Luid))
5523561bed7bSAmine Khaldi {
5524561bed7bSAmine Khaldi is_member = TRUE;
5525561bed7bSAmine Khaldi break;
5526561bed7bSAmine Khaldi }
5527561bed7bSAmine Khaldi }
5528561bed7bSAmine Khaldi
5529561bed7bSAmine Khaldi ok(!is_member, "Expected not to find privilege\n");
5530561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, privs);
5531c2c66affSColin Finck }
5532c2c66affSColin Finck
5533c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, token_groups);
5534c2c66affSColin Finck CloseHandle(r_token);
5535561bed7bSAmine Khaldi
5536561bed7bSAmine Khaldi ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &size);
5537561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
5538561bed7bSAmine Khaldi ret, GetLastError());
5539561bed7bSAmine Khaldi primary_group = HeapAlloc(GetProcessHeap(), 0, size);
5540561bed7bSAmine Khaldi ret = GetTokenInformation(token, TokenPrimaryGroup, primary_group, size, &size);
5541561bed7bSAmine Khaldi ok(ret, "got error %d\n", GetLastError());
5542561bed7bSAmine Khaldi
5543561bed7bSAmine Khaldi /* disable primary group */
5544561bed7bSAmine Khaldi sattr.Sid = primary_group->PrimaryGroup;
5545561bed7bSAmine Khaldi sattr.Attributes = 0;
5546561bed7bSAmine Khaldi r_token = NULL;
5547561bed7bSAmine Khaldi ret = pCreateRestrictedToken(token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token);
5548561bed7bSAmine Khaldi ok(ret, "got error %d\n", GetLastError());
5549561bed7bSAmine Khaldi
5550561bed7bSAmine Khaldi if (ret)
5551561bed7bSAmine Khaldi {
5552561bed7bSAmine Khaldi is_member = TRUE;
5553561bed7bSAmine Khaldi ret = pCheckTokenMembership(r_token, primary_group->PrimaryGroup, &is_member);
5554561bed7bSAmine Khaldi ok(ret, "got error %d\n", GetLastError());
5555561bed7bSAmine Khaldi ok(!is_member, "not a member\n");
5556561bed7bSAmine Khaldi
5557561bed7bSAmine Khaldi ret = GetTokenInformation(r_token, TokenPrimaryGroup, NULL, 0, &size);
5558561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
5559561bed7bSAmine Khaldi ret, GetLastError());
5560561bed7bSAmine Khaldi primary_group2 = HeapAlloc(GetProcessHeap(), 0, size);
5561561bed7bSAmine Khaldi ret = GetTokenInformation(r_token, TokenPrimaryGroup, primary_group2, size, &size);
5562561bed7bSAmine Khaldi ok(ret, "got error %d\n", GetLastError());
5563561bed7bSAmine Khaldi
5564561bed7bSAmine Khaldi ok(EqualSid(primary_group2->PrimaryGroup, primary_group->PrimaryGroup),
5565561bed7bSAmine Khaldi "Expected same primary group\n");
5566561bed7bSAmine Khaldi
5567561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, primary_group2);
5568561bed7bSAmine Khaldi }
5569561bed7bSAmine Khaldi
5570561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, primary_group);
5571561bed7bSAmine Khaldi CloseHandle(r_token);
5572561bed7bSAmine Khaldi
5573c2c66affSColin Finck CloseHandle(token);
5574c2c66affSColin Finck CloseHandle(process_token);
5575c2c66affSColin Finck }
5576c2c66affSColin Finck
validate_default_security_descriptor(SECURITY_DESCRIPTOR * sd)5577c2c66affSColin Finck static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd)
5578c2c66affSColin Finck {
5579c2c66affSColin Finck BOOL ret, present, defaulted;
5580c2c66affSColin Finck ACL *acl;
5581c2c66affSColin Finck void *sid;
5582c2c66affSColin Finck
5583c2c66affSColin Finck ret = IsValidSecurityDescriptor(sd);
5584c2c66affSColin Finck ok(ret, "security descriptor is not valid\n");
5585c2c66affSColin Finck
5586c2c66affSColin Finck present = -1;
5587c2c66affSColin Finck defaulted = -1;
5588c2c66affSColin Finck acl = (void *)0xdeadbeef;
5589c2c66affSColin Finck SetLastError(0xdeadbeef);
5590c2c66affSColin Finck ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
5591c2c66affSColin Finck ok(ret, "GetSecurityDescriptorDacl error %d\n", GetLastError());
5592c2c66affSColin Finck todo_wine
5593c2c66affSColin Finck ok(present == 1, "acl is not present\n");
5594c2c66affSColin Finck todo_wine
5595c2c66affSColin Finck ok(acl != (void *)0xdeadbeef && acl != NULL, "acl pointer is not set\n");
5596c2c66affSColin Finck ok(defaulted == 0, "defaulted is set to TRUE\n");
5597c2c66affSColin Finck
5598c2c66affSColin Finck defaulted = -1;
5599c2c66affSColin Finck sid = (void *)0xdeadbeef;
5600c2c66affSColin Finck SetLastError(0xdeadbeef);
5601c2c66affSColin Finck ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted);
5602c2c66affSColin Finck ok(ret, "GetSecurityDescriptorOwner error %d\n", GetLastError());
5603c2c66affSColin Finck todo_wine
5604c2c66affSColin Finck ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
5605c2c66affSColin Finck ok(defaulted == 0, "defaulted is set to TRUE\n");
5606c2c66affSColin Finck
5607c2c66affSColin Finck defaulted = -1;
5608c2c66affSColin Finck sid = (void *)0xdeadbeef;
5609c2c66affSColin Finck SetLastError(0xdeadbeef);
5610c2c66affSColin Finck ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted);
5611c2c66affSColin Finck ok(ret, "GetSecurityDescriptorGroup error %d\n", GetLastError());
5612c2c66affSColin Finck todo_wine
5613c2c66affSColin Finck ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
5614c2c66affSColin Finck ok(defaulted == 0, "defaulted is set to TRUE\n");
5615c2c66affSColin Finck }
5616c2c66affSColin Finck
test_default_handle_security(HANDLE token,HANDLE handle,GENERIC_MAPPING * mapping)5617c2c66affSColin Finck static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping)
5618c2c66affSColin Finck {
5619c2c66affSColin Finck DWORD ret, granted, priv_set_len;
5620c2c66affSColin Finck BOOL status;
5621c2c66affSColin Finck PRIVILEGE_SET priv_set;
5622c2c66affSColin Finck SECURITY_DESCRIPTOR *sd;
5623c2c66affSColin Finck
5624c2c66affSColin Finck sd = test_get_security_descriptor(handle, __LINE__);
5625c2c66affSColin Finck validate_default_security_descriptor(sd);
5626c2c66affSColin Finck
5627c2c66affSColin Finck priv_set_len = sizeof(priv_set);
5628c2c66affSColin Finck granted = 0xdeadbeef;
5629c2c66affSColin Finck status = 0xdeadbeef;
5630c2c66affSColin Finck SetLastError(0xdeadbeef);
5631c2c66affSColin Finck ret = AccessCheck(sd, token, MAXIMUM_ALLOWED, mapping, &priv_set, &priv_set_len, &granted, &status);
5632c2c66affSColin Finck todo_wine {
5633c2c66affSColin Finck ok(ret, "AccessCheck error %d\n", GetLastError());
5634c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
5635c2c66affSColin Finck ok(granted == mapping->GenericAll, "expected all access %#x, got %#x\n", mapping->GenericAll, granted);
5636c2c66affSColin Finck }
5637c2c66affSColin Finck priv_set_len = sizeof(priv_set);
5638c2c66affSColin Finck granted = 0xdeadbeef;
5639c2c66affSColin Finck status = 0xdeadbeef;
5640c2c66affSColin Finck SetLastError(0xdeadbeef);
5641c2c66affSColin Finck ret = AccessCheck(sd, token, 0, mapping, &priv_set, &priv_set_len, &granted, &status);
5642c2c66affSColin Finck todo_wine {
5643c2c66affSColin Finck ok(ret, "AccessCheck error %d\n", GetLastError());
5644c2c66affSColin Finck ok(status == 0 || broken(status == 1) /* NT4 */, "expected 0, got %d\n", status);
5645c2c66affSColin Finck ok(granted == 0 || broken(granted == mapping->GenericRead) /* NT4 */, "expected 0, got %#x\n", granted);
5646c2c66affSColin Finck }
5647c2c66affSColin Finck priv_set_len = sizeof(priv_set);
5648c2c66affSColin Finck granted = 0xdeadbeef;
5649c2c66affSColin Finck status = 0xdeadbeef;
5650c2c66affSColin Finck SetLastError(0xdeadbeef);
5651c2c66affSColin Finck ret = AccessCheck(sd, token, ACCESS_SYSTEM_SECURITY, mapping, &priv_set, &priv_set_len, &granted, &status);
5652c2c66affSColin Finck todo_wine {
5653c2c66affSColin Finck ok(ret, "AccessCheck error %d\n", GetLastError());
5654c2c66affSColin Finck ok(status == 0, "expected 0, got %d\n", status);
5655c2c66affSColin Finck ok(granted == 0, "expected 0, got %#x\n", granted);
5656c2c66affSColin Finck }
5657c2c66affSColin Finck priv_set_len = sizeof(priv_set);
5658c2c66affSColin Finck granted = 0xdeadbeef;
5659c2c66affSColin Finck status = 0xdeadbeef;
5660c2c66affSColin Finck SetLastError(0xdeadbeef);
5661c2c66affSColin Finck ret = AccessCheck(sd, token, mapping->GenericRead, mapping, &priv_set, &priv_set_len, &granted, &status);
5662c2c66affSColin Finck todo_wine {
5663c2c66affSColin Finck ok(ret, "AccessCheck error %d\n", GetLastError());
5664c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
5665c2c66affSColin Finck ok(granted == mapping->GenericRead, "expected read access %#x, got %#x\n", mapping->GenericRead, granted);
5666c2c66affSColin Finck }
5667c2c66affSColin Finck priv_set_len = sizeof(priv_set);
5668c2c66affSColin Finck granted = 0xdeadbeef;
5669c2c66affSColin Finck status = 0xdeadbeef;
5670c2c66affSColin Finck SetLastError(0xdeadbeef);
5671c2c66affSColin Finck ret = AccessCheck(sd, token, mapping->GenericWrite, mapping, &priv_set, &priv_set_len, &granted, &status);
5672c2c66affSColin Finck todo_wine {
5673c2c66affSColin Finck ok(ret, "AccessCheck error %d\n", GetLastError());
5674c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
5675c2c66affSColin Finck ok(granted == mapping->GenericWrite, "expected write access %#x, got %#x\n", mapping->GenericWrite, granted);
5676c2c66affSColin Finck }
5677c2c66affSColin Finck priv_set_len = sizeof(priv_set);
5678c2c66affSColin Finck granted = 0xdeadbeef;
5679c2c66affSColin Finck status = 0xdeadbeef;
5680c2c66affSColin Finck SetLastError(0xdeadbeef);
5681c2c66affSColin Finck ret = AccessCheck(sd, token, mapping->GenericExecute, mapping, &priv_set, &priv_set_len, &granted, &status);
5682c2c66affSColin Finck todo_wine {
5683c2c66affSColin Finck ok(ret, "AccessCheck error %d\n", GetLastError());
5684c2c66affSColin Finck ok(status == 1, "expected 1, got %d\n", status);
5685c2c66affSColin Finck ok(granted == mapping->GenericExecute, "expected execute access %#x, got %#x\n", mapping->GenericExecute, granted);
5686c2c66affSColin Finck }
5687c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sd);
5688c2c66affSColin Finck }
5689c2c66affSColin Finck
get_obj_access(HANDLE obj)5690c2c66affSColin Finck static ACCESS_MASK get_obj_access(HANDLE obj)
5691c2c66affSColin Finck {
5692c2c66affSColin Finck OBJECT_BASIC_INFORMATION info;
5693c2c66affSColin Finck NTSTATUS status;
5694c2c66affSColin Finck
5695c2c66affSColin Finck if (!pNtQueryObject) return 0;
5696c2c66affSColin Finck
5697c2c66affSColin Finck status = pNtQueryObject(obj, ObjectBasicInformation, &info, sizeof(info), NULL);
5698c2c66affSColin Finck ok(!status, "NtQueryObject error %#x\n", status);
5699c2c66affSColin Finck
5700c2c66affSColin Finck return info.GrantedAccess;
5701c2c66affSColin Finck }
5702c2c66affSColin Finck
test_mutex_security(HANDLE token)5703c2c66affSColin Finck static void test_mutex_security(HANDLE token)
5704c2c66affSColin Finck {
5705c2c66affSColin Finck DWORD ret, i, access;
5706c2c66affSColin Finck HANDLE mutex, dup;
5707c2c66affSColin Finck GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE | SYNCHRONIZE,
5708c2c66affSColin Finck STANDARD_RIGHTS_WRITE | MUTEX_MODIFY_STATE | SYNCHRONIZE,
5709c2c66affSColin Finck STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
5710c2c66affSColin Finck STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS };
5711c2c66affSColin Finck static const struct
5712c2c66affSColin Finck {
5713c2c66affSColin Finck int generic, mapped;
5714c2c66affSColin Finck } map[] =
5715c2c66affSColin Finck {
5716c2c66affSColin Finck { 0, 0 },
5717c2c66affSColin Finck { GENERIC_READ, STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE },
5718c2c66affSColin Finck { GENERIC_WRITE, STANDARD_RIGHTS_WRITE },
5719c2c66affSColin Finck { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
5720c2c66affSColin Finck { GENERIC_ALL, STANDARD_RIGHTS_ALL | MUTANT_QUERY_STATE }
5721c2c66affSColin Finck };
5722c2c66affSColin Finck
5723c2c66affSColin Finck SetLastError(0xdeadbeef);
5724c2c66affSColin Finck mutex = OpenMutexA(0, FALSE, "WineTestMutex");
5725c2c66affSColin Finck ok(!mutex, "mutex should not exist\n");
5726c2c66affSColin Finck ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
5727c2c66affSColin Finck
5728c2c66affSColin Finck SetLastError(0xdeadbeef);
5729c2c66affSColin Finck mutex = CreateMutexA(NULL, FALSE, "WineTestMutex");
5730c2c66affSColin Finck ok(mutex != 0, "CreateMutex error %d\n", GetLastError());
5731c2c66affSColin Finck
5732c2c66affSColin Finck access = get_obj_access(mutex);
5733c2c66affSColin Finck ok(access == MUTANT_ALL_ACCESS, "expected MUTANT_ALL_ACCESS, got %#x\n", access);
5734c2c66affSColin Finck
5735c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
5736c2c66affSColin Finck {
5737c2c66affSColin Finck SetLastError( 0xdeadbeef );
5738c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), mutex, GetCurrentProcess(), &dup,
5739c2c66affSColin Finck map[i].generic, FALSE, 0);
5740c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
5741c2c66affSColin Finck
5742c2c66affSColin Finck access = get_obj_access(dup);
5743c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
5744c2c66affSColin Finck
5745c2c66affSColin Finck CloseHandle(dup);
5746c2c66affSColin Finck
5747c2c66affSColin Finck SetLastError(0xdeadbeef);
5748c2c66affSColin Finck dup = OpenMutexA(0, FALSE, "WineTestMutex");
5749c2c66affSColin Finck todo_wine
5750c2c66affSColin Finck ok(!dup, "OpenMutex should fail\n");
5751c2c66affSColin Finck todo_wine
5752c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError());
5753c2c66affSColin Finck }
5754c2c66affSColin Finck
5755c2c66affSColin Finck test_default_handle_security(token, mutex, &mapping);
5756c2c66affSColin Finck
5757c2c66affSColin Finck CloseHandle (mutex);
5758c2c66affSColin Finck }
5759c2c66affSColin Finck
test_event_security(HANDLE token)5760c2c66affSColin Finck static void test_event_security(HANDLE token)
5761c2c66affSColin Finck {
5762c2c66affSColin Finck DWORD ret, i, access;
5763c2c66affSColin Finck HANDLE event, dup;
5764c2c66affSColin Finck GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | EVENT_QUERY_STATE | SYNCHRONIZE,
5765c2c66affSColin Finck STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE | SYNCHRONIZE,
5766c2c66affSColin Finck STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
5767c2c66affSColin Finck STANDARD_RIGHTS_ALL | EVENT_ALL_ACCESS };
5768c2c66affSColin Finck static const struct
5769c2c66affSColin Finck {
5770c2c66affSColin Finck int generic, mapped;
5771c2c66affSColin Finck } map[] =
5772c2c66affSColin Finck {
5773c2c66affSColin Finck { 0, 0 },
5774c2c66affSColin Finck { GENERIC_READ, STANDARD_RIGHTS_READ | EVENT_QUERY_STATE },
5775c2c66affSColin Finck { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE },
5776c2c66affSColin Finck { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
5777c2c66affSColin Finck { GENERIC_ALL, STANDARD_RIGHTS_ALL | EVENT_QUERY_STATE | EVENT_MODIFY_STATE }
5778c2c66affSColin Finck };
5779c2c66affSColin Finck
5780c2c66affSColin Finck SetLastError(0xdeadbeef);
5781c2c66affSColin Finck event = OpenEventA(0, FALSE, "WineTestEvent");
5782c2c66affSColin Finck ok(!event, "event should not exist\n");
5783c2c66affSColin Finck ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
5784c2c66affSColin Finck
5785c2c66affSColin Finck SetLastError(0xdeadbeef);
5786c2c66affSColin Finck event = CreateEventA(NULL, FALSE, FALSE, "WineTestEvent");
5787c2c66affSColin Finck ok(event != 0, "CreateEvent error %d\n", GetLastError());
5788c2c66affSColin Finck
5789c2c66affSColin Finck access = get_obj_access(event);
5790c2c66affSColin Finck ok(access == EVENT_ALL_ACCESS, "expected EVENT_ALL_ACCESS, got %#x\n", access);
5791c2c66affSColin Finck
5792c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
5793c2c66affSColin Finck {
5794c2c66affSColin Finck SetLastError( 0xdeadbeef );
5795c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), event, GetCurrentProcess(), &dup,
5796c2c66affSColin Finck map[i].generic, FALSE, 0);
5797c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
5798c2c66affSColin Finck
5799c2c66affSColin Finck access = get_obj_access(dup);
5800c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
5801c2c66affSColin Finck
5802c2c66affSColin Finck CloseHandle(dup);
5803c2c66affSColin Finck
5804c2c66affSColin Finck SetLastError(0xdeadbeef);
5805c2c66affSColin Finck dup = OpenEventA(0, FALSE, "WineTestEvent");
5806c2c66affSColin Finck todo_wine
5807c2c66affSColin Finck ok(!dup, "OpenEvent should fail\n");
5808c2c66affSColin Finck todo_wine
5809c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError());
5810c2c66affSColin Finck }
5811c2c66affSColin Finck
5812c2c66affSColin Finck test_default_handle_security(token, event, &mapping);
5813c2c66affSColin Finck
5814c2c66affSColin Finck CloseHandle(event);
5815c2c66affSColin Finck }
5816c2c66affSColin Finck
test_semaphore_security(HANDLE token)5817c2c66affSColin Finck static void test_semaphore_security(HANDLE token)
5818c2c66affSColin Finck {
5819c2c66affSColin Finck DWORD ret, i, access;
5820c2c66affSColin Finck HANDLE sem, dup;
5821c2c66affSColin Finck GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE,
5822c2c66affSColin Finck STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE,
5823c2c66affSColin Finck STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
5824c2c66affSColin Finck STANDARD_RIGHTS_ALL | SEMAPHORE_ALL_ACCESS };
5825c2c66affSColin Finck static const struct
5826c2c66affSColin Finck {
5827c2c66affSColin Finck int generic, mapped;
5828c2c66affSColin Finck } map[] =
5829c2c66affSColin Finck {
5830c2c66affSColin Finck { 0, 0 },
5831c2c66affSColin Finck { GENERIC_READ, STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE },
5832c2c66affSColin Finck { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE },
5833c2c66affSColin Finck { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
5834c2c66affSColin Finck { GENERIC_ALL, STANDARD_RIGHTS_ALL | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE }
5835c2c66affSColin Finck };
5836c2c66affSColin Finck
5837c2c66affSColin Finck SetLastError(0xdeadbeef);
5838c2c66affSColin Finck sem = OpenSemaphoreA(0, FALSE, "WineTestSemaphore");
5839c2c66affSColin Finck ok(!sem, "semaphore should not exist\n");
5840c2c66affSColin Finck ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
5841c2c66affSColin Finck
5842c2c66affSColin Finck SetLastError(0xdeadbeef);
5843c2c66affSColin Finck sem = CreateSemaphoreA(NULL, 0, 10, "WineTestSemaphore");
5844c2c66affSColin Finck ok(sem != 0, "CreateSemaphore error %d\n", GetLastError());
5845c2c66affSColin Finck
5846c2c66affSColin Finck access = get_obj_access(sem);
5847c2c66affSColin Finck ok(access == SEMAPHORE_ALL_ACCESS, "expected SEMAPHORE_ALL_ACCESS, got %#x\n", access);
5848c2c66affSColin Finck
5849c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
5850c2c66affSColin Finck {
5851c2c66affSColin Finck SetLastError( 0xdeadbeef );
5852c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), sem, GetCurrentProcess(), &dup,
5853c2c66affSColin Finck map[i].generic, FALSE, 0);
5854c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
5855c2c66affSColin Finck
5856c2c66affSColin Finck access = get_obj_access(dup);
5857c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
5858c2c66affSColin Finck
5859c2c66affSColin Finck CloseHandle(dup);
5860c2c66affSColin Finck }
5861c2c66affSColin Finck
5862c2c66affSColin Finck test_default_handle_security(token, sem, &mapping);
5863c2c66affSColin Finck
5864c2c66affSColin Finck CloseHandle(sem);
5865c2c66affSColin Finck }
5866c2c66affSColin Finck
5867c2c66affSColin Finck #define WINE_TEST_PIPE "\\\\.\\pipe\\WineTestPipe"
test_named_pipe_security(HANDLE token)5868c2c66affSColin Finck static void test_named_pipe_security(HANDLE token)
5869c2c66affSColin Finck {
5870c2c66affSColin Finck DWORD ret, i, access;
5871c2c66affSColin Finck HANDLE pipe, file, dup;
5872c2c66affSColin Finck GENERIC_MAPPING mapping = { FILE_GENERIC_READ,
5873c2c66affSColin Finck FILE_GENERIC_WRITE,
5874c2c66affSColin Finck FILE_GENERIC_EXECUTE,
5875c2c66affSColin Finck STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS };
5876c2c66affSColin Finck static const struct
5877c2c66affSColin Finck {
5878c2c66affSColin Finck int todo, generic, mapped;
5879c2c66affSColin Finck } map[] =
5880c2c66affSColin Finck {
5881c2c66affSColin Finck { 0, 0, 0 },
5882c2c66affSColin Finck { 1, GENERIC_READ, FILE_GENERIC_READ },
5883c2c66affSColin Finck { 1, GENERIC_WRITE, FILE_GENERIC_WRITE },
5884c2c66affSColin Finck { 1, GENERIC_EXECUTE, FILE_GENERIC_EXECUTE },
5885c2c66affSColin Finck { 1, GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }
5886c2c66affSColin Finck };
5887c2c66affSColin Finck static const struct
5888c2c66affSColin Finck {
5889c2c66affSColin Finck DWORD open_mode;
5890c2c66affSColin Finck DWORD access;
5891c2c66affSColin Finck } creation_access[] =
5892c2c66affSColin Finck {
5893c2c66affSColin Finck { PIPE_ACCESS_INBOUND, FILE_GENERIC_READ },
5894c2c66affSColin Finck { PIPE_ACCESS_OUTBOUND, FILE_GENERIC_WRITE },
5895c2c66affSColin Finck { PIPE_ACCESS_DUPLEX, FILE_GENERIC_READ|FILE_GENERIC_WRITE },
5896c2c66affSColin Finck { PIPE_ACCESS_INBOUND|WRITE_DAC, FILE_GENERIC_READ|WRITE_DAC },
5897c2c66affSColin Finck { PIPE_ACCESS_INBOUND|WRITE_OWNER, FILE_GENERIC_READ|WRITE_OWNER }
5898c2c66affSColin Finck /* ACCESS_SYSTEM_SECURITY is also valid, but will fail with ERROR_PRIVILEGE_NOT_HELD */
5899c2c66affSColin Finck };
5900c2c66affSColin Finck
5901c2c66affSColin Finck /* Test the different security access options for pipes */
5902c2c66affSColin Finck for (i = 0; i < sizeof(creation_access)/sizeof(creation_access[0]); i++)
5903c2c66affSColin Finck {
5904c2c66affSColin Finck SetLastError(0xdeadbeef);
5905c2c66affSColin Finck pipe = CreateNamedPipeA(WINE_TEST_PIPE, creation_access[i].open_mode,
5906c2c66affSColin Finck PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 0, 0,
5907c2c66affSColin Finck NMPWAIT_USE_DEFAULT_WAIT, NULL);
5908c2c66affSColin Finck ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe(0x%x) error %d\n",
5909c2c66affSColin Finck creation_access[i].open_mode, GetLastError());
5910c2c66affSColin Finck access = get_obj_access(pipe);
5911c2c66affSColin Finck ok(access == creation_access[i].access,
5912c2c66affSColin Finck "CreateNamedPipeA(0x%x) pipe expected access 0x%x (got 0x%x)\n",
5913c2c66affSColin Finck creation_access[i].open_mode, creation_access[i].access, access);
5914c2c66affSColin Finck CloseHandle(pipe);
5915c2c66affSColin Finck }
5916c2c66affSColin Finck
5917c2c66affSColin Finck SetLastError(0xdeadbeef);
5918c2c66affSColin Finck pipe = CreateNamedPipeA(WINE_TEST_PIPE, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
5919c2c66affSColin Finck PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES,
5920c2c66affSColin Finck 0, 0, NMPWAIT_USE_DEFAULT_WAIT, NULL);
5921c2c66affSColin Finck ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe error %d\n", GetLastError());
5922c2c66affSColin Finck
5923c2c66affSColin Finck test_default_handle_security(token, pipe, &mapping);
5924c2c66affSColin Finck
5925c2c66affSColin Finck SetLastError(0xdeadbeef);
5926c2c66affSColin Finck file = CreateFileA(WINE_TEST_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0);
5927c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
5928c2c66affSColin Finck
5929c2c66affSColin Finck access = get_obj_access(file);
5930c2c66affSColin Finck ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access);
5931c2c66affSColin Finck
5932c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
5933c2c66affSColin Finck {
5934c2c66affSColin Finck SetLastError( 0xdeadbeef );
5935c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5936c2c66affSColin Finck map[i].generic, FALSE, 0);
5937c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
5938c2c66affSColin Finck
5939c2c66affSColin Finck access = get_obj_access(dup);
5940c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
5941c2c66affSColin Finck
5942c2c66affSColin Finck CloseHandle(dup);
5943c2c66affSColin Finck }
5944c2c66affSColin Finck
5945c2c66affSColin Finck CloseHandle(file);
5946c2c66affSColin Finck CloseHandle(pipe);
5947c2c66affSColin Finck
5948c2c66affSColin Finck SetLastError(0xdeadbeef);
5949c2c66affSColin Finck file = CreateFileA("\\\\.\\pipe\\", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
5950c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE || broken(file == INVALID_HANDLE_VALUE) /* before Vista */, "CreateFile error %d\n", GetLastError());
5951c2c66affSColin Finck
5952c2c66affSColin Finck if (file != INVALID_HANDLE_VALUE)
5953c2c66affSColin Finck {
5954c2c66affSColin Finck access = get_obj_access(file);
5955c2c66affSColin Finck ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access);
5956c2c66affSColin Finck
5957c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
5958c2c66affSColin Finck {
5959c2c66affSColin Finck SetLastError( 0xdeadbeef );
5960c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5961c2c66affSColin Finck map[i].generic, FALSE, 0);
5962c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
5963c2c66affSColin Finck
5964c2c66affSColin Finck access = get_obj_access(dup);
5965c2c66affSColin Finck todo_wine_if (map[i].todo)
5966c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
5967c2c66affSColin Finck
5968c2c66affSColin Finck CloseHandle(dup);
5969c2c66affSColin Finck }
5970c2c66affSColin Finck }
5971c2c66affSColin Finck
5972c2c66affSColin Finck CloseHandle(file);
5973c2c66affSColin Finck }
5974c2c66affSColin Finck
test_file_security(HANDLE token)5975c2c66affSColin Finck static void test_file_security(HANDLE token)
5976c2c66affSColin Finck {
5977c2c66affSColin Finck DWORD ret, i, access, bytes;
5978c2c66affSColin Finck HANDLE file, dup;
5979c2c66affSColin Finck static const struct
5980c2c66affSColin Finck {
5981c2c66affSColin Finck int generic, mapped;
5982c2c66affSColin Finck } map[] =
5983c2c66affSColin Finck {
5984c2c66affSColin Finck { 0, 0 },
5985c2c66affSColin Finck { GENERIC_READ, FILE_GENERIC_READ },
5986c2c66affSColin Finck { GENERIC_WRITE, FILE_GENERIC_WRITE },
5987c2c66affSColin Finck { GENERIC_EXECUTE, FILE_GENERIC_EXECUTE },
5988c2c66affSColin Finck { GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }
5989c2c66affSColin Finck };
5990c2c66affSColin Finck char temp_path[MAX_PATH];
5991c2c66affSColin Finck char file_name[MAX_PATH];
5992c2c66affSColin Finck char buf[16];
5993c2c66affSColin Finck
5994c2c66affSColin Finck GetTempPathA(MAX_PATH, temp_path);
5995c2c66affSColin Finck GetTempFileNameA(temp_path, "tmp", 0, file_name);
5996c2c66affSColin Finck
5997c2c66affSColin Finck /* file */
5998c2c66affSColin Finck SetLastError(0xdeadbeef);
5999c2c66affSColin Finck file = CreateFileA(file_name, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, 0, NULL);
6000c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
6001c2c66affSColin Finck
6002c2c66affSColin Finck access = get_obj_access(file);
6003c2c66affSColin Finck ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access);
6004c2c66affSColin Finck
6005c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
6006c2c66affSColin Finck {
6007c2c66affSColin Finck SetLastError( 0xdeadbeef );
6008c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
6009c2c66affSColin Finck map[i].generic, FALSE, 0);
6010c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
6011c2c66affSColin Finck
6012c2c66affSColin Finck access = get_obj_access(dup);
6013c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6014c2c66affSColin Finck
6015c2c66affSColin Finck CloseHandle(dup);
6016c2c66affSColin Finck }
6017c2c66affSColin Finck
6018c2c66affSColin Finck CloseHandle(file);
6019c2c66affSColin Finck
6020c2c66affSColin Finck SetLastError(0xdeadbeef);
6021c2c66affSColin Finck file = CreateFileA(file_name, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
6022c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
6023c2c66affSColin Finck
6024c2c66affSColin Finck access = get_obj_access(file);
6025c2c66affSColin Finck todo_wine
6026c2c66affSColin Finck ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#x\n", access);
6027c2c66affSColin Finck
6028c2c66affSColin Finck bytes = 0xdeadbeef;
6029c2c66affSColin Finck SetLastError(0xdeadbeef);
6030c2c66affSColin Finck ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL);
6031c2c66affSColin Finck ok(!ret, "ReadFile should fail\n");
6032c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
6033c2c66affSColin Finck ok(bytes == 0, "expected 0, got %u\n", bytes);
6034c2c66affSColin Finck
6035c2c66affSColin Finck CloseHandle(file);
6036c2c66affSColin Finck
6037c2c66affSColin Finck SetLastError(0xdeadbeef);
6038c2c66affSColin Finck file = CreateFileA(file_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
6039c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
6040c2c66affSColin Finck
6041c2c66affSColin Finck access = get_obj_access(file);
6042c2c66affSColin Finck todo_wine
6043c2c66affSColin Finck ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#x\n", access);
6044c2c66affSColin Finck
6045c2c66affSColin Finck bytes = 0xdeadbeef;
6046c2c66affSColin Finck SetLastError(0xdeadbeef);
6047c2c66affSColin Finck ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL);
6048c2c66affSColin Finck ok(!ret, "ReadFile should fail\n");
6049c2c66affSColin Finck ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
6050c2c66affSColin Finck ok(bytes == 0, "expected 0, got %u\n", bytes);
6051c2c66affSColin Finck
6052c2c66affSColin Finck CloseHandle(file);
6053c2c66affSColin Finck DeleteFileA(file_name);
6054c2c66affSColin Finck
6055c2c66affSColin Finck /* directory */
6056c2c66affSColin Finck SetLastError(0xdeadbeef);
6057c2c66affSColin Finck file = CreateFileA(temp_path, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
6058c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
6059c2c66affSColin Finck
6060c2c66affSColin Finck access = get_obj_access(file);
6061c2c66affSColin Finck ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access);
6062c2c66affSColin Finck
6063c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
6064c2c66affSColin Finck {
6065c2c66affSColin Finck SetLastError( 0xdeadbeef );
6066c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
6067c2c66affSColin Finck map[i].generic, FALSE, 0);
6068c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
6069c2c66affSColin Finck
6070c2c66affSColin Finck access = get_obj_access(dup);
6071c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6072c2c66affSColin Finck
6073c2c66affSColin Finck CloseHandle(dup);
6074c2c66affSColin Finck }
6075c2c66affSColin Finck
6076c2c66affSColin Finck CloseHandle(file);
6077c2c66affSColin Finck
6078c2c66affSColin Finck SetLastError(0xdeadbeef);
6079c2c66affSColin Finck file = CreateFileA(temp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
6080c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
6081c2c66affSColin Finck
6082c2c66affSColin Finck access = get_obj_access(file);
6083c2c66affSColin Finck todo_wine
6084c2c66affSColin Finck ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#x\n", access);
6085c2c66affSColin Finck
6086c2c66affSColin Finck CloseHandle(file);
6087c2c66affSColin Finck
6088c2c66affSColin Finck SetLastError(0xdeadbeef);
6089c2c66affSColin Finck file = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
6090c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
6091c2c66affSColin Finck
6092c2c66affSColin Finck access = get_obj_access(file);
6093c2c66affSColin Finck todo_wine
6094c2c66affSColin Finck ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#x\n", access);
6095c2c66affSColin Finck
6096c2c66affSColin Finck CloseHandle(file);
6097c2c66affSColin Finck }
6098c2c66affSColin Finck
test_filemap_security(void)6099c2c66affSColin Finck static void test_filemap_security(void)
6100c2c66affSColin Finck {
6101c2c66affSColin Finck char temp_path[MAX_PATH];
6102c2c66affSColin Finck char file_name[MAX_PATH];
6103c2c66affSColin Finck DWORD ret, i, access;
6104c2c66affSColin Finck HANDLE file, mapping, dup, created_mapping;
6105c2c66affSColin Finck static const struct
6106c2c66affSColin Finck {
6107c2c66affSColin Finck int generic, mapped;
6108c2c66affSColin Finck BOOL open_only;
6109c2c66affSColin Finck } map[] =
6110c2c66affSColin Finck {
6111c2c66affSColin Finck { 0, 0 },
6112c2c66affSColin Finck { GENERIC_READ, STANDARD_RIGHTS_READ | SECTION_QUERY | SECTION_MAP_READ },
6113c2c66affSColin Finck { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE },
6114c2c66affSColin Finck { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE },
6115c2c66affSColin Finck { GENERIC_ALL, STANDARD_RIGHTS_REQUIRED | SECTION_ALL_ACCESS },
6116c2c66affSColin Finck { SECTION_MAP_READ | SECTION_MAP_WRITE, SECTION_MAP_READ | SECTION_MAP_WRITE },
6117c2c66affSColin Finck { SECTION_MAP_WRITE, SECTION_MAP_WRITE },
6118c2c66affSColin Finck { SECTION_MAP_READ | SECTION_QUERY, SECTION_MAP_READ | SECTION_QUERY },
6119c2c66affSColin Finck { SECTION_QUERY, SECTION_MAP_READ, TRUE },
6120c2c66affSColin Finck { SECTION_QUERY | SECTION_MAP_READ, SECTION_QUERY | SECTION_MAP_READ }
6121c2c66affSColin Finck };
6122c2c66affSColin Finck static const struct
6123c2c66affSColin Finck {
6124c2c66affSColin Finck int prot, mapped;
6125c2c66affSColin Finck } prot_map[] =
6126c2c66affSColin Finck {
6127c2c66affSColin Finck { 0, 0 },
6128c2c66affSColin Finck { PAGE_NOACCESS, 0 },
6129c2c66affSColin Finck { PAGE_READONLY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ },
6130c2c66affSColin Finck { PAGE_READWRITE, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE },
6131c2c66affSColin Finck { PAGE_WRITECOPY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ },
6132c2c66affSColin Finck { PAGE_EXECUTE, 0 },
6133c2c66affSColin Finck { PAGE_EXECUTE_READ, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE },
6134c2c66affSColin Finck { PAGE_EXECUTE_READWRITE, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE },
6135c2c66affSColin Finck { PAGE_EXECUTE_WRITECOPY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE }
6136c2c66affSColin Finck };
6137c2c66affSColin Finck
6138c2c66affSColin Finck GetTempPathA(MAX_PATH, temp_path);
6139c2c66affSColin Finck GetTempFileNameA(temp_path, "tmp", 0, file_name);
6140c2c66affSColin Finck
6141c2c66affSColin Finck SetLastError(0xdeadbeef);
6142c2c66affSColin Finck file = CreateFileA(file_name, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, NULL, CREATE_ALWAYS, 0, 0);
6143c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
6144c2c66affSColin Finck SetFilePointer(file, 4096, NULL, FILE_BEGIN);
6145c2c66affSColin Finck SetEndOfFile(file);
6146c2c66affSColin Finck
6147c2c66affSColin Finck for (i = 0; i < sizeof(prot_map)/sizeof(prot_map[0]); i++)
6148c2c66affSColin Finck {
6149c2c66affSColin Finck if (map[i].open_only) continue;
6150c2c66affSColin Finck
6151c2c66affSColin Finck SetLastError(0xdeadbeef);
6152c2c66affSColin Finck mapping = CreateFileMappingW(file, NULL, prot_map[i].prot, 0, 4096, NULL);
6153c2c66affSColin Finck if (prot_map[i].mapped)
6154c2c66affSColin Finck {
6155c2c66affSColin Finck if (!mapping)
6156c2c66affSColin Finck {
6157c2c66affSColin Finck /* NT4 and win2k don't support EXEC on file mappings */
6158c2c66affSColin Finck if (prot_map[i].prot == PAGE_EXECUTE_READ || prot_map[i].prot == PAGE_EXECUTE_READWRITE || prot_map[i].prot == PAGE_EXECUTE_WRITECOPY)
6159c2c66affSColin Finck {
6160c2c66affSColin Finck win_skip("CreateFileMapping doesn't support PAGE_EXECUTE protection\n");
6161c2c66affSColin Finck continue;
6162c2c66affSColin Finck }
6163c2c66affSColin Finck }
6164c2c66affSColin Finck ok(mapping != 0, "CreateFileMapping(%04x) error %d\n", prot_map[i].prot, GetLastError());
6165c2c66affSColin Finck }
6166c2c66affSColin Finck else
6167c2c66affSColin Finck {
6168c2c66affSColin Finck ok(!mapping, "CreateFileMapping(%04x) should fail\n", prot_map[i].prot);
6169c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
6170c2c66affSColin Finck continue;
6171c2c66affSColin Finck }
6172c2c66affSColin Finck
6173c2c66affSColin Finck access = get_obj_access(mapping);
6174c2c66affSColin Finck ok(access == prot_map[i].mapped, "%d: expected %#x, got %#x\n", i, prot_map[i].mapped, access);
6175c2c66affSColin Finck
6176c2c66affSColin Finck CloseHandle(mapping);
6177c2c66affSColin Finck }
6178c2c66affSColin Finck
6179c2c66affSColin Finck SetLastError(0xdeadbeef);
6180c2c66affSColin Finck mapping = CreateFileMappingW(file, NULL, PAGE_EXECUTE_READWRITE, 0, 4096, NULL);
6181c2c66affSColin Finck if (!mapping)
6182c2c66affSColin Finck {
6183c2c66affSColin Finck /* NT4 and win2k don't support EXEC on file mappings */
6184c2c66affSColin Finck win_skip("CreateFileMapping doesn't support PAGE_EXECUTE protection\n");
6185c2c66affSColin Finck CloseHandle(file);
6186c2c66affSColin Finck DeleteFileA(file_name);
6187c2c66affSColin Finck return;
6188c2c66affSColin Finck }
6189c2c66affSColin Finck ok(mapping != 0, "CreateFileMapping error %d\n", GetLastError());
6190c2c66affSColin Finck
6191c2c66affSColin Finck access = get_obj_access(mapping);
6192c2c66affSColin Finck ok(access == (STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE),
6193c2c66affSColin Finck "expected STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, got %#x\n", access);
6194c2c66affSColin Finck
6195c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
6196c2c66affSColin Finck {
6197c2c66affSColin Finck if (map[i].open_only) continue;
6198c2c66affSColin Finck
6199c2c66affSColin Finck SetLastError( 0xdeadbeef );
6200c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), mapping, GetCurrentProcess(), &dup,
6201c2c66affSColin Finck map[i].generic, FALSE, 0);
6202c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
6203c2c66affSColin Finck
6204c2c66affSColin Finck access = get_obj_access(dup);
6205c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6206c2c66affSColin Finck
6207c2c66affSColin Finck CloseHandle(dup);
6208c2c66affSColin Finck }
6209c2c66affSColin Finck
6210c2c66affSColin Finck CloseHandle(mapping);
6211c2c66affSColin Finck CloseHandle(file);
6212c2c66affSColin Finck DeleteFileA(file_name);
6213c2c66affSColin Finck
6214c2c66affSColin Finck created_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000,
6215c2c66affSColin Finck "Wine Test Open Mapping");
6216c2c66affSColin Finck ok(created_mapping != NULL, "CreateFileMapping failed with error %u\n", GetLastError());
6217c2c66affSColin Finck
6218c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
6219c2c66affSColin Finck {
6220c2c66affSColin Finck if (!map[i].generic) continue;
6221c2c66affSColin Finck
6222c2c66affSColin Finck mapping = OpenFileMappingA(map[i].generic, FALSE, "Wine Test Open Mapping");
6223c2c66affSColin Finck ok(mapping != NULL, "OpenFileMapping failed with error %d\n", GetLastError());
6224c2c66affSColin Finck access = get_obj_access(mapping);
6225c2c66affSColin Finck ok(access == map[i].mapped, "%d: unexpected access flags %#x, expected %#x\n",
6226c2c66affSColin Finck i, access, map[i].mapped);
6227c2c66affSColin Finck CloseHandle(mapping);
6228c2c66affSColin Finck }
6229c2c66affSColin Finck
6230c2c66affSColin Finck CloseHandle(created_mapping);
6231c2c66affSColin Finck }
6232c2c66affSColin Finck
test_thread_security(void)6233c2c66affSColin Finck static void test_thread_security(void)
6234c2c66affSColin Finck {
6235c2c66affSColin Finck DWORD ret, i, access;
6236c2c66affSColin Finck HANDLE thread, dup;
6237c2c66affSColin Finck static const struct
6238c2c66affSColin Finck {
6239c2c66affSColin Finck int generic, mapped;
6240c2c66affSColin Finck } map[] =
6241c2c66affSColin Finck {
6242c2c66affSColin Finck { 0, 0 },
6243c2c66affSColin Finck { GENERIC_READ, STANDARD_RIGHTS_READ | THREAD_QUERY_INFORMATION | THREAD_GET_CONTEXT },
6244c2c66affSColin Finck { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT | THREAD_TERMINATE | THREAD_SUSPEND_RESUME | 0x4 },
6245c2c66affSColin Finck { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
6246c2c66affSColin Finck { GENERIC_ALL, THREAD_ALL_ACCESS_NT4 }
6247c2c66affSColin Finck };
6248c2c66affSColin Finck
6249c2c66affSColin Finck SetLastError(0xdeadbeef);
6250c2c66affSColin Finck thread = CreateThread(NULL, 0, (void *)0xdeadbeef, NULL, CREATE_SUSPENDED, &ret);
6251c2c66affSColin Finck ok(thread != 0, "CreateThread error %d\n", GetLastError());
6252c2c66affSColin Finck
6253c2c66affSColin Finck access = get_obj_access(thread);
6254c2c66affSColin Finck ok(access == THREAD_ALL_ACCESS_NT4 || access == THREAD_ALL_ACCESS_VISTA, "expected THREAD_ALL_ACCESS, got %#x\n", access);
6255c2c66affSColin Finck
6256c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
6257c2c66affSColin Finck {
6258c2c66affSColin Finck SetLastError( 0xdeadbeef );
6259c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup,
6260c2c66affSColin Finck map[i].generic, FALSE, 0);
6261c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
6262c2c66affSColin Finck
6263c2c66affSColin Finck access = get_obj_access(dup);
6264c2c66affSColin Finck switch (map[i].generic)
6265c2c66affSColin Finck {
6266c2c66affSColin Finck case GENERIC_READ:
6267c2c66affSColin Finck case GENERIC_EXECUTE:
6268c2c66affSColin Finck ok(access == map[i].mapped ||
6269c2c66affSColin Finck access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ ||
6270c2c66affSColin Finck access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */,
6271c2c66affSColin Finck "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6272c2c66affSColin Finck break;
6273c2c66affSColin Finck case GENERIC_WRITE:
6274c2c66affSColin Finck todo_wine
6275c2c66affSColin Finck ok(access == map[i].mapped ||
6276c2c66affSColin Finck access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION) /* Vista+ */ ||
6277c2c66affSColin Finck access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */,
6278c2c66affSColin Finck "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6279c2c66affSColin Finck break;
6280c2c66affSColin Finck case GENERIC_ALL:
6281c2c66affSColin Finck ok(access == map[i].mapped || access == THREAD_ALL_ACCESS_VISTA,
6282c2c66affSColin Finck "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6283c2c66affSColin Finck break;
6284c2c66affSColin Finck default:
6285c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6286c2c66affSColin Finck break;
6287c2c66affSColin Finck }
6288c2c66affSColin Finck
6289c2c66affSColin Finck CloseHandle(dup);
6290c2c66affSColin Finck }
6291c2c66affSColin Finck
6292c2c66affSColin Finck SetLastError( 0xdeadbeef );
6293c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup,
6294c2c66affSColin Finck THREAD_QUERY_INFORMATION, FALSE, 0);
6295c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
6296c2c66affSColin Finck access = get_obj_access(dup);
6297c2c66affSColin Finck ok(access == (THREAD_QUERY_INFORMATION | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ ||
6298c2c66affSColin Finck access == THREAD_QUERY_INFORMATION /* before Vista */,
6299c2c66affSColin Finck "expected THREAD_QUERY_INFORMATION|THREAD_QUERY_LIMITED_INFORMATION, got %#x\n", access);
6300c2c66affSColin Finck CloseHandle(dup);
6301c2c66affSColin Finck
6302c2c66affSColin Finck TerminateThread(thread, 0);
6303c2c66affSColin Finck CloseHandle(thread);
6304c2c66affSColin Finck }
6305c2c66affSColin Finck
test_process_access(void)6306c2c66affSColin Finck static void test_process_access(void)
6307c2c66affSColin Finck {
6308c2c66affSColin Finck DWORD ret, i, access;
6309c2c66affSColin Finck HANDLE process, dup;
6310c2c66affSColin Finck STARTUPINFOA sti;
6311c2c66affSColin Finck PROCESS_INFORMATION pi;
6312c2c66affSColin Finck char cmdline[] = "winver.exe";
6313c2c66affSColin Finck static const struct
6314c2c66affSColin Finck {
6315c2c66affSColin Finck int generic, mapped;
6316c2c66affSColin Finck } map[] =
6317c2c66affSColin Finck {
6318c2c66affSColin Finck { 0, 0 },
6319c2c66affSColin Finck { GENERIC_READ, STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ },
6320c2c66affSColin Finck { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME |
6321c2c66affSColin Finck PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION },
6322c2c66affSColin Finck { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
6323c2c66affSColin Finck { GENERIC_ALL, PROCESS_ALL_ACCESS_NT4 }
6324c2c66affSColin Finck };
6325c2c66affSColin Finck
6326c2c66affSColin Finck memset(&sti, 0, sizeof(sti));
6327c2c66affSColin Finck sti.cb = sizeof(sti);
6328c2c66affSColin Finck SetLastError(0xdeadbeef);
6329c2c66affSColin Finck ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sti, &pi);
6330c2c66affSColin Finck ok(ret, "CreateProcess() error %d\n", GetLastError());
6331c2c66affSColin Finck
6332c2c66affSColin Finck CloseHandle(pi.hThread);
6333c2c66affSColin Finck process = pi.hProcess;
6334c2c66affSColin Finck
6335c2c66affSColin Finck access = get_obj_access(process);
6336c2c66affSColin Finck ok(access == PROCESS_ALL_ACCESS_NT4 || access == PROCESS_ALL_ACCESS_VISTA, "expected PROCESS_ALL_ACCESS, got %#x\n", access);
6337c2c66affSColin Finck
6338c2c66affSColin Finck for (i = 0; i < sizeof(map)/sizeof(map[0]); i++)
6339c2c66affSColin Finck {
6340c2c66affSColin Finck SetLastError( 0xdeadbeef );
6341c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6342c2c66affSColin Finck map[i].generic, FALSE, 0);
6343c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
6344c2c66affSColin Finck
6345c2c66affSColin Finck access = get_obj_access(dup);
6346c2c66affSColin Finck switch (map[i].generic)
6347c2c66affSColin Finck {
6348c2c66affSColin Finck case GENERIC_READ:
6349c2c66affSColin Finck ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */,
6350c2c66affSColin Finck "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6351c2c66affSColin Finck break;
6352c2c66affSColin Finck case GENERIC_WRITE:
6353c2c66affSColin Finck ok(access == map[i].mapped ||
6354c2c66affSColin Finck access == (map[i].mapped | PROCESS_TERMINATE) /* before Vista */ ||
6355561bed7bSAmine Khaldi access == (map[i].mapped | PROCESS_SET_LIMITED_INFORMATION) /* win8 */ ||
6356561bed7bSAmine Khaldi access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SET_LIMITED_INFORMATION) /* Win10 Anniversary Update */,
6357c2c66affSColin Finck "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6358c2c66affSColin Finck break;
6359c2c66affSColin Finck case GENERIC_EXECUTE:
6360c2c66affSColin Finck ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE) /* Vista+ */,
6361c2c66affSColin Finck "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6362c2c66affSColin Finck break;
6363c2c66affSColin Finck case GENERIC_ALL:
6364c2c66affSColin Finck ok(access == map[i].mapped || access == PROCESS_ALL_ACCESS_VISTA,
6365c2c66affSColin Finck "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6366c2c66affSColin Finck break;
6367c2c66affSColin Finck default:
6368c2c66affSColin Finck ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
6369c2c66affSColin Finck break;
6370c2c66affSColin Finck }
6371c2c66affSColin Finck
6372c2c66affSColin Finck CloseHandle(dup);
6373c2c66affSColin Finck }
6374c2c66affSColin Finck
6375c2c66affSColin Finck SetLastError( 0xdeadbeef );
6376c2c66affSColin Finck ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6377c2c66affSColin Finck PROCESS_QUERY_INFORMATION, FALSE, 0);
6378c2c66affSColin Finck ok(ret, "DuplicateHandle error %d\n", GetLastError());
6379c2c66affSColin Finck access = get_obj_access(dup);
6380c2c66affSColin Finck ok(access == (PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */ ||
6381c2c66affSColin Finck access == PROCESS_QUERY_INFORMATION /* before Vista */,
6382c2c66affSColin Finck "expected PROCESS_QUERY_INFORMATION|PROCESS_QUERY_LIMITED_INFORMATION, got %#x\n", access);
6383c2c66affSColin Finck CloseHandle(dup);
6384c2c66affSColin Finck
6385c2c66affSColin Finck TerminateProcess(process, 0);
6386c2c66affSColin Finck CloseHandle(process);
6387c2c66affSColin Finck }
6388c2c66affSColin Finck
validate_impersonation_token(HANDLE token,DWORD * token_type)6389c2c66affSColin Finck static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type)
6390c2c66affSColin Finck {
6391c2c66affSColin Finck DWORD ret, needed;
6392c2c66affSColin Finck TOKEN_TYPE type;
6393c2c66affSColin Finck SECURITY_IMPERSONATION_LEVEL sil;
6394c2c66affSColin Finck
6395c2c66affSColin Finck type = 0xdeadbeef;
6396c2c66affSColin Finck needed = 0;
6397c2c66affSColin Finck SetLastError(0xdeadbeef);
6398c2c66affSColin Finck ret = GetTokenInformation(token, TokenType, &type, sizeof(type), &needed);
6399c2c66affSColin Finck ok(ret, "GetTokenInformation error %d\n", GetLastError());
6400c2c66affSColin Finck ok(needed == sizeof(type), "GetTokenInformation should return required buffer length\n");
6401c2c66affSColin Finck ok(type == TokenPrimary || type == TokenImpersonation, "expected TokenPrimary or TokenImpersonation, got %d\n", type);
6402c2c66affSColin Finck
6403c2c66affSColin Finck *token_type = type;
6404c2c66affSColin Finck if (type != TokenImpersonation) return FALSE;
6405c2c66affSColin Finck
6406c2c66affSColin Finck needed = 0;
6407c2c66affSColin Finck SetLastError(0xdeadbeef);
6408c2c66affSColin Finck ret = GetTokenInformation(token, TokenImpersonationLevel, &sil, sizeof(sil), &needed);
6409c2c66affSColin Finck ok(ret, "GetTokenInformation error %d\n", GetLastError());
6410c2c66affSColin Finck ok(needed == sizeof(sil), "GetTokenInformation should return required buffer length\n");
6411c2c66affSColin Finck ok(sil == SecurityImpersonation, "expected SecurityImpersonation, got %d\n", sil);
6412c2c66affSColin Finck
6413c2c66affSColin Finck needed = 0xdeadbeef;
6414c2c66affSColin Finck SetLastError(0xdeadbeef);
6415c2c66affSColin Finck ret = GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &needed);
6416c2c66affSColin Finck ok(!ret, "GetTokenInformation should fail\n");
6417c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
6418c2c66affSColin Finck ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
6419c2c66affSColin Finck ok(needed > sizeof(TOKEN_DEFAULT_DACL), "GetTokenInformation returned empty default DACL\n");
6420c2c66affSColin Finck
6421c2c66affSColin Finck needed = 0xdeadbeef;
6422c2c66affSColin Finck SetLastError(0xdeadbeef);
6423c2c66affSColin Finck ret = GetTokenInformation(token, TokenOwner, NULL, 0, &needed);
6424c2c66affSColin Finck ok(!ret, "GetTokenInformation should fail\n");
6425c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
6426c2c66affSColin Finck ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
6427c2c66affSColin Finck ok(needed > sizeof(TOKEN_OWNER), "GetTokenInformation returned empty token owner\n");
6428c2c66affSColin Finck
6429c2c66affSColin Finck needed = 0xdeadbeef;
6430c2c66affSColin Finck SetLastError(0xdeadbeef);
6431c2c66affSColin Finck ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &needed);
6432c2c66affSColin Finck ok(!ret, "GetTokenInformation should fail\n");
6433c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
6434c2c66affSColin Finck ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
6435c2c66affSColin Finck ok(needed > sizeof(TOKEN_PRIMARY_GROUP), "GetTokenInformation returned empty token primary group\n");
6436c2c66affSColin Finck
6437c2c66affSColin Finck return TRUE;
6438c2c66affSColin Finck }
6439c2c66affSColin Finck
test_kernel_objects_security(void)6440c2c66affSColin Finck static void test_kernel_objects_security(void)
6441c2c66affSColin Finck {
6442c2c66affSColin Finck HANDLE token, process_token;
6443c2c66affSColin Finck DWORD ret, token_type;
6444c2c66affSColin Finck
6445c2c66affSColin Finck ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token);
6446c2c66affSColin Finck ok(ret, "OpenProcessToken error %d\n", GetLastError());
6447c2c66affSColin Finck
6448c2c66affSColin Finck ret = validate_impersonation_token(process_token, &token_type);
6449c2c66affSColin Finck ok(token_type == TokenPrimary, "expected TokenPrimary, got %d\n", token_type);
6450c2c66affSColin Finck ok(!ret, "access token should not be an impersonation token\n");
6451c2c66affSColin Finck
6452c2c66affSColin Finck ret = DuplicateToken(process_token, SecurityImpersonation, &token);
6453c2c66affSColin Finck ok(ret, "DuplicateToken error %d\n", GetLastError());
6454c2c66affSColin Finck
6455c2c66affSColin Finck ret = validate_impersonation_token(token, &token_type);
6456c2c66affSColin Finck ok(ret, "access token should be a valid impersonation token\n");
6457c2c66affSColin Finck ok(token_type == TokenImpersonation, "expected TokenImpersonation, got %d\n", token_type);
6458c2c66affSColin Finck
6459c2c66affSColin Finck test_mutex_security(token);
6460c2c66affSColin Finck test_event_security(token);
6461c2c66affSColin Finck test_named_pipe_security(token);
6462c2c66affSColin Finck test_semaphore_security(token);
6463c2c66affSColin Finck test_file_security(token);
6464c2c66affSColin Finck test_filemap_security();
6465c2c66affSColin Finck test_thread_security();
6466c2c66affSColin Finck test_process_access();
6467c2c66affSColin Finck /* FIXME: test other kernel object types */
6468c2c66affSColin Finck
6469c2c66affSColin Finck CloseHandle(process_token);
6470c2c66affSColin Finck CloseHandle(token);
6471c2c66affSColin Finck }
6472c2c66affSColin Finck
test_TokenIntegrityLevel(void)6473c2c66affSColin Finck static void test_TokenIntegrityLevel(void)
6474c2c66affSColin Finck {
6475c2c66affSColin Finck TOKEN_MANDATORY_LABEL *tml;
6476c2c66affSColin Finck BYTE buffer[64]; /* using max. 28 byte in win7 x64 */
6477c2c66affSColin Finck HANDLE token;
6478c2c66affSColin Finck DWORD size;
6479c2c66affSColin Finck DWORD res;
6480c2c66affSColin Finck static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6481c2c66affSColin Finck {SECURITY_MANDATORY_HIGH_RID}};
6482c2c66affSColin Finck static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6483c2c66affSColin Finck {SECURITY_MANDATORY_MEDIUM_RID}};
6484c2c66affSColin Finck
6485c2c66affSColin Finck SetLastError(0xdeadbeef);
6486c2c66affSColin Finck res = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
6487c2c66affSColin Finck ok(res, "got %d with %d (expected TRUE)\n", res, GetLastError());
6488c2c66affSColin Finck
6489c2c66affSColin Finck SetLastError(0xdeadbeef);
6490c2c66affSColin Finck res = GetTokenInformation(token, TokenIntegrityLevel, buffer, sizeof(buffer), &size);
6491c2c66affSColin Finck
6492c2c66affSColin Finck /* not supported before Vista */
6493c2c66affSColin Finck if (!res && ((GetLastError() == ERROR_INVALID_PARAMETER) || GetLastError() == ERROR_INVALID_FUNCTION))
6494c2c66affSColin Finck {
6495c2c66affSColin Finck win_skip("TokenIntegrityLevel not supported\n");
6496c2c66affSColin Finck CloseHandle(token);
6497c2c66affSColin Finck return;
6498c2c66affSColin Finck }
6499c2c66affSColin Finck
6500c2c66affSColin Finck ok(res, "got %u with %u (expected TRUE)\n", res, GetLastError());
6501c2c66affSColin Finck if (!res)
6502c2c66affSColin Finck {
6503c2c66affSColin Finck CloseHandle(token);
6504c2c66affSColin Finck return;
6505c2c66affSColin Finck }
6506c2c66affSColin Finck
6507c2c66affSColin Finck tml = (TOKEN_MANDATORY_LABEL*) buffer;
6508c2c66affSColin Finck ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED),
6509c2c66affSColin Finck "got 0x%x (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED));
6510c2c66affSColin Finck
6511c2c66affSColin Finck ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
6512c2c66affSColin Finck "got %s (expected %s or %s)\n", debugstr_sid(tml->Label.Sid),
6513c2c66affSColin Finck debugstr_sid(&medium_level), debugstr_sid(&high_level));
6514c2c66affSColin Finck
6515c2c66affSColin Finck CloseHandle(token);
6516c2c66affSColin Finck }
6517c2c66affSColin Finck
test_default_dacl_owner_sid(void)6518c2c66affSColin Finck static void test_default_dacl_owner_sid(void)
6519c2c66affSColin Finck {
6520c2c66affSColin Finck HANDLE handle;
6521c2c66affSColin Finck BOOL ret, defaulted, present, found;
6522c2c66affSColin Finck DWORD size, index;
6523c2c66affSColin Finck SECURITY_DESCRIPTOR *sd;
6524c2c66affSColin Finck SECURITY_ATTRIBUTES sa;
6525c2c66affSColin Finck PSID owner;
6526c2c66affSColin Finck ACL *dacl;
6527c2c66affSColin Finck ACCESS_ALLOWED_ACE *ace;
6528c2c66affSColin Finck
6529c2c66affSColin Finck sd = HeapAlloc( GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH );
6530c2c66affSColin Finck ret = InitializeSecurityDescriptor( sd, SECURITY_DESCRIPTOR_REVISION );
6531c2c66affSColin Finck ok( ret, "error %u\n", GetLastError() );
6532c2c66affSColin Finck
6533c2c66affSColin Finck sa.nLength = sizeof(SECURITY_ATTRIBUTES);
6534c2c66affSColin Finck sa.lpSecurityDescriptor = sd;
6535c2c66affSColin Finck sa.bInheritHandle = FALSE;
6536c2c66affSColin Finck handle = CreateEventA( &sa, TRUE, TRUE, "test_event" );
6537c2c66affSColin Finck ok( handle != NULL, "error %u\n", GetLastError() );
6538c2c66affSColin Finck
6539c2c66affSColin Finck size = 0;
6540c2c66affSColin Finck ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &size );
6541c2c66affSColin Finck ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "error %u\n", GetLastError() );
6542c2c66affSColin Finck
6543c2c66affSColin Finck sd = HeapAlloc( GetProcessHeap(), 0, size );
6544c2c66affSColin Finck ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, sd, size, &size );
6545c2c66affSColin Finck ok( ret, "error %u\n", GetLastError() );
6546c2c66affSColin Finck
6547c2c66affSColin Finck owner = (void *)0xdeadbeef;
6548c2c66affSColin Finck defaulted = TRUE;
6549c2c66affSColin Finck ret = GetSecurityDescriptorOwner( sd, &owner, &defaulted );
6550c2c66affSColin Finck ok( ret, "error %u\n", GetLastError() );
6551c2c66affSColin Finck ok( owner != (void *)0xdeadbeef, "owner not set\n" );
6552c2c66affSColin Finck ok( !defaulted, "owner defaulted\n" );
6553c2c66affSColin Finck
6554c2c66affSColin Finck dacl = (void *)0xdeadbeef;
6555c2c66affSColin Finck present = FALSE;
6556c2c66affSColin Finck defaulted = TRUE;
6557c2c66affSColin Finck ret = GetSecurityDescriptorDacl( sd, &present, &dacl, &defaulted );
6558c2c66affSColin Finck ok( ret, "error %u\n", GetLastError() );
6559c2c66affSColin Finck ok( present, "dacl not present\n" );
6560c2c66affSColin Finck ok( dacl != (void *)0xdeadbeef, "dacl not set\n" );
6561c2c66affSColin Finck ok( !defaulted, "dacl defaulted\n" );
6562c2c66affSColin Finck
6563c2c66affSColin Finck index = 0;
6564c2c66affSColin Finck found = FALSE;
6565c2c66affSColin Finck while (pGetAce( dacl, index++, (void **)&ace ))
6566c2c66affSColin Finck {
6567c2c66affSColin Finck if (EqualSid( &ace->SidStart, owner )) found = TRUE;
6568c2c66affSColin Finck }
6569c2c66affSColin Finck ok( found, "owner sid not found in dacl\n" );
6570c2c66affSColin Finck
6571c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, sa.lpSecurityDescriptor );
6572c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, sd );
6573c2c66affSColin Finck CloseHandle( handle );
6574c2c66affSColin Finck }
6575c2c66affSColin Finck
test_AdjustTokenPrivileges(void)6576c2c66affSColin Finck static void test_AdjustTokenPrivileges(void)
6577c2c66affSColin Finck {
6578561bed7bSAmine Khaldi TOKEN_PRIVILEGES tp;
6579c2c66affSColin Finck HANDLE token;
6580c2c66affSColin Finck DWORD len;
6581c2c66affSColin Finck LUID luid;
6582c2c66affSColin Finck BOOL ret;
6583c2c66affSColin Finck
6584c2c66affSColin Finck if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
6585c2c66affSColin Finck return;
6586c2c66affSColin Finck
6587c2c66affSColin Finck if (!LookupPrivilegeValueA(NULL, SE_BACKUP_NAME, &luid))
6588c2c66affSColin Finck {
6589c2c66affSColin Finck CloseHandle(token);
6590c2c66affSColin Finck return;
6591c2c66affSColin Finck }
6592c2c66affSColin Finck
6593c2c66affSColin Finck tp.PrivilegeCount = 1;
6594c2c66affSColin Finck tp.Privileges[0].Luid = luid;
6595c2c66affSColin Finck tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6596c2c66affSColin Finck
6597c2c66affSColin Finck len = 0xdeadbeef;
6598c2c66affSColin Finck ret = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, &len);
6599c2c66affSColin Finck ok(ret, "got %d\n", ret);
6600c2c66affSColin Finck ok(len == 0xdeadbeef, "got length %d\n", len);
6601c2c66affSColin Finck
6602c2c66affSColin Finck /* revert */
6603c2c66affSColin Finck tp.PrivilegeCount = 1;
6604c2c66affSColin Finck tp.Privileges[0].Luid = luid;
6605c2c66affSColin Finck tp.Privileges[0].Attributes = 0;
6606561bed7bSAmine Khaldi ret = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
6607561bed7bSAmine Khaldi ok(ret, "got %d\n", ret);
6608c2c66affSColin Finck
6609c2c66affSColin Finck CloseHandle(token);
6610c2c66affSColin Finck }
6611c2c66affSColin Finck
test_AddAce(void)6612c2c66affSColin Finck static void test_AddAce(void)
6613c2c66affSColin Finck {
6614c2c66affSColin Finck static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
6615c2c66affSColin Finck
6616c2c66affSColin Finck char acl_buf[1024], ace_buf[256];
6617c2c66affSColin Finck ACCESS_ALLOWED_ACE *ace = (ACCESS_ALLOWED_ACE*)ace_buf;
6618c2c66affSColin Finck PACL acl = (PACL)acl_buf;
6619c2c66affSColin Finck BOOL ret;
6620c2c66affSColin Finck
6621c2c66affSColin Finck memset(ace, 0, sizeof(ace_buf));
6622c2c66affSColin Finck ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
6623c2c66affSColin Finck ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)+sizeof(SID);
6624c2c66affSColin Finck memcpy(&ace->SidStart, &sidWorld, sizeof(sidWorld));
6625c2c66affSColin Finck
6626c2c66affSColin Finck ret = InitializeAcl(acl, sizeof(acl_buf), ACL_REVISION2);
6627c2c66affSColin Finck ok(ret, "InitializeAcl failed: %d\n", GetLastError());
6628c2c66affSColin Finck
6629c2c66affSColin Finck ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
6630c2c66affSColin Finck ok(ret, "AddAce failed: %d\n", GetLastError());
6631c2c66affSColin Finck ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
6632c2c66affSColin Finck ok(ret, "AddAce failed: %d\n", GetLastError());
6633c2c66affSColin Finck ret = AddAce(acl, ACL_REVISION3, MAXDWORD, ace, ace->Header.AceSize);
6634c2c66affSColin Finck ok(ret, "AddAce failed: %d\n", GetLastError());
6635c2c66affSColin Finck ok(acl->AclRevision == ACL_REVISION3, "acl->AclRevision = %d\n", acl->AclRevision);
6636c2c66affSColin Finck ret = AddAce(acl, ACL_REVISION4, MAXDWORD, ace, ace->Header.AceSize);
6637c2c66affSColin Finck ok(ret, "AddAce failed: %d\n", GetLastError());
6638c2c66affSColin Finck ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision);
6639c2c66affSColin Finck ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
6640c2c66affSColin Finck ok(ret, "AddAce failed: %d\n", GetLastError());
6641c2c66affSColin Finck ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision);
6642c2c66affSColin Finck ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
6643c2c66affSColin Finck ok(ret, "AddAce failed: %d\n", GetLastError());
6644c2c66affSColin Finck
6645c2c66affSColin Finck ret = AddAce(acl, MIN_ACL_REVISION-1, MAXDWORD, ace, ace->Header.AceSize);
6646c2c66affSColin Finck ok(ret, "AddAce failed: %d\n", GetLastError());
6647c2c66affSColin Finck /* next test succeededs but corrupts ACL */
6648c2c66affSColin Finck ret = AddAce(acl, MAX_ACL_REVISION+1, MAXDWORD, ace, ace->Header.AceSize);
6649c2c66affSColin Finck ok(ret, "AddAce failed: %d\n", GetLastError());
6650c2c66affSColin Finck ok(acl->AclRevision == MAX_ACL_REVISION+1, "acl->AclRevision = %d\n", acl->AclRevision);
6651c2c66affSColin Finck SetLastError(0xdeadbeef);
6652c2c66affSColin Finck ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
6653c2c66affSColin Finck ok(!ret, "AddAce succeeded\n");
6654c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %d\n", GetLastError());
6655c2c66affSColin Finck }
6656c2c66affSColin Finck
test_AddMandatoryAce(void)6657c2c66affSColin Finck static void test_AddMandatoryAce(void)
6658c2c66affSColin Finck {
6659c2c66affSColin Finck static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6660c2c66affSColin Finck {SECURITY_MANDATORY_LOW_RID}};
6661c2c66affSColin Finck static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6662c2c66affSColin Finck {SECURITY_MANDATORY_MEDIUM_RID}};
6663561bed7bSAmine Khaldi static SID_IDENTIFIER_AUTHORITY sia_world = {SECURITY_WORLD_SID_AUTHORITY};
6664c2c66affSColin Finck char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
6665c2c66affSColin Finck SECURITY_DESCRIPTOR *sd2, *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
6666c2c66affSColin Finck BOOL defaulted, present, ret, found, found2;
6667561bed7bSAmine Khaldi ACL_SIZE_INFORMATION acl_size_info;
6668561bed7bSAmine Khaldi SYSTEM_MANDATORY_LABEL_ACE *ace;
6669561bed7bSAmine Khaldi char buffer_acl[256];
6670561bed7bSAmine Khaldi ACL *acl = (ACL *)&buffer_acl;
6671561bed7bSAmine Khaldi SECURITY_ATTRIBUTES sa;
6672c2c66affSColin Finck DWORD index, size;
6673561bed7bSAmine Khaldi HANDLE handle;
6674561bed7bSAmine Khaldi SID *everyone;
6675561bed7bSAmine Khaldi ACL *sacl;
6676c2c66affSColin Finck
6677c2c66affSColin Finck if (!pAddMandatoryAce)
6678c2c66affSColin Finck {
6679c2c66affSColin Finck win_skip("AddMandatoryAce not supported, skipping test\n");
6680c2c66affSColin Finck return;
6681c2c66affSColin Finck }
6682c2c66affSColin Finck
6683c2c66affSColin Finck ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
6684561bed7bSAmine Khaldi ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError());
6685c2c66affSColin Finck
6686561bed7bSAmine Khaldi sa.nLength = sizeof(sa);
6687c2c66affSColin Finck sa.lpSecurityDescriptor = sd;
6688c2c66affSColin Finck sa.bInheritHandle = FALSE;
6689c2c66affSColin Finck
6690c2c66affSColin Finck handle = CreateEventA(&sa, TRUE, TRUE, "test_event");
6691c2c66affSColin Finck ok(handle != NULL, "CreateEventA failed with error %u\n", GetLastError());
6692c2c66affSColin Finck
6693c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6694c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6695561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
6696c2c66affSColin Finck
6697c2c66affSColin Finck sd2 = HeapAlloc(GetProcessHeap(), 0, size);
6698c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6699561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
6700c2c66affSColin Finck
6701561bed7bSAmine Khaldi sacl = (void *)0xdeadbeef;
6702c2c66affSColin Finck present = TRUE;
6703561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6704561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6705561bed7bSAmine Khaldi ok(!present, "SACL is present\n");
6706561bed7bSAmine Khaldi ok(sacl == (void *)0xdeadbeef, "SACL is set\n");
6707c2c66affSColin Finck
6708c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sd2);
6709c2c66affSColin Finck CloseHandle(handle);
6710c2c66affSColin Finck
6711*3c1b7834SAmine Khaldi memset(buffer_acl, 0, sizeof(buffer_acl));
6712561bed7bSAmine Khaldi ret = InitializeAcl(acl, 256, ACL_REVISION);
6713c2c66affSColin Finck ok(ret, "InitializeAcl failed with %u\n", GetLastError());
6714c2c66affSColin Finck
6715c2c66affSColin Finck SetLastError(0xdeadbeef);
6716561bed7bSAmine Khaldi ret = pAddMandatoryAce(acl, ACL_REVISION, 0, 0x1234, &low_level);
6717c2c66affSColin Finck ok(!ret, "AddMandatoryAce succeeded\n");
6718c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_PARAMETER,
6719c2c66affSColin Finck "Expected ERROR_INVALID_PARAMETER got %u\n", GetLastError());
6720c2c66affSColin Finck
6721561bed7bSAmine Khaldi ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level);
6722c2c66affSColin Finck ok(ret, "AddMandatoryAce failed with %u\n", GetLastError());
6723c2c66affSColin Finck
6724c2c66affSColin Finck index = 0;
6725c2c66affSColin Finck found = FALSE;
6726561bed7bSAmine Khaldi while (pGetAce(acl, index++, (void **)&ace))
6727c2c66affSColin Finck {
6728c2c66affSColin Finck if (ace->Header.AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
6729c2c66affSColin Finck ok(ace->Header.AceFlags == 0, "Expected flags 0, got %x\n", ace->Header.AceFlags);
6730c2c66affSColin Finck ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP,
6731c2c66affSColin Finck "Expected mask SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, got %x\n", ace->Mask);
6732c2c66affSColin Finck ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n");
6733c2c66affSColin Finck found = TRUE;
6734c2c66affSColin Finck }
6735c2c66affSColin Finck ok(found, "Could not find mandatory label ace\n");
6736c2c66affSColin Finck
6737561bed7bSAmine Khaldi ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
6738561bed7bSAmine Khaldi ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6739c2c66affSColin Finck
6740c2c66affSColin Finck handle = CreateEventA(&sa, TRUE, TRUE, "test_event");
6741c2c66affSColin Finck ok(handle != NULL, "CreateEventA failed with error %u\n", GetLastError());
6742c2c66affSColin Finck
6743c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6744c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6745561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
6746c2c66affSColin Finck
6747c2c66affSColin Finck sd2 = HeapAlloc(GetProcessHeap(), 0, size);
6748c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6749561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
6750c2c66affSColin Finck
6751561bed7bSAmine Khaldi sacl = (void *)0xdeadbeef;
6752c2c66affSColin Finck present = FALSE;
6753c2c66affSColin Finck defaulted = TRUE;
6754561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6755561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6756561bed7bSAmine Khaldi ok(present, "SACL not present\n");
6757561bed7bSAmine Khaldi ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
6758561bed7bSAmine Khaldi ok(!defaulted, "SACL defaulted\n");
6759561bed7bSAmine Khaldi ret = pGetAclInformation(sacl, &acl_size_info, sizeof(acl_size_info), AclSizeInformation);
6760561bed7bSAmine Khaldi ok(ret, "GetAclInformation failed with error %u\n", GetLastError());
6761561bed7bSAmine Khaldi ok(acl_size_info.AceCount == 1, "SACL contains an unexpected ACE count %u\n", acl_size_info.AceCount);
6762c2c66affSColin Finck
6763561bed7bSAmine Khaldi ret = pGetAce(sacl, 0, (void **)&ace);
6764561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
6765561bed7bSAmine Khaldi ok (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType);
6766561bed7bSAmine Khaldi ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags);
6767561bed7bSAmine Khaldi ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#x\n", ace->Mask);
6768c2c66affSColin Finck ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n");
6769c2c66affSColin Finck
6770c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sd2);
6771c2c66affSColin Finck
6772561bed7bSAmine Khaldi ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level);
6773561bed7bSAmine Khaldi ok(ret, "AddMandatoryAce failed with error %u\n", GetLastError());
6774c2c66affSColin Finck
6775c2c66affSColin Finck ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6776561bed7bSAmine Khaldi ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError());
6777c2c66affSColin Finck
6778c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6779c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6780561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
6781c2c66affSColin Finck
6782c2c66affSColin Finck sd2 = HeapAlloc(GetProcessHeap(), 0, size);
6783c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6784561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
6785c2c66affSColin Finck
6786561bed7bSAmine Khaldi sacl = (void *)0xdeadbeef;
6787c2c66affSColin Finck present = FALSE;
6788c2c66affSColin Finck defaulted = TRUE;
6789561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6790561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6791561bed7bSAmine Khaldi ok(present, "SACL not present\n");
6792561bed7bSAmine Khaldi ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
6793561bed7bSAmine Khaldi ok(sacl->AceCount == 2, "Expected 2 ACEs, got %d\n", sacl->AceCount);
6794561bed7bSAmine Khaldi ok(!defaulted, "SACL defaulted\n");
6795c2c66affSColin Finck
6796c2c66affSColin Finck index = 0;
6797c2c66affSColin Finck found = found2 = FALSE;
6798561bed7bSAmine Khaldi while (pGetAce(sacl, index++, (void **)&ace))
6799c2c66affSColin Finck {
6800c2c66affSColin Finck if (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
6801c2c66affSColin Finck {
6802c2c66affSColin Finck if (EqualSid(&ace->SidStart, &low_level))
6803c2c66affSColin Finck {
6804c2c66affSColin Finck found = TRUE;
6805561bed7bSAmine Khaldi ok(!ace->Header.AceFlags, "Expected 0 as flags, got %#x\n", ace->Header.AceFlags);
6806c2c66affSColin Finck ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP,
6807561bed7bSAmine Khaldi "Expected SYSTEM_MANDATORY_LABEL_NO_WRITE_UP as mask, got %#x\n", ace->Mask);
6808c2c66affSColin Finck }
6809c2c66affSColin Finck if (EqualSid(&ace->SidStart, &medium_level))
6810c2c66affSColin Finck {
6811c2c66affSColin Finck found2 = TRUE;
6812561bed7bSAmine Khaldi ok(!ace->Header.AceFlags, "Expected 0 as flags, got %#x\n", ace->Header.AceFlags);
6813c2c66affSColin Finck ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP,
6814561bed7bSAmine Khaldi "Expected SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP as mask, got %#x\n", ace->Mask);
6815c2c66affSColin Finck }
6816c2c66affSColin Finck }
6817c2c66affSColin Finck }
6818c2c66affSColin Finck ok(found, "Could not find low mandatory label\n");
6819c2c66affSColin Finck ok(found2, "Could not find medium mandatory label\n");
6820c2c66affSColin Finck
6821c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sd2);
6822c2c66affSColin Finck
6823c2c66affSColin Finck ret = SetSecurityDescriptorSacl(sd, FALSE, NULL, FALSE);
6824561bed7bSAmine Khaldi ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6825c2c66affSColin Finck
6826c2c66affSColin Finck ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6827561bed7bSAmine Khaldi ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError());
6828c2c66affSColin Finck
6829c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6830c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6831561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
6832c2c66affSColin Finck
6833c2c66affSColin Finck sd2 = HeapAlloc(GetProcessHeap(), 0, size);
6834c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6835561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
6836c2c66affSColin Finck
6837561bed7bSAmine Khaldi sacl = (void *)0xdeadbeef;
6838c2c66affSColin Finck present = FALSE;
6839c2c66affSColin Finck defaulted = TRUE;
6840561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6841561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6842561bed7bSAmine Khaldi ok(present, "SACL not present\n");
6843561bed7bSAmine Khaldi ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n");
6844561bed7bSAmine Khaldi ok(!defaulted, "SACL defaulted\n");
6845561bed7bSAmine Khaldi ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount);
6846c2c66affSColin Finck
6847c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sd2);
6848c2c66affSColin Finck
6849561bed7bSAmine Khaldi ret = InitializeAcl(acl, 256, ACL_REVISION);
6850561bed7bSAmine Khaldi ok(ret, "InitializeAcl failed with error %u\n", GetLastError());
6851c2c66affSColin Finck
6852561bed7bSAmine Khaldi ret = pAddMandatoryAce(acl, ACL_REVISION3, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level);
6853561bed7bSAmine Khaldi ok(ret, "AddMandatoryAce failed with error %u\n", GetLastError());
6854c2c66affSColin Finck
6855561bed7bSAmine Khaldi ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
6856561bed7bSAmine Khaldi ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6857c2c66affSColin Finck
6858c2c66affSColin Finck ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6859561bed7bSAmine Khaldi ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError());
6860c2c66affSColin Finck
6861c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6862c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6863561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
6864c2c66affSColin Finck
6865c2c66affSColin Finck sd2 = HeapAlloc(GetProcessHeap(), 0, size);
6866c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6867561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
6868c2c66affSColin Finck
6869561bed7bSAmine Khaldi sacl = (void *)0xdeadbeef;
6870c2c66affSColin Finck present = FALSE;
6871c2c66affSColin Finck defaulted = TRUE;
6872561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6873561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6874561bed7bSAmine Khaldi ok(present, "SACL not present\n");
6875561bed7bSAmine Khaldi ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
6876561bed7bSAmine Khaldi ok(sacl->AclRevision == ACL_REVISION3, "Expected revision 3, got %d\n", sacl->AclRevision);
6877561bed7bSAmine Khaldi ok(!defaulted, "SACL defaulted\n");
6878c2c66affSColin Finck
6879c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sd2);
6880c2c66affSColin Finck
6881561bed7bSAmine Khaldi ret = InitializeAcl(acl, 256, ACL_REVISION);
6882561bed7bSAmine Khaldi ok(ret, "InitializeAcl failed with error %u\n", GetLastError());
6883561bed7bSAmine Khaldi
6884561bed7bSAmine Khaldi ret = AllocateAndInitializeSid(&sia_world, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, (void **)&everyone);
6885561bed7bSAmine Khaldi ok(ret, "AllocateAndInitializeSid failed with error %u\n", GetLastError());
6886561bed7bSAmine Khaldi
6887561bed7bSAmine Khaldi ret = AddAccessAllowedAce(acl, ACL_REVISION, KEY_READ, everyone);
6888561bed7bSAmine Khaldi ok(ret, "AddAccessAllowedAce failed with error %u\n", GetLastError());
6889561bed7bSAmine Khaldi
6890561bed7bSAmine Khaldi ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
6891561bed7bSAmine Khaldi ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6892561bed7bSAmine Khaldi
6893561bed7bSAmine Khaldi ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6894561bed7bSAmine Khaldi ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError());
6895c2c66affSColin Finck
6896c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6897c2c66affSColin Finck ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6898561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
6899c2c66affSColin Finck
6900c2c66affSColin Finck sd2 = HeapAlloc(GetProcessHeap(), 0, size);
6901c2c66affSColin Finck ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6902561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
6903c2c66affSColin Finck
6904561bed7bSAmine Khaldi sacl = (void *)0xdeadbeef;
6905c2c66affSColin Finck present = FALSE;
6906c2c66affSColin Finck defaulted = TRUE;
6907561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6908561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
6909561bed7bSAmine Khaldi ok(present, "SACL not present\n");
6910561bed7bSAmine Khaldi ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n");
6911561bed7bSAmine Khaldi ok(!defaulted, "SACL defaulted\n");
6912561bed7bSAmine Khaldi ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount);
6913c2c66affSColin Finck
6914561bed7bSAmine Khaldi FreeSid(everyone);
6915c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, sd2);
6916c2c66affSColin Finck CloseHandle(handle);
6917c2c66affSColin Finck }
6918c2c66affSColin Finck
test_system_security_access(void)6919c2c66affSColin Finck static void test_system_security_access(void)
6920c2c66affSColin Finck {
6921c2c66affSColin Finck static const WCHAR testkeyW[] =
6922c2c66affSColin Finck {'S','O','F','T','W','A','R','E','\\','W','i','n','e','\\','S','A','C','L','t','e','s','t',0};
6923c2c66affSColin Finck LONG res;
6924c2c66affSColin Finck HKEY hkey;
6925c2c66affSColin Finck PSECURITY_DESCRIPTOR sd;
6926c2c66affSColin Finck ACL *sacl;
6927c2c66affSColin Finck DWORD err, len = 128;
6928c2c66affSColin Finck TOKEN_PRIVILEGES priv, *priv_prev;
6929c2c66affSColin Finck HANDLE token;
6930c2c66affSColin Finck LUID luid;
6931c2c66affSColin Finck BOOL ret;
6932c2c66affSColin Finck
6933c2c66affSColin Finck if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token )) return;
6934c2c66affSColin Finck if (!LookupPrivilegeValueA( NULL, SE_SECURITY_NAME, &luid ))
6935c2c66affSColin Finck {
6936c2c66affSColin Finck CloseHandle( token );
6937c2c66affSColin Finck return;
6938c2c66affSColin Finck }
6939c2c66affSColin Finck
6940c2c66affSColin Finck /* ACCESS_SYSTEM_SECURITY requires special privilege */
6941c2c66affSColin Finck res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ|ACCESS_SYSTEM_SECURITY, NULL, &hkey, NULL );
6942c2c66affSColin Finck if (res == ERROR_ACCESS_DENIED)
6943c2c66affSColin Finck {
6944c2c66affSColin Finck skip( "unprivileged user\n" );
6945c2c66affSColin Finck CloseHandle( token );
6946c2c66affSColin Finck return;
6947c2c66affSColin Finck }
6948c2c66affSColin Finck todo_wine ok( res == ERROR_PRIVILEGE_NOT_HELD, "got %d\n", res );
6949c2c66affSColin Finck
6950c2c66affSColin Finck priv.PrivilegeCount = 1;
6951c2c66affSColin Finck priv.Privileges[0].Luid = luid;
6952c2c66affSColin Finck priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6953c2c66affSColin Finck
6954c2c66affSColin Finck priv_prev = HeapAlloc( GetProcessHeap(), 0, len );
6955c2c66affSColin Finck ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len );
6956c2c66affSColin Finck ok( ret, "got %u\n", GetLastError());
6957c2c66affSColin Finck
6958c2c66affSColin Finck res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ|ACCESS_SYSTEM_SECURITY, NULL, &hkey, NULL );
6959c2c66affSColin Finck if (res == ERROR_PRIVILEGE_NOT_HELD)
6960c2c66affSColin Finck {
6961c2c66affSColin Finck win_skip( "privilege not held\n" );
6962c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, priv_prev );
6963c2c66affSColin Finck CloseHandle( token );
6964c2c66affSColin Finck return;
6965c2c66affSColin Finck }
6966c2c66affSColin Finck ok( !res, "got %d\n", res );
6967c2c66affSColin Finck
6968c2c66affSColin Finck /* restore privileges */
6969c2c66affSColin Finck ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL );
6970c2c66affSColin Finck ok( ret, "got %u\n", GetLastError() );
6971c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, priv_prev );
6972c2c66affSColin Finck
6973c2c66affSColin Finck /* privilege is checked on access */
6974c2c66affSColin Finck err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6975c2c66affSColin Finck todo_wine ok( err == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", err );
6976*3c1b7834SAmine Khaldi if (err == ERROR_SUCCESS)
6977*3c1b7834SAmine Khaldi LocalFree( sd );
6978c2c66affSColin Finck
6979c2c66affSColin Finck priv.PrivilegeCount = 1;
6980c2c66affSColin Finck priv.Privileges[0].Luid = luid;
6981c2c66affSColin Finck priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6982c2c66affSColin Finck
6983c2c66affSColin Finck priv_prev = HeapAlloc( GetProcessHeap(), 0, len );
6984c2c66affSColin Finck ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len );
6985c2c66affSColin Finck ok( ret, "got %u\n", GetLastError());
6986c2c66affSColin Finck
6987c2c66affSColin Finck err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6988c2c66affSColin Finck ok( err == ERROR_SUCCESS, "got %u\n", err );
6989c2c66affSColin Finck RegCloseKey( hkey );
6990c2c66affSColin Finck LocalFree( sd );
6991c2c66affSColin Finck
6992c2c66affSColin Finck /* handle created without ACCESS_SYSTEM_SECURITY, privilege held */
6993c2c66affSColin Finck res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL );
6994c2c66affSColin Finck ok( res == ERROR_SUCCESS, "got %d\n", res );
6995c2c66affSColin Finck
6996c2c66affSColin Finck sd = NULL;
6997c2c66affSColin Finck err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6998c2c66affSColin Finck todo_wine ok( err == ERROR_SUCCESS, "got %u\n", err );
6999c2c66affSColin Finck RegCloseKey( hkey );
7000c2c66affSColin Finck LocalFree( sd );
7001c2c66affSColin Finck
7002c2c66affSColin Finck /* restore privileges */
7003c2c66affSColin Finck ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL );
7004c2c66affSColin Finck ok( ret, "got %u\n", GetLastError() );
7005c2c66affSColin Finck HeapFree( GetProcessHeap(), 0, priv_prev );
7006c2c66affSColin Finck
7007c2c66affSColin Finck /* handle created without ACCESS_SYSTEM_SECURITY, privilege not held */
7008c2c66affSColin Finck res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL );
7009c2c66affSColin Finck ok( res == ERROR_SUCCESS, "got %d\n", res );
7010c2c66affSColin Finck
7011c2c66affSColin Finck err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
7012c2c66affSColin Finck todo_wine ok( err == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", err );
7013c2c66affSColin Finck RegCloseKey( hkey );
7014c2c66affSColin Finck
7015c2c66affSColin Finck res = RegDeleteKeyW( HKEY_LOCAL_MACHINE, testkeyW );
7016c2c66affSColin Finck ok( !res, "got %d\n", res );
7017c2c66affSColin Finck CloseHandle( token );
7018c2c66affSColin Finck }
7019c2c66affSColin Finck
test_GetWindowsAccountDomainSid(void)7020c2c66affSColin Finck static void test_GetWindowsAccountDomainSid(void)
7021c2c66affSColin Finck {
7022c2c66affSColin Finck char *user, buffer1[SECURITY_MAX_SID_SIZE], buffer2[SECURITY_MAX_SID_SIZE];
7023c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
7024c2c66affSColin Finck PSID domain_sid = (PSID *)&buffer1;
7025c2c66affSColin Finck PSID domain_sid2 = (PSID *)&buffer2;
7026c2c66affSColin Finck DWORD sid_size;
7027c2c66affSColin Finck PSID user_sid;
7028c2c66affSColin Finck HANDLE token;
7029c2c66affSColin Finck BOOL bret = TRUE;
7030c2c66affSColin Finck int i;
7031c2c66affSColin Finck
7032c2c66affSColin Finck if (!pGetWindowsAccountDomainSid)
7033c2c66affSColin Finck {
7034c2c66affSColin Finck win_skip("GetWindowsAccountDomainSid not available\n");
7035c2c66affSColin Finck return;
7036c2c66affSColin Finck }
7037c2c66affSColin Finck
7038c2c66affSColin Finck if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
7039c2c66affSColin Finck {
7040c2c66affSColin Finck if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
7041c2c66affSColin Finck else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
7042c2c66affSColin Finck }
7043c2c66affSColin Finck if (!bret)
7044c2c66affSColin Finck {
7045c2c66affSColin Finck win_skip("Failed to get current user token\n");
7046c2c66affSColin Finck return;
7047c2c66affSColin Finck }
7048c2c66affSColin Finck
7049c2c66affSColin Finck bret = GetTokenInformation(token, TokenUser, NULL, 0, &sid_size);
7050c2c66affSColin Finck ok(!bret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7051c2c66affSColin Finck "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
7052c2c66affSColin Finck user = HeapAlloc(GetProcessHeap(), 0, sid_size);
7053c2c66affSColin Finck bret = GetTokenInformation(token, TokenUser, user, sid_size, &sid_size);
7054c2c66affSColin Finck ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
7055c2c66affSColin Finck CloseHandle(token);
7056c2c66affSColin Finck user_sid = ((TOKEN_USER *)user)->User.Sid;
7057c2c66affSColin Finck
7058c2c66affSColin Finck SetLastError(0xdeadbeef);
7059c2c66affSColin Finck bret = pGetWindowsAccountDomainSid(0, 0, 0);
7060c2c66affSColin Finck ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
7061c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_SID, "expected ERROR_INVALID_SID, got %d\n", GetLastError());
7062c2c66affSColin Finck
7063c2c66affSColin Finck SetLastError(0xdeadbeef);
7064c2c66affSColin Finck bret = pGetWindowsAccountDomainSid(user_sid, 0, 0);
7065c2c66affSColin Finck ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
7066c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
7067c2c66affSColin Finck
7068c2c66affSColin Finck sid_size = SECURITY_MAX_SID_SIZE;
7069c2c66affSColin Finck SetLastError(0xdeadbeef);
7070c2c66affSColin Finck bret = pGetWindowsAccountDomainSid(user_sid, 0, &sid_size);
7071c2c66affSColin Finck ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
7072c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
7073c2c66affSColin Finck ok(sid_size == GetSidLengthRequired(4), "expected size %d, got %d\n", GetSidLengthRequired(4), sid_size);
7074c2c66affSColin Finck
7075c2c66affSColin Finck SetLastError(0xdeadbeef);
7076c2c66affSColin Finck bret = pGetWindowsAccountDomainSid(user_sid, domain_sid, 0);
7077c2c66affSColin Finck ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
7078c2c66affSColin Finck ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
7079c2c66affSColin Finck
7080c2c66affSColin Finck sid_size = 1;
7081c2c66affSColin Finck SetLastError(0xdeadbeef);
7082c2c66affSColin Finck bret = pGetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size);
7083c2c66affSColin Finck ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
7084c2c66affSColin Finck ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
7085c2c66affSColin Finck ok(sid_size == GetSidLengthRequired(4), "expected size %d, got %d\n", GetSidLengthRequired(4), sid_size);
7086c2c66affSColin Finck
7087c2c66affSColin Finck sid_size = SECURITY_MAX_SID_SIZE;
7088c2c66affSColin Finck bret = pGetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size);
7089c2c66affSColin Finck ok(bret, "GetWindowsAccountDomainSid failed with error %d\n", GetLastError());
7090c2c66affSColin Finck ok(sid_size == GetSidLengthRequired(4), "expected size %d, got %d\n", GetSidLengthRequired(4), sid_size);
7091c2c66affSColin Finck InitializeSid(domain_sid2, &domain_ident, 4);
7092c2c66affSColin Finck for (i = 0; i < 4; i++)
7093c2c66affSColin Finck *GetSidSubAuthority(domain_sid2, i) = *GetSidSubAuthority(user_sid, i);
7094c2c66affSColin Finck ok(EqualSid(domain_sid, domain_sid2), "unexpected domain sid %s != %s\n",
7095c2c66affSColin Finck debugstr_sid(domain_sid), debugstr_sid(domain_sid2));
7096c2c66affSColin Finck
7097c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, user);
7098c2c66affSColin Finck }
7099c2c66affSColin Finck
test_GetSidIdentifierAuthority(void)7100c2c66affSColin Finck static void test_GetSidIdentifierAuthority(void)
7101c2c66affSColin Finck {
7102c2c66affSColin Finck char buffer[SECURITY_MAX_SID_SIZE];
7103c2c66affSColin Finck PSID authority_sid = (PSID *)buffer;
7104c2c66affSColin Finck PSID_IDENTIFIER_AUTHORITY id;
7105c2c66affSColin Finck BOOL ret;
7106c2c66affSColin Finck
7107c2c66affSColin Finck if (!pGetSidIdentifierAuthority)
7108c2c66affSColin Finck {
7109c2c66affSColin Finck win_skip("GetSidIdentifierAuthority not available\n");
7110c2c66affSColin Finck return;
7111c2c66affSColin Finck }
7112c2c66affSColin Finck
7113c2c66affSColin Finck memset(buffer, 0xcc, sizeof(buffer));
7114c2c66affSColin Finck ret = IsValidSid(authority_sid);
7115c2c66affSColin Finck ok(!ret, "expected FALSE, got %u\n", ret);
7116c2c66affSColin Finck
7117c2c66affSColin Finck SetLastError(0xdeadbeef);
7118c2c66affSColin Finck id = GetSidIdentifierAuthority(authority_sid);
7119c2c66affSColin Finck ok(id != NULL, "got NULL pointer as identifier authority\n");
7120c2c66affSColin Finck ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", GetLastError());
7121c2c66affSColin Finck
7122c2c66affSColin Finck SetLastError(0xdeadbeef);
7123c2c66affSColin Finck id = GetSidIdentifierAuthority(NULL);
7124c2c66affSColin Finck ok(id != NULL, "got NULL pointer as identifier authority\n");
7125c2c66affSColin Finck ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", GetLastError());
7126c2c66affSColin Finck }
7127c2c66affSColin Finck
test_pseudo_tokens(void)7128c2c66affSColin Finck static void test_pseudo_tokens(void)
7129c2c66affSColin Finck {
7130c2c66affSColin Finck TOKEN_STATISTICS statistics1, statistics2;
7131c2c66affSColin Finck HANDLE token;
7132c2c66affSColin Finck DWORD retlen;
7133c2c66affSColin Finck BOOL ret;
7134c2c66affSColin Finck
7135c2c66affSColin Finck ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
7136c2c66affSColin Finck ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
7137c2c66affSColin Finck memset(&statistics1, 0x11, sizeof(statistics1));
7138c2c66affSColin Finck ret = GetTokenInformation(token, TokenStatistics, &statistics1, sizeof(statistics1), &retlen);
7139c2c66affSColin Finck ok(ret, "GetTokenInformation failed with %u\n", GetLastError());
7140c2c66affSColin Finck CloseHandle(token);
7141c2c66affSColin Finck
7142c2c66affSColin Finck /* test GetCurrentProcessToken() */
7143c2c66affSColin Finck SetLastError(0xdeadbeef);
7144c2c66affSColin Finck memset(&statistics2, 0x22, sizeof(statistics2));
7145c2c66affSColin Finck ret = GetTokenInformation(GetCurrentProcessToken(), TokenStatistics,
7146c2c66affSColin Finck &statistics2, sizeof(statistics2), &retlen);
7147c2c66affSColin Finck ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE),
7148c2c66affSColin Finck "GetTokenInformation failed with %u\n", GetLastError());
7149c2c66affSColin Finck if (ret)
7150c2c66affSColin Finck ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n");
7151c2c66affSColin Finck else
7152c2c66affSColin Finck win_skip("CurrentProcessToken not supported, skipping test\n");
7153c2c66affSColin Finck
7154c2c66affSColin Finck /* test GetCurrentThreadEffectiveToken() */
7155c2c66affSColin Finck SetLastError(0xdeadbeef);
7156c2c66affSColin Finck memset(&statistics2, 0x22, sizeof(statistics2));
7157c2c66affSColin Finck ret = GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenStatistics,
7158c2c66affSColin Finck &statistics2, sizeof(statistics2), &retlen);
7159c2c66affSColin Finck ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE),
7160c2c66affSColin Finck "GetTokenInformation failed with %u\n", GetLastError());
7161c2c66affSColin Finck if (ret)
7162c2c66affSColin Finck ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n");
7163c2c66affSColin Finck else
7164c2c66affSColin Finck win_skip("CurrentThreadEffectiveToken not supported, skipping test\n");
7165c2c66affSColin Finck
7166c2c66affSColin Finck SetLastError(0xdeadbeef);
7167c2c66affSColin Finck ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token);
7168c2c66affSColin Finck ok(!ret, "OpenThreadToken should have failed\n");
7169c2c66affSColin Finck ok(GetLastError() == ERROR_NO_TOKEN, "Expected ERROR_NO_TOKEN, got %u\n", GetLastError());
7170c2c66affSColin Finck
7171c2c66affSColin Finck /* test GetCurrentThreadToken() */
7172c2c66affSColin Finck SetLastError(0xdeadbeef);
7173c2c66affSColin Finck ret = GetTokenInformation(GetCurrentThreadToken(), TokenStatistics,
7174c2c66affSColin Finck &statistics2, sizeof(statistics2), &retlen);
7175c2c66affSColin Finck todo_wine ok(GetLastError() == ERROR_NO_TOKEN || broken(GetLastError() == ERROR_INVALID_HANDLE),
7176c2c66affSColin Finck "Expected ERROR_NO_TOKEN, got %u\n", GetLastError());
7177c2c66affSColin Finck }
7178c2c66affSColin Finck
test_maximum_allowed(void)7179c2c66affSColin Finck static void test_maximum_allowed(void)
7180c2c66affSColin Finck {
7181c2c66affSColin Finck HANDLE (WINAPI *pCreateEventExA)(SECURITY_ATTRIBUTES *, LPCSTR, DWORD, DWORD);
7182c2c66affSColin Finck char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH], buffer_acl[256];
7183c2c66affSColin Finck SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
7184c2c66affSColin Finck SECURITY_ATTRIBUTES sa;
7185c2c66affSColin Finck ACL *acl = (ACL *)&buffer_acl;
7186c2c66affSColin Finck HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
7187c2c66affSColin Finck ACCESS_MASK mask;
7188c2c66affSColin Finck HANDLE handle;
7189c2c66affSColin Finck BOOL ret;
7190c2c66affSColin Finck
7191c2c66affSColin Finck pCreateEventExA = (void *)GetProcAddress(hkernel32, "CreateEventExA");
7192c2c66affSColin Finck if (!pCreateEventExA)
7193c2c66affSColin Finck {
7194c2c66affSColin Finck win_skip("CreateEventExA is not available\n");
7195c2c66affSColin Finck return;
7196c2c66affSColin Finck }
7197c2c66affSColin Finck
7198c2c66affSColin Finck ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7199c2c66affSColin Finck ok(ret, "InitializeSecurityDescriptor failed with %u\n", GetLastError());
7200*3c1b7834SAmine Khaldi memset(buffer_acl, 0, sizeof(buffer_acl));
7201c2c66affSColin Finck ret = InitializeAcl(acl, 256, ACL_REVISION);
7202c2c66affSColin Finck ok(ret, "InitializeAcl failed with %u\n", GetLastError());
7203c2c66affSColin Finck ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE);
7204c2c66affSColin Finck ok(ret, "SetSecurityDescriptorDacl failed with %u\n", GetLastError());
7205c2c66affSColin Finck
7206c2c66affSColin Finck sa.nLength = sizeof(SECURITY_ATTRIBUTES);
7207c2c66affSColin Finck sa.lpSecurityDescriptor = sd;
7208c2c66affSColin Finck sa.bInheritHandle = FALSE;
7209c2c66affSColin Finck
7210c2c66affSColin Finck handle = pCreateEventExA(&sa, NULL, 0, MAXIMUM_ALLOWED | 0x4);
7211c2c66affSColin Finck ok(handle != NULL, "CreateEventExA failed with error %u\n", GetLastError());
7212c2c66affSColin Finck mask = get_obj_access(handle);
7213c2c66affSColin Finck ok(mask == EVENT_ALL_ACCESS, "Expected %x, got %x\n", EVENT_ALL_ACCESS, mask);
7214c2c66affSColin Finck CloseHandle(handle);
7215c2c66affSColin Finck }
7216c2c66affSColin Finck
test_token_label(void)7217561bed7bSAmine Khaldi static void test_token_label(void)
7218561bed7bSAmine Khaldi {
7219561bed7bSAmine Khaldi static SID medium_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7220561bed7bSAmine Khaldi {SECURITY_MANDATORY_MEDIUM_RID}};
7221561bed7bSAmine Khaldi static SID high_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7222561bed7bSAmine Khaldi {SECURITY_MANDATORY_HIGH_RID}};
7223561bed7bSAmine Khaldi SECURITY_DESCRIPTOR_CONTROL control;
7224561bed7bSAmine Khaldi SYSTEM_MANDATORY_LABEL_ACE *ace;
7225561bed7bSAmine Khaldi BOOL ret, present, defaulted;
7226561bed7bSAmine Khaldi SECURITY_DESCRIPTOR *sd;
7227561bed7bSAmine Khaldi ACL *sacl = NULL, *dacl;
7228561bed7bSAmine Khaldi DWORD size, revision;
7229561bed7bSAmine Khaldi HANDLE token;
7230561bed7bSAmine Khaldi char *str;
7231561bed7bSAmine Khaldi SID *sid;
7232561bed7bSAmine Khaldi
7233561bed7bSAmine Khaldi ret = OpenProcessToken(GetCurrentProcess(), READ_CONTROL | WRITE_OWNER, &token);
7234561bed7bSAmine Khaldi ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
7235561bed7bSAmine Khaldi
7236561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7237561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7238561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
7239561bed7bSAmine Khaldi
7240561bed7bSAmine Khaldi sd = HeapAlloc(GetProcessHeap(), 0, size);
7241561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7242561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7243561bed7bSAmine Khaldi
7244561bed7bSAmine Khaldi ret = GetSecurityDescriptorControl(sd, &control, &revision);
7245561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
7246561bed7bSAmine Khaldi todo_wine ok(control == (SE_SELF_RELATIVE | SE_SACL_AUTO_INHERITED | SE_SACL_PRESENT) ||
7247561bed7bSAmine Khaldi broken(control == SE_SELF_RELATIVE) /* WinXP, Win2003 */,
7248561bed7bSAmine Khaldi "Unexpected security descriptor control %#x\n", control);
7249561bed7bSAmine Khaldi ok(revision == 1, "Unexpected security descriptor revision %u\n", revision);
7250561bed7bSAmine Khaldi
7251561bed7bSAmine Khaldi sid = (void *)0xdeadbeef;
7252561bed7bSAmine Khaldi defaulted = TRUE;
7253561bed7bSAmine Khaldi ret = GetSecurityDescriptorOwner(sd, (void **)&sid, &defaulted);
7254561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorOwner failed with error %u\n", GetLastError());
7255561bed7bSAmine Khaldi ok(!sid, "Owner present\n");
7256561bed7bSAmine Khaldi ok(!defaulted, "Owner defaulted\n");
7257561bed7bSAmine Khaldi
7258561bed7bSAmine Khaldi sid = (void *)0xdeadbeef;
7259561bed7bSAmine Khaldi defaulted = TRUE;
7260561bed7bSAmine Khaldi ret = GetSecurityDescriptorGroup(sd, (void **)&sid, &defaulted);
7261561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorGroup failed with error %u\n", GetLastError());
7262561bed7bSAmine Khaldi ok(!sid, "Group present\n");
7263561bed7bSAmine Khaldi ok(!defaulted, "Group defaulted\n");
7264561bed7bSAmine Khaldi
7265561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd, &present, &sacl, &defaulted);
7266561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7267561bed7bSAmine Khaldi ok(present || broken(!present) /* WinXP, Win2003 */, "No SACL in the security descriptor\n");
7268561bed7bSAmine Khaldi ok(sacl || broken(!sacl) /* WinXP, Win2003 */, "NULL SACL in the security descriptor\n");
7269561bed7bSAmine Khaldi
7270561bed7bSAmine Khaldi if (present)
7271561bed7bSAmine Khaldi {
7272561bed7bSAmine Khaldi ok(!defaulted, "SACL defaulted\n");
7273561bed7bSAmine Khaldi ok(sacl->AceCount == 1, "SACL contains an unexpected ACE count %u\n", sacl->AceCount);
7274561bed7bSAmine Khaldi
7275561bed7bSAmine Khaldi ret = pGetAce(sacl, 0, (void **)&ace);
7276561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7277561bed7bSAmine Khaldi
7278561bed7bSAmine Khaldi ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7279561bed7bSAmine Khaldi "Unexpected ACE type %#x\n", ace->Header.AceType);
7280561bed7bSAmine Khaldi ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags);
7281561bed7bSAmine Khaldi ok(ace->Header.AceSize, "Unexpected ACE size %u\n", ace->Header.AceSize);
7282561bed7bSAmine Khaldi ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#x\n", ace->Mask);
7283561bed7bSAmine Khaldi
7284561bed7bSAmine Khaldi sid = (SID *)&ace->SidStart;
7285561bed7bSAmine Khaldi ConvertSidToStringSidA(sid, &str);
7286561bed7bSAmine Khaldi ok(EqualSid(sid, &medium_sid) || EqualSid(sid, &high_sid), "Got unexpected SID %s\n", str);
7287561bed7bSAmine Khaldi LocalFree(str);
7288561bed7bSAmine Khaldi }
7289561bed7bSAmine Khaldi
7290561bed7bSAmine Khaldi ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
7291561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
7292561bed7bSAmine Khaldi todo_wine ok(!present, "DACL present\n");
7293561bed7bSAmine Khaldi
7294561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd);
7295561bed7bSAmine Khaldi CloseHandle(token);
7296561bed7bSAmine Khaldi }
7297561bed7bSAmine Khaldi
test_token_security_descriptor(void)7298561bed7bSAmine Khaldi static void test_token_security_descriptor(void)
7299561bed7bSAmine Khaldi {
7300561bed7bSAmine Khaldi static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7301561bed7bSAmine Khaldi {SECURITY_MANDATORY_LOW_RID}};
7302561bed7bSAmine Khaldi static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7303561bed7bSAmine Khaldi {SECURITY_MANDATORY_MEDIUM_RID}};
7304561bed7bSAmine Khaldi static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7305561bed7bSAmine Khaldi {SECURITY_MANDATORY_HIGH_RID}};
7306561bed7bSAmine Khaldi char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
7307561bed7bSAmine Khaldi SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2, *sd3;
7308561bed7bSAmine Khaldi char buffer_acl[256], buffer[MAX_PATH];
7309561bed7bSAmine Khaldi ACL *acl = (ACL *)&buffer_acl, *acl2, *acl_child, *sacl;
7310561bed7bSAmine Khaldi BOOL defaulted, present, ret, found;
7311561bed7bSAmine Khaldi HANDLE token, token2, token3, token4, token5, token6;
7312561bed7bSAmine Khaldi EXPLICIT_ACCESSW exp_access;
7313561bed7bSAmine Khaldi TOKEN_MANDATORY_LABEL *tml;
7314561bed7bSAmine Khaldi BYTE buffer_integrity[64];
7315561bed7bSAmine Khaldi PROCESS_INFORMATION info;
7316561bed7bSAmine Khaldi DWORD size, index, retd;
7317561bed7bSAmine Khaldi ACCESS_ALLOWED_ACE *ace;
7318561bed7bSAmine Khaldi SECURITY_ATTRIBUTES sa;
7319561bed7bSAmine Khaldi STARTUPINFOA startup;
7320561bed7bSAmine Khaldi PSID psid;
7321561bed7bSAmine Khaldi
7322561bed7bSAmine Khaldi if (!pDuplicateTokenEx || !pConvertStringSidToSidA || !pAddAccessAllowedAceEx || !pGetAce
7323561bed7bSAmine Khaldi || !pSetEntriesInAclW)
7324561bed7bSAmine Khaldi {
7325561bed7bSAmine Khaldi win_skip("Some functions not available\n");
7326561bed7bSAmine Khaldi return;
7327561bed7bSAmine Khaldi }
7328561bed7bSAmine Khaldi
7329561bed7bSAmine Khaldi /* Test whether we can create tokens with security descriptors */
7330561bed7bSAmine Khaldi ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
7331561bed7bSAmine Khaldi ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
7332561bed7bSAmine Khaldi
7333561bed7bSAmine Khaldi ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7334561bed7bSAmine Khaldi ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError());
7335561bed7bSAmine Khaldi
7336*3c1b7834SAmine Khaldi memset(buffer_acl, 0, sizeof(buffer_acl));
7337561bed7bSAmine Khaldi ret = InitializeAcl(acl, 256, ACL_REVISION);
7338561bed7bSAmine Khaldi ok(ret, "InitializeAcl failed with error %u\n", GetLastError());
7339561bed7bSAmine Khaldi
7340561bed7bSAmine Khaldi ret = pConvertStringSidToSidA("S-1-5-6", &psid);
7341561bed7bSAmine Khaldi ok(ret, "ConvertStringSidToSidA failed with error %u\n", GetLastError());
7342561bed7bSAmine Khaldi
7343561bed7bSAmine Khaldi ret = pAddAccessAllowedAceEx(acl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, GENERIC_ALL, psid);
7344561bed7bSAmine Khaldi ok(ret, "AddAccessAllowedAceEx failed with error %u\n", GetLastError());
7345561bed7bSAmine Khaldi
7346561bed7bSAmine Khaldi ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE);
7347561bed7bSAmine Khaldi ok(ret, "SetSecurityDescriptorDacl failed with error %u\n", GetLastError());
7348561bed7bSAmine Khaldi
7349561bed7bSAmine Khaldi sa.nLength = sizeof(SECURITY_ATTRIBUTES);
7350561bed7bSAmine Khaldi sa.lpSecurityDescriptor = sd;
7351561bed7bSAmine Khaldi sa.bInheritHandle = FALSE;
7352561bed7bSAmine Khaldi
7353561bed7bSAmine Khaldi ret = pDuplicateTokenEx(token, MAXIMUM_ALLOWED, &sa, SecurityImpersonation, TokenImpersonation, &token2);
7354561bed7bSAmine Khaldi ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError());
7355561bed7bSAmine Khaldi
7356561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7357561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7358561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
7359561bed7bSAmine Khaldi
7360561bed7bSAmine Khaldi sd2 = HeapAlloc(GetProcessHeap(), 0, size);
7361561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, sd2, size, &size);
7362561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7363561bed7bSAmine Khaldi
7364561bed7bSAmine Khaldi acl2 = (void *)0xdeadbeef;
7365561bed7bSAmine Khaldi present = FALSE;
7366561bed7bSAmine Khaldi defaulted = TRUE;
7367561bed7bSAmine Khaldi ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
7368561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
7369561bed7bSAmine Khaldi ok(present, "acl2 not present\n");
7370561bed7bSAmine Khaldi ok(acl2 != (void *)0xdeadbeef, "acl2 not set\n");
7371561bed7bSAmine Khaldi ok(acl2->AceCount == 1, "Expected 1 ACE, got %d\n", acl2->AceCount);
7372561bed7bSAmine Khaldi ok(!defaulted, "acl2 defaulted\n");
7373561bed7bSAmine Khaldi
7374561bed7bSAmine Khaldi ret = pGetAce(acl2, 0, (void **)&ace);
7375561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7376561bed7bSAmine Khaldi ok(ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType);
7377561bed7bSAmine Khaldi ok(EqualSid(&ace->SidStart, psid), "Expected access allowed ACE\n");
7378561bed7bSAmine Khaldi ok(ace->Header.AceFlags == NO_PROPAGATE_INHERIT_ACE,
7379561bed7bSAmine Khaldi "Expected NO_PROPAGATE_INHERIT_ACE as flags, got %x\n", ace->Header.AceFlags);
7380561bed7bSAmine Khaldi
7381561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd2);
7382561bed7bSAmine Khaldi
7383561bed7bSAmine Khaldi /* Duplicate token without security attributes.
7384561bed7bSAmine Khaldi * Tokens do not inherit the security descriptor in DuplicateToken. */
7385561bed7bSAmine Khaldi ret = pDuplicateTokenEx(token2, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &token3);
7386561bed7bSAmine Khaldi ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError());
7387561bed7bSAmine Khaldi
7388561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7389561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7390561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
7391561bed7bSAmine Khaldi
7392561bed7bSAmine Khaldi sd2 = HeapAlloc(GetProcessHeap(), 0, size);
7393561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, sd2, size, &size);
7394561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7395561bed7bSAmine Khaldi
7396561bed7bSAmine Khaldi acl2 = (void *)0xdeadbeef;
7397561bed7bSAmine Khaldi present = FALSE;
7398561bed7bSAmine Khaldi defaulted = TRUE;
7399561bed7bSAmine Khaldi ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
7400561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
7401561bed7bSAmine Khaldi ok(present, "DACL not present\n");
7402561bed7bSAmine Khaldi
7403561bed7bSAmine Khaldi if (present)
7404561bed7bSAmine Khaldi {
7405561bed7bSAmine Khaldi ok(acl2 != (void *)0xdeadbeef, "DACL not set\n");
7406561bed7bSAmine Khaldi ok(!defaulted, "DACL defaulted\n");
7407561bed7bSAmine Khaldi
7408561bed7bSAmine Khaldi index = 0;
7409561bed7bSAmine Khaldi found = FALSE;
7410561bed7bSAmine Khaldi while (pGetAce(acl2, index++, (void **)&ace))
7411561bed7bSAmine Khaldi {
7412561bed7bSAmine Khaldi if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace->SidStart, psid))
7413561bed7bSAmine Khaldi found = TRUE;
7414561bed7bSAmine Khaldi }
7415561bed7bSAmine Khaldi ok(!found, "Access allowed ACE was inherited\n");
7416561bed7bSAmine Khaldi }
7417561bed7bSAmine Khaldi
7418561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd2);
7419561bed7bSAmine Khaldi
7420561bed7bSAmine Khaldi /* When creating a child process, the process does inherit the token of
7421561bed7bSAmine Khaldi * the parent but not the DACL of the token */
7422561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7423561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7424561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
7425561bed7bSAmine Khaldi
7426561bed7bSAmine Khaldi sd2 = HeapAlloc(GetProcessHeap(), 0, size);
7427561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd2, size, &size);
7428561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7429561bed7bSAmine Khaldi
7430561bed7bSAmine Khaldi acl2 = (void *)0xdeadbeef;
7431561bed7bSAmine Khaldi present = FALSE;
7432561bed7bSAmine Khaldi defaulted = TRUE;
7433561bed7bSAmine Khaldi ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
7434561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
7435561bed7bSAmine Khaldi ok(present, "DACL not present\n");
7436561bed7bSAmine Khaldi ok(acl2 != (void *)0xdeadbeef, "DACL not set\n");
7437561bed7bSAmine Khaldi ok(!defaulted, "DACL defaulted\n");
7438561bed7bSAmine Khaldi
7439561bed7bSAmine Khaldi exp_access.grfAccessPermissions = GENERIC_ALL;
7440561bed7bSAmine Khaldi exp_access.grfAccessMode = GRANT_ACCESS;
7441561bed7bSAmine Khaldi exp_access.grfInheritance = NO_PROPAGATE_INHERIT_ACE;
7442561bed7bSAmine Khaldi exp_access.Trustee.pMultipleTrustee = NULL;
7443561bed7bSAmine Khaldi exp_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
7444561bed7bSAmine Khaldi exp_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
7445561bed7bSAmine Khaldi exp_access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
7446561bed7bSAmine Khaldi exp_access.Trustee.ptstrName = (void*)psid;
7447561bed7bSAmine Khaldi
7448561bed7bSAmine Khaldi retd = pSetEntriesInAclW(1, &exp_access, acl2, &acl_child);
7449561bed7bSAmine Khaldi ok(retd == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", retd);
7450561bed7bSAmine Khaldi
7451561bed7bSAmine Khaldi memset(sd, 0, sizeof(buffer_sd));
7452561bed7bSAmine Khaldi ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7453561bed7bSAmine Khaldi ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError());
7454561bed7bSAmine Khaldi
7455561bed7bSAmine Khaldi ret = SetSecurityDescriptorDacl(sd, TRUE, acl_child, FALSE);
7456561bed7bSAmine Khaldi ok(ret, "SetSecurityDescriptorDacl failed with error %u\n", GetLastError());
7457561bed7bSAmine Khaldi
7458561bed7bSAmine Khaldi ret = SetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd);
7459561bed7bSAmine Khaldi ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError());
7460561bed7bSAmine Khaldi
7461561bed7bSAmine Khaldi /* The security label is also not inherited */
7462561bed7bSAmine Khaldi if (pAddMandatoryAce)
7463561bed7bSAmine Khaldi {
7464561bed7bSAmine Khaldi memset(buffer_integrity, 0, sizeof(buffer_integrity));
7465561bed7bSAmine Khaldi ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
7466561bed7bSAmine Khaldi ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
7467561bed7bSAmine Khaldi tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
7468561bed7bSAmine Khaldi ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
7469561bed7bSAmine Khaldi "Expected medium or high integrity level\n");
7470561bed7bSAmine Khaldi
7471561bed7bSAmine Khaldi if (EqualSid(tml->Label.Sid, &high_level))
7472561bed7bSAmine Khaldi {
7473561bed7bSAmine Khaldi DWORD process_id;
7474561bed7bSAmine Khaldi HANDLE process;
7475561bed7bSAmine Khaldi HWND shell;
7476561bed7bSAmine Khaldi
7477561bed7bSAmine Khaldi /* This test tries to get a medium token and then impersonates this token. The
7478561bed7bSAmine Khaldi * idea is to check whether the sd label of a newly created token depends on the
7479561bed7bSAmine Khaldi * current active token or the integrity level of the newly created token. */
7480561bed7bSAmine Khaldi
7481561bed7bSAmine Khaldi /* Steal process token of the explorer.exe process */
7482561bed7bSAmine Khaldi shell = GetShellWindow();
7483561bed7bSAmine Khaldi todo_wine ok(shell != NULL, "Failed to get shell window\n");
7484561bed7bSAmine Khaldi if (!shell) shell = GetDesktopWindow(); /* FIXME: Workaround for Wine */
7485561bed7bSAmine Khaldi ok(GetWindowThreadProcessId(shell, &process_id),
7486561bed7bSAmine Khaldi "Failed to get process id of shell window: %u\n", GetLastError());
7487561bed7bSAmine Khaldi process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process_id);
7488561bed7bSAmine Khaldi ok(process != NULL, "Failed to open process: %u\n", GetLastError());
7489561bed7bSAmine Khaldi ok(OpenProcessToken(process, TOKEN_ALL_ACCESS, &token4),
7490561bed7bSAmine Khaldi "Failed to open process token: %u\n", GetLastError());
7491561bed7bSAmine Khaldi CloseHandle(process);
7492561bed7bSAmine Khaldi
7493561bed7bSAmine Khaldi /* Check TokenIntegrityLevel and LABEL_SECURITY_INFORMATION of explorer.exe token */
7494561bed7bSAmine Khaldi memset(buffer_integrity, 0, sizeof(buffer_integrity));
7495561bed7bSAmine Khaldi ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
7496561bed7bSAmine Khaldi ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
7497561bed7bSAmine Khaldi tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
7498561bed7bSAmine Khaldi ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
7499561bed7bSAmine Khaldi
7500561bed7bSAmine Khaldi size = 0;
7501561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7502561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7503561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
7504561bed7bSAmine Khaldi
7505561bed7bSAmine Khaldi sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7506561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size);
7507561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7508561bed7bSAmine Khaldi
7509561bed7bSAmine Khaldi sacl = NULL;
7510561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
7511561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7512561bed7bSAmine Khaldi ok(present, "No SACL in the security descriptor\n");
7513561bed7bSAmine Khaldi ok(sacl != NULL, "NULL SACL in the security descriptor\n");
7514561bed7bSAmine Khaldi
7515561bed7bSAmine Khaldi if (sacl)
7516561bed7bSAmine Khaldi {
7517561bed7bSAmine Khaldi ret = pGetAce(sacl, 0, (void **)&ace);
7518561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7519561bed7bSAmine Khaldi ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7520561bed7bSAmine Khaldi "Unexpected ACE type %#x\n", ace->Header.AceType);
7521561bed7bSAmine Khaldi ok(EqualSid(&ace->SidStart, &medium_level),
7522561bed7bSAmine Khaldi "Expected medium integrity level\n");
7523561bed7bSAmine Khaldi }
7524561bed7bSAmine Khaldi
7525561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd3);
7526561bed7bSAmine Khaldi
7527561bed7bSAmine Khaldi /* Start child process with the explorer.exe token */
7528561bed7bSAmine Khaldi memset(&startup, 0, sizeof(startup));
7529561bed7bSAmine Khaldi startup.cb = sizeof(startup);
7530561bed7bSAmine Khaldi startup.dwFlags = STARTF_USESHOWWINDOW;
7531561bed7bSAmine Khaldi startup.wShowWindow = SW_SHOWNORMAL;
7532561bed7bSAmine Khaldi
7533561bed7bSAmine Khaldi sprintf(buffer, "%s tests/security.c test_token_sd_medium", myARGV[0]);
7534561bed7bSAmine Khaldi ret = CreateProcessAsUserA(token4, NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
7535561bed7bSAmine Khaldi ok(ret || GetLastError() == ERROR_PRIVILEGE_NOT_HELD,
7536561bed7bSAmine Khaldi "CreateProcess failed with error %u\n", GetLastError());
7537561bed7bSAmine Khaldi if (ret)
7538561bed7bSAmine Khaldi {
7539561bed7bSAmine Khaldi winetest_wait_child_process(info.hProcess);
7540561bed7bSAmine Khaldi CloseHandle(info.hProcess);
7541561bed7bSAmine Khaldi CloseHandle(info.hThread);
7542561bed7bSAmine Khaldi }
7543561bed7bSAmine Khaldi else
7544561bed7bSAmine Khaldi win_skip("Skipping test for creating process with medium level token\n");
7545561bed7bSAmine Khaldi
7546561bed7bSAmine Khaldi ret = DuplicateTokenEx(token4, 0, NULL, SecurityImpersonation, TokenImpersonation, &token5);
7547561bed7bSAmine Khaldi ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError());
7548561bed7bSAmine Khaldi ret = SetThreadToken(NULL, token5);
7549561bed7bSAmine Khaldi ok(ret, "SetThreadToken failed with error %u\n", GetLastError());
7550561bed7bSAmine Khaldi CloseHandle(token4);
7551561bed7bSAmine Khaldi
7552561bed7bSAmine Khaldi /* Restrict current process token while impersonating a medium integrity token */
7553561bed7bSAmine Khaldi ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token6);
7554561bed7bSAmine Khaldi ok(ret, "CreateRestrictedToken failed with error %u\n", GetLastError());
7555561bed7bSAmine Khaldi
7556561bed7bSAmine Khaldi memset(buffer_integrity, 0, sizeof(buffer_integrity));
7557561bed7bSAmine Khaldi ret = GetTokenInformation(token6, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
7558561bed7bSAmine Khaldi ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
7559561bed7bSAmine Khaldi tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
7560561bed7bSAmine Khaldi ok(EqualSid(tml->Label.Sid, &high_level), "Expected high integrity level\n");
7561561bed7bSAmine Khaldi
7562561bed7bSAmine Khaldi size = 0;
7563561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7564561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7565561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
7566561bed7bSAmine Khaldi
7567561bed7bSAmine Khaldi sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7568561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, sd3, size, &size);
7569561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7570561bed7bSAmine Khaldi
7571561bed7bSAmine Khaldi sacl = NULL;
7572561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
7573561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7574561bed7bSAmine Khaldi ok(present, "No SACL in the security descriptor\n");
7575561bed7bSAmine Khaldi ok(sacl != NULL, "NULL SACL in the security descriptor\n");
7576561bed7bSAmine Khaldi
7577561bed7bSAmine Khaldi if (sacl)
7578561bed7bSAmine Khaldi {
7579561bed7bSAmine Khaldi ret = pGetAce(sacl, 0, (void **)&ace);
7580561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7581561bed7bSAmine Khaldi ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7582561bed7bSAmine Khaldi "Unexpected ACE type %#x\n", ace->Header.AceType);
7583561bed7bSAmine Khaldi ok(EqualSid(&ace->SidStart, &medium_level),
7584561bed7bSAmine Khaldi "Expected medium integrity level\n");
7585561bed7bSAmine Khaldi }
7586561bed7bSAmine Khaldi
7587561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd3);
7588561bed7bSAmine Khaldi RevertToSelf();
7589561bed7bSAmine Khaldi CloseHandle(token5);
7590561bed7bSAmine Khaldi
7591561bed7bSAmine Khaldi /* Start child process with the restricted token */
7592561bed7bSAmine Khaldi sprintf(buffer, "%s tests/security.c test_token_sd_restricted", myARGV[0]);
7593561bed7bSAmine Khaldi ret = CreateProcessAsUserA(token6, NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
7594561bed7bSAmine Khaldi ok(ret, "CreateProcess failed with error %u\n", GetLastError());
7595561bed7bSAmine Khaldi winetest_wait_child_process(info.hProcess);
7596561bed7bSAmine Khaldi CloseHandle(info.hProcess);
7597561bed7bSAmine Khaldi CloseHandle(info.hThread);
7598561bed7bSAmine Khaldi CloseHandle(token6);
7599561bed7bSAmine Khaldi
7600561bed7bSAmine Khaldi /* DuplicateTokenEx should assign security label even when SA points to empty SD */
7601561bed7bSAmine Khaldi memset(sd, 0, sizeof(buffer_sd));
7602561bed7bSAmine Khaldi ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7603561bed7bSAmine Khaldi ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError());
7604561bed7bSAmine Khaldi
7605561bed7bSAmine Khaldi sa.nLength = sizeof(SECURITY_ATTRIBUTES);
7606561bed7bSAmine Khaldi sa.lpSecurityDescriptor = sd;
7607561bed7bSAmine Khaldi sa.bInheritHandle = FALSE;
7608561bed7bSAmine Khaldi
7609561bed7bSAmine Khaldi ret = DuplicateTokenEx(token, 0, &sa, 0, TokenPrimary, &token6);
7610561bed7bSAmine Khaldi ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError());
7611561bed7bSAmine Khaldi
7612561bed7bSAmine Khaldi size = 0;
7613561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7614561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7615561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
7616561bed7bSAmine Khaldi
7617561bed7bSAmine Khaldi sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7618561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, sd3, size, &size);
7619561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7620561bed7bSAmine Khaldi
7621561bed7bSAmine Khaldi sacl = NULL;
7622561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
7623561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7624561bed7bSAmine Khaldi ok(present, "No SACL in the security descriptor\n");
7625561bed7bSAmine Khaldi ok(sacl != NULL, "NULL SACL in the security descriptor\n");
7626561bed7bSAmine Khaldi
7627561bed7bSAmine Khaldi if (sacl)
7628561bed7bSAmine Khaldi {
7629561bed7bSAmine Khaldi ret = pGetAce(sacl, 0, (void **)&ace);
7630561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7631561bed7bSAmine Khaldi ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7632561bed7bSAmine Khaldi "Unexpected ACE type %#x\n", ace->Header.AceType);
7633561bed7bSAmine Khaldi ok(EqualSid(&ace->SidStart, &high_level),
7634561bed7bSAmine Khaldi "Expected high integrity level\n");
7635561bed7bSAmine Khaldi }
7636561bed7bSAmine Khaldi
7637561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd3);
7638561bed7bSAmine Khaldi CloseHandle(token6);
7639561bed7bSAmine Khaldi }
7640561bed7bSAmine Khaldi else
7641561bed7bSAmine Khaldi skip("Skipping test, running without admin rights\n");
7642561bed7bSAmine Khaldi
7643561bed7bSAmine Khaldi ret = InitializeAcl(acl, 256, ACL_REVISION);
7644561bed7bSAmine Khaldi ok(ret, "InitializeAcl failed with error %u\n", GetLastError());
7645561bed7bSAmine Khaldi
7646561bed7bSAmine Khaldi ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level);
7647561bed7bSAmine Khaldi ok(ret, "AddMandatoryAce failed with error %u\n", GetLastError());
7648561bed7bSAmine Khaldi
7649561bed7bSAmine Khaldi memset(sd, 0, sizeof(buffer_sd));
7650561bed7bSAmine Khaldi ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7651561bed7bSAmine Khaldi ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError());
7652561bed7bSAmine Khaldi
7653561bed7bSAmine Khaldi ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
7654561bed7bSAmine Khaldi ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7655561bed7bSAmine Khaldi
7656561bed7bSAmine Khaldi ret = SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd);
7657561bed7bSAmine Khaldi ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError());
7658561bed7bSAmine Khaldi
7659561bed7bSAmine Khaldi /* changing the label of the security descriptor does not change the integrity level of the token itself */
7660561bed7bSAmine Khaldi memset(buffer_integrity, 0, sizeof(buffer_integrity));
7661561bed7bSAmine Khaldi ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
7662561bed7bSAmine Khaldi ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
7663561bed7bSAmine Khaldi tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
7664561bed7bSAmine Khaldi ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
7665561bed7bSAmine Khaldi "Expected medium or high integrity level\n");
7666561bed7bSAmine Khaldi
7667561bed7bSAmine Khaldi /* restricting / duplicating a token resets the mandatory sd label */
7668561bed7bSAmine Khaldi ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token4);
7669561bed7bSAmine Khaldi ok(ret, "CreateRestrictedToken failed with error %u\n", GetLastError());
7670561bed7bSAmine Khaldi
7671561bed7bSAmine Khaldi memset(buffer_integrity, 0, sizeof(buffer_integrity));
7672561bed7bSAmine Khaldi ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
7673561bed7bSAmine Khaldi ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
7674561bed7bSAmine Khaldi tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
7675561bed7bSAmine Khaldi ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
7676561bed7bSAmine Khaldi "Expected medium or high integrity level\n");
7677561bed7bSAmine Khaldi
7678561bed7bSAmine Khaldi size = 0;
7679561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7680561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7681561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
7682561bed7bSAmine Khaldi
7683561bed7bSAmine Khaldi sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7684561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size);
7685561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7686561bed7bSAmine Khaldi
7687561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
7688561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7689561bed7bSAmine Khaldi ok(present, "No SACL in the security descriptor\n");
7690561bed7bSAmine Khaldi ok(sacl != NULL, "NULL SACL in the security descriptor\n");
7691561bed7bSAmine Khaldi
7692561bed7bSAmine Khaldi if (sacl)
7693561bed7bSAmine Khaldi {
7694561bed7bSAmine Khaldi ret = pGetAce(sacl, 0, (void **)&ace);
7695561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7696561bed7bSAmine Khaldi ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7697561bed7bSAmine Khaldi "Unexpected ACE type %#x\n", ace->Header.AceType);
7698561bed7bSAmine Khaldi ok(EqualSid(&ace->SidStart, &medium_level) || EqualSid(&ace->SidStart, &high_level),
7699561bed7bSAmine Khaldi "Low integrity level should not have been inherited\n");
7700561bed7bSAmine Khaldi }
7701561bed7bSAmine Khaldi
7702561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd3);
7703561bed7bSAmine Khaldi CloseHandle(token4);
7704561bed7bSAmine Khaldi
7705561bed7bSAmine Khaldi ret = DuplicateTokenEx(token, 0, NULL, 0, TokenPrimary, &token4);
7706561bed7bSAmine Khaldi ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError());
7707561bed7bSAmine Khaldi
7708561bed7bSAmine Khaldi memset(buffer_integrity, 0, sizeof(buffer_integrity));
7709561bed7bSAmine Khaldi ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
7710561bed7bSAmine Khaldi ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
7711561bed7bSAmine Khaldi tml = (TOKEN_MANDATORY_LABEL*) buffer_integrity;
7712561bed7bSAmine Khaldi ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
7713561bed7bSAmine Khaldi "Expected medium or high integrity level\n");
7714561bed7bSAmine Khaldi
7715561bed7bSAmine Khaldi size = 0;
7716561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7717561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7718561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
7719561bed7bSAmine Khaldi
7720561bed7bSAmine Khaldi sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
7721561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size);
7722561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7723561bed7bSAmine Khaldi
7724561bed7bSAmine Khaldi sacl = NULL;
7725561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
7726561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7727561bed7bSAmine Khaldi ok(present, "No SACL in the security descriptor\n");
7728561bed7bSAmine Khaldi ok(sacl != NULL, "NULL SACL in the security descriptor\n");
7729561bed7bSAmine Khaldi
7730561bed7bSAmine Khaldi if (sacl)
7731561bed7bSAmine Khaldi {
7732561bed7bSAmine Khaldi ret = pGetAce(sacl, 0, (void **)&ace);
7733561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7734561bed7bSAmine Khaldi ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7735561bed7bSAmine Khaldi "Unexpected ACE type %#x\n", ace->Header.AceType);
7736561bed7bSAmine Khaldi ok(EqualSid(&ace->SidStart, &medium_level) || EqualSid(&ace->SidStart, &high_level),
7737561bed7bSAmine Khaldi "Low integrity level should not have been inherited\n");
7738561bed7bSAmine Khaldi }
7739561bed7bSAmine Khaldi
7740561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd3);
7741561bed7bSAmine Khaldi CloseHandle(token4);
7742561bed7bSAmine Khaldi }
7743561bed7bSAmine Khaldi else
7744561bed7bSAmine Khaldi win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
7745561bed7bSAmine Khaldi
7746561bed7bSAmine Khaldi /* Start child process with our modified token */
7747561bed7bSAmine Khaldi memset(&startup, 0, sizeof(startup));
7748561bed7bSAmine Khaldi startup.cb = sizeof(startup);
7749561bed7bSAmine Khaldi startup.dwFlags = STARTF_USESHOWWINDOW;
7750561bed7bSAmine Khaldi startup.wShowWindow = SW_SHOWNORMAL;
7751561bed7bSAmine Khaldi
7752561bed7bSAmine Khaldi sprintf(buffer, "%s tests/security.c test_token_sd", myARGV[0]);
7753561bed7bSAmine Khaldi ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
7754561bed7bSAmine Khaldi ok(ret, "CreateProcess failed with error %u\n", GetLastError());
7755561bed7bSAmine Khaldi winetest_wait_child_process(info.hProcess);
7756561bed7bSAmine Khaldi CloseHandle(info.hProcess);
7757561bed7bSAmine Khaldi CloseHandle(info.hThread);
7758561bed7bSAmine Khaldi
7759561bed7bSAmine Khaldi LocalFree(acl_child);
7760*3c1b7834SAmine Khaldi HeapFree(GetProcessHeap(), 0, sd2);
7761561bed7bSAmine Khaldi LocalFree(psid);
7762561bed7bSAmine Khaldi
7763561bed7bSAmine Khaldi CloseHandle(token3);
7764561bed7bSAmine Khaldi CloseHandle(token2);
7765561bed7bSAmine Khaldi CloseHandle(token);
7766561bed7bSAmine Khaldi }
7767561bed7bSAmine Khaldi
test_child_token_sd(void)7768561bed7bSAmine Khaldi static void test_child_token_sd(void)
7769561bed7bSAmine Khaldi {
7770561bed7bSAmine Khaldi static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7771561bed7bSAmine Khaldi {SECURITY_MANDATORY_LOW_RID}};
7772561bed7bSAmine Khaldi SYSTEM_MANDATORY_LABEL_ACE *ace_label;
7773561bed7bSAmine Khaldi BOOL ret, present, defaulted;
7774561bed7bSAmine Khaldi ACCESS_ALLOWED_ACE *acc_ace;
7775561bed7bSAmine Khaldi SECURITY_DESCRIPTOR *sd;
7776561bed7bSAmine Khaldi DWORD size, i;
7777561bed7bSAmine Khaldi HANDLE token;
7778561bed7bSAmine Khaldi PSID psid;
7779561bed7bSAmine Khaldi ACL *acl;
7780561bed7bSAmine Khaldi
7781561bed7bSAmine Khaldi ret = pConvertStringSidToSidA("S-1-5-6", &psid);
7782561bed7bSAmine Khaldi ok(ret, "ConvertStringSidToSidA failed with error %u\n", GetLastError());
7783561bed7bSAmine Khaldi
7784561bed7bSAmine Khaldi ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
7785561bed7bSAmine Khaldi ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
7786561bed7bSAmine Khaldi
7787561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7788561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7789561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
7790561bed7bSAmine Khaldi
7791561bed7bSAmine Khaldi sd = HeapAlloc(GetProcessHeap(), 0, size);
7792561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd, size, &size);
7793561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7794561bed7bSAmine Khaldi
7795561bed7bSAmine Khaldi acl = NULL;
7796561bed7bSAmine Khaldi present = FALSE;
7797561bed7bSAmine Khaldi defaulted = TRUE;
7798561bed7bSAmine Khaldi ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
7799561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
7800561bed7bSAmine Khaldi ok(present, "DACL not present\n");
7801561bed7bSAmine Khaldi ok(acl && acl != (void *)0xdeadbeef, "Got invalid DACL\n");
7802561bed7bSAmine Khaldi ok(!defaulted, "DACL defaulted\n");
7803561bed7bSAmine Khaldi
7804561bed7bSAmine Khaldi ok(acl->AceCount, "Expected at least one ACE\n");
7805561bed7bSAmine Khaldi for (i = 0; i < acl->AceCount; i++)
7806561bed7bSAmine Khaldi {
7807561bed7bSAmine Khaldi ok(pGetAce(acl, i, (void **)&acc_ace), "GetAce failed with error %u\n", GetLastError());
7808561bed7bSAmine Khaldi ok(acc_ace->Header.AceType != ACCESS_ALLOWED_ACE_TYPE || !EqualSid(&acc_ace->SidStart, psid),
7809561bed7bSAmine Khaldi "ACE inherited from the parent\n");
7810561bed7bSAmine Khaldi }
7811561bed7bSAmine Khaldi
7812561bed7bSAmine Khaldi LocalFree(psid);
7813561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd);
7814561bed7bSAmine Khaldi
7815561bed7bSAmine Khaldi if (!pAddMandatoryAce)
7816561bed7bSAmine Khaldi {
7817561bed7bSAmine Khaldi win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
7818561bed7bSAmine Khaldi return;
7819561bed7bSAmine Khaldi }
7820561bed7bSAmine Khaldi
7821561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7822561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7823561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
7824561bed7bSAmine Khaldi
7825561bed7bSAmine Khaldi sd = HeapAlloc(GetProcessHeap(), 0, size);
7826561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7827561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7828561bed7bSAmine Khaldi
7829561bed7bSAmine Khaldi acl = NULL;
7830561bed7bSAmine Khaldi present = FALSE;
7831561bed7bSAmine Khaldi defaulted = TRUE;
7832561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted);
7833561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7834561bed7bSAmine Khaldi ok(present, "SACL not present\n");
7835561bed7bSAmine Khaldi ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n");
7836561bed7bSAmine Khaldi ok(!defaulted, "SACL defaulted\n");
7837561bed7bSAmine Khaldi ok(acl->AceCount == 1, "Expected exactly one ACE\n");
7838561bed7bSAmine Khaldi ret = pGetAce(acl, 0, (void **)&ace_label);
7839561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7840561bed7bSAmine Khaldi ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7841561bed7bSAmine Khaldi "Unexpected ACE type %#x\n", ace_label->Header.AceType);
7842561bed7bSAmine Khaldi ok(!EqualSid(&ace_label->SidStart, &low_level),
7843561bed7bSAmine Khaldi "Low integrity level should not have been inherited\n");
7844561bed7bSAmine Khaldi
7845561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd);
7846561bed7bSAmine Khaldi }
7847561bed7bSAmine Khaldi
test_child_token_sd_restricted(void)7848561bed7bSAmine Khaldi static void test_child_token_sd_restricted(void)
7849561bed7bSAmine Khaldi {
7850561bed7bSAmine Khaldi static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7851561bed7bSAmine Khaldi {SECURITY_MANDATORY_HIGH_RID}};
7852561bed7bSAmine Khaldi SYSTEM_MANDATORY_LABEL_ACE *ace_label;
7853561bed7bSAmine Khaldi BOOL ret, present, defaulted;
7854561bed7bSAmine Khaldi TOKEN_MANDATORY_LABEL *tml;
7855561bed7bSAmine Khaldi BYTE buffer_integrity[64];
7856561bed7bSAmine Khaldi SECURITY_DESCRIPTOR *sd;
7857561bed7bSAmine Khaldi HANDLE token;
7858561bed7bSAmine Khaldi DWORD size;
7859561bed7bSAmine Khaldi ACL *acl;
7860561bed7bSAmine Khaldi
7861561bed7bSAmine Khaldi if (!pAddMandatoryAce)
7862561bed7bSAmine Khaldi {
7863561bed7bSAmine Khaldi win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
7864561bed7bSAmine Khaldi return;
7865561bed7bSAmine Khaldi }
7866561bed7bSAmine Khaldi
7867561bed7bSAmine Khaldi ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
7868561bed7bSAmine Khaldi ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
7869561bed7bSAmine Khaldi
7870561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7871561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7872561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
7873561bed7bSAmine Khaldi
7874561bed7bSAmine Khaldi sd = HeapAlloc(GetProcessHeap(), 0, size);
7875561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7876561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7877561bed7bSAmine Khaldi
7878561bed7bSAmine Khaldi acl = NULL;
7879561bed7bSAmine Khaldi present = FALSE;
7880561bed7bSAmine Khaldi defaulted = TRUE;
7881561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted);
7882561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7883561bed7bSAmine Khaldi ok(present, "SACL not present\n");
7884561bed7bSAmine Khaldi ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n");
7885561bed7bSAmine Khaldi ok(!defaulted, "SACL defaulted\n");
7886561bed7bSAmine Khaldi ok(acl->AceCount == 1, "Expected exactly one ACE\n");
7887561bed7bSAmine Khaldi ret = pGetAce(acl, 0, (void **)&ace_label);
7888561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7889561bed7bSAmine Khaldi ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7890561bed7bSAmine Khaldi "Unexpected ACE type %#x\n", ace_label->Header.AceType);
7891561bed7bSAmine Khaldi ok(EqualSid(&ace_label->SidStart, &high_level),
7892561bed7bSAmine Khaldi "Expected high integrity level\n");
7893561bed7bSAmine Khaldi
7894561bed7bSAmine Khaldi memset(buffer_integrity, 0, sizeof(buffer_integrity));
7895561bed7bSAmine Khaldi ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
7896561bed7bSAmine Khaldi ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
7897561bed7bSAmine Khaldi tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
7898561bed7bSAmine Khaldi ok(EqualSid(tml->Label.Sid, &high_level), "Expected high integrity level\n");
7899561bed7bSAmine Khaldi
7900561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd);
7901561bed7bSAmine Khaldi }
7902561bed7bSAmine Khaldi
test_child_token_sd_medium(void)7903561bed7bSAmine Khaldi static void test_child_token_sd_medium(void)
7904561bed7bSAmine Khaldi {
7905561bed7bSAmine Khaldi static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7906561bed7bSAmine Khaldi {SECURITY_MANDATORY_MEDIUM_RID}};
7907561bed7bSAmine Khaldi SYSTEM_MANDATORY_LABEL_ACE *ace_label;
7908561bed7bSAmine Khaldi BOOL ret, present, defaulted;
7909561bed7bSAmine Khaldi TOKEN_MANDATORY_LABEL *tml;
7910561bed7bSAmine Khaldi BYTE buffer_integrity[64];
7911561bed7bSAmine Khaldi SECURITY_DESCRIPTOR *sd;
7912561bed7bSAmine Khaldi HANDLE token;
7913561bed7bSAmine Khaldi DWORD size;
7914561bed7bSAmine Khaldi ACL *acl;
7915561bed7bSAmine Khaldi
7916561bed7bSAmine Khaldi if (!pAddMandatoryAce)
7917561bed7bSAmine Khaldi {
7918561bed7bSAmine Khaldi win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
7919561bed7bSAmine Khaldi return;
7920561bed7bSAmine Khaldi }
7921561bed7bSAmine Khaldi
7922561bed7bSAmine Khaldi ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
7923561bed7bSAmine Khaldi ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
7924561bed7bSAmine Khaldi
7925561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7926561bed7bSAmine Khaldi ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7927561bed7bSAmine Khaldi "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError());
7928561bed7bSAmine Khaldi
7929561bed7bSAmine Khaldi sd = HeapAlloc(GetProcessHeap(), 0, size);
7930561bed7bSAmine Khaldi ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7931561bed7bSAmine Khaldi ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
7932561bed7bSAmine Khaldi
7933561bed7bSAmine Khaldi acl = NULL;
7934561bed7bSAmine Khaldi present = FALSE;
7935561bed7bSAmine Khaldi defaulted = TRUE;
7936561bed7bSAmine Khaldi ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted);
7937561bed7bSAmine Khaldi ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
7938561bed7bSAmine Khaldi ok(present, "SACL not present\n");
7939561bed7bSAmine Khaldi ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n");
7940561bed7bSAmine Khaldi ok(!defaulted, "SACL defaulted\n");
7941561bed7bSAmine Khaldi ok(acl->AceCount == 1, "Expected exactly one ACE\n");
7942561bed7bSAmine Khaldi ret = pGetAce(acl, 0, (void **)&ace_label);
7943561bed7bSAmine Khaldi ok(ret, "GetAce failed with error %u\n", GetLastError());
7944561bed7bSAmine Khaldi ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7945561bed7bSAmine Khaldi "Unexpected ACE type %#x\n", ace_label->Header.AceType);
7946561bed7bSAmine Khaldi ok(EqualSid(&ace_label->SidStart, &medium_level),
7947561bed7bSAmine Khaldi "Expected medium integrity level\n");
7948561bed7bSAmine Khaldi
7949561bed7bSAmine Khaldi memset(buffer_integrity, 0, sizeof(buffer_integrity));
7950561bed7bSAmine Khaldi ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size);
7951561bed7bSAmine Khaldi ok(ret, "GetTokenInformation failed with error %u\n", GetLastError());
7952561bed7bSAmine Khaldi tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity;
7953561bed7bSAmine Khaldi ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n");
7954561bed7bSAmine Khaldi
7955561bed7bSAmine Khaldi HeapFree(GetProcessHeap(), 0, sd);
7956561bed7bSAmine Khaldi }
7957561bed7bSAmine Khaldi
test_GetExplicitEntriesFromAclW(void)7958c2c66affSColin Finck static void test_GetExplicitEntriesFromAclW(void)
7959c2c66affSColin Finck {
7960c2c66affSColin Finck static const WCHAR wszCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'};
7961c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
7962c2c66affSColin Finck SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
7963c2c66affSColin Finck PSID everyone_sid = NULL, users_sid = NULL;
7964c2c66affSColin Finck EXPLICIT_ACCESSW access;
7965c2c66affSColin Finck EXPLICIT_ACCESSW *access2;
7966c2c66affSColin Finck PACL new_acl, old_acl = NULL;
7967c2c66affSColin Finck ULONG count;
7968c2c66affSColin Finck DWORD res;
7969c2c66affSColin Finck
7970c2c66affSColin Finck if (!pGetExplicitEntriesFromAclW)
7971c2c66affSColin Finck {
7972c2c66affSColin Finck win_skip("GetExplicitEntriesFromAclW is not available\n");
7973c2c66affSColin Finck return;
7974c2c66affSColin Finck }
7975c2c66affSColin Finck
7976c2c66affSColin Finck if (!pSetEntriesInAclW)
7977c2c66affSColin Finck {
7978c2c66affSColin Finck win_skip("SetEntriesInAclW is not available\n");
7979c2c66affSColin Finck return;
7980c2c66affSColin Finck }
7981c2c66affSColin Finck
7982c2c66affSColin Finck old_acl = HeapAlloc(GetProcessHeap(), 0, 256);
7983c2c66affSColin Finck res = InitializeAcl(old_acl, 256, ACL_REVISION);
7984c2c66affSColin Finck if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
7985c2c66affSColin Finck {
7986c2c66affSColin Finck win_skip("ACLs not implemented - skipping tests\n");
7987c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, old_acl);
7988c2c66affSColin Finck return;
7989c2c66affSColin Finck }
7990c2c66affSColin Finck ok(res, "InitializeAcl failed with error %d\n", GetLastError());
7991c2c66affSColin Finck
7992c2c66affSColin Finck res = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid);
7993c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
7994c2c66affSColin Finck
7995c2c66affSColin Finck res = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
7996c2c66affSColin Finck DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &users_sid);
7997c2c66affSColin Finck ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
7998c2c66affSColin Finck
7999c2c66affSColin Finck res = AddAccessAllowedAce(old_acl, ACL_REVISION, KEY_READ, users_sid);
8000c2c66affSColin Finck ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
8001c2c66affSColin Finck
8002c2c66affSColin Finck access2 = NULL;
8003c2c66affSColin Finck res = pGetExplicitEntriesFromAclW(old_acl, &count, &access2);
8004c2c66affSColin Finck ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError());
8005c2c66affSColin Finck ok(count == 1, "Expected count == 1, got %d\n", count);
8006c2c66affSColin Finck ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
8007c2c66affSColin Finck ok(access2[0].grfAccessPermissions == KEY_READ, "Expected KEY_READ, got %d\n", access2[0].grfAccessPermissions);
8008c2c66affSColin Finck ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
8009c2c66affSColin Finck ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance);
8010c2c66affSColin Finck ok(EqualSid(access2[0].Trustee.ptstrName, users_sid), "Expected equal SIDs\n");
8011c2c66affSColin Finck LocalFree(access2);
8012c2c66affSColin Finck
8013c2c66affSColin Finck access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
8014c2c66affSColin Finck access.Trustee.pMultipleTrustee = NULL;
8015c2c66affSColin Finck
8016c2c66affSColin Finck access.grfAccessPermissions = KEY_WRITE;
8017c2c66affSColin Finck access.grfAccessMode = GRANT_ACCESS;
8018c2c66affSColin Finck access.grfInheritance = NO_INHERITANCE;
8019c2c66affSColin Finck access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
8020c2c66affSColin Finck access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
8021c2c66affSColin Finck access.Trustee.ptstrName = everyone_sid;
8022c2c66affSColin Finck res = pSetEntriesInAclW(1, &access, old_acl, &new_acl);
8023c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
8024c2c66affSColin Finck ok(new_acl != NULL, "returned acl was NULL\n");
8025c2c66affSColin Finck
8026c2c66affSColin Finck access2 = NULL;
8027c2c66affSColin Finck res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2);
8028c2c66affSColin Finck ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError());
8029c2c66affSColin Finck ok(count == 2, "Expected count == 2, got %d\n", count);
8030c2c66affSColin Finck ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
8031c2c66affSColin Finck ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions);
8032c2c66affSColin Finck ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN,
8033c2c66affSColin Finck "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType);
8034c2c66affSColin Finck ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
8035c2c66affSColin Finck ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance);
8036c2c66affSColin Finck ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n");
8037c2c66affSColin Finck LocalFree(access2);
8038c2c66affSColin Finck LocalFree(new_acl);
8039c2c66affSColin Finck
8040c2c66affSColin Finck access.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
8041c2c66affSColin Finck res = pSetEntriesInAclW(1, &access, old_acl, &new_acl);
8042c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
8043c2c66affSColin Finck ok(new_acl != NULL, "returned acl was NULL\n");
8044c2c66affSColin Finck
8045c2c66affSColin Finck access2 = NULL;
8046c2c66affSColin Finck res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2);
8047c2c66affSColin Finck ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError());
8048c2c66affSColin Finck ok(count == 2, "Expected count == 2, got %d\n", count);
8049c2c66affSColin Finck ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
8050c2c66affSColin Finck ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions);
8051c2c66affSColin Finck ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN,
8052c2c66affSColin Finck "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType);
8053c2c66affSColin Finck ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
8054c2c66affSColin Finck ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance);
8055c2c66affSColin Finck ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n");
8056c2c66affSColin Finck LocalFree(access2);
8057c2c66affSColin Finck LocalFree(new_acl);
8058c2c66affSColin Finck
8059c2c66affSColin Finck access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
8060c2c66affSColin Finck access.Trustee.ptstrName = (LPWSTR)wszCurrentUser;
8061c2c66affSColin Finck res = pSetEntriesInAclW(1, &access, old_acl, &new_acl);
8062c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
8063c2c66affSColin Finck ok(new_acl != NULL, "returned acl was NULL\n");
8064c2c66affSColin Finck
8065c2c66affSColin Finck access2 = NULL;
8066c2c66affSColin Finck res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2);
8067c2c66affSColin Finck ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError());
8068c2c66affSColin Finck ok(count == 2, "Expected count == 2, got %d\n", count);
8069c2c66affSColin Finck ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
8070c2c66affSColin Finck ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions);
8071c2c66affSColin Finck ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN,
8072c2c66affSColin Finck "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType);
8073c2c66affSColin Finck ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
8074c2c66affSColin Finck ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance);
8075c2c66affSColin Finck LocalFree(access2);
8076c2c66affSColin Finck LocalFree(new_acl);
8077c2c66affSColin Finck
8078c2c66affSColin Finck access.grfAccessMode = REVOKE_ACCESS;
8079c2c66affSColin Finck access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
8080c2c66affSColin Finck access.Trustee.ptstrName = users_sid;
8081c2c66affSColin Finck res = pSetEntriesInAclW(1, &access, old_acl, &new_acl);
8082c2c66affSColin Finck ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
8083c2c66affSColin Finck ok(new_acl != NULL, "returned acl was NULL\n");
8084c2c66affSColin Finck
8085c2c66affSColin Finck access2 = (void *)0xdeadbeef;
8086c2c66affSColin Finck res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2);
8087c2c66affSColin Finck ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError());
8088c2c66affSColin Finck ok(count == 0, "Expected count == 0, got %d\n", count);
8089c2c66affSColin Finck ok(access2 == NULL, "access2 was not NULL\n");
8090c2c66affSColin Finck LocalFree(new_acl);
8091c2c66affSColin Finck
8092c2c66affSColin Finck FreeSid(users_sid);
8093c2c66affSColin Finck FreeSid(everyone_sid);
8094c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, old_acl);
8095c2c66affSColin Finck }
8096c2c66affSColin Finck
test_BuildSecurityDescriptorW(void)8097c2c66affSColin Finck static void test_BuildSecurityDescriptorW(void)
8098c2c66affSColin Finck {
8099c2c66affSColin Finck SECURITY_DESCRIPTOR old_sd, *new_sd, *rel_sd;
8100c2c66affSColin Finck ULONG new_sd_size;
8101c2c66affSColin Finck DWORD buf_size;
8102c2c66affSColin Finck char buf[1024];
8103c2c66affSColin Finck BOOL success;
8104c2c66affSColin Finck DWORD ret;
8105c2c66affSColin Finck
8106c2c66affSColin Finck InitializeSecurityDescriptor(&old_sd, SECURITY_DESCRIPTOR_REVISION);
8107c2c66affSColin Finck
8108c2c66affSColin Finck buf_size = sizeof(buf);
8109c2c66affSColin Finck rel_sd = (SECURITY_DESCRIPTOR *)buf;
8110c2c66affSColin Finck success = MakeSelfRelativeSD(&old_sd, rel_sd, &buf_size);
8111c2c66affSColin Finck ok(success, "MakeSelfRelativeSD failed with %u\n", GetLastError());
8112c2c66affSColin Finck
8113c2c66affSColin Finck new_sd = NULL;
8114c2c66affSColin Finck new_sd_size = 0;
8115c2c66affSColin Finck ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, NULL, &new_sd_size, (void **)&new_sd);
8116c2c66affSColin Finck ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %u\n", ret);
8117c2c66affSColin Finck ok(new_sd != NULL, "expected new_sd != NULL\n");
8118c2c66affSColin Finck ok(new_sd_size == sizeof(old_sd), "expected new_sd_size == sizeof(old_sd), got %u\n", new_sd_size);
8119c2c66affSColin Finck LocalFree(new_sd);
8120c2c66affSColin Finck
8121c2c66affSColin Finck new_sd = (void *)0xdeadbeef;
8122c2c66affSColin Finck ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, &old_sd, &new_sd_size, (void **)&new_sd);
8123c2c66affSColin Finck ok(ret == ERROR_INVALID_SECURITY_DESCR, "expected ERROR_INVALID_SECURITY_DESCR, got %u\n", ret);
8124c2c66affSColin Finck ok(new_sd == (void *)0xdeadbeef, "expected new_sd == 0xdeadbeef, got %p\n", new_sd);
8125c2c66affSColin Finck
8126c2c66affSColin Finck new_sd = NULL;
8127c2c66affSColin Finck new_sd_size = 0;
8128c2c66affSColin Finck ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, rel_sd, &new_sd_size, (void **)&new_sd);
8129c2c66affSColin Finck ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %u\n", ret);
8130c2c66affSColin Finck ok(new_sd != NULL, "expected new_sd != NULL\n");
8131c2c66affSColin Finck ok(new_sd_size == sizeof(old_sd), "expected new_sd_size == sizeof(old_sd), got %u\n", new_sd_size);
8132c2c66affSColin Finck LocalFree(new_sd);
8133c2c66affSColin Finck }
8134c2c66affSColin Finck
START_TEST(security)8135c2c66affSColin Finck START_TEST(security)
8136c2c66affSColin Finck {
8137c2c66affSColin Finck init();
8138c2c66affSColin Finck if (!hmod) return;
8139c2c66affSColin Finck
8140c2c66affSColin Finck if (myARGC >= 3)
8141c2c66affSColin Finck {
8142c2c66affSColin Finck if (!strcmp(myARGV[2], "test_token_sd"))
8143c2c66affSColin Finck test_child_token_sd();
8144561bed7bSAmine Khaldi else if (!strcmp(myARGV[2], "test_token_sd_restricted"))
8145561bed7bSAmine Khaldi test_child_token_sd_restricted();
8146561bed7bSAmine Khaldi else if (!strcmp(myARGV[2], "test_token_sd_medium"))
8147561bed7bSAmine Khaldi test_child_token_sd_medium();
8148c2c66affSColin Finck else
8149c2c66affSColin Finck test_process_security_child();
8150c2c66affSColin Finck return;
8151c2c66affSColin Finck }
8152c2c66affSColin Finck test_kernel_objects_security();
8153c2c66affSColin Finck test_sid();
8154c2c66affSColin Finck test_trustee();
8155c2c66affSColin Finck test_luid();
8156c2c66affSColin Finck test_CreateWellKnownSid();
8157c2c66affSColin Finck test_FileSecurity();
8158c2c66affSColin Finck test_AccessCheck();
8159c2c66affSColin Finck test_token_attr();
8160c2c66affSColin Finck test_GetTokenInformation();
8161c2c66affSColin Finck test_LookupAccountSid();
8162c2c66affSColin Finck test_LookupAccountName();
8163c2c66affSColin Finck test_security_descriptor();
8164c2c66affSColin Finck test_process_security();
8165c2c66affSColin Finck test_impersonation_level();
8166c2c66affSColin Finck test_SetEntriesInAclW();
8167c2c66affSColin Finck test_SetEntriesInAclA();
8168c2c66affSColin Finck test_CreateDirectoryA();
8169c2c66affSColin Finck test_GetNamedSecurityInfoA();
8170c2c66affSColin Finck test_ConvertStringSecurityDescriptor();
8171c2c66affSColin Finck test_ConvertSecurityDescriptorToString();
8172c2c66affSColin Finck test_PrivateObjectSecurity();
8173c2c66affSColin Finck test_acls();
8174c2c66affSColin Finck test_GetWindowsAccountDomainSid();
8175c2c66affSColin Finck test_GetSecurityInfo();
8176c2c66affSColin Finck test_GetSidSubAuthority();
8177c2c66affSColin Finck test_CheckTokenMembership();
8178c2c66affSColin Finck test_EqualSid();
8179c2c66affSColin Finck test_GetUserNameA();
8180c2c66affSColin Finck test_GetUserNameW();
8181c2c66affSColin Finck test_CreateRestrictedToken();
8182c2c66affSColin Finck test_TokenIntegrityLevel();
8183c2c66affSColin Finck test_default_dacl_owner_sid();
8184c2c66affSColin Finck test_AdjustTokenPrivileges();
8185c2c66affSColin Finck test_AddAce();
8186c2c66affSColin Finck test_AddMandatoryAce();
8187c2c66affSColin Finck test_system_security_access();
8188c2c66affSColin Finck test_GetSidIdentifierAuthority();
8189c2c66affSColin Finck test_pseudo_tokens();
8190c2c66affSColin Finck test_maximum_allowed();
8191561bed7bSAmine Khaldi test_token_label();
8192c2c66affSColin Finck test_GetExplicitEntriesFromAclW();
8193c2c66affSColin Finck test_BuildSecurityDescriptorW();
8194c2c66affSColin Finck
8195561bed7bSAmine Khaldi /* Must be the last test, modifies process token */
8196c2c66affSColin Finck test_token_security_descriptor();
8197c2c66affSColin Finck }
8198