1 /* 2 * Unit tests for security functions 3 * 4 * Copyright (c) 2004 Mike McCormack 5 * Copyright (c) 2011,2013,2014,2016 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include <stdarg.h> 23 #include <stdio.h> 24 25 #include "ntstatus.h" 26 #define WIN32_NO_STATUS 27 #include "windef.h" 28 #include "winbase.h" 29 #include "winerror.h" 30 #include "winternl.h" 31 #include "aclapi.h" 32 #include "winnt.h" 33 #include "sddl.h" 34 #include "ntsecapi.h" 35 #include "lmcons.h" 36 37 #include "wine/test.h" 38 39 /* FIXME: Inspect */ 40 #define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3) 41 #define GetCurrentThreadToken() ((HANDLE)~(ULONG_PTR)4) 42 #define GetCurrentThreadEffectiveToken() ((HANDLE)~(ULONG_PTR)5) 43 44 #ifndef PROCESS_QUERY_LIMITED_INFORMATION 45 #define PROCESS_QUERY_LIMITED_INFORMATION 0x1000 46 #endif 47 48 /* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */ 49 #define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000) 50 #define PROCESS_ALL_ACCESS_VISTA (PROCESS_ALL_ACCESS | 0xf000) 51 52 #ifndef EVENT_QUERY_STATE 53 #define EVENT_QUERY_STATE 0x0001 54 #endif 55 56 #ifndef SEMAPHORE_QUERY_STATE 57 #define SEMAPHORE_QUERY_STATE 0x0001 58 #endif 59 60 #ifndef THREAD_SET_LIMITED_INFORMATION 61 #define THREAD_SET_LIMITED_INFORMATION 0x0400 62 #define THREAD_QUERY_LIMITED_INFORMATION 0x0800 63 #endif 64 65 #define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff) 66 #define THREAD_ALL_ACCESS_VISTA (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff) 67 68 #define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_, #expr " expected " format " got " format "\n", (value), (ret_)); } 69 70 static BOOL (WINAPI *pAddAccessAllowedAceEx)(PACL, DWORD, DWORD, DWORD, PSID); 71 static BOOL (WINAPI *pAddAccessDeniedAceEx)(PACL, DWORD, DWORD, DWORD, PSID); 72 static BOOL (WINAPI *pAddAuditAccessAceEx)(PACL, DWORD, DWORD, DWORD, PSID, BOOL, BOOL); 73 static BOOL (WINAPI *pAddMandatoryAce)(PACL,DWORD,DWORD,DWORD,PSID); 74 static VOID (WINAPI *pBuildTrusteeWithSidA)( PTRUSTEEA pTrustee, PSID pSid ); 75 static VOID (WINAPI *pBuildTrusteeWithNameA)( PTRUSTEEA pTrustee, LPSTR pName ); 76 static VOID (WINAPI *pBuildTrusteeWithObjectsAndNameA)( PTRUSTEEA pTrustee, 77 POBJECTS_AND_NAME_A pObjName, 78 SE_OBJECT_TYPE ObjectType, 79 LPSTR ObjectTypeName, 80 LPSTR InheritedObjectTypeName, 81 LPSTR Name ); 82 static VOID (WINAPI *pBuildTrusteeWithObjectsAndSidA)( PTRUSTEEA pTrustee, 83 POBJECTS_AND_SID pObjSid, 84 GUID* pObjectGuid, 85 GUID* pInheritedObjectGuid, 86 PSID pSid ); 87 static LPSTR (WINAPI *pGetTrusteeNameA)( PTRUSTEEA pTrustee ); 88 static BOOL (WINAPI *pMakeSelfRelativeSD)( PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR, LPDWORD ); 89 static BOOL (WINAPI *pConvertStringSidToSidA)( LPCSTR str, PSID pSid ); 90 static BOOL (WINAPI *pCheckTokenMembership)(HANDLE, PSID, PBOOL); 91 static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR, DWORD, 92 PSECURITY_DESCRIPTOR*, PULONG ); 93 static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorW)(LPCWSTR, DWORD, 94 PSECURITY_DESCRIPTOR*, PULONG ); 95 static BOOL (WINAPI *pConvertSecurityDescriptorToStringSecurityDescriptorA)(PSECURITY_DESCRIPTOR, DWORD, 96 SECURITY_INFORMATION, LPSTR *, PULONG ); 97 static BOOL (WINAPI *pGetFileSecurityA)(LPCSTR, SECURITY_INFORMATION, 98 PSECURITY_DESCRIPTOR, DWORD, LPDWORD); 99 static BOOL (WINAPI *pSetFileSecurityA)(LPCSTR, SECURITY_INFORMATION, 100 PSECURITY_DESCRIPTOR); 101 static DWORD (WINAPI *pGetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION, 102 PSID*, PSID*, PACL*, PACL*, 103 PSECURITY_DESCRIPTOR*); 104 static DWORD (WINAPI *pSetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION, 105 PSID, PSID, PACL, PACL); 106 static PDWORD (WINAPI *pGetSidSubAuthority)(PSID, DWORD); 107 static PUCHAR (WINAPI *pGetSidSubAuthorityCount)(PSID); 108 static BOOL (WINAPI *pIsValidSid)(PSID); 109 static DWORD (WINAPI *pRtlAdjustPrivilege)(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN); 110 static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*); 111 static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES, 112 SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE); 113 114 static NTSTATUS (WINAPI *pLsaQueryInformationPolicy)(LSA_HANDLE,POLICY_INFORMATION_CLASS,PVOID*); 115 static NTSTATUS (WINAPI *pLsaClose)(LSA_HANDLE); 116 static NTSTATUS (WINAPI *pLsaFreeMemory)(PVOID); 117 static NTSTATUS (WINAPI *pLsaOpenPolicy)(PLSA_UNICODE_STRING,PLSA_OBJECT_ATTRIBUTES,ACCESS_MASK,PLSA_HANDLE); 118 static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG); 119 static DWORD (WINAPI *pSetEntriesInAclW)(ULONG, PEXPLICIT_ACCESSW, PACL, PACL*); 120 static DWORD (WINAPI *pSetEntriesInAclA)(ULONG, PEXPLICIT_ACCESSA, PACL, PACL*); 121 static BOOL (WINAPI *pSetSecurityDescriptorControl)(PSECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, 122 SECURITY_DESCRIPTOR_CONTROL); 123 static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, 124 PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*); 125 static DWORD (WINAPI *pSetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, 126 PSID, PSID, PACL, PACL); 127 static NTSTATUS (WINAPI *pNtAccessCheck)(PSECURITY_DESCRIPTOR, HANDLE, ACCESS_MASK, PGENERIC_MAPPING, 128 PPRIVILEGE_SET, PULONG, PULONG, NTSTATUS*); 129 static BOOL (WINAPI *pCreateRestrictedToken)(HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, 130 PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE); 131 static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS); 132 static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*); 133 static NTSTATUS (WINAPI *pNtSetSecurityObject)(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); 134 static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG); 135 static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*); 136 static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_STRING,BOOLEAN); 137 static BOOL (WINAPI *pGetWindowsAccountDomainSid)(PSID,PSID,DWORD*); 138 static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ); 139 static NTSTATUS (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); 140 static PSID_IDENTIFIER_AUTHORITY (WINAPI *pGetSidIdentifierAuthority)(PSID); 141 static DWORD (WINAPI *pGetExplicitEntriesFromAclW)(PACL,PULONG,PEXPLICIT_ACCESSW*); 142 143 static HMODULE hmod; 144 static int myARGC; 145 static char** myARGV; 146 147 #define SID_SLOTS 4 148 static char debugsid_str[SID_SLOTS][256]; 149 static int debugsid_index = 0; 150 static const char* debugstr_sid(PSID sid) 151 { 152 LPSTR sidstr; 153 DWORD le = GetLastError(); 154 char* res = debugsid_str[debugsid_index]; 155 debugsid_index = (debugsid_index + 1) % SID_SLOTS; 156 157 if (!ConvertSidToStringSidA(sid, &sidstr)) 158 sprintf(res, "ConvertSidToStringSidA failed le=%u", GetLastError()); 159 else if (strlen(sidstr) > sizeof(*debugsid_str) - 1) 160 { 161 memcpy(res, sidstr, sizeof(*debugsid_str) - 4); 162 strcpy(res + sizeof(*debugsid_str) - 4, "..."); 163 LocalFree(sidstr); 164 } 165 else 166 { 167 strcpy(res, sidstr); 168 LocalFree(sidstr); 169 } 170 /* Restore the last error in case ConvertSidToStringSidA() modified it */ 171 SetLastError(le); 172 return res; 173 } 174 175 static void init(void) 176 { 177 HMODULE hntdll; 178 179 hntdll = GetModuleHandleA("ntdll.dll"); 180 pNtQueryObject = (void *)GetProcAddress( hntdll, "NtQueryObject" ); 181 pNtAccessCheck = (void *)GetProcAddress( hntdll, "NtAccessCheck" ); 182 pNtSetSecurityObject = (void *)GetProcAddress(hntdll, "NtSetSecurityObject"); 183 pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile"); 184 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U"); 185 pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString"); 186 pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString"); 187 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); 188 189 hmod = GetModuleHandleA("advapi32.dll"); 190 pAddAccessAllowedAceEx = (void *)GetProcAddress(hmod, "AddAccessAllowedAceEx"); 191 pAddAccessDeniedAceEx = (void *)GetProcAddress(hmod, "AddAccessDeniedAceEx"); 192 pAddAuditAccessAceEx = (void *)GetProcAddress(hmod, "AddAuditAccessAceEx"); 193 pAddMandatoryAce = (void *)GetProcAddress(hmod, "AddMandatoryAce"); 194 pCheckTokenMembership = (void *)GetProcAddress(hmod, "CheckTokenMembership"); 195 pConvertStringSecurityDescriptorToSecurityDescriptorA = 196 (void *)GetProcAddress(hmod, "ConvertStringSecurityDescriptorToSecurityDescriptorA" ); 197 pConvertStringSecurityDescriptorToSecurityDescriptorW = 198 (void *)GetProcAddress(hmod, "ConvertStringSecurityDescriptorToSecurityDescriptorW" ); 199 pConvertSecurityDescriptorToStringSecurityDescriptorA = 200 (void *)GetProcAddress(hmod, "ConvertSecurityDescriptorToStringSecurityDescriptorA" ); 201 pGetFileSecurityA = (void *)GetProcAddress(hmod, "GetFileSecurityA" ); 202 pSetFileSecurityA = (void *)GetProcAddress(hmod, "SetFileSecurityA" ); 203 pCreateWellKnownSid = (void *)GetProcAddress( hmod, "CreateWellKnownSid" ); 204 pGetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "GetNamedSecurityInfoA"); 205 pSetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "SetNamedSecurityInfoA"); 206 pGetSidSubAuthority = (void *)GetProcAddress(hmod, "GetSidSubAuthority"); 207 pGetSidSubAuthorityCount = (void *)GetProcAddress(hmod, "GetSidSubAuthorityCount"); 208 pIsValidSid = (void *)GetProcAddress(hmod, "IsValidSid"); 209 pMakeSelfRelativeSD = (void *)GetProcAddress(hmod, "MakeSelfRelativeSD"); 210 pSetEntriesInAclW = (void *)GetProcAddress(hmod, "SetEntriesInAclW"); 211 pSetEntriesInAclA = (void *)GetProcAddress(hmod, "SetEntriesInAclA"); 212 pSetSecurityDescriptorControl = (void *)GetProcAddress(hmod, "SetSecurityDescriptorControl"); 213 pGetSecurityInfo = (void *)GetProcAddress(hmod, "GetSecurityInfo"); 214 pSetSecurityInfo = (void *)GetProcAddress(hmod, "SetSecurityInfo"); 215 pCreateRestrictedToken = (void *)GetProcAddress(hmod, "CreateRestrictedToken"); 216 pConvertStringSidToSidA = (void *)GetProcAddress(hmod, "ConvertStringSidToSidA"); 217 pGetAclInformation = (void *)GetProcAddress(hmod, "GetAclInformation"); 218 pGetAce = (void *)GetProcAddress(hmod, "GetAce"); 219 pGetWindowsAccountDomainSid = (void *)GetProcAddress(hmod, "GetWindowsAccountDomainSid"); 220 pGetSidIdentifierAuthority = (void *)GetProcAddress(hmod, "GetSidIdentifierAuthority"); 221 pDuplicateTokenEx = (void *)GetProcAddress(hmod, "DuplicateTokenEx"); 222 pGetExplicitEntriesFromAclW = (void *)GetProcAddress(hmod, "GetExplicitEntriesFromAclW"); 223 224 myARGC = winetest_get_mainargs( &myARGV ); 225 } 226 227 static SECURITY_DESCRIPTOR* test_get_security_descriptor(HANDLE handle, int line) 228 { 229 /* use HeapFree(GetProcessHeap(), 0, sd); when done */ 230 DWORD ret, length, needed; 231 SECURITY_DESCRIPTOR *sd; 232 233 needed = 0xdeadbeef; 234 SetLastError(0xdeadbeef); 235 ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 236 NULL, 0, &needed); 237 ok_(__FILE__, line)(!ret, "GetKernelObjectSecurity should fail\n"); 238 ok_(__FILE__, line)(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 239 ok_(__FILE__, line)(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n"); 240 241 length = needed; 242 sd = HeapAlloc(GetProcessHeap(), 0, length); 243 244 needed = 0xdeadbeef; 245 SetLastError(0xdeadbeef); 246 ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 247 sd, length, &needed); 248 ok_(__FILE__, line)(ret, "GetKernelObjectSecurity error %d\n", GetLastError()); 249 ok_(__FILE__, line)(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed); 250 return sd; 251 } 252 253 static void test_owner_equal(HANDLE Handle, PSID expected, int line) 254 { 255 BOOL res; 256 SECURITY_DESCRIPTOR *queriedSD = NULL; 257 PSID owner; 258 BOOL owner_defaulted; 259 260 queriedSD = test_get_security_descriptor( Handle, line ); 261 262 res = GetSecurityDescriptorOwner(queriedSD, &owner, &owner_defaulted); 263 ok_(__FILE__, line)(res, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); 264 265 ok_(__FILE__, line)(EqualSid(owner, expected), "Owner SIDs are not equal %s != %s\n", 266 debugstr_sid(owner), debugstr_sid(expected)); 267 ok_(__FILE__, line)(!owner_defaulted, "Defaulted is true\n"); 268 269 HeapFree(GetProcessHeap(), 0, queriedSD); 270 } 271 272 static void test_group_equal(HANDLE Handle, PSID expected, int line) 273 { 274 BOOL res; 275 SECURITY_DESCRIPTOR *queriedSD = NULL; 276 PSID group; 277 BOOL group_defaulted; 278 279 queriedSD = test_get_security_descriptor( Handle, line ); 280 281 res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted); 282 ok_(__FILE__, line)(res, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); 283 284 ok_(__FILE__, line)(EqualSid(group, expected), "Group SIDs are not equal %s != %s\n", 285 debugstr_sid(group), debugstr_sid(expected)); 286 ok_(__FILE__, line)(!group_defaulted, "Defaulted is true\n"); 287 288 HeapFree(GetProcessHeap(), 0, queriedSD); 289 } 290 291 static void test_sid(void) 292 { 293 static struct 294 { 295 SID_IDENTIFIER_AUTHORITY auth; 296 const char *refStr; 297 } refs[] = { 298 { { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" }, 299 { { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1" }, 300 { { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1" }, 301 { { {0x00,0x00,0x00,0x00,0x01,0x02} }, "S-1-258-1" }, 302 { { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" }, 303 { { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" }, 304 }; 305 static const struct 306 { 307 const char *str; 308 WELL_KNOWN_SID_TYPE sid_type; 309 BOOL optional; 310 } strsid_table[] = { 311 /* Please keep the list sorted. */ 312 { "AC", WinBuiltinAnyPackageSid, TRUE }, 313 { "AN", WinAnonymousSid }, 314 { "AO", WinBuiltinAccountOperatorsSid }, 315 { "AU", WinAuthenticatedUserSid }, 316 { "BA", WinBuiltinAdministratorsSid }, 317 { "BG", WinBuiltinGuestsSid }, 318 { "BO", WinBuiltinBackupOperatorsSid }, 319 { "BU", WinBuiltinUsersSid }, 320 { "CA", WinAccountCertAdminsSid, TRUE}, 321 { "CG", WinCreatorGroupSid }, 322 { "CO", WinCreatorOwnerSid }, 323 { "DA", WinAccountDomainAdminsSid, TRUE}, 324 { "DC", WinAccountComputersSid, TRUE}, 325 { "DD", WinAccountControllersSid, TRUE}, 326 { "DG", WinAccountDomainGuestsSid, TRUE}, 327 { "DU", WinAccountDomainUsersSid, TRUE}, 328 { "EA", WinAccountEnterpriseAdminsSid, TRUE}, 329 { "ED", WinEnterpriseControllersSid }, 330 { "IU", WinInteractiveSid }, 331 { "LA", WinAccountAdministratorSid }, 332 { "LG", WinAccountGuestSid }, 333 { "LS", WinLocalServiceSid }, 334 { "NO", WinBuiltinNetworkConfigurationOperatorsSid }, 335 { "NS", WinNetworkServiceSid }, 336 { "NU", WinNetworkSid }, 337 { "PA", WinAccountPolicyAdminsSid, TRUE}, 338 { "PO", WinBuiltinPrintOperatorsSid }, 339 { "PS", WinSelfSid }, 340 { "PU", WinBuiltinPowerUsersSid }, 341 { "RC", WinRestrictedCodeSid }, 342 { "RD", WinBuiltinRemoteDesktopUsersSid }, 343 { "RE", WinBuiltinReplicatorSid }, 344 { "RS", WinAccountRasAndIasServersSid, TRUE }, 345 { "RU", WinBuiltinPreWindows2000CompatibleAccessSid }, 346 { "SA", WinAccountSchemaAdminsSid, TRUE }, 347 { "SO", WinBuiltinSystemOperatorsSid }, 348 { "SU", WinServiceSid }, 349 { "SY", WinLocalSystemSid }, 350 { "WD", WinWorldSid }, 351 }; 352 SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY }; 353 const char noSubAuthStr[] = "S-1-5"; 354 unsigned int i; 355 PSID psid, domain_sid; 356 SID *pisid; 357 BOOL r; 358 LPSTR str; 359 360 if( !pConvertStringSidToSidA ) 361 { 362 win_skip("ConvertSidToStringSidA or ConvertStringSidToSidA not available\n"); 363 return; 364 } 365 366 r = pConvertStringSidToSidA( NULL, NULL ); 367 ok( !r, "expected failure with NULL parameters\n" ); 368 if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED ) 369 return; 370 ok( GetLastError() == ERROR_INVALID_PARAMETER, 371 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n", 372 GetLastError() ); 373 374 r = pConvertStringSidToSidA( refs[0].refStr, NULL ); 375 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER, 376 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n", 377 GetLastError() ); 378 379 r = pConvertStringSidToSidA( NULL, &str ); 380 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER, 381 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %d\n", 382 GetLastError() ); 383 384 r = pConvertStringSidToSidA( noSubAuthStr, &psid ); 385 ok( !r, 386 "expected failure with no sub authorities\n" ); 387 ok( GetLastError() == ERROR_INVALID_SID, 388 "expected GetLastError() is ERROR_INVALID_SID, got %d\n", 389 GetLastError() ); 390 391 ok(pConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid), "ConvertStringSidToSidA failed\n"); 392 pisid = psid; 393 ok(pisid->SubAuthorityCount == 4, "Invalid sub authority count - expected 4, got %d\n", pisid->SubAuthorityCount); 394 ok(pisid->SubAuthority[0] == 21, "Invalid subauthority 0 - expected 21, got %d\n", pisid->SubAuthority[0]); 395 ok(pisid->SubAuthority[3] == 4576, "Invalid subauthority 0 - expected 4576, got %d\n", pisid->SubAuthority[3]); 396 LocalFree(str); 397 LocalFree(psid); 398 399 for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ ) 400 { 401 r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0, 402 &psid ); 403 ok( r, "failed to allocate sid\n" ); 404 r = ConvertSidToStringSidA( psid, &str ); 405 ok( r, "failed to convert sid\n" ); 406 if (r) 407 { 408 ok( !strcmp( str, refs[i].refStr ), 409 "incorrect sid, expected %s, got %s\n", refs[i].refStr, str ); 410 LocalFree( str ); 411 } 412 if( psid ) 413 FreeSid( psid ); 414 415 r = pConvertStringSidToSidA( refs[i].refStr, &psid ); 416 ok( r, "failed to parse sid string\n" ); 417 pisid = psid; 418 ok( pisid && 419 !memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value, 420 sizeof(refs[i].auth) ), 421 "string sid %s didn't parse to expected value\n" 422 "(got 0x%04x%08x, expected 0x%04x%08x)\n", 423 refs[i].refStr, 424 MAKEWORD( pisid->IdentifierAuthority.Value[1], 425 pisid->IdentifierAuthority.Value[0] ), 426 MAKELONG( MAKEWORD( pisid->IdentifierAuthority.Value[5], 427 pisid->IdentifierAuthority.Value[4] ), 428 MAKEWORD( pisid->IdentifierAuthority.Value[3], 429 pisid->IdentifierAuthority.Value[2] ) ), 430 MAKEWORD( refs[i].auth.Value[1], refs[i].auth.Value[0] ), 431 MAKELONG( MAKEWORD( refs[i].auth.Value[5], refs[i].auth.Value[4] ), 432 MAKEWORD( refs[i].auth.Value[3], refs[i].auth.Value[2] ) ) ); 433 if( psid ) 434 LocalFree( psid ); 435 } 436 437 /* string constant format not supported before XP */ 438 r = pConvertStringSidToSidA("AN", &psid); 439 if(!r) 440 { 441 win_skip("String constant format not supported\n"); 442 return; 443 } 444 LocalFree(psid); 445 446 AllocateAndInitializeSid(&domain_ident, 4, SECURITY_NT_NON_UNIQUE, 0, 0, 0, 0, 0, 0, 0, &domain_sid); 447 448 for(i = 0; i < sizeof(strsid_table) / sizeof(strsid_table[0]); i++) 449 { 450 SetLastError(0xdeadbeef); 451 r = pConvertStringSidToSidA(strsid_table[i].str, &psid); 452 453 if (!(strsid_table[i].optional)) 454 { 455 ok(r, "%s: got %u\n", strsid_table[i].str, GetLastError()); 456 } 457 458 if (r) 459 { 460 char buf[SECURITY_MAX_SID_SIZE]; 461 char *sid_string, *well_known_sid_string; 462 DWORD n, size; 463 464 /* zero out domain id before comparison to simplify things */ 465 if (strsid_table[i].sid_type == WinAccountAdministratorSid || 466 strsid_table[i].sid_type == WinAccountGuestSid) 467 { 468 for (n = 1; n <= 3; n++) 469 *GetSidSubAuthority(psid, n) = 0; 470 } 471 472 r = ConvertSidToStringSidA(psid, &sid_string); 473 ok(r, "%s: ConvertSidToStringSid error %u\n", strsid_table[i].str, GetLastError()); 474 if (winetest_debug > 1) 475 trace("%s => %s\n", strsid_table[i].str, sid_string); 476 477 size = sizeof(buf); 478 r = pCreateWellKnownSid(strsid_table[i].sid_type, domain_sid, buf, &size); 479 ok(r, "%u: CreateWellKnownSid(%u) error %u\n", i, strsid_table[i].sid_type, GetLastError()); 480 481 r = ConvertSidToStringSidA(buf, &well_known_sid_string); 482 ok(r, "%u: ConvertSidToStringSi(%u) error %u\n", i, strsid_table[i].sid_type, GetLastError()); 483 if (winetest_debug > 1) 484 trace("%u => %s\n", strsid_table[i].sid_type, well_known_sid_string); 485 486 ok(strcmp(sid_string, well_known_sid_string) == 0, 487 "%u: (%u) expected %s, got %s\n", i, strsid_table[i].sid_type, well_known_sid_string, sid_string); 488 489 LocalFree(well_known_sid_string); 490 LocalFree(sid_string); 491 LocalFree(psid); 492 } 493 else 494 { 495 if (GetLastError() != ERROR_INVALID_SID) 496 trace(" %s: couldn't be converted, returned %d\n", strsid_table[i].str, GetLastError()); 497 else 498 trace(" %s: couldn't be converted\n", strsid_table[i].str); 499 } 500 } 501 502 LocalFree(domain_sid); 503 } 504 505 static void test_trustee(void) 506 { 507 GUID ObjectType = {0x12345678, 0x1234, 0x5678, {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}}; 508 GUID InheritedObjectType = {0x23456789, 0x2345, 0x6786, {0x2, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}}; 509 GUID ZeroGuid; 510 OBJECTS_AND_NAME_A oan; 511 OBJECTS_AND_SID oas; 512 TRUSTEEA trustee; 513 PSID psid; 514 char szObjectTypeName[] = "ObjectTypeName"; 515 char szInheritedObjectTypeName[] = "InheritedObjectTypeName"; 516 char szTrusteeName[] = "szTrusteeName"; 517 SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} }; 518 519 memset( &ZeroGuid, 0x00, sizeof (ZeroGuid) ); 520 521 pBuildTrusteeWithSidA = (void *)GetProcAddress( hmod, "BuildTrusteeWithSidA" ); 522 pBuildTrusteeWithNameA = (void *)GetProcAddress( hmod, "BuildTrusteeWithNameA" ); 523 pBuildTrusteeWithObjectsAndNameA = (void *)GetProcAddress (hmod, "BuildTrusteeWithObjectsAndNameA" ); 524 pBuildTrusteeWithObjectsAndSidA = (void *)GetProcAddress (hmod, "BuildTrusteeWithObjectsAndSidA" ); 525 pGetTrusteeNameA = (void *)GetProcAddress (hmod, "GetTrusteeNameA" ); 526 if( !pBuildTrusteeWithSidA || !pBuildTrusteeWithNameA || 527 !pBuildTrusteeWithObjectsAndNameA || !pBuildTrusteeWithObjectsAndSidA || 528 !pGetTrusteeNameA ) 529 return; 530 531 if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) ) 532 { 533 trace( "failed to init SID\n" ); 534 return; 535 } 536 537 /* test BuildTrusteeWithSidA */ 538 memset( &trustee, 0xff, sizeof trustee ); 539 pBuildTrusteeWithSidA( &trustee, psid ); 540 541 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n"); 542 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, 543 "MultipleTrusteeOperation wrong\n"); 544 ok( trustee.TrusteeForm == TRUSTEE_IS_SID, "TrusteeForm wrong\n"); 545 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n"); 546 ok( trustee.ptstrName == psid, "ptstrName wrong\n" ); 547 548 /* test BuildTrusteeWithObjectsAndSidA (test 1) */ 549 memset( &trustee, 0xff, sizeof trustee ); 550 memset( &oas, 0xff, sizeof(oas) ); 551 pBuildTrusteeWithObjectsAndSidA(&trustee, &oas, &ObjectType, 552 &InheritedObjectType, psid); 553 554 ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n"); 555 ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n"); 556 ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_SID, "TrusteeForm wrong\n"); 557 ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n"); 558 ok(trustee.ptstrName == (LPSTR)&oas, "ptstrName wrong\n"); 559 560 ok(oas.ObjectsPresent == (ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT), "ObjectsPresent wrong\n"); 561 ok(!memcmp(&oas.ObjectTypeGuid, &ObjectType, sizeof(GUID)), "ObjectTypeGuid wrong\n"); 562 ok(!memcmp(&oas.InheritedObjectTypeGuid, &InheritedObjectType, sizeof(GUID)), "InheritedObjectTypeGuid wrong\n"); 563 ok(oas.pSid == psid, "pSid wrong\n"); 564 565 /* test GetTrusteeNameA */ 566 ok(pGetTrusteeNameA(&trustee) == (LPSTR)&oas, "GetTrusteeName returned wrong value\n"); 567 568 /* test BuildTrusteeWithObjectsAndSidA (test 2) */ 569 memset( &trustee, 0xff, sizeof trustee ); 570 memset( &oas, 0xff, sizeof(oas) ); 571 pBuildTrusteeWithObjectsAndSidA(&trustee, &oas, NULL, 572 &InheritedObjectType, psid); 573 574 ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n"); 575 ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n"); 576 ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_SID, "TrusteeForm wrong\n"); 577 ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n"); 578 ok(trustee.ptstrName == (LPSTR)&oas, "ptstrName wrong\n"); 579 580 ok(oas.ObjectsPresent == ACE_INHERITED_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n"); 581 ok(!memcmp(&oas.ObjectTypeGuid, &ZeroGuid, sizeof(GUID)), "ObjectTypeGuid wrong\n"); 582 ok(!memcmp(&oas.InheritedObjectTypeGuid, &InheritedObjectType, sizeof(GUID)), "InheritedObjectTypeGuid wrong\n"); 583 ok(oas.pSid == psid, "pSid wrong\n"); 584 585 FreeSid( psid ); 586 587 /* test BuildTrusteeWithNameA */ 588 memset( &trustee, 0xff, sizeof trustee ); 589 pBuildTrusteeWithNameA( &trustee, szTrusteeName ); 590 591 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n"); 592 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, 593 "MultipleTrusteeOperation wrong\n"); 594 ok( trustee.TrusteeForm == TRUSTEE_IS_NAME, "TrusteeForm wrong\n"); 595 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n"); 596 ok( trustee.ptstrName == szTrusteeName, "ptstrName wrong\n" ); 597 598 /* test BuildTrusteeWithObjectsAndNameA (test 1) */ 599 memset( &trustee, 0xff, sizeof trustee ); 600 memset( &oan, 0xff, sizeof(oan) ); 601 pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, szObjectTypeName, 602 szInheritedObjectTypeName, szTrusteeName); 603 604 ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n"); 605 ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n"); 606 ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n"); 607 ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n"); 608 ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n"); 609 610 ok(oan.ObjectsPresent == (ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT), "ObjectsPresent wrong\n"); 611 ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n"); 612 ok(oan.InheritedObjectTypeName == szInheritedObjectTypeName, "InheritedObjectTypeName wrong\n"); 613 ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n"); 614 615 /* test GetTrusteeNameA */ 616 ok(pGetTrusteeNameA(&trustee) == (LPSTR)&oan, "GetTrusteeName returned wrong value\n"); 617 618 /* test BuildTrusteeWithObjectsAndNameA (test 2) */ 619 memset( &trustee, 0xff, sizeof trustee ); 620 memset( &oan, 0xff, sizeof(oan) ); 621 pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, NULL, 622 szInheritedObjectTypeName, szTrusteeName); 623 624 ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n"); 625 ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n"); 626 ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n"); 627 ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n"); 628 ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n"); 629 630 ok(oan.ObjectsPresent == ACE_INHERITED_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n"); 631 ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n"); 632 ok(oan.InheritedObjectTypeName == szInheritedObjectTypeName, "InheritedObjectTypeName wrong\n"); 633 ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n"); 634 635 /* test BuildTrusteeWithObjectsAndNameA (test 3) */ 636 memset( &trustee, 0xff, sizeof trustee ); 637 memset( &oan, 0xff, sizeof(oan) ); 638 pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, szObjectTypeName, 639 NULL, szTrusteeName); 640 641 ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n"); 642 ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n"); 643 ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n"); 644 ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n"); 645 ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n"); 646 647 ok(oan.ObjectsPresent == ACE_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n"); 648 ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n"); 649 ok(oan.InheritedObjectTypeName == NULL, "InheritedObjectTypeName wrong\n"); 650 ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n"); 651 } 652 653 /* If the first isn't defined, assume none is */ 654 #ifndef SE_MIN_WELL_KNOWN_PRIVILEGE 655 #define SE_MIN_WELL_KNOWN_PRIVILEGE 2L 656 #define SE_CREATE_TOKEN_PRIVILEGE 2L 657 #define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L 658 #define SE_LOCK_MEMORY_PRIVILEGE 4L 659 #define SE_INCREASE_QUOTA_PRIVILEGE 5L 660 #define SE_MACHINE_ACCOUNT_PRIVILEGE 6L 661 #define SE_TCB_PRIVILEGE 7L 662 #define SE_SECURITY_PRIVILEGE 8L 663 #define SE_TAKE_OWNERSHIP_PRIVILEGE 9L 664 #define SE_LOAD_DRIVER_PRIVILEGE 10L 665 #define SE_SYSTEM_PROFILE_PRIVILEGE 11L 666 #define SE_SYSTEMTIME_PRIVILEGE 12L 667 #define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L 668 #define SE_INC_BASE_PRIORITY_PRIVILEGE 14L 669 #define SE_CREATE_PAGEFILE_PRIVILEGE 15L 670 #define SE_CREATE_PERMANENT_PRIVILEGE 16L 671 #define SE_BACKUP_PRIVILEGE 17L 672 #define SE_RESTORE_PRIVILEGE 18L 673 #define SE_SHUTDOWN_PRIVILEGE 19L 674 #define SE_DEBUG_PRIVILEGE 20L 675 #define SE_AUDIT_PRIVILEGE 21L 676 #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L 677 #define SE_CHANGE_NOTIFY_PRIVILEGE 23L 678 #define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L 679 #define SE_UNDOCK_PRIVILEGE 25L 680 #define SE_SYNC_AGENT_PRIVILEGE 26L 681 #define SE_ENABLE_DELEGATION_PRIVILEGE 27L 682 #define SE_MANAGE_VOLUME_PRIVILEGE 28L 683 #define SE_IMPERSONATE_PRIVILEGE 29L 684 #define SE_CREATE_GLOBAL_PRIVILEGE 30L 685 #define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE 686 #endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */ 687 688 static void test_allocateLuid(void) 689 { 690 BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID); 691 LUID luid1, luid2; 692 BOOL ret; 693 694 pAllocateLocallyUniqueId = (void*)GetProcAddress(hmod, "AllocateLocallyUniqueId"); 695 if (!pAllocateLocallyUniqueId) return; 696 697 ret = pAllocateLocallyUniqueId(&luid1); 698 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 699 return; 700 701 ok(ret, 702 "AllocateLocallyUniqueId failed: %d\n", GetLastError()); 703 ret = pAllocateLocallyUniqueId(&luid2); 704 ok( ret, 705 "AllocateLocallyUniqueId failed: %d\n", GetLastError()); 706 ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0, 707 "AllocateLocallyUniqueId returned a well-known LUID\n"); 708 ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart, 709 "AllocateLocallyUniqueId returned non-unique LUIDs\n"); 710 ret = pAllocateLocallyUniqueId(NULL); 711 ok( !ret && GetLastError() == ERROR_NOACCESS, 712 "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %d\n", 713 GetLastError()); 714 } 715 716 static void test_lookupPrivilegeName(void) 717 { 718 BOOL (WINAPI *pLookupPrivilegeNameA)(LPCSTR, PLUID, LPSTR, LPDWORD); 719 char buf[MAX_PATH]; /* arbitrary, seems long enough */ 720 DWORD cchName = sizeof(buf); 721 LUID luid = { 0, 0 }; 722 LONG i; 723 BOOL ret; 724 725 /* check whether it's available first */ 726 pLookupPrivilegeNameA = (void*)GetProcAddress(hmod, "LookupPrivilegeNameA"); 727 if (!pLookupPrivilegeNameA) return; 728 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; 729 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName); 730 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 731 return; 732 733 /* check with a short buffer */ 734 cchName = 0; 735 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; 736 ret = pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName); 737 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 738 "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %d\n", 739 GetLastError()); 740 ok(cchName == strlen("SeCreateTokenPrivilege") + 1, 741 "LookupPrivilegeNameA returned an incorrect required length for\n" 742 "SeCreateTokenPrivilege (got %d, expected %d)\n", cchName, 743 lstrlenA("SeCreateTokenPrivilege") + 1); 744 /* check a known value and its returned length on success */ 745 cchName = sizeof(buf); 746 ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) && 747 cchName == strlen("SeCreateTokenPrivilege"), 748 "LookupPrivilegeNameA returned an incorrect output length for\n" 749 "SeCreateTokenPrivilege (got %d, expected %d)\n", cchName, 750 (int)strlen("SeCreateTokenPrivilege")); 751 /* check known values */ 752 for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i <= SE_MAX_WELL_KNOWN_PRIVILEGE; i++) 753 { 754 luid.LowPart = i; 755 cchName = sizeof(buf); 756 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName); 757 ok( ret || GetLastError() == ERROR_NO_SUCH_PRIVILEGE, 758 "LookupPrivilegeNameA(0.%d) failed: %d\n", i, GetLastError()); 759 } 760 /* check a bogus LUID */ 761 luid.LowPart = 0xdeadbeef; 762 cchName = sizeof(buf); 763 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName); 764 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE, 765 "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n", 766 GetLastError()); 767 /* check on a bogus system */ 768 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; 769 cchName = sizeof(buf); 770 ret = pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName); 771 ok( !ret && (GetLastError() == RPC_S_SERVER_UNAVAILABLE || 772 GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */, 773 "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d\n", 774 GetLastError()); 775 } 776 777 struct NameToLUID 778 { 779 const char *name; 780 DWORD lowPart; 781 }; 782 783 static void test_lookupPrivilegeValue(void) 784 { 785 static const struct NameToLUID privs[] = { 786 { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE }, 787 { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE }, 788 { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE }, 789 { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE }, 790 { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE }, 791 { "SeTcbPrivilege", SE_TCB_PRIVILEGE }, 792 { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE }, 793 { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE }, 794 { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE }, 795 { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE }, 796 { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE }, 797 { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE }, 798 { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE }, 799 { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE }, 800 { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE }, 801 { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE }, 802 { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE }, 803 { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE }, 804 { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE }, 805 { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE }, 806 { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE }, 807 { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILEGE }, 808 { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE }, 809 { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE }, 810 { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE }, 811 { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE }, 812 { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE }, 813 { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE }, 814 { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE }, 815 }; 816 BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID); 817 unsigned int i; 818 LUID luid; 819 BOOL ret; 820 821 /* check whether it's available first */ 822 pLookupPrivilegeValueA = (void*)GetProcAddress(hmod, "LookupPrivilegeValueA"); 823 if (!pLookupPrivilegeValueA) return; 824 ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid); 825 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 826 return; 827 828 /* check a bogus system name */ 829 ret = pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid); 830 ok( !ret && (GetLastError() == RPC_S_SERVER_UNAVAILABLE || 831 GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */, 832 "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %d\n", 833 GetLastError()); 834 /* check a NULL string */ 835 ret = pLookupPrivilegeValueA(NULL, 0, &luid); 836 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE, 837 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n", 838 GetLastError()); 839 /* check a bogus privilege name */ 840 ret = pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid); 841 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE, 842 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %d\n", 843 GetLastError()); 844 /* check case insensitive */ 845 ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid); 846 ok( ret, 847 "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %d\n", 848 GetLastError()); 849 for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++) 850 { 851 /* Not all privileges are implemented on all Windows versions, so 852 * don't worry if the call fails 853 */ 854 if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid)) 855 { 856 ok(luid.LowPart == privs[i].lowPart, 857 "LookupPrivilegeValueA returned an invalid LUID for %s\n", 858 privs[i].name); 859 } 860 } 861 } 862 863 static void test_luid(void) 864 { 865 test_allocateLuid(); 866 test_lookupPrivilegeName(); 867 test_lookupPrivilegeValue(); 868 } 869 870 static void test_FileSecurity(void) 871 { 872 char wintmpdir [MAX_PATH]; 873 char path [MAX_PATH]; 874 char file [MAX_PATH]; 875 HANDLE fh, token; 876 DWORD sdSize, retSize, rc, granted, priv_set_len; 877 PRIVILEGE_SET priv_set; 878 BOOL status; 879 BYTE *sd; 880 GENERIC_MAPPING mapping = { FILE_READ_DATA, FILE_WRITE_DATA, FILE_EXECUTE, FILE_ALL_ACCESS }; 881 const SECURITY_INFORMATION request = OWNER_SECURITY_INFORMATION 882 | GROUP_SECURITY_INFORMATION 883 | DACL_SECURITY_INFORMATION; 884 885 if (!pGetFileSecurityA) { 886 win_skip ("GetFileSecurity is not available\n"); 887 return; 888 } 889 890 if (!pSetFileSecurityA) { 891 win_skip ("SetFileSecurity is not available\n"); 892 return; 893 } 894 895 if (!GetTempPathA (sizeof (wintmpdir), wintmpdir)) { 896 win_skip ("GetTempPathA failed\n"); 897 return; 898 } 899 900 /* Create a temporary directory and in it a temporary file */ 901 strcat (strcpy (path, wintmpdir), "rary"); 902 SetLastError(0xdeadbeef); 903 rc = CreateDirectoryA (path, NULL); 904 ok (rc || GetLastError() == ERROR_ALREADY_EXISTS, "CreateDirectoryA " 905 "failed for '%s' with %d\n", path, GetLastError()); 906 907 strcat (strcpy (file, path), "\\ess"); 908 SetLastError(0xdeadbeef); 909 fh = CreateFileA (file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); 910 ok (fh != INVALID_HANDLE_VALUE, "CreateFileA " 911 "failed for '%s' with %d\n", file, GetLastError()); 912 CloseHandle (fh); 913 914 /* For the temporary file ... */ 915 916 /* Get size needed */ 917 retSize = 0; 918 SetLastError(0xdeadbeef); 919 rc = pGetFileSecurityA (file, request, NULL, 0, &retSize); 920 if (!rc && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) { 921 win_skip("GetFileSecurityA is not implemented\n"); 922 goto cleanup; 923 } 924 ok (!rc, "GetFileSecurityA " 925 "was expected to fail for '%s'\n", file); 926 ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA " 927 "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError()); 928 ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize); 929 930 sdSize = retSize; 931 sd = HeapAlloc (GetProcessHeap (), 0, sdSize); 932 933 /* Get security descriptor for real */ 934 retSize = -1; 935 SetLastError(0xdeadbeef); 936 rc = pGetFileSecurityA (file, request, sd, sdSize, &retSize); 937 ok (rc, "GetFileSecurityA " 938 "was not expected to fail '%s': %d\n", file, GetLastError()); 939 ok (retSize == sdSize || 940 broken(retSize == 0), /* NT4 */ 941 "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize); 942 943 /* Use it to set security descriptor */ 944 SetLastError(0xdeadbeef); 945 rc = pSetFileSecurityA (file, request, sd); 946 ok (rc, "SetFileSecurityA " 947 "was not expected to fail '%s': %d\n", file, GetLastError()); 948 949 HeapFree (GetProcessHeap (), 0, sd); 950 951 /* Repeat for the temporary directory ... */ 952 953 /* Get size needed */ 954 retSize = 0; 955 SetLastError(0xdeadbeef); 956 rc = pGetFileSecurityA (path, request, NULL, 0, &retSize); 957 ok (!rc, "GetFileSecurityA " 958 "was expected to fail for '%s'\n", path); 959 ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA " 960 "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError()); 961 ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %d\n", retSize); 962 963 sdSize = retSize; 964 sd = HeapAlloc (GetProcessHeap (), 0, sdSize); 965 966 /* Get security descriptor for real */ 967 retSize = -1; 968 SetLastError(0xdeadbeef); 969 rc = pGetFileSecurityA (path, request, sd, sdSize, &retSize); 970 ok (rc, "GetFileSecurityA " 971 "was not expected to fail '%s': %d\n", path, GetLastError()); 972 ok (retSize == sdSize || 973 broken(retSize == 0), /* NT4 */ 974 "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize); 975 976 /* Use it to set security descriptor */ 977 SetLastError(0xdeadbeef); 978 rc = pSetFileSecurityA (path, request, sd); 979 ok (rc, "SetFileSecurityA " 980 "was not expected to fail '%s': %d\n", path, GetLastError()); 981 HeapFree (GetProcessHeap (), 0, sd); 982 983 /* Old test */ 984 strcpy (wintmpdir, "\\Should not exist"); 985 SetLastError(0xdeadbeef); 986 rc = pGetFileSecurityA (wintmpdir, OWNER_SECURITY_INFORMATION, NULL, 0, &sdSize); 987 ok (!rc, "GetFileSecurityA should fail for not existing directories/files\n"); 988 ok (GetLastError() == ERROR_FILE_NOT_FOUND, 989 "last error ERROR_FILE_NOT_FOUND expected, got %d\n", GetLastError()); 990 991 cleanup: 992 /* Remove temporary file and directory */ 993 DeleteFileA(file); 994 RemoveDirectoryA(path); 995 996 /* Test file access permissions for a file with FILE_ATTRIBUTE_ARCHIVE */ 997 SetLastError(0xdeadbeef); 998 rc = GetTempPathA(sizeof(wintmpdir), wintmpdir); 999 ok(rc, "GetTempPath error %d\n", GetLastError()); 1000 1001 SetLastError(0xdeadbeef); 1002 rc = GetTempFileNameA(wintmpdir, "tmp", 0, file); 1003 ok(rc, "GetTempFileName error %d\n", GetLastError()); 1004 1005 rc = GetFileAttributesA(file); 1006 rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED); 1007 ok(rc == FILE_ATTRIBUTE_ARCHIVE, "expected FILE_ATTRIBUTE_ARCHIVE got %#x\n", rc); 1008 1009 rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, 1010 NULL, 0, &sdSize); 1011 ok(!rc, "GetFileSecurity should fail\n"); 1012 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1013 "expected ERROR_INSUFFICIENT_BUFFER got %d\n", GetLastError()); 1014 ok(sdSize > sizeof(SECURITY_DESCRIPTOR), "got sd size %d\n", sdSize); 1015 1016 sd = HeapAlloc(GetProcessHeap (), 0, sdSize); 1017 retSize = 0xdeadbeef; 1018 SetLastError(0xdeadbeef); 1019 rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, 1020 sd, sdSize, &retSize); 1021 ok(rc, "GetFileSecurity error %d\n", GetLastError()); 1022 ok(retSize == sdSize || broken(retSize == 0) /* NT4 */, "expected %d, got %d\n", sdSize, retSize); 1023 1024 SetLastError(0xdeadbeef); 1025 rc = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token); 1026 ok(!rc, "OpenThreadToken should fail\n"); 1027 ok(GetLastError() == ERROR_NO_TOKEN, "expected ERROR_NO_TOKEN, got %d\n", GetLastError()); 1028 1029 SetLastError(0xdeadbeef); 1030 rc = ImpersonateSelf(SecurityIdentification); 1031 ok(rc, "ImpersonateSelf error %d\n", GetLastError()); 1032 1033 SetLastError(0xdeadbeef); 1034 rc = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token); 1035 ok(rc, "OpenThreadToken error %d\n", GetLastError()); 1036 1037 SetLastError(0xdeadbeef); 1038 rc = RevertToSelf(); 1039 ok(rc, "RevertToSelf error %d\n", GetLastError()); 1040 1041 priv_set_len = sizeof(priv_set); 1042 granted = 0xdeadbeef; 1043 status = 0xdeadbeef; 1044 SetLastError(0xdeadbeef); 1045 rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status); 1046 ok(rc, "AccessCheck error %d\n", GetLastError()); 1047 ok(status == 1, "expected 1, got %d\n", status); 1048 ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#x\n", granted); 1049 1050 granted = 0xdeadbeef; 1051 status = 0xdeadbeef; 1052 SetLastError(0xdeadbeef); 1053 rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status); 1054 ok(rc, "AccessCheck error %d\n", GetLastError()); 1055 ok(status == 1, "expected 1, got %d\n", status); 1056 ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#x\n", granted); 1057 1058 granted = 0xdeadbeef; 1059 status = 0xdeadbeef; 1060 SetLastError(0xdeadbeef); 1061 rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status); 1062 ok(rc, "AccessCheck error %d\n", GetLastError()); 1063 ok(status == 1, "expected 1, got %d\n", status); 1064 ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#x\n", granted); 1065 1066 granted = 0xdeadbeef; 1067 status = 0xdeadbeef; 1068 SetLastError(0xdeadbeef); 1069 rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status); 1070 ok(rc, "AccessCheck error %d\n", GetLastError()); 1071 ok(status == 1, "expected 1, got %d\n", status); 1072 ok(granted == DELETE, "expected DELETE, got %#x\n", granted); 1073 1074 granted = 0xdeadbeef; 1075 status = 0xdeadbeef; 1076 SetLastError(0xdeadbeef); 1077 rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status); 1078 ok(rc, "AccessCheck error %d\n", GetLastError()); 1079 ok(status == 1, "expected 1, got %d\n", status); 1080 ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#x\n", granted); 1081 1082 granted = 0xdeadbeef; 1083 status = 0xdeadbeef; 1084 SetLastError(0xdeadbeef); 1085 rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status); 1086 ok(rc, "AccessCheck error %d\n", GetLastError()); 1087 ok(status == 1, "expected 1, got %d\n", status); 1088 ok(granted == 0x1ff, "expected 0x1ff, got %#x\n", granted); 1089 1090 granted = 0xdeadbeef; 1091 status = 0xdeadbeef; 1092 SetLastError(0xdeadbeef); 1093 rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status); 1094 ok(rc, "AccessCheck error %d\n", GetLastError()); 1095 ok(status == 1, "expected 1, got %d\n", status); 1096 ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", granted); 1097 1098 SetLastError(0xdeadbeef); 1099 rc = AccessCheck(sd, token, 0xffffffff, &mapping, &priv_set, &priv_set_len, &granted, &status); 1100 ok(!rc, "AccessCheck should fail\n"); 1101 ok(GetLastError() == ERROR_GENERIC_NOT_MAPPED, "expected ERROR_GENERIC_NOT_MAPPED, got %d\n", GetLastError()); 1102 1103 /* Test file access permissions for a file with FILE_ATTRIBUTE_READONLY */ 1104 SetLastError(0xdeadbeef); 1105 fh = CreateFileA(file, FILE_READ_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0); 1106 ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 1107 retSize = 0xdeadbeef; 1108 SetLastError(0xdeadbeef); 1109 rc = WriteFile(fh, "1", 1, &retSize, NULL); 1110 ok(!rc, "WriteFile should fail\n"); 1111 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 1112 ok(retSize == 0, "expected 0, got %d\n", retSize); 1113 CloseHandle(fh); 1114 1115 rc = GetFileAttributesA(file); 1116 rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED); 1117 todo_wine 1118 ok(rc == (FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY), 1119 "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#x\n", rc); 1120 1121 SetLastError(0xdeadbeef); 1122 rc = SetFileAttributesA(file, FILE_ATTRIBUTE_ARCHIVE); 1123 ok(rc, "SetFileAttributes error %d\n", GetLastError()); 1124 SetLastError(0xdeadbeef); 1125 rc = DeleteFileA(file); 1126 ok(rc, "DeleteFile error %d\n", GetLastError()); 1127 1128 SetLastError(0xdeadbeef); 1129 fh = CreateFileA(file, FILE_READ_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0); 1130 ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 1131 retSize = 0xdeadbeef; 1132 SetLastError(0xdeadbeef); 1133 rc = WriteFile(fh, "1", 1, &retSize, NULL); 1134 ok(!rc, "WriteFile should fail\n"); 1135 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 1136 ok(retSize == 0, "expected 0, got %d\n", retSize); 1137 CloseHandle(fh); 1138 1139 rc = GetFileAttributesA(file); 1140 rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED); 1141 ok(rc == (FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY), 1142 "expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#x\n", rc); 1143 1144 retSize = 0xdeadbeef; 1145 SetLastError(0xdeadbeef); 1146 rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, 1147 sd, sdSize, &retSize); 1148 ok(rc, "GetFileSecurity error %d\n", GetLastError()); 1149 ok(retSize == sdSize || broken(retSize == 0) /* NT4 */, "expected %d, got %d\n", sdSize, retSize); 1150 1151 priv_set_len = sizeof(priv_set); 1152 granted = 0xdeadbeef; 1153 status = 0xdeadbeef; 1154 SetLastError(0xdeadbeef); 1155 rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status); 1156 ok(rc, "AccessCheck error %d\n", GetLastError()); 1157 ok(status == 1, "expected 1, got %d\n", status); 1158 ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#x\n", granted); 1159 1160 granted = 0xdeadbeef; 1161 status = 0xdeadbeef; 1162 SetLastError(0xdeadbeef); 1163 rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status); 1164 ok(rc, "AccessCheck error %d\n", GetLastError()); 1165 todo_wine { 1166 ok(status == 1, "expected 1, got %d\n", status); 1167 ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#x\n", granted); 1168 } 1169 granted = 0xdeadbeef; 1170 status = 0xdeadbeef; 1171 SetLastError(0xdeadbeef); 1172 rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status); 1173 ok(rc, "AccessCheck error %d\n", GetLastError()); 1174 ok(status == 1, "expected 1, got %d\n", status); 1175 ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#x\n", granted); 1176 1177 granted = 0xdeadbeef; 1178 status = 0xdeadbeef; 1179 SetLastError(0xdeadbeef); 1180 rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status); 1181 ok(rc, "AccessCheck error %d\n", GetLastError()); 1182 todo_wine { 1183 ok(status == 1, "expected 1, got %d\n", status); 1184 ok(granted == DELETE, "expected DELETE, got %#x\n", granted); 1185 } 1186 granted = 0xdeadbeef; 1187 status = 0xdeadbeef; 1188 SetLastError(0xdeadbeef); 1189 rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status); 1190 ok(rc, "AccessCheck error %d\n", GetLastError()); 1191 todo_wine { 1192 ok(status == 1, "expected 1, got %d\n", status); 1193 ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#x\n", granted); 1194 } 1195 granted = 0xdeadbeef; 1196 status = 0xdeadbeef; 1197 SetLastError(0xdeadbeef); 1198 rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status); 1199 ok(rc, "AccessCheck error %d\n", GetLastError()); 1200 todo_wine { 1201 ok(status == 1, "expected 1, got %d\n", status); 1202 ok(granted == 0x1ff, "expected 0x1ff, got %#x\n", granted); 1203 } 1204 granted = 0xdeadbeef; 1205 status = 0xdeadbeef; 1206 SetLastError(0xdeadbeef); 1207 rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status); 1208 ok(rc, "AccessCheck error %d\n", GetLastError()); 1209 todo_wine { 1210 ok(status == 1, "expected 1, got %d\n", status); 1211 ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", granted); 1212 } 1213 SetLastError(0xdeadbeef); 1214 rc = DeleteFileA(file); 1215 ok(!rc, "DeleteFile should fail\n"); 1216 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 1217 SetLastError(0xdeadbeef); 1218 rc = SetFileAttributesA(file, FILE_ATTRIBUTE_ARCHIVE); 1219 ok(rc, "SetFileAttributes error %d\n", GetLastError()); 1220 SetLastError(0xdeadbeef); 1221 rc = DeleteFileA(file); 1222 ok(rc, "DeleteFile error %d\n", GetLastError()); 1223 1224 CloseHandle(token); 1225 HeapFree(GetProcessHeap(), 0, sd); 1226 } 1227 1228 static void test_AccessCheck(void) 1229 { 1230 PSID EveryoneSid = NULL, AdminSid = NULL, UsersSid = NULL; 1231 PACL Acl = NULL; 1232 SECURITY_DESCRIPTOR *SecurityDescriptor = NULL; 1233 SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; 1234 SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY }; 1235 GENERIC_MAPPING Mapping = { KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS }; 1236 ACCESS_MASK Access; 1237 BOOL AccessStatus; 1238 HANDLE Token; 1239 HANDLE ProcessToken; 1240 BOOL ret; 1241 DWORD PrivSetLen; 1242 PRIVILEGE_SET *PrivSet; 1243 BOOL res; 1244 HMODULE NtDllModule; 1245 BOOLEAN Enabled; 1246 DWORD err; 1247 NTSTATUS ntret, ntAccessStatus; 1248 1249 NtDllModule = GetModuleHandleA("ntdll.dll"); 1250 if (!NtDllModule) 1251 { 1252 skip("not running on NT, skipping test\n"); 1253 return; 1254 } 1255 pRtlAdjustPrivilege = (void *)GetProcAddress(NtDllModule, "RtlAdjustPrivilege"); 1256 if (!pRtlAdjustPrivilege) 1257 { 1258 win_skip("missing RtlAdjustPrivilege, skipping test\n"); 1259 return; 1260 } 1261 1262 Acl = HeapAlloc(GetProcessHeap(), 0, 256); 1263 res = InitializeAcl(Acl, 256, ACL_REVISION); 1264 if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 1265 { 1266 skip("ACLs not implemented - skipping tests\n"); 1267 HeapFree(GetProcessHeap(), 0, Acl); 1268 return; 1269 } 1270 ok(res, "InitializeAcl failed with error %d\n", GetLastError()); 1271 1272 res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); 1273 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 1274 1275 res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, 1276 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdminSid); 1277 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 1278 1279 res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, 1280 DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid); 1281 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 1282 1283 SecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); 1284 1285 res = InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); 1286 ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError()); 1287 1288 res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); 1289 ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); 1290 1291 PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]); 1292 PrivSet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, PrivSetLen); 1293 PrivSet->PrivilegeCount = 16; 1294 1295 res = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &ProcessToken); 1296 ok(res, "OpenProcessToken failed with error %d\n", GetLastError()); 1297 1298 pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, FALSE, TRUE, &Enabled); 1299 1300 res = DuplicateToken(ProcessToken, SecurityImpersonation, &Token); 1301 ok(res, "DuplicateToken failed with error %d\n", GetLastError()); 1302 1303 /* SD without owner/group */ 1304 SetLastError(0xdeadbeef); 1305 Access = AccessStatus = 0x1abe11ed; 1306 ret = AccessCheck(SecurityDescriptor, Token, KEY_QUERY_VALUE, &Mapping, 1307 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1308 err = GetLastError(); 1309 ok(!ret && err == ERROR_INVALID_SECURITY_DESCR, "AccessCheck should have " 1310 "failed with ERROR_INVALID_SECURITY_DESCR, instead of %d\n", err); 1311 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1312 "Access and/or AccessStatus were changed!\n"); 1313 1314 /* Set owner and group */ 1315 res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE); 1316 ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); 1317 res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, TRUE); 1318 ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); 1319 1320 /* Generic access mask */ 1321 SetLastError(0xdeadbeef); 1322 Access = AccessStatus = 0x1abe11ed; 1323 ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, 1324 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1325 err = GetLastError(); 1326 ok(!ret && err == ERROR_GENERIC_NOT_MAPPED, "AccessCheck should have failed " 1327 "with ERROR_GENERIC_NOT_MAPPED, instead of %d\n", err); 1328 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1329 "Access and/or AccessStatus were changed!\n"); 1330 1331 /* Generic access mask - no privilegeset buffer */ 1332 SetLastError(0xdeadbeef); 1333 Access = AccessStatus = 0x1abe11ed; 1334 ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, 1335 NULL, &PrivSetLen, &Access, &AccessStatus); 1336 err = GetLastError(); 1337 ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed " 1338 "with ERROR_NOACCESS, instead of %d\n", err); 1339 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1340 "Access and/or AccessStatus were changed!\n"); 1341 1342 /* Generic access mask - no returnlength */ 1343 SetLastError(0xdeadbeef); 1344 Access = AccessStatus = 0x1abe11ed; 1345 ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, 1346 PrivSet, NULL, &Access, &AccessStatus); 1347 err = GetLastError(); 1348 ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed " 1349 "with ERROR_NOACCESS, instead of %d\n", err); 1350 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1351 "Access and/or AccessStatus were changed!\n"); 1352 1353 /* Generic access mask - no privilegeset buffer, no returnlength */ 1354 SetLastError(0xdeadbeef); 1355 Access = AccessStatus = 0x1abe11ed; 1356 ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, 1357 NULL, NULL, &Access, &AccessStatus); 1358 err = GetLastError(); 1359 ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed " 1360 "with ERROR_NOACCESS, instead of %d\n", err); 1361 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1362 "Access and/or AccessStatus were changed!\n"); 1363 1364 /* sd with no dacl present */ 1365 Access = AccessStatus = 0x1abe11ed; 1366 ret = SetSecurityDescriptorDacl(SecurityDescriptor, FALSE, NULL, FALSE); 1367 ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); 1368 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1369 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1370 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1371 ok(AccessStatus && (Access == KEY_READ), 1372 "AccessCheck failed to grant access with error %d\n", 1373 GetLastError()); 1374 1375 /* sd with no dacl present - no privilegeset buffer */ 1376 SetLastError(0xdeadbeef); 1377 Access = AccessStatus = 0x1abe11ed; 1378 ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, 1379 NULL, &PrivSetLen, &Access, &AccessStatus); 1380 err = GetLastError(); 1381 ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed " 1382 "with ERROR_NOACCESS, instead of %d\n", err); 1383 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1384 "Access and/or AccessStatus were changed!\n"); 1385 1386 if(pNtAccessCheck) 1387 { 1388 /* Generic access mask - no privilegeset buffer */ 1389 SetLastError(0xdeadbeef); 1390 Access = ntAccessStatus = 0x1abe11ed; 1391 ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, 1392 NULL, &PrivSetLen, &Access, &ntAccessStatus); 1393 err = GetLastError(); 1394 ok(ntret == STATUS_ACCESS_VIOLATION, 1395 "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret); 1396 ok(err == 0xdeadbeef, 1397 "NtAccessCheck shouldn't set last error, got %d\n", err); 1398 ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, 1399 "Access and/or AccessStatus were changed!\n"); 1400 1401 /* Generic access mask - no returnlength */ 1402 SetLastError(0xdeadbeef); 1403 Access = ntAccessStatus = 0x1abe11ed; 1404 ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, 1405 PrivSet, NULL, &Access, &ntAccessStatus); 1406 err = GetLastError(); 1407 ok(ntret == STATUS_ACCESS_VIOLATION, 1408 "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret); 1409 ok(err == 0xdeadbeef, 1410 "NtAccessCheck shouldn't set last error, got %d\n", err); 1411 ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, 1412 "Access and/or AccessStatus were changed!\n"); 1413 1414 /* Generic access mask - no privilegeset buffer, no returnlength */ 1415 SetLastError(0xdeadbeef); 1416 Access = ntAccessStatus = 0x1abe11ed; 1417 ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping, 1418 NULL, NULL, &Access, &ntAccessStatus); 1419 err = GetLastError(); 1420 ok(ntret == STATUS_ACCESS_VIOLATION, 1421 "NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %x\n", ntret); 1422 ok(err == 0xdeadbeef, 1423 "NtAccessCheck shouldn't set last error, got %d\n", err); 1424 ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed, 1425 "Access and/or AccessStatus were changed!\n"); 1426 } 1427 else 1428 win_skip("NtAccessCheck unavailable. Skipping.\n"); 1429 1430 /* sd with NULL dacl */ 1431 Access = AccessStatus = 0x1abe11ed; 1432 ret = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, NULL, FALSE); 1433 ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); 1434 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1435 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1436 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1437 ok(AccessStatus && (Access == KEY_READ), 1438 "AccessCheck failed to grant access with error %d\n", 1439 GetLastError()); 1440 ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping, 1441 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1442 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1443 ok(AccessStatus && (Access == KEY_ALL_ACCESS), 1444 "AccessCheck failed to grant access with error %d\n", 1445 GetLastError()); 1446 1447 /* sd with blank dacl */ 1448 ret = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); 1449 ok(ret, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); 1450 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1451 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1452 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1453 err = GetLastError(); 1454 ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed " 1455 "with ERROR_ACCESS_DENIED, instead of %d\n", err); 1456 ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access); 1457 1458 res = AddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, EveryoneSid); 1459 ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); 1460 1461 res = AddAccessDeniedAce(Acl, ACL_REVISION, KEY_SET_VALUE, AdminSid); 1462 ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError()); 1463 1464 /* sd with dacl */ 1465 Access = AccessStatus = 0x1abe11ed; 1466 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1467 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1468 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1469 ok(AccessStatus && (Access == KEY_READ), 1470 "AccessCheck failed to grant access with error %d\n", 1471 GetLastError()); 1472 1473 ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping, 1474 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1475 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1476 ok(AccessStatus, 1477 "AccessCheck failed to grant any access with error %d\n", 1478 GetLastError()); 1479 trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08x\n", Access); 1480 1481 /* Null PrivSet with null PrivSetLen pointer */ 1482 SetLastError(0xdeadbeef); 1483 Access = AccessStatus = 0x1abe11ed; 1484 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1485 NULL, NULL, &Access, &AccessStatus); 1486 err = GetLastError(); 1487 ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " 1488 "failed with ERROR_NOACCESS, instead of %d\n", err); 1489 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1490 "Access and/or AccessStatus were changed!\n"); 1491 1492 /* Null PrivSet with zero PrivSetLen */ 1493 SetLastError(0xdeadbeef); 1494 Access = AccessStatus = 0x1abe11ed; 1495 PrivSetLen = 0; 1496 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1497 0, &PrivSetLen, &Access, &AccessStatus); 1498 err = GetLastError(); 1499 ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " 1500 "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); 1501 ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); 1502 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1503 "Access and/or AccessStatus were changed!\n"); 1504 1505 /* Null PrivSet with insufficient PrivSetLen */ 1506 SetLastError(0xdeadbeef); 1507 Access = AccessStatus = 0x1abe11ed; 1508 PrivSetLen = 1; 1509 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1510 0, &PrivSetLen, &Access, &AccessStatus); 1511 err = GetLastError(); 1512 ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " 1513 "failed with ERROR_NOACCESS, instead of %d\n", err); 1514 ok(PrivSetLen == 1, "PrivSetLen returns %d\n", PrivSetLen); 1515 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1516 "Access and/or AccessStatus were changed!\n"); 1517 1518 /* Null PrivSet with insufficient PrivSetLen */ 1519 SetLastError(0xdeadbeef); 1520 Access = AccessStatus = 0x1abe11ed; 1521 PrivSetLen = sizeof(PRIVILEGE_SET) - 1; 1522 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1523 0, &PrivSetLen, &Access, &AccessStatus); 1524 err = GetLastError(); 1525 ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " 1526 "failed with ERROR_NOACCESS, instead of %d\n", err); 1527 ok(PrivSetLen == sizeof(PRIVILEGE_SET) - 1, "PrivSetLen returns %d\n", PrivSetLen); 1528 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1529 "Access and/or AccessStatus were changed!\n"); 1530 1531 /* Null PrivSet with minimal sufficient PrivSetLen */ 1532 SetLastError(0xdeadbeef); 1533 Access = AccessStatus = 0x1abe11ed; 1534 PrivSetLen = sizeof(PRIVILEGE_SET); 1535 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1536 0, &PrivSetLen, &Access, &AccessStatus); 1537 err = GetLastError(); 1538 ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " 1539 "failed with ERROR_NOACCESS, instead of %d\n", err); 1540 ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); 1541 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1542 "Access and/or AccessStatus were changed!\n"); 1543 1544 /* Valid PrivSet with zero PrivSetLen */ 1545 SetLastError(0xdeadbeef); 1546 Access = AccessStatus = 0x1abe11ed; 1547 PrivSetLen = 0; 1548 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1549 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1550 err = GetLastError(); 1551 ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " 1552 "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); 1553 ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); 1554 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1555 "Access and/or AccessStatus were changed!\n"); 1556 1557 /* Valid PrivSet with insufficient PrivSetLen */ 1558 SetLastError(0xdeadbeef); 1559 Access = AccessStatus = 0x1abe11ed; 1560 PrivSetLen = 1; 1561 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1562 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1563 err = GetLastError(); 1564 todo_wine 1565 ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " 1566 "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); 1567 todo_wine 1568 ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); 1569 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1570 "Access and/or AccessStatus were changed!\n"); 1571 1572 /* Valid PrivSet with insufficient PrivSetLen */ 1573 SetLastError(0xdeadbeef); 1574 Access = AccessStatus = 0x1abe11ed; 1575 PrivSetLen = sizeof(PRIVILEGE_SET) - 1; 1576 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1577 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1578 err = GetLastError(); 1579 todo_wine 1580 ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " 1581 "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); 1582 todo_wine 1583 ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); 1584 todo_wine 1585 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1586 "Access and/or AccessStatus were changed!\n"); 1587 1588 /* Valid PrivSet with minimal sufficient PrivSetLen */ 1589 SetLastError(0xdeadbeef); 1590 Access = AccessStatus = 0x1abe11ed; 1591 PrivSetLen = sizeof(PRIVILEGE_SET); 1592 memset(PrivSet, 0xcc, PrivSetLen); 1593 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1594 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1595 err = GetLastError(); 1596 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1597 todo_wine 1598 ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); 1599 ok(AccessStatus && (Access == KEY_READ), 1600 "AccessCheck failed to grant access with error %d\n", GetLastError()); 1601 ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n", 1602 PrivSet->PrivilegeCount); 1603 1604 /* Valid PrivSet with sufficient PrivSetLen */ 1605 SetLastError(0xdeadbeef); 1606 Access = AccessStatus = 0x1abe11ed; 1607 PrivSetLen = sizeof(PRIVILEGE_SET) + 1; 1608 memset(PrivSet, 0xcc, PrivSetLen); 1609 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1610 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1611 err = GetLastError(); 1612 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1613 todo_wine 1614 ok(PrivSetLen == sizeof(PRIVILEGE_SET) + 1, "PrivSetLen returns %d\n", PrivSetLen); 1615 ok(AccessStatus && (Access == KEY_READ), 1616 "AccessCheck failed to grant access with error %d\n", GetLastError()); 1617 ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n", 1618 PrivSet->PrivilegeCount); 1619 1620 PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]); 1621 1622 /* Null PrivSet with valid PrivSetLen */ 1623 SetLastError(0xdeadbeef); 1624 Access = AccessStatus = 0x1abe11ed; 1625 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1626 0, &PrivSetLen, &Access, &AccessStatus); 1627 err = GetLastError(); 1628 ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have " 1629 "failed with ERROR_NOACCESS, instead of %d\n", err); 1630 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1631 "Access and/or AccessStatus were changed!\n"); 1632 1633 /* Access denied by SD */ 1634 SetLastError(0xdeadbeef); 1635 Access = AccessStatus = 0x1abe11ed; 1636 ret = AccessCheck(SecurityDescriptor, Token, KEY_WRITE, &Mapping, 1637 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1638 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1639 err = GetLastError(); 1640 ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed " 1641 "with ERROR_ACCESS_DENIED, instead of %d\n", err); 1642 ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access); 1643 1644 SetLastError(0xdeadbeef); 1645 PrivSet->PrivilegeCount = 16; 1646 ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping, 1647 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1648 ok(ret && !AccessStatus && GetLastError() == ERROR_PRIVILEGE_NOT_HELD, 1649 "AccessCheck should have failed with ERROR_PRIVILEGE_NOT_HELD, instead of %d\n", 1650 GetLastError()); 1651 1652 ret = ImpersonateLoggedOnUser(Token); 1653 ok(ret, "ImpersonateLoggedOnUser failed with error %d\n", GetLastError()); 1654 ret = pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, TRUE, TRUE, &Enabled); 1655 if (!ret) 1656 { 1657 /* Valid PrivSet with zero PrivSetLen */ 1658 SetLastError(0xdeadbeef); 1659 Access = AccessStatus = 0x1abe11ed; 1660 PrivSetLen = 0; 1661 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1662 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1663 err = GetLastError(); 1664 ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " 1665 "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); 1666 ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); 1667 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1668 "Access and/or AccessStatus were changed!\n"); 1669 1670 /* Valid PrivSet with insufficient PrivSetLen */ 1671 SetLastError(0xdeadbeef); 1672 Access = AccessStatus = 0x1abe11ed; 1673 PrivSetLen = sizeof(PRIVILEGE_SET) - 1; 1674 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1675 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1676 err = GetLastError(); 1677 todo_wine 1678 ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have " 1679 "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err); 1680 todo_wine 1681 ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen); 1682 todo_wine 1683 ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed, 1684 "Access and/or AccessStatus were changed!\n"); 1685 1686 /* Valid PrivSet with minimal sufficient PrivSetLen */ 1687 SetLastError(0xdeadbeef); 1688 Access = AccessStatus = 0x1abe11ed; 1689 PrivSetLen = sizeof(PRIVILEGE_SET); 1690 memset(PrivSet, 0xcc, PrivSetLen); 1691 ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping, 1692 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1693 ok(ret && AccessStatus && GetLastError() == 0xdeadbeef, 1694 "AccessCheck should have succeeded, error %d\n", 1695 GetLastError()); 1696 ok(Access == ACCESS_SYSTEM_SECURITY, 1697 "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n", 1698 Access); 1699 ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n", 1700 PrivSet->PrivilegeCount); 1701 1702 /* Valid PrivSet with large PrivSetLen */ 1703 SetLastError(0xdeadbeef); 1704 Access = AccessStatus = 0x1abe11ed; 1705 PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]); 1706 memset(PrivSet, 0xcc, PrivSetLen); 1707 ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping, 1708 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1709 ok(ret && AccessStatus && GetLastError() == 0xdeadbeef, 1710 "AccessCheck should have succeeded, error %d\n", 1711 GetLastError()); 1712 ok(Access == ACCESS_SYSTEM_SECURITY, 1713 "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n", 1714 Access); 1715 ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n", 1716 PrivSet->PrivilegeCount); 1717 } 1718 else 1719 trace("Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test\n", 1720 ret); 1721 ret = RevertToSelf(); 1722 ok(ret, "RevertToSelf failed with error %d\n", GetLastError()); 1723 1724 /* test INHERIT_ONLY_ACE */ 1725 ret = InitializeAcl(Acl, 256, ACL_REVISION); 1726 ok(ret, "InitializeAcl failed with error %d\n", GetLastError()); 1727 1728 /* NT doesn't have AddAccessAllowedAceEx. Skipping this call/test doesn't influence 1729 * the next ones. 1730 */ 1731 if (pAddAccessAllowedAceEx) 1732 { 1733 ret = pAddAccessAllowedAceEx(Acl, ACL_REVISION, INHERIT_ONLY_ACE, KEY_READ, EveryoneSid); 1734 ok(ret, "AddAccessAllowedAceEx failed with error %d\n", GetLastError()); 1735 } 1736 else 1737 win_skip("AddAccessAllowedAceEx is not available\n"); 1738 1739 ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping, 1740 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1741 ok(ret, "AccessCheck failed with error %d\n", GetLastError()); 1742 err = GetLastError(); 1743 ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed " 1744 "with ERROR_ACCESS_DENIED, instead of %d\n", err); 1745 ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access); 1746 1747 CloseHandle(Token); 1748 1749 res = DuplicateToken(ProcessToken, SecurityAnonymous, &Token); 1750 ok(res, "DuplicateToken failed with error %d\n", GetLastError()); 1751 1752 SetLastError(0xdeadbeef); 1753 ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping, 1754 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1755 err = GetLastError(); 1756 ok(!ret && err == ERROR_BAD_IMPERSONATION_LEVEL, "AccessCheck should have failed " 1757 "with ERROR_BAD_IMPERSONATION_LEVEL, instead of %d\n", err); 1758 1759 CloseHandle(Token); 1760 1761 SetLastError(0xdeadbeef); 1762 ret = AccessCheck(SecurityDescriptor, ProcessToken, KEY_READ, &Mapping, 1763 PrivSet, &PrivSetLen, &Access, &AccessStatus); 1764 err = GetLastError(); 1765 ok(!ret && err == ERROR_NO_IMPERSONATION_TOKEN, "AccessCheck should have failed " 1766 "with ERROR_NO_IMPERSONATION_TOKEN, instead of %d\n", err); 1767 1768 CloseHandle(ProcessToken); 1769 1770 if (EveryoneSid) 1771 FreeSid(EveryoneSid); 1772 if (AdminSid) 1773 FreeSid(AdminSid); 1774 if (UsersSid) 1775 FreeSid(UsersSid); 1776 HeapFree(GetProcessHeap(), 0, Acl); 1777 HeapFree(GetProcessHeap(), 0, SecurityDescriptor); 1778 HeapFree(GetProcessHeap(), 0, PrivSet); 1779 } 1780 1781 /* test GetTokenInformation for the various attributes */ 1782 static void test_token_attr(void) 1783 { 1784 HANDLE Token, ImpersonationToken; 1785 DWORD Size, Size2; 1786 TOKEN_PRIVILEGES *Privileges; 1787 TOKEN_GROUPS *Groups; 1788 TOKEN_USER *User; 1789 TOKEN_DEFAULT_DACL *Dacl; 1790 BOOL ret; 1791 DWORD i, GLE; 1792 LPSTR SidString; 1793 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 1794 ACL *acl; 1795 1796 /* cygwin-like use case */ 1797 SetLastError(0xdeadbeef); 1798 ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &Token); 1799 if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 1800 { 1801 win_skip("OpenProcessToken is not implemented\n"); 1802 return; 1803 } 1804 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); 1805 if (ret) 1806 { 1807 DWORD buf[256]; /* GetTokenInformation wants a dword-aligned buffer */ 1808 Size = sizeof(buf); 1809 ret = GetTokenInformation(Token, TokenUser,(void*)buf, Size, &Size); 1810 ok(ret, "GetTokenInformation failed with error %d\n", GetLastError()); 1811 Size = sizeof(ImpersonationLevel); 1812 ret = GetTokenInformation(Token, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size); 1813 GLE = GetLastError(); 1814 ok(!ret && (GLE == ERROR_INVALID_PARAMETER), "GetTokenInformation(TokenImpersonationLevel) on primary token should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GLE); 1815 CloseHandle(Token); 1816 } 1817 1818 SetLastError(0xdeadbeef); 1819 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &Token); 1820 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); 1821 1822 /* groups */ 1823 /* insufficient buffer length */ 1824 SetLastError(0xdeadbeef); 1825 Size2 = 0; 1826 ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size2); 1827 ok(Size2 > 1, "got %d\n", Size2); 1828 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1829 "%d with error %d\n", ret, GetLastError()); 1830 Size2 -= 1; 1831 Groups = HeapAlloc(GetProcessHeap(), 0, Size2); 1832 memset(Groups, 0xcc, Size2); 1833 Size = 0; 1834 ret = GetTokenInformation(Token, TokenGroups, Groups, Size2, &Size); 1835 ok(Size > 1, "got %d\n", Size); 1836 ok((!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) || broken(ret) /* wow64 */, 1837 "%d with error %d\n", ret, GetLastError()); 1838 if(!ret) 1839 ok(*((BYTE*)Groups) == 0xcc, "buffer altered\n"); 1840 1841 HeapFree(GetProcessHeap(), 0, Groups); 1842 1843 SetLastError(0xdeadbeef); 1844 ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size); 1845 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1846 "GetTokenInformation(TokenGroups) %s with error %d\n", 1847 ret ? "succeeded" : "failed", GetLastError()); 1848 Groups = HeapAlloc(GetProcessHeap(), 0, Size); 1849 SetLastError(0xdeadbeef); 1850 ret = GetTokenInformation(Token, TokenGroups, Groups, Size, &Size); 1851 ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n", GetLastError()); 1852 ok(GetLastError() == 0xdeadbeef, 1853 "GetTokenInformation shouldn't have set last error to %d\n", 1854 GetLastError()); 1855 trace("TokenGroups:\n"); 1856 for (i = 0; i < Groups->GroupCount; i++) 1857 { 1858 DWORD NameLength = 255; 1859 CHAR Name[255]; 1860 DWORD DomainLength = 255; 1861 CHAR Domain[255]; 1862 SID_NAME_USE SidNameUse; 1863 Name[0] = '\0'; 1864 Domain[0] = '\0'; 1865 ret = LookupAccountSidA(NULL, Groups->Groups[i].Sid, Name, &NameLength, Domain, &DomainLength, &SidNameUse); 1866 if (ret) 1867 { 1868 ConvertSidToStringSidA(Groups->Groups[i].Sid, &SidString); 1869 trace("%s, %s\\%s use: %d attr: 0x%08x\n", SidString, Domain, Name, SidNameUse, Groups->Groups[i].Attributes); 1870 LocalFree(SidString); 1871 } 1872 else trace("attr: 0x%08x LookupAccountSid failed with error %d\n", Groups->Groups[i].Attributes, GetLastError()); 1873 } 1874 HeapFree(GetProcessHeap(), 0, Groups); 1875 1876 /* user */ 1877 ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size); 1878 ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1879 "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 1880 User = HeapAlloc(GetProcessHeap(), 0, Size); 1881 ret = GetTokenInformation(Token, TokenUser, User, Size, &Size); 1882 ok(ret, 1883 "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 1884 1885 ConvertSidToStringSidA(User->User.Sid, &SidString); 1886 trace("TokenUser: %s attr: 0x%08x\n", SidString, User->User.Attributes); 1887 LocalFree(SidString); 1888 HeapFree(GetProcessHeap(), 0, User); 1889 1890 /* logon */ 1891 ret = GetTokenInformation(Token, TokenLogonSid, NULL, 0, &Size); 1892 if (!ret && (GetLastError() == ERROR_INVALID_PARAMETER)) 1893 todo_wine win_skip("TokenLogonSid not supported. Skipping tests\n"); 1894 else 1895 { 1896 ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1897 "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError()); 1898 Groups = HeapAlloc(GetProcessHeap(), 0, Size); 1899 ret = GetTokenInformation(Token, TokenLogonSid, Groups, Size, &Size); 1900 ok(ret, 1901 "GetTokenInformation(TokenLogonSid) failed with error %d\n", GetLastError()); 1902 if (ret) 1903 { 1904 ok(Groups->GroupCount == 1, "got %d\n", Groups->GroupCount); 1905 if(Groups->GroupCount == 1) 1906 { 1907 ConvertSidToStringSidA(Groups->Groups[0].Sid, &SidString); 1908 trace("TokenLogon: %s\n", SidString); 1909 LocalFree(SidString); 1910 1911 /* S-1-5-5-0-XXXXXX */ 1912 ret = IsWellKnownSid(Groups->Groups[0].Sid, WinLogonIdsSid); 1913 ok(ret, "Unknown SID\n"); 1914 } 1915 } 1916 1917 HeapFree(GetProcessHeap(), 0, Groups); 1918 } 1919 1920 /* privileges */ 1921 ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size); 1922 ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1923 "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError()); 1924 Privileges = HeapAlloc(GetProcessHeap(), 0, Size); 1925 ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size); 1926 ok(ret, 1927 "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError()); 1928 trace("TokenPrivileges:\n"); 1929 for (i = 0; i < Privileges->PrivilegeCount; i++) 1930 { 1931 CHAR Name[256]; 1932 DWORD NameLen = sizeof(Name)/sizeof(Name[0]); 1933 LookupPrivilegeNameA(NULL, &Privileges->Privileges[i].Luid, Name, &NameLen); 1934 trace("\t%s, 0x%x\n", Name, Privileges->Privileges[i].Attributes); 1935 } 1936 HeapFree(GetProcessHeap(), 0, Privileges); 1937 1938 ret = DuplicateToken(Token, SecurityAnonymous, &ImpersonationToken); 1939 ok(ret, "DuplicateToken failed with error %d\n", GetLastError()); 1940 1941 Size = sizeof(ImpersonationLevel); 1942 ret = GetTokenInformation(ImpersonationToken, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size); 1943 ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError()); 1944 ok(ImpersonationLevel == SecurityAnonymous, "ImpersonationLevel should have been SecurityAnonymous instead of %d\n", ImpersonationLevel); 1945 1946 CloseHandle(ImpersonationToken); 1947 1948 /* default dacl */ 1949 ret = GetTokenInformation(Token, TokenDefaultDacl, NULL, 0, &Size); 1950 ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1951 "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); 1952 1953 Dacl = HeapAlloc(GetProcessHeap(), 0, Size); 1954 ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size); 1955 ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); 1956 1957 SetLastError(0xdeadbeef); 1958 ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, 0); 1959 GLE = GetLastError(); 1960 ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n"); 1961 ok(GLE == ERROR_BAD_LENGTH, "expected ERROR_BAD_LENGTH got %u\n", GLE); 1962 1963 SetLastError(0xdeadbeef); 1964 ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, Size); 1965 GLE = GetLastError(); 1966 ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n"); 1967 ok(GLE == ERROR_NOACCESS, "expected ERROR_NOACCESS got %u\n", GLE); 1968 1969 acl = Dacl->DefaultDacl; 1970 Dacl->DefaultDacl = NULL; 1971 1972 ret = SetTokenInformation(Token, TokenDefaultDacl, Dacl, Size); 1973 ok(ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n"); 1974 1975 Size2 = 0; 1976 Dacl->DefaultDacl = (ACL *)0xdeadbeef; 1977 ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2); 1978 ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); 1979 ok(Dacl->DefaultDacl == NULL, "expected NULL, got %p\n", Dacl->DefaultDacl); 1980 ok(Size2 == sizeof(TOKEN_DEFAULT_DACL) || broken(Size2 == 2*sizeof(TOKEN_DEFAULT_DACL)), /* WoW64 */ 1981 "got %u expected sizeof(TOKEN_DEFAULT_DACL)\n", Size2); 1982 1983 Dacl->DefaultDacl = acl; 1984 ret = SetTokenInformation(Token, TokenDefaultDacl, Dacl, Size); 1985 ok(ret, "SetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); 1986 1987 if (Size2 == sizeof(TOKEN_DEFAULT_DACL)) { 1988 ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2); 1989 ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %u\n", GetLastError()); 1990 } else 1991 win_skip("TOKEN_DEFAULT_DACL size too small on WoW64\n"); 1992 1993 HeapFree(GetProcessHeap(), 0, Dacl); 1994 CloseHandle(Token); 1995 } 1996 1997 static void test_GetTokenInformation(void) 1998 { 1999 DWORD is_app_container, size; 2000 HANDLE token; 2001 BOOL ret; 2002 2003 ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); 2004 ok(ret, "OpenProcessToken failed: %u\n", GetLastError()); 2005 2006 size = 0; 2007 is_app_container = 0xdeadbeef; 2008 ret = GetTokenInformation(token, TokenIsAppContainer, &is_app_container, 2009 sizeof(is_app_container), &size); 2010 ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER || 2011 GetLastError() == ERROR_INVALID_FUNCTION), /* pre-win8 */ 2012 "GetTokenInformation failed: %u\n", GetLastError()); 2013 if(ret) { 2014 ok(size == sizeof(is_app_container), "size = %u\n", size); 2015 ok(!is_app_container, "is_app_container = %x\n", is_app_container); 2016 } 2017 2018 CloseHandle(token); 2019 } 2020 2021 typedef union _MAX_SID 2022 { 2023 SID sid; 2024 char max[SECURITY_MAX_SID_SIZE]; 2025 } MAX_SID; 2026 2027 static void test_sid_str(PSID * sid) 2028 { 2029 char *str_sid; 2030 BOOL ret = ConvertSidToStringSidA(sid, &str_sid); 2031 ok(ret, "ConvertSidToStringSidA() failed: %d\n", GetLastError()); 2032 if (ret) 2033 { 2034 char account[MAX_PATH], domain[MAX_PATH]; 2035 SID_NAME_USE use; 2036 DWORD acc_size = MAX_PATH; 2037 DWORD dom_size = MAX_PATH; 2038 ret = LookupAccountSidA (NULL, sid, account, &acc_size, domain, &dom_size, &use); 2039 ok(ret || GetLastError() == ERROR_NONE_MAPPED, 2040 "LookupAccountSid(%s) failed: %d\n", str_sid, GetLastError()); 2041 if (ret) 2042 trace(" %s %s\\%s %d\n", str_sid, domain, account, use); 2043 else if (GetLastError() == ERROR_NONE_MAPPED) 2044 trace(" %s couldn't be mapped\n", str_sid); 2045 LocalFree(str_sid); 2046 } 2047 } 2048 2049 static const struct well_known_sid_value 2050 { 2051 BOOL without_domain; 2052 const char *sid_string; 2053 } well_known_sid_values[] = { 2054 /* 0 */ {TRUE, "S-1-0-0"}, {TRUE, "S-1-1-0"}, {TRUE, "S-1-2-0"}, {TRUE, "S-1-3-0"}, 2055 /* 4 */ {TRUE, "S-1-3-1"}, {TRUE, "S-1-3-2"}, {TRUE, "S-1-3-3"}, {TRUE, "S-1-5"}, 2056 /* 8 */ {FALSE, "S-1-5-1"}, {TRUE, "S-1-5-2"}, {TRUE, "S-1-5-3"}, {TRUE, "S-1-5-4"}, 2057 /* 12 */ {TRUE, "S-1-5-6"}, {TRUE, "S-1-5-7"}, {TRUE, "S-1-5-8"}, {TRUE, "S-1-5-9"}, 2058 /* 16 */ {TRUE, "S-1-5-10"}, {TRUE, "S-1-5-11"}, {TRUE, "S-1-5-12"}, {TRUE, "S-1-5-13"}, 2059 /* 20 */ {TRUE, "S-1-5-14"}, {FALSE, NULL}, {TRUE, "S-1-5-18"}, {TRUE, "S-1-5-19"}, 2060 /* 24 */ {TRUE, "S-1-5-20"}, {TRUE, "S-1-5-32"}, 2061 /* 26 */ {FALSE, "S-1-5-32-544"}, {TRUE, "S-1-5-32-545"}, {TRUE, "S-1-5-32-546"}, 2062 /* 29 */ {TRUE, "S-1-5-32-547"}, {TRUE, "S-1-5-32-548"}, {TRUE, "S-1-5-32-549"}, 2063 /* 32 */ {TRUE, "S-1-5-32-550"}, {TRUE, "S-1-5-32-551"}, {TRUE, "S-1-5-32-552"}, 2064 /* 35 */ {TRUE, "S-1-5-32-554"}, {TRUE, "S-1-5-32-555"}, {TRUE, "S-1-5-32-556"}, 2065 /* 38 */ {FALSE, "S-1-5-21-12-23-34-45-56-500"}, {FALSE, "S-1-5-21-12-23-34-45-56-501"}, 2066 /* 40 */ {FALSE, "S-1-5-21-12-23-34-45-56-502"}, {FALSE, "S-1-5-21-12-23-34-45-56-512"}, 2067 /* 42 */ {FALSE, "S-1-5-21-12-23-34-45-56-513"}, {FALSE, "S-1-5-21-12-23-34-45-56-514"}, 2068 /* 44 */ {FALSE, "S-1-5-21-12-23-34-45-56-515"}, {FALSE, "S-1-5-21-12-23-34-45-56-516"}, 2069 /* 46 */ {FALSE, "S-1-5-21-12-23-34-45-56-517"}, {FALSE, "S-1-5-21-12-23-34-45-56-518"}, 2070 /* 48 */ {FALSE, "S-1-5-21-12-23-34-45-56-519"}, {FALSE, "S-1-5-21-12-23-34-45-56-520"}, 2071 /* 50 */ {FALSE, "S-1-5-21-12-23-34-45-56-553"}, 2072 /* Added in Windows Server 2003 */ 2073 /* 51 */ {TRUE, "S-1-5-64-10"}, {TRUE, "S-1-5-64-21"}, {TRUE, "S-1-5-64-14"}, 2074 /* 54 */ {TRUE, "S-1-5-15"}, {TRUE, "S-1-5-1000"}, {FALSE, "S-1-5-32-557"}, 2075 /* 57 */ {TRUE, "S-1-5-32-558"}, {TRUE, "S-1-5-32-559"}, {TRUE, "S-1-5-32-560"}, 2076 /* 60 */ {TRUE, "S-1-5-32-561"}, {TRUE, "S-1-5-32-562"}, 2077 /* Added in Windows Vista: */ 2078 /* 62 */ {TRUE, "S-1-5-32-568"}, 2079 /* 63 */ {TRUE, "S-1-5-17"}, {FALSE, "S-1-5-32-569"}, {TRUE, "S-1-16-0"}, 2080 /* 66 */ {TRUE, "S-1-16-4096"}, {TRUE, "S-1-16-8192"}, {TRUE, "S-1-16-12288"}, 2081 /* 69 */ {TRUE, "S-1-16-16384"}, {TRUE, "S-1-5-33"}, {TRUE, "S-1-3-4"}, 2082 /* 72 */ {FALSE, "S-1-5-21-12-23-34-45-56-571"}, {FALSE, "S-1-5-21-12-23-34-45-56-572"}, 2083 /* 74 */ {TRUE, "S-1-5-22"}, {FALSE, "S-1-5-21-12-23-34-45-56-521"}, {TRUE, "S-1-5-32-573"}, 2084 /* 77 */ {FALSE, "S-1-5-21-12-23-34-45-56-498"}, {TRUE, "S-1-5-32-574"}, {TRUE, "S-1-16-8448"}, 2085 /* 80 */ {FALSE, NULL}, {TRUE, "S-1-2-1"}, {TRUE, "S-1-5-65-1"}, {FALSE, NULL}, 2086 /* 84 */ {TRUE, "S-1-15-2-1"}, 2087 }; 2088 2089 static void test_CreateWellKnownSid(void) 2090 { 2091 SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY }; 2092 PSID domainsid, sid; 2093 DWORD size, error; 2094 BOOL ret; 2095 unsigned int i; 2096 2097 if (!pCreateWellKnownSid) 2098 { 2099 win_skip("CreateWellKnownSid not available\n"); 2100 return; 2101 } 2102 2103 size = 0; 2104 SetLastError(0xdeadbeef); 2105 ret = pCreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size); 2106 error = GetLastError(); 2107 ok(!ret, "CreateWellKnownSid succeeded\n"); 2108 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error); 2109 ok(size, "expected size > 0\n"); 2110 2111 SetLastError(0xdeadbeef); 2112 ret = pCreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size); 2113 error = GetLastError(); 2114 ok(!ret, "CreateWellKnownSid succeeded\n"); 2115 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 2116 2117 sid = HeapAlloc(GetProcessHeap(), 0, size); 2118 ret = pCreateWellKnownSid(WinInteractiveSid, NULL, sid, &size); 2119 ok(ret, "CreateWellKnownSid failed %u\n", GetLastError()); 2120 HeapFree(GetProcessHeap(), 0, sid); 2121 2122 /* a domain sid usually have three subauthorities but we test that CreateWellKnownSid doesn't check it */ 2123 AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid); 2124 2125 for (i = 0; i < sizeof(well_known_sid_values)/sizeof(well_known_sid_values[0]); i++) 2126 { 2127 const struct well_known_sid_value *value = &well_known_sid_values[i]; 2128 char sid_buffer[SECURITY_MAX_SID_SIZE]; 2129 LPSTR str; 2130 DWORD cb; 2131 2132 if (value->sid_string == NULL) 2133 continue; 2134 2135 /* some SIDs aren't implemented by all Windows versions - detect it */ 2136 cb = sizeof(sid_buffer); 2137 if (!pCreateWellKnownSid(i, NULL, sid_buffer, &cb)) 2138 { 2139 skip("Well known SID %u not implemented\n", i); 2140 continue; 2141 } 2142 2143 cb = sizeof(sid_buffer); 2144 ok(pCreateWellKnownSid(i, value->without_domain ? NULL : domainsid, sid_buffer, &cb), "Couldn't create well known sid %u\n", i); 2145 expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%d"); 2146 ok(IsValidSid(sid_buffer), "The sid is not valid\n"); 2147 ok(ConvertSidToStringSidA(sid_buffer, &str), "Couldn't convert SID to string\n"); 2148 ok(strcmp(str, value->sid_string) == 0, "%d: SID mismatch - expected %s, got %s\n", i, 2149 value->sid_string, str); 2150 LocalFree(str); 2151 2152 if (value->without_domain) 2153 { 2154 char buf2[SECURITY_MAX_SID_SIZE]; 2155 cb = sizeof(buf2); 2156 ok(pCreateWellKnownSid(i, domainsid, buf2, &cb), "Couldn't create well known sid %u with optional domain\n", i); 2157 expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%d"); 2158 ok(memcmp(buf2, sid_buffer, cb) == 0, "SID create with domain is different than without (%u)\n", i); 2159 } 2160 } 2161 2162 FreeSid(domainsid); 2163 } 2164 2165 static void test_LookupAccountSid(void) 2166 { 2167 SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY }; 2168 CHAR accountA[MAX_PATH], domainA[MAX_PATH], usernameA[MAX_PATH]; 2169 DWORD acc_sizeA, dom_sizeA, user_sizeA; 2170 DWORD real_acc_sizeA, real_dom_sizeA; 2171 WCHAR accountW[MAX_PATH], domainW[MAX_PATH]; 2172 DWORD acc_sizeW, dom_sizeW; 2173 DWORD real_acc_sizeW, real_dom_sizeW; 2174 PSID pUsersSid = NULL; 2175 SID_NAME_USE use; 2176 BOOL ret; 2177 DWORD error, size, cbti = 0; 2178 MAX_SID max_sid; 2179 CHAR *str_sidA; 2180 int i; 2181 HANDLE hToken; 2182 PTOKEN_USER ptiUser = NULL; 2183 2184 /* native windows crashes if account size, domain size, or name use is NULL */ 2185 2186 ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, 2187 DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pUsersSid); 2188 ok(ret || (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED), 2189 "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 2190 2191 /* not running on NT so give up */ 2192 if (!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 2193 return; 2194 2195 real_acc_sizeA = MAX_PATH; 2196 real_dom_sizeA = MAX_PATH; 2197 ret = LookupAccountSidA(NULL, pUsersSid, accountA, &real_acc_sizeA, domainA, &real_dom_sizeA, &use); 2198 ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n"); 2199 2200 /* try NULL account */ 2201 acc_sizeA = MAX_PATH; 2202 dom_sizeA = MAX_PATH; 2203 ret = LookupAccountSidA(NULL, pUsersSid, NULL, &acc_sizeA, domainA, &dom_sizeA, &use); 2204 ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n"); 2205 2206 /* try NULL domain */ 2207 acc_sizeA = MAX_PATH; 2208 dom_sizeA = MAX_PATH; 2209 ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, NULL, &dom_sizeA, &use); 2210 ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n"); 2211 2212 /* try a small account buffer */ 2213 acc_sizeA = 1; 2214 dom_sizeA = MAX_PATH; 2215 accountA[0] = 0; 2216 ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use); 2217 ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n"); 2218 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2219 "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); 2220 2221 /* try a 0 sized account buffer */ 2222 acc_sizeA = 0; 2223 dom_sizeA = MAX_PATH; 2224 accountA[0] = 0; 2225 LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use); 2226 /* this can fail or succeed depending on OS version but the size will always be returned */ 2227 ok(acc_sizeA == real_acc_sizeA + 1, 2228 "LookupAccountSidA() Expected acc_size = %u, got %u\n", 2229 real_acc_sizeA + 1, acc_sizeA); 2230 2231 /* try a 0 sized account buffer */ 2232 acc_sizeA = 0; 2233 dom_sizeA = MAX_PATH; 2234 LookupAccountSidA(NULL, pUsersSid, NULL, &acc_sizeA, domainA, &dom_sizeA, &use); 2235 /* this can fail or succeed depending on OS version but the size will always be returned */ 2236 ok(acc_sizeA == real_acc_sizeA + 1, 2237 "LookupAccountSid() Expected acc_size = %u, got %u\n", 2238 real_acc_sizeA + 1, acc_sizeA); 2239 2240 /* try a small domain buffer */ 2241 dom_sizeA = 1; 2242 acc_sizeA = MAX_PATH; 2243 accountA[0] = 0; 2244 ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use); 2245 ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n"); 2246 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2247 "LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); 2248 2249 /* try a 0 sized domain buffer */ 2250 dom_sizeA = 0; 2251 acc_sizeA = MAX_PATH; 2252 accountA[0] = 0; 2253 LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use); 2254 /* this can fail or succeed depending on OS version but the size will always be returned */ 2255 ok(dom_sizeA == real_dom_sizeA + 1, 2256 "LookupAccountSidA() Expected dom_size = %u, got %u\n", 2257 real_dom_sizeA + 1, dom_sizeA); 2258 2259 /* try a 0 sized domain buffer */ 2260 dom_sizeA = 0; 2261 acc_sizeA = MAX_PATH; 2262 LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, NULL, &dom_sizeA, &use); 2263 /* this can fail or succeed depending on OS version but the size will always be returned */ 2264 ok(dom_sizeA == real_dom_sizeA + 1, 2265 "LookupAccountSidA() Expected dom_size = %u, got %u\n", 2266 real_dom_sizeA + 1, dom_sizeA); 2267 2268 real_acc_sizeW = MAX_PATH; 2269 real_dom_sizeW = MAX_PATH; 2270 ret = LookupAccountSidW(NULL, pUsersSid, accountW, &real_acc_sizeW, domainW, &real_dom_sizeW, &use); 2271 ok(ret, "LookupAccountSidW() Expected TRUE, got FALSE\n"); 2272 2273 /* try an invalid system name */ 2274 real_acc_sizeA = MAX_PATH; 2275 real_dom_sizeA = MAX_PATH; 2276 ret = LookupAccountSidA("deepthought", pUsersSid, accountA, &real_acc_sizeA, domainA, &real_dom_sizeA, &use); 2277 ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n"); 2278 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* Vista */, 2279 "LookupAccountSidA() Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %u\n", GetLastError()); 2280 2281 /* native windows crashes if domainW or accountW is NULL */ 2282 2283 /* try a small account buffer */ 2284 acc_sizeW = 1; 2285 dom_sizeW = MAX_PATH; 2286 accountW[0] = 0; 2287 ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use); 2288 ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n"); 2289 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2290 "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); 2291 2292 /* try a 0 sized account buffer */ 2293 acc_sizeW = 0; 2294 dom_sizeW = MAX_PATH; 2295 accountW[0] = 0; 2296 LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use); 2297 /* this can fail or succeed depending on OS version but the size will always be returned */ 2298 ok(acc_sizeW == real_acc_sizeW + 1, 2299 "LookupAccountSidW() Expected acc_size = %u, got %u\n", 2300 real_acc_sizeW + 1, acc_sizeW); 2301 2302 /* try a 0 sized account buffer */ 2303 acc_sizeW = 0; 2304 dom_sizeW = MAX_PATH; 2305 LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, domainW, &dom_sizeW, &use); 2306 /* this can fail or succeed depending on OS version but the size will always be returned */ 2307 ok(acc_sizeW == real_acc_sizeW + 1, 2308 "LookupAccountSidW() Expected acc_size = %u, got %u\n", 2309 real_acc_sizeW + 1, acc_sizeW); 2310 2311 /* try a small domain buffer */ 2312 dom_sizeW = 1; 2313 acc_sizeW = MAX_PATH; 2314 accountW[0] = 0; 2315 ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use); 2316 ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n"); 2317 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2318 "LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError()); 2319 2320 /* try a 0 sized domain buffer */ 2321 dom_sizeW = 0; 2322 acc_sizeW = MAX_PATH; 2323 accountW[0] = 0; 2324 LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use); 2325 /* this can fail or succeed depending on OS version but the size will always be returned */ 2326 ok(dom_sizeW == real_dom_sizeW + 1, 2327 "LookupAccountSidW() Expected dom_size = %u, got %u\n", 2328 real_dom_sizeW + 1, dom_sizeW); 2329 2330 /* try a 0 sized domain buffer */ 2331 dom_sizeW = 0; 2332 acc_sizeW = MAX_PATH; 2333 LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, NULL, &dom_sizeW, &use); 2334 /* this can fail or succeed depending on OS version but the size will always be returned */ 2335 ok(dom_sizeW == real_dom_sizeW + 1, 2336 "LookupAccountSidW() Expected dom_size = %u, got %u\n", 2337 real_dom_sizeW + 1, dom_sizeW); 2338 2339 acc_sizeW = dom_sizeW = use = 0; 2340 SetLastError(0xdeadbeef); 2341 ret = LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, NULL, &dom_sizeW, &use); 2342 error = GetLastError(); 2343 ok(!ret, "LookupAccountSidW failed %u\n", GetLastError()); 2344 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error); 2345 ok(acc_sizeW, "expected non-zero account size\n"); 2346 ok(dom_sizeW, "expected non-zero domain size\n"); 2347 ok(!use, "expected zero use %u\n", use); 2348 2349 FreeSid(pUsersSid); 2350 2351 /* Test LookupAccountSid with Sid retrieved from token information. 2352 This assumes this process is running under the account of the current user.*/ 2353 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &hToken); 2354 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); 2355 ret = GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti); 2356 ok(!ret, "GetTokenInformation failed with error %d\n", GetLastError()); 2357 ptiUser = HeapAlloc(GetProcessHeap(), 0, cbti); 2358 if (GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti)) 2359 { 2360 acc_sizeA = dom_sizeA = MAX_PATH; 2361 ret = LookupAccountSidA(NULL, ptiUser->User.Sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use); 2362 ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n"); 2363 user_sizeA = MAX_PATH; 2364 ret = GetUserNameA(usernameA , &user_sizeA); 2365 ok(ret, "GetUserNameA() Expected TRUE, got FALSE\n"); 2366 ok(lstrcmpA(usernameA, accountA) == 0, "LookupAccountSidA() Expected account name: %s got: %s\n", usernameA, accountA ); 2367 } 2368 HeapFree(GetProcessHeap(), 0, ptiUser); 2369 2370 if (pCreateWellKnownSid) 2371 { 2372 trace("Well Known SIDs:\n"); 2373 for (i = 0; i <= 84; i++) 2374 { 2375 size = SECURITY_MAX_SID_SIZE; 2376 if (pCreateWellKnownSid(i, NULL, &max_sid.sid, &size)) 2377 { 2378 if (ConvertSidToStringSidA(&max_sid.sid, &str_sidA)) 2379 { 2380 acc_sizeA = MAX_PATH; 2381 dom_sizeA = MAX_PATH; 2382 if (LookupAccountSidA(NULL, &max_sid.sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use)) 2383 trace(" %d: %s %s\\%s %d\n", i, str_sidA, domainA, accountA, use); 2384 LocalFree(str_sidA); 2385 } 2386 } 2387 else 2388 { 2389 if (GetLastError() != ERROR_INVALID_PARAMETER) 2390 trace(" CreateWellKnownSid(%d) failed: %d\n", i, GetLastError()); 2391 else 2392 trace(" %d: not supported\n", i); 2393 } 2394 } 2395 2396 pLsaQueryInformationPolicy = (void *)GetProcAddress( hmod, "LsaQueryInformationPolicy"); 2397 pLsaOpenPolicy = (void *)GetProcAddress( hmod, "LsaOpenPolicy"); 2398 pLsaFreeMemory = (void *)GetProcAddress( hmod, "LsaFreeMemory"); 2399 pLsaClose = (void *)GetProcAddress( hmod, "LsaClose"); 2400 2401 if (pLsaQueryInformationPolicy && pLsaOpenPolicy && pLsaFreeMemory && pLsaClose) 2402 { 2403 NTSTATUS status; 2404 LSA_HANDLE handle; 2405 LSA_OBJECT_ATTRIBUTES object_attributes; 2406 2407 ZeroMemory(&object_attributes, sizeof(object_attributes)); 2408 object_attributes.Length = sizeof(object_attributes); 2409 2410 status = pLsaOpenPolicy( NULL, &object_attributes, POLICY_ALL_ACCESS, &handle); 2411 ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, 2412 "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x\n", status); 2413 2414 /* try a more restricted access mask if necessary */ 2415 if (status == STATUS_ACCESS_DENIED) { 2416 trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n"); 2417 status = pLsaOpenPolicy( NULL, &object_attributes, POLICY_VIEW_LOCAL_INFORMATION, &handle); 2418 ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x\n", status); 2419 } 2420 2421 if (status == STATUS_SUCCESS) 2422 { 2423 PPOLICY_ACCOUNT_DOMAIN_INFO info; 2424 status = pLsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (PVOID*)&info); 2425 ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy() failed, returned 0x%08x\n", status); 2426 if (status == STATUS_SUCCESS) 2427 { 2428 ok(info->DomainSid!=0, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) missing SID\n"); 2429 if (info->DomainSid) 2430 { 2431 int count = *GetSidSubAuthorityCount(info->DomainSid); 2432 CopySid(GetSidLengthRequired(count), &max_sid, info->DomainSid); 2433 test_sid_str((PSID)&max_sid.sid); 2434 max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_ADMIN; 2435 max_sid.sid.SubAuthorityCount = count + 1; 2436 test_sid_str((PSID)&max_sid.sid); 2437 max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_GUEST; 2438 test_sid_str((PSID)&max_sid.sid); 2439 max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ADMINS; 2440 test_sid_str((PSID)&max_sid.sid); 2441 max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_USERS; 2442 test_sid_str((PSID)&max_sid.sid); 2443 max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_GUESTS; 2444 test_sid_str((PSID)&max_sid.sid); 2445 max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_COMPUTERS; 2446 test_sid_str((PSID)&max_sid.sid); 2447 max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CONTROLLERS; 2448 test_sid_str((PSID)&max_sid.sid); 2449 max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CERT_ADMINS; 2450 test_sid_str((PSID)&max_sid.sid); 2451 max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_SCHEMA_ADMINS; 2452 test_sid_str((PSID)&max_sid.sid); 2453 max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ENTERPRISE_ADMINS; 2454 test_sid_str((PSID)&max_sid.sid); 2455 max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_POLICY_ADMINS; 2456 test_sid_str((PSID)&max_sid.sid); 2457 max_sid.sid.SubAuthority[count] = DOMAIN_ALIAS_RID_RAS_SERVERS; 2458 test_sid_str((PSID)&max_sid.sid); 2459 max_sid.sid.SubAuthority[count] = 1000; /* first user account */ 2460 test_sid_str((PSID)&max_sid.sid); 2461 } 2462 2463 pLsaFreeMemory((LPVOID)info); 2464 } 2465 2466 status = pLsaClose(handle); 2467 ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status); 2468 } 2469 } 2470 } 2471 } 2472 2473 static BOOL get_sid_info(PSID psid, LPSTR *user, LPSTR *dom) 2474 { 2475 static CHAR account[UNLEN + 1]; 2476 static CHAR domain[UNLEN + 1]; 2477 DWORD size, dom_size; 2478 SID_NAME_USE use; 2479 2480 *user = account; 2481 *dom = domain; 2482 2483 size = dom_size = UNLEN + 1; 2484 account[0] = '\0'; 2485 domain[0] = '\0'; 2486 SetLastError(0xdeadbeef); 2487 return LookupAccountSidA(NULL, psid, account, &size, domain, &dom_size, &use); 2488 } 2489 2490 static void check_wellknown_name(const char* name, WELL_KNOWN_SID_TYPE result) 2491 { 2492 SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY }; 2493 PSID domainsid = NULL; 2494 char wk_sid[SECURITY_MAX_SID_SIZE]; 2495 DWORD cb; 2496 2497 DWORD sid_size, domain_size; 2498 SID_NAME_USE sid_use; 2499 LPSTR domain, account, sid_domain, wk_domain, wk_account; 2500 PSID psid; 2501 BOOL ret ,ret2; 2502 2503 sid_size = 0; 2504 domain_size = 0; 2505 ret = LookupAccountNameA(NULL, name, NULL, &sid_size, NULL, &domain_size, &sid_use); 2506 ok(!ret, " %s Should have failed to lookup account name\n", name); 2507 psid = HeapAlloc(GetProcessHeap(),0,sid_size); 2508 domain = HeapAlloc(GetProcessHeap(),0,domain_size); 2509 ret = LookupAccountNameA(NULL, name, psid, &sid_size, domain, &domain_size, &sid_use); 2510 2511 if (!result) 2512 { 2513 ok(!ret, " %s Should have failed to lookup account name\n",name); 2514 goto cleanup; 2515 } 2516 2517 AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid); 2518 cb = sizeof(wk_sid); 2519 if (!pCreateWellKnownSid(result, domainsid, wk_sid, &cb)) 2520 { 2521 win_skip("SID %i is not available on the system\n",result); 2522 goto cleanup; 2523 } 2524 2525 ret2 = get_sid_info(wk_sid, &wk_account, &wk_domain); 2526 if (!ret2 && GetLastError() == ERROR_NONE_MAPPED) 2527 { 2528 win_skip("CreateWellKnownSid() succeeded but the account '%s' is not present (W2K)\n", name); 2529 goto cleanup; 2530 } 2531 2532 get_sid_info(psid, &account, &sid_domain); 2533 2534 ok(ret, "Failed to lookup account name %s\n",name); 2535 ok(sid_size != 0, "sid_size was zero\n"); 2536 2537 ok(EqualSid(psid,wk_sid),"%s Sid %s fails to match well known sid %s!\n", 2538 name, debugstr_sid(psid), debugstr_sid(wk_sid)); 2539 2540 ok(!lstrcmpA(account, wk_account), "Expected %s , got %s\n", account, wk_account); 2541 ok(!lstrcmpA(domain, wk_domain), "Expected %s, got %s\n", wk_domain, domain); 2542 ok(sid_use == SidTypeWellKnownGroup , "Expected Use (5), got %d\n", sid_use); 2543 2544 cleanup: 2545 FreeSid(domainsid); 2546 HeapFree(GetProcessHeap(),0,psid); 2547 HeapFree(GetProcessHeap(),0,domain); 2548 } 2549 2550 static void test_LookupAccountName(void) 2551 { 2552 DWORD sid_size, domain_size, user_size; 2553 DWORD sid_save, domain_save; 2554 CHAR user_name[UNLEN + 1]; 2555 CHAR computer_name[UNLEN + 1]; 2556 SID_NAME_USE sid_use; 2557 LPSTR domain, account, sid_dom; 2558 PSID psid; 2559 BOOL ret; 2560 2561 /* native crashes if (assuming all other parameters correct): 2562 * - peUse is NULL 2563 * - Sid is NULL and cbSid is > 0 2564 * - cbSid or cchReferencedDomainName are NULL 2565 * - ReferencedDomainName is NULL and cchReferencedDomainName is the correct size 2566 */ 2567 2568 user_size = UNLEN + 1; 2569 SetLastError(0xdeadbeef); 2570 ret = GetUserNameA(user_name, &user_size); 2571 ok(ret, "Failed to get user name : %d\n", GetLastError()); 2572 2573 /* get sizes */ 2574 sid_size = 0; 2575 domain_size = 0; 2576 sid_use = 0xcafebabe; 2577 SetLastError(0xdeadbeef); 2578 ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, NULL, &domain_size, &sid_use); 2579 if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 2580 { 2581 win_skip("LookupAccountNameA is not implemented\n"); 2582 return; 2583 } 2584 ok(!ret, "Expected 0, got %d\n", ret); 2585 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2586 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2587 ok(sid_size != 0, "Expected non-zero sid size\n"); 2588 ok(domain_size != 0, "Expected non-zero domain size\n"); 2589 ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use); 2590 2591 sid_save = sid_size; 2592 domain_save = domain_size; 2593 2594 psid = HeapAlloc(GetProcessHeap(), 0, sid_size); 2595 domain = HeapAlloc(GetProcessHeap(), 0, domain_size); 2596 2597 /* try valid account name */ 2598 ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, domain, &domain_size, &sid_use); 2599 get_sid_info(psid, &account, &sid_dom); 2600 ok(ret, "Failed to lookup account name\n"); 2601 ok(sid_size == GetLengthSid(psid), "Expected %d, got %d\n", GetLengthSid(psid), sid_size); 2602 ok(!lstrcmpA(account, user_name), "Expected %s, got %s\n", user_name, account); 2603 ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain); 2604 ok(domain_size == domain_save - 1, "Expected %d, got %d\n", domain_save - 1, domain_size); 2605 ok(strlen(domain) == domain_size, "Expected %d, got %d\n", lstrlenA(domain), domain_size); 2606 ok(sid_use == SidTypeUser, "Expected SidTypeUser (%d), got %d\n", SidTypeUser, sid_use); 2607 domain_size = domain_save; 2608 sid_size = sid_save; 2609 2610 if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH) 2611 { 2612 skip("Non-English locale (test with hardcoded 'Everyone')\n"); 2613 } 2614 else 2615 { 2616 ret = LookupAccountNameA(NULL, "Everyone", psid, &sid_size, domain, &domain_size, &sid_use); 2617 get_sid_info(psid, &account, &sid_dom); 2618 ok(ret, "Failed to lookup account name\n"); 2619 ok(sid_size != 0, "sid_size was zero\n"); 2620 ok(!lstrcmpA(account, "Everyone"), "Expected Everyone, got %s\n", account); 2621 ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain); 2622 ok(domain_size == 0, "Expected 0, got %d\n", domain_size); 2623 ok(strlen(domain) == domain_size, "Expected %d, got %d\n", lstrlenA(domain), domain_size); 2624 ok(sid_use == SidTypeWellKnownGroup, "Expected SidTypeWellKnownGroup (%d), got %d\n", SidTypeWellKnownGroup, sid_use); 2625 domain_size = domain_save; 2626 } 2627 2628 /* NULL Sid with zero sid size */ 2629 SetLastError(0xdeadbeef); 2630 sid_size = 0; 2631 ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use); 2632 ok(!ret, "Expected 0, got %d\n", ret); 2633 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2634 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2635 ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size); 2636 ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size); 2637 2638 /* try cchReferencedDomainName - 1 */ 2639 SetLastError(0xdeadbeef); 2640 domain_size--; 2641 ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use); 2642 ok(!ret, "Expected 0, got %d\n", ret); 2643 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2644 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2645 ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size); 2646 ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size); 2647 2648 /* NULL ReferencedDomainName with zero domain name size */ 2649 SetLastError(0xdeadbeef); 2650 domain_size = 0; 2651 ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, NULL, &domain_size, &sid_use); 2652 ok(!ret, "Expected 0, got %d\n", ret); 2653 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2654 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2655 ok(sid_size == sid_save, "Expected %d, got %d\n", sid_save, sid_size); 2656 ok(domain_size == domain_save, "Expected %d, got %d\n", domain_save, domain_size); 2657 2658 HeapFree(GetProcessHeap(), 0, psid); 2659 HeapFree(GetProcessHeap(), 0, domain); 2660 2661 /* get sizes for NULL account name */ 2662 sid_size = 0; 2663 domain_size = 0; 2664 sid_use = 0xcafebabe; 2665 SetLastError(0xdeadbeef); 2666 ret = LookupAccountNameA(NULL, NULL, NULL, &sid_size, NULL, &domain_size, &sid_use); 2667 if (!ret && GetLastError() == ERROR_NONE_MAPPED) 2668 win_skip("NULL account name doesn't work on NT4\n"); 2669 else 2670 { 2671 ok(!ret, "Expected 0, got %d\n", ret); 2672 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2673 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2674 ok(sid_size != 0, "Expected non-zero sid size\n"); 2675 ok(domain_size != 0, "Expected non-zero domain size\n"); 2676 ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use); 2677 2678 psid = HeapAlloc(GetProcessHeap(), 0, sid_size); 2679 domain = HeapAlloc(GetProcessHeap(), 0, domain_size); 2680 2681 /* try NULL account name */ 2682 ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain, &domain_size, &sid_use); 2683 get_sid_info(psid, &account, &sid_dom); 2684 ok(ret, "Failed to lookup account name\n"); 2685 /* Using a fixed string will not work on different locales */ 2686 ok(!lstrcmpiA(account, domain), 2687 "Got %s for account and %s for domain, these should be the same\n", account, domain); 2688 ok(sid_use == SidTypeDomain, "Expected SidTypeDomain (%d), got %d\n", SidTypeDomain, sid_use); 2689 2690 HeapFree(GetProcessHeap(), 0, psid); 2691 HeapFree(GetProcessHeap(), 0, domain); 2692 } 2693 2694 /* try an invalid account name */ 2695 SetLastError(0xdeadbeef); 2696 sid_size = 0; 2697 domain_size = 0; 2698 ret = LookupAccountNameA(NULL, "oogabooga", NULL, &sid_size, NULL, &domain_size, &sid_use); 2699 ok(!ret, "Expected 0, got %d\n", ret); 2700 ok(GetLastError() == ERROR_NONE_MAPPED || 2701 broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE), 2702 "Expected ERROR_NONE_MAPPED, got %d\n", GetLastError()); 2703 ok(sid_size == 0, "Expected 0, got %d\n", sid_size); 2704 ok(domain_size == 0, "Expected 0, got %d\n", domain_size); 2705 2706 /* try an invalid system name */ 2707 SetLastError(0xdeadbeef); 2708 sid_size = 0; 2709 domain_size = 0; 2710 ret = LookupAccountNameA("deepthought", NULL, NULL, &sid_size, NULL, &domain_size, &sid_use); 2711 ok(!ret, "Expected 0, got %d\n", ret); 2712 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* Vista */, 2713 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError()); 2714 ok(sid_size == 0, "Expected 0, got %d\n", sid_size); 2715 ok(domain_size == 0, "Expected 0, got %d\n", domain_size); 2716 2717 /* try with the computer name as the account name */ 2718 domain_size = sizeof(computer_name); 2719 GetComputerNameA(computer_name, &domain_size); 2720 sid_size = 0; 2721 domain_size = 0; 2722 ret = LookupAccountNameA(NULL, computer_name, NULL, &sid_size, NULL, &domain_size, &sid_use); 2723 ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER || 2724 GetLastError() == ERROR_NONE_MAPPED /* in a domain */ || 2725 broken(GetLastError() == ERROR_TRUSTED_DOMAIN_FAILURE) || 2726 broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE)), 2727 "LookupAccountNameA failed: %d\n", GetLastError()); 2728 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 2729 { 2730 psid = HeapAlloc(GetProcessHeap(), 0, sid_size); 2731 domain = HeapAlloc(GetProcessHeap(), 0, domain_size); 2732 ret = LookupAccountNameA(NULL, computer_name, psid, &sid_size, domain, &domain_size, &sid_use); 2733 ok(ret, "LookupAccountNameA failed: %d\n", GetLastError()); 2734 ok(sid_use == SidTypeDomain || 2735 (sid_use == SidTypeUser && ! strcmp(computer_name, user_name)), "expected SidTypeDomain for %s, got %d\n", computer_name, sid_use); 2736 HeapFree(GetProcessHeap(), 0, domain); 2737 HeapFree(GetProcessHeap(), 0, psid); 2738 } 2739 2740 /* Well Known names */ 2741 if (!pCreateWellKnownSid) 2742 { 2743 win_skip("CreateWellKnownSid not available\n"); 2744 return; 2745 } 2746 2747 if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH) 2748 { 2749 skip("Non-English locale (skipping well known name creation tests)\n"); 2750 return; 2751 } 2752 2753 check_wellknown_name("LocalService", WinLocalServiceSid); 2754 check_wellknown_name("Local Service", WinLocalServiceSid); 2755 /* 2 spaces */ 2756 check_wellknown_name("Local Service", 0); 2757 check_wellknown_name("NetworkService", WinNetworkServiceSid); 2758 check_wellknown_name("Network Service", WinNetworkServiceSid); 2759 2760 /* example of some names where the spaces are not optional */ 2761 check_wellknown_name("Terminal Server User", WinTerminalServerSid); 2762 check_wellknown_name("TerminalServer User", 0); 2763 check_wellknown_name("TerminalServerUser", 0); 2764 check_wellknown_name("Terminal ServerUser", 0); 2765 2766 check_wellknown_name("enterprise domain controllers",WinEnterpriseControllersSid); 2767 check_wellknown_name("enterprisedomain controllers", 0); 2768 check_wellknown_name("enterprise domaincontrollers", 0); 2769 check_wellknown_name("enterprisedomaincontrollers", 0); 2770 2771 /* case insensitivity */ 2772 check_wellknown_name("lOCAlServICE", WinLocalServiceSid); 2773 2774 /* fully qualified account names */ 2775 check_wellknown_name("NT AUTHORITY\\LocalService", WinLocalServiceSid); 2776 check_wellknown_name("nt authority\\Network Service", WinNetworkServiceSid); 2777 check_wellknown_name("nt authority test\\Network Service", 0); 2778 check_wellknown_name("Dummy\\Network Service", 0); 2779 check_wellknown_name("ntauthority\\Network Service", 0); 2780 } 2781 2782 static void test_security_descriptor(void) 2783 { 2784 SECURITY_DESCRIPTOR sd, *sd_rel, *sd_rel2, *sd_abs; 2785 char buf[8192]; 2786 DWORD size, size_dacl, size_sacl, size_owner, size_group; 2787 BOOL isDefault, isPresent, ret; 2788 PACL pacl, dacl, sacl; 2789 PSID psid, owner, group; 2790 2791 SetLastError(0xdeadbeef); 2792 ret = InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); 2793 if (ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 2794 { 2795 win_skip("InitializeSecurityDescriptor is not implemented\n"); 2796 return; 2797 } 2798 2799 ok(GetSecurityDescriptorOwner(&sd, &psid, &isDefault), "GetSecurityDescriptorOwner failed\n"); 2800 expect_eq(psid, NULL, PSID, "%p"); 2801 expect_eq(isDefault, FALSE, BOOL, "%d"); 2802 sd.Control |= SE_DACL_PRESENT | SE_SACL_PRESENT; 2803 2804 SetLastError(0xdeadbeef); 2805 size = 5; 2806 expect_eq(MakeSelfRelativeSD(&sd, buf, &size), FALSE, BOOL, "%d"); 2807 expect_eq(GetLastError(), ERROR_INSUFFICIENT_BUFFER, DWORD, "%u"); 2808 ok(size > 5, "Size not increased\n"); 2809 if (size <= 8192) 2810 { 2811 expect_eq(MakeSelfRelativeSD(&sd, buf, &size), TRUE, BOOL, "%d"); 2812 ok(GetSecurityDescriptorOwner(&sd, &psid, &isDefault), "GetSecurityDescriptorOwner failed\n"); 2813 expect_eq(psid, NULL, PSID, "%p"); 2814 expect_eq(isDefault, FALSE, BOOL, "%d"); 2815 ok(GetSecurityDescriptorGroup(&sd, &psid, &isDefault), "GetSecurityDescriptorGroup failed\n"); 2816 expect_eq(psid, NULL, PSID, "%p"); 2817 expect_eq(isDefault, FALSE, BOOL, "%d"); 2818 ok(GetSecurityDescriptorDacl(&sd, &isPresent, &pacl, &isDefault), "GetSecurityDescriptorDacl failed\n"); 2819 expect_eq(isPresent, TRUE, BOOL, "%d"); 2820 expect_eq(psid, NULL, PSID, "%p"); 2821 expect_eq(isDefault, FALSE, BOOL, "%d"); 2822 ok(GetSecurityDescriptorSacl(&sd, &isPresent, &pacl, &isDefault), "GetSecurityDescriptorSacl failed\n"); 2823 expect_eq(isPresent, TRUE, BOOL, "%d"); 2824 expect_eq(psid, NULL, PSID, "%p"); 2825 expect_eq(isDefault, FALSE, BOOL, "%d"); 2826 } 2827 2828 ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( 2829 "O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)" 2830 "(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)" 2831 "(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, (void **)&sd_rel, NULL); 2832 ok(ret, "got %u\n", GetLastError()); 2833 2834 size = 0; 2835 ret = MakeSelfRelativeSD(sd_rel, NULL, &size); 2836 todo_wine ok(!ret && GetLastError() == ERROR_BAD_DESCRIPTOR_FORMAT, "got %u\n", GetLastError()); 2837 2838 /* convert to absolute form */ 2839 size = size_dacl = size_sacl = size_owner = size_group = 0; 2840 ret = MakeAbsoluteSD(sd_rel, NULL, &size, NULL, &size_dacl, NULL, &size_sacl, NULL, &size_owner, NULL, 2841 &size_group); 2842 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); 2843 2844 sd_abs = HeapAlloc(GetProcessHeap(), 0, size + size_dacl + size_sacl + size_owner + size_group); 2845 dacl = (PACL)(sd_abs + 1); 2846 sacl = (PACL)((char *)dacl + size_dacl); 2847 owner = (PSID)((char *)sacl + size_sacl); 2848 group = (PSID)((char *)owner + size_owner); 2849 ret = MakeAbsoluteSD(sd_rel, sd_abs, &size, dacl, &size_dacl, sacl, &size_sacl, owner, &size_owner, 2850 group, &size_group); 2851 ok(ret, "got %u\n", GetLastError()); 2852 2853 size = 0; 2854 ret = MakeSelfRelativeSD(sd_abs, NULL, &size); 2855 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError()); 2856 ok(size == 184, "got %u\n", size); 2857 2858 size += 4; 2859 sd_rel2 = HeapAlloc(GetProcessHeap(), 0, size); 2860 ret = MakeSelfRelativeSD(sd_abs, sd_rel2, &size); 2861 ok(ret, "got %u\n", GetLastError()); 2862 ok(size == 188, "got %u\n", size); 2863 2864 HeapFree(GetProcessHeap(), 0, sd_abs); 2865 HeapFree(GetProcessHeap(), 0, sd_rel2); 2866 LocalFree(sd_rel); 2867 } 2868 2869 #define TEST_GRANTED_ACCESS(a,b) test_granted_access(a,b,0,__LINE__) 2870 #define TEST_GRANTED_ACCESS2(a,b,c) test_granted_access(a,b,c,__LINE__) 2871 static void test_granted_access(HANDLE handle, ACCESS_MASK access, 2872 ACCESS_MASK alt, int line) 2873 { 2874 OBJECT_BASIC_INFORMATION obj_info; 2875 NTSTATUS status; 2876 2877 if (!pNtQueryObject) 2878 { 2879 skip_(__FILE__, line)("Not NT platform - skipping tests\n"); 2880 return; 2881 } 2882 2883 status = pNtQueryObject( handle, ObjectBasicInformation, &obj_info, 2884 sizeof(obj_info), NULL ); 2885 ok_(__FILE__, line)(!status, "NtQueryObject with err: %08x\n", status); 2886 if (alt) 2887 ok_(__FILE__, line)(obj_info.GrantedAccess == access || 2888 obj_info.GrantedAccess == alt, "Granted access should be 0x%08x " 2889 "or 0x%08x, instead of 0x%08x\n", access, alt, obj_info.GrantedAccess); 2890 else 2891 ok_(__FILE__, line)(obj_info.GrantedAccess == access, "Granted access should " 2892 "be 0x%08x, instead of 0x%08x\n", access, obj_info.GrantedAccess); 2893 } 2894 2895 #define CHECK_SET_SECURITY(o,i,e) \ 2896 do{ \ 2897 BOOL res_; \ 2898 DWORD err; \ 2899 SetLastError( 0xdeadbeef ); \ 2900 res_ = SetKernelObjectSecurity( o, i, SecurityDescriptor ); \ 2901 err = GetLastError(); \ 2902 if (e == ERROR_SUCCESS) \ 2903 ok(res_, "SetKernelObjectSecurity failed with %d\n", err); \ 2904 else \ 2905 ok(!res_ && err == e, "SetKernelObjectSecurity should have failed " \ 2906 "with %s, instead of %d\n", #e, err); \ 2907 }while(0) 2908 2909 static void test_process_security(void) 2910 { 2911 BOOL res; 2912 PTOKEN_USER user; 2913 PTOKEN_OWNER owner; 2914 PTOKEN_PRIMARY_GROUP group; 2915 PSID AdminSid = NULL, UsersSid = NULL, UserSid = NULL; 2916 PACL Acl = NULL, ThreadAcl = NULL; 2917 SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL; 2918 char buffer[MAX_PATH], account[MAX_PATH], domain[MAX_PATH]; 2919 PROCESS_INFORMATION info; 2920 STARTUPINFOA startup; 2921 SECURITY_ATTRIBUTES psa, tsa; 2922 HANDLE token, event; 2923 DWORD size, acc_size, dom_size, ret; 2924 SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; 2925 PSID EveryoneSid = NULL; 2926 SID_NAME_USE use; 2927 2928 Acl = HeapAlloc(GetProcessHeap(), 0, 256); 2929 res = InitializeAcl(Acl, 256, ACL_REVISION); 2930 if (!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 2931 { 2932 win_skip("ACLs not implemented - skipping tests\n"); 2933 HeapFree(GetProcessHeap(), 0, Acl); 2934 return; 2935 } 2936 ok(res, "InitializeAcl failed with error %d\n", GetLastError()); 2937 2938 res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); 2939 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 2940 2941 /* get owner from the token we might be running as a user not admin */ 2942 res = OpenProcessToken( GetCurrentProcess(), MAXIMUM_ALLOWED, &token ); 2943 ok(res, "OpenProcessToken failed with error %d\n", GetLastError()); 2944 if (!res) 2945 { 2946 HeapFree(GetProcessHeap(), 0, Acl); 2947 return; 2948 } 2949 2950 res = GetTokenInformation( token, TokenOwner, NULL, 0, &size ); 2951 ok(!res, "Expected failure, got %d\n", res); 2952 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2953 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2954 2955 owner = HeapAlloc(GetProcessHeap(), 0, size); 2956 res = GetTokenInformation( token, TokenOwner, owner, size, &size ); 2957 ok(res, "GetTokenInformation failed with error %d\n", GetLastError()); 2958 AdminSid = owner->Owner; 2959 test_sid_str(AdminSid); 2960 2961 res = GetTokenInformation( token, TokenPrimaryGroup, NULL, 0, &size ); 2962 ok(!res, "Expected failure, got %d\n", res); 2963 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2964 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2965 2966 group = HeapAlloc(GetProcessHeap(), 0, size); 2967 res = GetTokenInformation( token, TokenPrimaryGroup, group, size, &size ); 2968 ok(res, "GetTokenInformation failed with error %d\n", GetLastError()); 2969 UsersSid = group->PrimaryGroup; 2970 test_sid_str(UsersSid); 2971 2972 acc_size = sizeof(account); 2973 dom_size = sizeof(domain); 2974 ret = LookupAccountSidA( NULL, UsersSid, account, &acc_size, domain, &dom_size, &use ); 2975 ok(ret, "LookupAccountSid failed with %d\n", ret); 2976 ok(use == SidTypeGroup, "expect SidTypeGroup, got %d\n", use); 2977 ok(!strcmp(account, "None"), "expect None, got %s\n", account); 2978 2979 res = GetTokenInformation( token, TokenUser, NULL, 0, &size ); 2980 ok(!res, "Expected failure, got %d\n", res); 2981 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 2982 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2983 2984 user = HeapAlloc(GetProcessHeap(), 0, size); 2985 res = GetTokenInformation( token, TokenUser, user, size, &size ); 2986 ok(res, "GetTokenInformation failed with error %d\n", GetLastError()); 2987 UserSid = user->User.Sid; 2988 test_sid_str(UserSid); 2989 ok(EqualPrefixSid(UsersSid, UserSid), "TokenPrimaryGroup Sid and TokenUser Sid don't match.\n"); 2990 2991 CloseHandle( token ); 2992 if (!res) 2993 { 2994 HeapFree(GetProcessHeap(), 0, group); 2995 HeapFree(GetProcessHeap(), 0, owner); 2996 HeapFree(GetProcessHeap(), 0, user); 2997 HeapFree(GetProcessHeap(), 0, Acl); 2998 return; 2999 } 3000 3001 res = AddAccessDeniedAce(Acl, ACL_REVISION, PROCESS_VM_READ, AdminSid); 3002 ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError()); 3003 res = AddAccessAllowedAce(Acl, ACL_REVISION, PROCESS_ALL_ACCESS, AdminSid); 3004 ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); 3005 3006 SecurityDescriptor = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); 3007 res = InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); 3008 ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError()); 3009 3010 event = CreateEventA( NULL, TRUE, TRUE, "test_event" ); 3011 ok(event != NULL, "CreateEvent %d\n", GetLastError()); 3012 3013 SecurityDescriptor->Revision = 0; 3014 CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_UNKNOWN_REVISION ); 3015 SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION; 3016 3017 CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_INVALID_SECURITY_DESCR ); 3018 CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_INVALID_SECURITY_DESCR ); 3019 CHECK_SET_SECURITY( event, SACL_SECURITY_INFORMATION, ERROR_ACCESS_DENIED ); 3020 CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); 3021 /* NULL DACL is valid and means that everyone has access */ 3022 SecurityDescriptor->Control |= SE_DACL_PRESENT; 3023 CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); 3024 3025 /* Set owner and group and dacl */ 3026 res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE); 3027 ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); 3028 CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_SUCCESS ); 3029 test_owner_equal( event, AdminSid, __LINE__ ); 3030 3031 res = SetSecurityDescriptorGroup(SecurityDescriptor, EveryoneSid, FALSE); 3032 ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); 3033 CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS ); 3034 test_group_equal( event, EveryoneSid, __LINE__ ); 3035 3036 res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); 3037 ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); 3038 CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); 3039 /* setting a dacl should not change the owner or group */ 3040 test_owner_equal( event, AdminSid, __LINE__ ); 3041 test_group_equal( event, EveryoneSid, __LINE__ ); 3042 3043 /* Test again with a different SID in case the previous SID also happens to 3044 * be the one that is incorrectly replacing the group. */ 3045 res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, FALSE); 3046 ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); 3047 CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS ); 3048 test_group_equal( event, UsersSid, __LINE__ ); 3049 3050 res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); 3051 ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); 3052 CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); 3053 test_group_equal( event, UsersSid, __LINE__ ); 3054 3055 sprintf(buffer, "%s tests/security.c test", myARGV[0]); 3056 memset(&startup, 0, sizeof(startup)); 3057 startup.cb = sizeof(startup); 3058 startup.dwFlags = STARTF_USESHOWWINDOW; 3059 startup.wShowWindow = SW_SHOWNORMAL; 3060 3061 psa.nLength = sizeof(psa); 3062 psa.lpSecurityDescriptor = SecurityDescriptor; 3063 psa.bInheritHandle = TRUE; 3064 3065 ThreadSecurityDescriptor = HeapAlloc( GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH ); 3066 res = InitializeSecurityDescriptor( ThreadSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); 3067 ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError()); 3068 3069 ThreadAcl = HeapAlloc( GetProcessHeap(), 0, 256 ); 3070 res = InitializeAcl( ThreadAcl, 256, ACL_REVISION ); 3071 ok(res, "InitializeAcl failed with error %d\n", GetLastError()); 3072 res = AddAccessDeniedAce( ThreadAcl, ACL_REVISION, THREAD_SET_THREAD_TOKEN, AdminSid ); 3073 ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError() ); 3074 res = AddAccessAllowedAce( ThreadAcl, ACL_REVISION, THREAD_ALL_ACCESS, AdminSid ); 3075 ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); 3076 3077 res = SetSecurityDescriptorOwner( ThreadSecurityDescriptor, AdminSid, FALSE ); 3078 ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); 3079 res = SetSecurityDescriptorGroup( ThreadSecurityDescriptor, UsersSid, FALSE ); 3080 ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); 3081 res = SetSecurityDescriptorDacl( ThreadSecurityDescriptor, TRUE, ThreadAcl, FALSE ); 3082 ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); 3083 3084 tsa.nLength = sizeof(tsa); 3085 tsa.lpSecurityDescriptor = ThreadSecurityDescriptor; 3086 tsa.bInheritHandle = TRUE; 3087 3088 /* Doesn't matter what ACL say we should get full access for ourselves */ 3089 res = CreateProcessA( NULL, buffer, &psa, &tsa, FALSE, 0, NULL, NULL, &startup, &info ); 3090 ok(res, "CreateProcess with err:%d\n", GetLastError()); 3091 TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4, 3092 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); 3093 TEST_GRANTED_ACCESS2( info.hThread, THREAD_ALL_ACCESS_NT4, 3094 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); 3095 winetest_wait_child_process( info.hProcess ); 3096 3097 FreeSid(EveryoneSid); 3098 CloseHandle( info.hProcess ); 3099 CloseHandle( info.hThread ); 3100 CloseHandle( event ); 3101 HeapFree(GetProcessHeap(), 0, group); 3102 HeapFree(GetProcessHeap(), 0, owner); 3103 HeapFree(GetProcessHeap(), 0, user); 3104 HeapFree(GetProcessHeap(), 0, Acl); 3105 HeapFree(GetProcessHeap(), 0, SecurityDescriptor); 3106 HeapFree(GetProcessHeap(), 0, ThreadAcl); 3107 HeapFree(GetProcessHeap(), 0, ThreadSecurityDescriptor); 3108 } 3109 3110 static void test_process_security_child(void) 3111 { 3112 HANDLE handle, handle1; 3113 BOOL ret; 3114 DWORD err; 3115 3116 handle = OpenProcess( PROCESS_TERMINATE, FALSE, GetCurrentProcessId() ); 3117 ok(handle != NULL, "OpenProcess(PROCESS_TERMINATE) with err:%d\n", GetLastError()); 3118 TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE ); 3119 3120 ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), 3121 &handle1, 0, TRUE, DUPLICATE_SAME_ACCESS ); 3122 ok(ret, "duplicating handle err:%d\n", GetLastError()); 3123 TEST_GRANTED_ACCESS( handle1, PROCESS_TERMINATE ); 3124 3125 CloseHandle( handle1 ); 3126 3127 SetLastError( 0xdeadbeef ); 3128 ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), 3129 &handle1, PROCESS_ALL_ACCESS, TRUE, 0 ); 3130 err = GetLastError(); 3131 ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed " 3132 "with STATUS_ACCESS_DENIED, instead of err:%d\n", err); 3133 3134 CloseHandle( handle ); 3135 3136 /* These two should fail - they are denied by ACL */ 3137 handle = OpenProcess( PROCESS_VM_READ, FALSE, GetCurrentProcessId() ); 3138 ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n"); 3139 handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() ); 3140 ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n"); 3141 3142 /* Documented privilege elevation */ 3143 ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), 3144 &handle, 0, TRUE, DUPLICATE_SAME_ACCESS ); 3145 ok(ret, "duplicating handle err:%d\n", GetLastError()); 3146 TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4, 3147 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); 3148 3149 CloseHandle( handle ); 3150 3151 /* Same only explicitly asking for all access rights */ 3152 ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), 3153 &handle, PROCESS_ALL_ACCESS, TRUE, 0 ); 3154 ok(ret, "duplicating handle err:%d\n", GetLastError()); 3155 TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4, 3156 PROCESS_ALL_ACCESS | PROCESS_QUERY_LIMITED_INFORMATION ); 3157 ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), 3158 &handle1, PROCESS_VM_READ, TRUE, 0 ); 3159 ok(ret, "duplicating handle err:%d\n", GetLastError()); 3160 TEST_GRANTED_ACCESS( handle1, PROCESS_VM_READ ); 3161 CloseHandle( handle1 ); 3162 CloseHandle( handle ); 3163 3164 /* Test thread security */ 3165 handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() ); 3166 ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%d\n", GetLastError()); 3167 TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE ); 3168 CloseHandle( handle ); 3169 3170 handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() ); 3171 ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n"); 3172 } 3173 3174 static void test_impersonation_level(void) 3175 { 3176 HANDLE Token, ProcessToken; 3177 HANDLE Token2; 3178 DWORD Size; 3179 TOKEN_PRIVILEGES *Privileges; 3180 TOKEN_USER *User; 3181 PRIVILEGE_SET *PrivilegeSet; 3182 BOOL AccessGranted; 3183 BOOL ret; 3184 HKEY hkey; 3185 DWORD error; 3186 3187 if( !pDuplicateTokenEx ) { 3188 win_skip("DuplicateTokenEx is not available\n"); 3189 return; 3190 } 3191 SetLastError(0xdeadbeef); 3192 ret = ImpersonateSelf(SecurityAnonymous); 3193 if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 3194 { 3195 win_skip("ImpersonateSelf is not implemented\n"); 3196 return; 3197 } 3198 ok(ret, "ImpersonateSelf(SecurityAnonymous) failed with error %d\n", GetLastError()); 3199 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token); 3200 ok(!ret, "OpenThreadToken should have failed\n"); 3201 error = GetLastError(); 3202 ok(error == ERROR_CANT_OPEN_ANONYMOUS, "OpenThreadToken on anonymous token should have returned ERROR_CANT_OPEN_ANONYMOUS instead of %d\n", error); 3203 /* can't perform access check when opening object against an anonymous impersonation token */ 3204 todo_wine { 3205 error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey); 3206 ok(error == ERROR_INVALID_HANDLE || error == ERROR_CANT_OPEN_ANONYMOUS || error == ERROR_BAD_IMPERSONATION_LEVEL, 3207 "RegOpenKeyEx failed with %d\n", error); 3208 } 3209 RevertToSelf(); 3210 3211 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken); 3212 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); 3213 3214 ret = pDuplicateTokenEx(ProcessToken, 3215 TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, NULL, 3216 SecurityAnonymous, TokenImpersonation, &Token); 3217 ok(ret, "DuplicateTokenEx failed with error %d\n", GetLastError()); 3218 /* can't increase the impersonation level */ 3219 ret = DuplicateToken(Token, SecurityIdentification, &Token2); 3220 error = GetLastError(); 3221 ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, 3222 "Duplicating a token and increasing the impersonation level should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error); 3223 /* we can query anything from an anonymous token, including the user */ 3224 ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size); 3225 error = GetLastError(); 3226 ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error); 3227 User = HeapAlloc(GetProcessHeap(), 0, Size); 3228 ret = GetTokenInformation(Token, TokenUser, User, Size, &Size); 3229 ok(ret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 3230 HeapFree(GetProcessHeap(), 0, User); 3231 3232 /* PrivilegeCheck fails with SecurityAnonymous level */ 3233 ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size); 3234 error = GetLastError(); 3235 ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", error); 3236 Privileges = HeapAlloc(GetProcessHeap(), 0, Size); 3237 ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size); 3238 ok(ret, "GetTokenInformation(TokenPrivileges) failed with error %d\n", GetLastError()); 3239 3240 PrivilegeSet = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PRIVILEGE_SET, Privilege[Privileges->PrivilegeCount])); 3241 PrivilegeSet->PrivilegeCount = Privileges->PrivilegeCount; 3242 memcpy(PrivilegeSet->Privilege, Privileges->Privileges, PrivilegeSet->PrivilegeCount * sizeof(PrivilegeSet->Privilege[0])); 3243 PrivilegeSet->Control = PRIVILEGE_SET_ALL_NECESSARY; 3244 HeapFree(GetProcessHeap(), 0, Privileges); 3245 3246 ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted); 3247 error = GetLastError(); 3248 ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, "PrivilegeCheck for SecurityAnonymous token should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error); 3249 3250 CloseHandle(Token); 3251 3252 ret = ImpersonateSelf(SecurityIdentification); 3253 ok(ret, "ImpersonateSelf(SecurityIdentification) failed with error %d\n", GetLastError()); 3254 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token); 3255 ok(ret, "OpenThreadToken failed with error %d\n", GetLastError()); 3256 3257 /* can't perform access check when opening object against an identification impersonation token */ 3258 error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey); 3259 todo_wine { 3260 ok(error == ERROR_INVALID_HANDLE || error == ERROR_BAD_IMPERSONATION_LEVEL, 3261 "RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE or ERROR_BAD_IMPERSONATION_LEVEL instead of %d\n", error); 3262 } 3263 ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted); 3264 ok(ret, "PrivilegeCheck for SecurityIdentification failed with error %d\n", GetLastError()); 3265 CloseHandle(Token); 3266 RevertToSelf(); 3267 3268 ret = ImpersonateSelf(SecurityImpersonation); 3269 ok(ret, "ImpersonateSelf(SecurityImpersonation) failed with error %d\n", GetLastError()); 3270 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token); 3271 ok(ret, "OpenThreadToken failed with error %d\n", GetLastError()); 3272 error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey); 3273 ok(error == ERROR_SUCCESS, "RegOpenKeyEx should have succeeded instead of failing with %d\n", error); 3274 RegCloseKey(hkey); 3275 ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted); 3276 ok(ret, "PrivilegeCheck for SecurityImpersonation failed with error %d\n", GetLastError()); 3277 RevertToSelf(); 3278 3279 CloseHandle(Token); 3280 CloseHandle(ProcessToken); 3281 3282 HeapFree(GetProcessHeap(), 0, PrivilegeSet); 3283 } 3284 3285 static void test_SetEntriesInAclW(void) 3286 { 3287 DWORD res; 3288 PSID EveryoneSid = NULL, UsersSid = NULL; 3289 PACL OldAcl = NULL, NewAcl; 3290 SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; 3291 SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY }; 3292 EXPLICIT_ACCESSW ExplicitAccess; 3293 static const WCHAR wszEveryone[] = {'E','v','e','r','y','o','n','e',0}; 3294 static const WCHAR wszCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'}; 3295 3296 if (!pSetEntriesInAclW) 3297 { 3298 win_skip("SetEntriesInAclW is not available\n"); 3299 return; 3300 } 3301 3302 NewAcl = (PACL)0xdeadbeef; 3303 res = pSetEntriesInAclW(0, NULL, NULL, &NewAcl); 3304 if(res == ERROR_CALL_NOT_IMPLEMENTED) 3305 { 3306 win_skip("SetEntriesInAclW is not implemented\n"); 3307 return; 3308 } 3309 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 3310 ok(NewAcl == NULL || 3311 broken(NewAcl != NULL), /* NT4 */ 3312 "NewAcl=%p, expected NULL\n", NewAcl); 3313 LocalFree(NewAcl); 3314 3315 OldAcl = HeapAlloc(GetProcessHeap(), 0, 256); 3316 res = InitializeAcl(OldAcl, 256, ACL_REVISION); 3317 if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 3318 { 3319 win_skip("ACLs not implemented - skipping tests\n"); 3320 HeapFree(GetProcessHeap(), 0, OldAcl); 3321 return; 3322 } 3323 ok(res, "InitializeAcl failed with error %d\n", GetLastError()); 3324 3325 res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); 3326 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 3327 3328 res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, 3329 DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid); 3330 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 3331 3332 res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid); 3333 ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); 3334 3335 ExplicitAccess.grfAccessPermissions = KEY_WRITE; 3336 ExplicitAccess.grfAccessMode = GRANT_ACCESS; 3337 ExplicitAccess.grfInheritance = NO_INHERITANCE; 3338 ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; 3339 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; 3340 ExplicitAccess.Trustee.ptstrName = EveryoneSid; 3341 ExplicitAccess.Trustee.MultipleTrusteeOperation = 0xDEADBEEF; 3342 ExplicitAccess.Trustee.pMultipleTrustee = (PVOID)0xDEADBEEF; 3343 res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); 3344 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 3345 ok(NewAcl != NULL, "returned acl was NULL\n"); 3346 LocalFree(NewAcl); 3347 3348 ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; 3349 ExplicitAccess.Trustee.pMultipleTrustee = NULL; 3350 ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 3351 res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); 3352 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 3353 ok(NewAcl != NULL, "returned acl was NULL\n"); 3354 LocalFree(NewAcl); 3355 3356 if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH) 3357 { 3358 skip("Non-English locale (test with hardcoded 'Everyone')\n"); 3359 } 3360 else 3361 { 3362 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; 3363 ExplicitAccess.Trustee.ptstrName = (LPWSTR)wszEveryone; 3364 res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); 3365 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 3366 ok(NewAcl != NULL, "returned acl was NULL\n"); 3367 LocalFree(NewAcl); 3368 3369 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM; 3370 res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); 3371 ok(res == ERROR_INVALID_PARAMETER || 3372 broken(res == ERROR_NOT_SUPPORTED), /* NT4 */ 3373 "SetEntriesInAclW failed: %u\n", res); 3374 ok(NewAcl == NULL || 3375 broken(NewAcl != NULL), /* NT4 */ 3376 "returned acl wasn't NULL: %p\n", NewAcl); 3377 3378 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; 3379 ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE; 3380 res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); 3381 ok(res == ERROR_INVALID_PARAMETER || 3382 broken(res == ERROR_NOT_SUPPORTED), /* NT4 */ 3383 "SetEntriesInAclW failed: %u\n", res); 3384 ok(NewAcl == NULL || 3385 broken(NewAcl != NULL), /* NT4 */ 3386 "returned acl wasn't NULL: %p\n", NewAcl); 3387 3388 ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 3389 ExplicitAccess.grfAccessMode = SET_ACCESS; 3390 res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); 3391 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 3392 ok(NewAcl != NULL, "returned acl was NULL\n"); 3393 LocalFree(NewAcl); 3394 } 3395 3396 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; 3397 ExplicitAccess.Trustee.ptstrName = (LPWSTR)wszCurrentUser; 3398 res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); 3399 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 3400 ok(NewAcl != NULL, "returned acl was NULL\n"); 3401 LocalFree(NewAcl); 3402 3403 ExplicitAccess.grfAccessMode = REVOKE_ACCESS; 3404 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; 3405 ExplicitAccess.Trustee.ptstrName = UsersSid; 3406 res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl); 3407 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 3408 ok(NewAcl != NULL, "returned acl was NULL\n"); 3409 LocalFree(NewAcl); 3410 3411 FreeSid(UsersSid); 3412 FreeSid(EveryoneSid); 3413 HeapFree(GetProcessHeap(), 0, OldAcl); 3414 } 3415 3416 static void test_SetEntriesInAclA(void) 3417 { 3418 DWORD res; 3419 PSID EveryoneSid = NULL, UsersSid = NULL; 3420 PACL OldAcl = NULL, NewAcl; 3421 SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; 3422 SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY }; 3423 EXPLICIT_ACCESSA ExplicitAccess; 3424 static const CHAR szEveryone[] = {'E','v','e','r','y','o','n','e',0}; 3425 static const CHAR szCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'}; 3426 3427 if (!pSetEntriesInAclA) 3428 { 3429 win_skip("SetEntriesInAclA is not available\n"); 3430 return; 3431 } 3432 3433 NewAcl = (PACL)0xdeadbeef; 3434 res = pSetEntriesInAclA(0, NULL, NULL, &NewAcl); 3435 if(res == ERROR_CALL_NOT_IMPLEMENTED) 3436 { 3437 win_skip("SetEntriesInAclA is not implemented\n"); 3438 return; 3439 } 3440 ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); 3441 ok(NewAcl == NULL || 3442 broken(NewAcl != NULL), /* NT4 */ 3443 "NewAcl=%p, expected NULL\n", NewAcl); 3444 LocalFree(NewAcl); 3445 3446 OldAcl = HeapAlloc(GetProcessHeap(), 0, 256); 3447 res = InitializeAcl(OldAcl, 256, ACL_REVISION); 3448 if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 3449 { 3450 win_skip("ACLs not implemented - skipping tests\n"); 3451 HeapFree(GetProcessHeap(), 0, OldAcl); 3452 return; 3453 } 3454 ok(res, "InitializeAcl failed with error %d\n", GetLastError()); 3455 3456 res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); 3457 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 3458 3459 res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, 3460 DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid); 3461 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 3462 3463 res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid); 3464 ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); 3465 3466 ExplicitAccess.grfAccessPermissions = KEY_WRITE; 3467 ExplicitAccess.grfAccessMode = GRANT_ACCESS; 3468 ExplicitAccess.grfInheritance = NO_INHERITANCE; 3469 ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; 3470 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; 3471 ExplicitAccess.Trustee.ptstrName = EveryoneSid; 3472 ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 3473 ExplicitAccess.Trustee.pMultipleTrustee = NULL; 3474 res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); 3475 ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); 3476 ok(NewAcl != NULL, "returned acl was NULL\n"); 3477 LocalFree(NewAcl); 3478 3479 ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; 3480 ExplicitAccess.Trustee.pMultipleTrustee = NULL; 3481 ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 3482 res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); 3483 ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); 3484 ok(NewAcl != NULL, "returned acl was NULL\n"); 3485 LocalFree(NewAcl); 3486 3487 if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH) 3488 { 3489 skip("Non-English locale (test with hardcoded 'Everyone')\n"); 3490 } 3491 else 3492 { 3493 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; 3494 ExplicitAccess.Trustee.ptstrName = (LPSTR)szEveryone; 3495 res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); 3496 ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); 3497 ok(NewAcl != NULL, "returned acl was NULL\n"); 3498 LocalFree(NewAcl); 3499 3500 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM; 3501 res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); 3502 ok(res == ERROR_INVALID_PARAMETER || 3503 broken(res == ERROR_NOT_SUPPORTED), /* NT4 */ 3504 "SetEntriesInAclA failed: %u\n", res); 3505 ok(NewAcl == NULL || 3506 broken(NewAcl != NULL), /* NT4 */ 3507 "returned acl wasn't NULL: %p\n", NewAcl); 3508 3509 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; 3510 ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE; 3511 res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); 3512 ok(res == ERROR_INVALID_PARAMETER || 3513 broken(res == ERROR_NOT_SUPPORTED), /* NT4 */ 3514 "SetEntriesInAclA failed: %u\n", res); 3515 ok(NewAcl == NULL || 3516 broken(NewAcl != NULL), /* NT4 */ 3517 "returned acl wasn't NULL: %p\n", NewAcl); 3518 3519 ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 3520 ExplicitAccess.grfAccessMode = SET_ACCESS; 3521 res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); 3522 ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); 3523 ok(NewAcl != NULL, "returned acl was NULL\n"); 3524 LocalFree(NewAcl); 3525 } 3526 3527 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME; 3528 ExplicitAccess.Trustee.ptstrName = (LPSTR)szCurrentUser; 3529 res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); 3530 ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); 3531 ok(NewAcl != NULL, "returned acl was NULL\n"); 3532 LocalFree(NewAcl); 3533 3534 ExplicitAccess.grfAccessMode = REVOKE_ACCESS; 3535 ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID; 3536 ExplicitAccess.Trustee.ptstrName = UsersSid; 3537 res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl); 3538 ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res); 3539 ok(NewAcl != NULL, "returned acl was NULL\n"); 3540 LocalFree(NewAcl); 3541 3542 FreeSid(UsersSid); 3543 FreeSid(EveryoneSid); 3544 HeapFree(GetProcessHeap(), 0, OldAcl); 3545 } 3546 3547 /* helper function for test_CreateDirectoryA */ 3548 static void get_nt_pathW(const char *name, UNICODE_STRING *nameW) 3549 { 3550 UNICODE_STRING strW; 3551 ANSI_STRING str; 3552 NTSTATUS status; 3553 BOOLEAN ret; 3554 3555 pRtlInitAnsiString(&str, name); 3556 3557 status = pRtlAnsiStringToUnicodeString(&strW, &str, TRUE); 3558 ok(!status, "RtlAnsiStringToUnicodeString failed with %08x\n", status); 3559 3560 ret = pRtlDosPathNameToNtPathName_U(strW.Buffer, nameW, NULL, NULL); 3561 ok(ret, "RtlDosPathNameToNtPathName_U failed\n"); 3562 3563 pRtlFreeUnicodeString(&strW); 3564 } 3565 3566 static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD flags, DWORD mask, 3567 BOOL todo_count, BOOL todo_sid, BOOL todo_flags, int line) 3568 { 3569 ACL_SIZE_INFORMATION acl_size; 3570 ACCESS_ALLOWED_ACE *ace; 3571 BOOL bret; 3572 3573 bret = pGetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation); 3574 ok_(__FILE__, line)(bret, "GetAclInformation failed\n"); 3575 3576 todo_wine_if (todo_count) 3577 ok_(__FILE__, line)(acl_size.AceCount == 2, 3578 "GetAclInformation returned unexpected entry count (%d != 2)\n", 3579 acl_size.AceCount); 3580 3581 if (acl_size.AceCount > 0) 3582 { 3583 bret = pGetAce(dacl, 0, (VOID **)&ace); 3584 ok_(__FILE__, line)(bret, "Failed to get Current User ACE\n"); 3585 3586 bret = EqualSid(&ace->SidStart, user_sid); 3587 todo_wine_if (todo_sid) 3588 ok_(__FILE__, line)(bret, "Current User ACE (%s) != Current User SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); 3589 3590 todo_wine_if (todo_flags) 3591 ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags, 3592 "Current User ACE has unexpected flags (0x%x != 0x%x)\n", 3593 ((ACE_HEADER *)ace)->AceFlags, flags); 3594 3595 ok_(__FILE__, line)(ace->Mask == mask, 3596 "Current User ACE has unexpected mask (0x%x != 0x%x)\n", 3597 ace->Mask, mask); 3598 } 3599 if (acl_size.AceCount > 1) 3600 { 3601 bret = pGetAce(dacl, 1, (VOID **)&ace); 3602 ok_(__FILE__, line)(bret, "Failed to get Administators Group ACE\n"); 3603 3604 bret = EqualSid(&ace->SidStart, admin_sid); 3605 todo_wine_if (todo_sid) 3606 ok_(__FILE__, line)(bret, "Administators Group ACE (%s) != Administators Group SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); 3607 3608 todo_wine_if (todo_flags) 3609 ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags, 3610 "Administators Group ACE has unexpected flags (0x%x != 0x%x)\n", 3611 ((ACE_HEADER *)ace)->AceFlags, flags); 3612 3613 ok_(__FILE__, line)(ace->Mask == mask, 3614 "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n", 3615 ace->Mask, mask); 3616 } 3617 } 3618 3619 static void test_CreateDirectoryA(void) 3620 { 3621 char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user; 3622 DWORD sid_size = sizeof(admin_ptr), user_size; 3623 PSID admin_sid = (PSID) admin_ptr, user_sid; 3624 char sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; 3625 PSECURITY_DESCRIPTOR pSD = &sd; 3626 ACL_SIZE_INFORMATION acl_size; 3627 UNICODE_STRING tmpfileW; 3628 SECURITY_ATTRIBUTES sa; 3629 OBJECT_ATTRIBUTES attr; 3630 char tmpfile[MAX_PATH]; 3631 char tmpdir[MAX_PATH]; 3632 HANDLE token, hTemp; 3633 IO_STATUS_BLOCK io; 3634 struct _SID *owner; 3635 BOOL bret = TRUE; 3636 NTSTATUS status; 3637 DWORD error; 3638 PACL pDacl; 3639 3640 if (!pGetSecurityInfo || !pGetNamedSecurityInfoA || !pCreateWellKnownSid) 3641 { 3642 win_skip("Required functions are not available\n"); 3643 return; 3644 } 3645 3646 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token)) 3647 { 3648 if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE; 3649 else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE; 3650 } 3651 if (!bret) 3652 { 3653 win_skip("Failed to get current user token\n"); 3654 return; 3655 } 3656 bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size); 3657 ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 3658 "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 3659 user = HeapAlloc(GetProcessHeap(), 0, user_size); 3660 bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size); 3661 ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 3662 CloseHandle( token ); 3663 user_sid = ((TOKEN_USER *)user)->User.Sid; 3664 3665 sa.nLength = sizeof(sa); 3666 sa.lpSecurityDescriptor = pSD; 3667 sa.bInheritHandle = TRUE; 3668 InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); 3669 pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); 3670 pDacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100); 3671 bret = InitializeAcl(pDacl, 100, ACL_REVISION); 3672 ok(bret, "Failed to initialize ACL.\n"); 3673 bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 3674 GENERIC_ALL, user_sid); 3675 ok(bret, "Failed to add Current User to ACL.\n"); 3676 bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 3677 GENERIC_ALL, admin_sid); 3678 ok(bret, "Failed to add Administrator Group to ACL.\n"); 3679 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 3680 ok(bret, "Failed to add ACL to security descriptor.\n"); 3681 3682 GetTempPathA(MAX_PATH, tmpdir); 3683 lstrcatA(tmpdir, "Please Remove Me"); 3684 bret = CreateDirectoryA(tmpdir, &sa); 3685 ok(bret == TRUE, "CreateDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError()); 3686 HeapFree(GetProcessHeap(), 0, pDacl); 3687 3688 SetLastError(0xdeadbeef); 3689 error = pGetNamedSecurityInfoA(tmpdir, SE_FILE_OBJECT, 3690 OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner, 3691 NULL, &pDacl, NULL, &pSD); 3692 if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 3693 { 3694 win_skip("GetNamedSecurityInfoA is not implemented\n"); 3695 goto done; 3696 } 3697 ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); 3698 test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 3699 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); 3700 LocalFree(pSD); 3701 3702 /* Test inheritance of ACLs in CreateFile without security descriptor */ 3703 strcpy(tmpfile, tmpdir); 3704 lstrcatA(tmpfile, "/tmpfile"); 3705 3706 hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, 3707 CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL); 3708 ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError()); 3709 3710 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, 3711 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3712 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3713 ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n"); 3714 test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE, 3715 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); 3716 LocalFree(pSD); 3717 CloseHandle(hTemp); 3718 3719 /* Test inheritance of ACLs in CreateFile with security descriptor - 3720 * When a security descriptor is set, then inheritance doesn't take effect */ 3721 pSD = &sd; 3722 InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); 3723 pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); 3724 bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); 3725 ok(bret, "Failed to initialize ACL\n"); 3726 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 3727 ok(bret, "Failed to add ACL to security descriptor\n"); 3728 3729 strcpy(tmpfile, tmpdir); 3730 lstrcatA(tmpfile, "/tmpfile"); 3731 3732 sa.nLength = sizeof(sa); 3733 sa.lpSecurityDescriptor = pSD; 3734 sa.bInheritHandle = TRUE; 3735 hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, &sa, 3736 CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL); 3737 ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError()); 3738 HeapFree(GetProcessHeap(), 0, pDacl); 3739 3740 error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT, 3741 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3742 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3743 ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); 3744 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 3745 ok(bret, "GetAclInformation failed\n"); 3746 ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", 3747 acl_size.AceCount); 3748 LocalFree(pSD); 3749 3750 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, 3751 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3752 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3753 ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); 3754 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 3755 ok(bret, "GetAclInformation failed\n"); 3756 ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", 3757 acl_size.AceCount); 3758 LocalFree(pSD); 3759 CloseHandle(hTemp); 3760 3761 /* Test inheritance of ACLs in NtCreateFile without security descriptor */ 3762 strcpy(tmpfile, tmpdir); 3763 lstrcatA(tmpfile, "/tmpfile"); 3764 get_nt_pathW(tmpfile, &tmpfileW); 3765 3766 attr.Length = sizeof(attr); 3767 attr.RootDirectory = 0; 3768 attr.ObjectName = &tmpfileW; 3769 attr.Attributes = OBJ_CASE_INSENSITIVE; 3770 attr.SecurityDescriptor = NULL; 3771 attr.SecurityQualityOfService = NULL; 3772 3773 status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0, 3774 FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0); 3775 ok(!status, "NtCreateFile failed with %08x\n", status); 3776 pRtlFreeUnicodeString(&tmpfileW); 3777 3778 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, 3779 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3780 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3781 ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n"); 3782 test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE, 3783 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); 3784 LocalFree(pSD); 3785 CloseHandle(hTemp); 3786 3787 /* Test inheritance of ACLs in NtCreateFile with security descriptor - 3788 * When a security descriptor is set, then inheritance doesn't take effect */ 3789 pSD = &sd; 3790 InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); 3791 pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); 3792 bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); 3793 ok(bret, "Failed to initialize ACL\n"); 3794 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 3795 ok(bret, "Failed to add ACL to security descriptor\n"); 3796 3797 strcpy(tmpfile, tmpdir); 3798 lstrcatA(tmpfile, "/tmpfile"); 3799 get_nt_pathW(tmpfile, &tmpfileW); 3800 3801 attr.Length = sizeof(attr); 3802 attr.RootDirectory = 0; 3803 attr.ObjectName = &tmpfileW; 3804 attr.Attributes = OBJ_CASE_INSENSITIVE; 3805 attr.SecurityDescriptor = pSD; 3806 attr.SecurityQualityOfService = NULL; 3807 3808 status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0, 3809 FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0); 3810 ok(!status, "NtCreateFile failed with %08x\n", status); 3811 pRtlFreeUnicodeString(&tmpfileW); 3812 HeapFree(GetProcessHeap(), 0, pDacl); 3813 3814 error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT, 3815 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3816 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3817 ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); 3818 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 3819 ok(bret, "GetAclInformation failed\n"); 3820 ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", 3821 acl_size.AceCount); 3822 LocalFree(pSD); 3823 3824 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, 3825 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3826 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3827 ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); 3828 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 3829 ok(bret, "GetAclInformation failed\n"); 3830 todo_wine 3831 ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", 3832 acl_size.AceCount); 3833 LocalFree(pSD); 3834 CloseHandle(hTemp); 3835 3836 /* Test inheritance of ACLs in CreateDirectory without security descriptor */ 3837 strcpy(tmpfile, tmpdir); 3838 lstrcatA(tmpfile, "/tmpdir"); 3839 bret = CreateDirectoryA(tmpfile, NULL); 3840 ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError()); 3841 3842 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, 3843 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3844 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3845 ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n"); 3846 test_inherited_dacl(pDacl, admin_sid, user_sid, 3847 OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE, 3848 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); 3849 LocalFree(pSD); 3850 bret = RemoveDirectoryA(tmpfile); 3851 ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError()); 3852 3853 /* Test inheritance of ACLs in CreateDirectory with security descriptor */ 3854 pSD = &sd; 3855 InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); 3856 pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); 3857 bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); 3858 ok(bret, "Failed to initialize ACL\n"); 3859 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 3860 ok(bret, "Failed to add ACL to security desciptor\n"); 3861 3862 strcpy(tmpfile, tmpdir); 3863 lstrcatA(tmpfile, "/tmpdir1"); 3864 3865 sa.nLength = sizeof(sa); 3866 sa.lpSecurityDescriptor = pSD; 3867 sa.bInheritHandle = TRUE; 3868 bret = CreateDirectoryA(tmpfile, &sa); 3869 ok(bret == TRUE, "CreateDirectoryA failed with error %u\n", GetLastError()); 3870 HeapFree(GetProcessHeap(), 0, pDacl); 3871 3872 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, 3873 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3874 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3875 ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); 3876 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 3877 ok(bret, "GetAclInformation failed\n"); 3878 todo_wine 3879 ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", 3880 acl_size.AceCount); 3881 LocalFree(pSD); 3882 3883 SetLastError(0xdeadbeef); 3884 bret = RemoveDirectoryA(tmpfile); 3885 error = GetLastError(); 3886 ok(bret == FALSE, "RemoveDirectoryA unexpected succeeded\n"); 3887 ok(error == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %u\n", error); 3888 3889 pSD = &sd; 3890 InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); 3891 pDacl = HeapAlloc(GetProcessHeap(), 0, 100); 3892 bret = InitializeAcl(pDacl, 100, ACL_REVISION); 3893 ok(bret, "Failed to initialize ACL.\n"); 3894 bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); 3895 ok(bret, "Failed to add Current User to ACL.\n"); 3896 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 3897 ok(bret, "Failed to add ACL to security desciptor.\n"); 3898 error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, 3899 NULL, pDacl, NULL); 3900 ok(error == ERROR_SUCCESS, "SetNamedSecurityInfoA failed with error %u\n", error); 3901 HeapFree(GetProcessHeap(), 0, pDacl); 3902 3903 bret = RemoveDirectoryA(tmpfile); 3904 ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n", GetLastError()); 3905 3906 /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) without security descriptor */ 3907 strcpy(tmpfile, tmpdir); 3908 lstrcatA(tmpfile, "/tmpdir"); 3909 get_nt_pathW(tmpfile, &tmpfileW); 3910 3911 attr.Length = sizeof(attr); 3912 attr.RootDirectory = 0; 3913 attr.ObjectName = &tmpfileW; 3914 attr.Attributes = OBJ_CASE_INSENSITIVE; 3915 attr.SecurityDescriptor = NULL; 3916 attr.SecurityQualityOfService = NULL; 3917 3918 status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, 3919 FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0); 3920 ok(!status, "NtCreateFile failed with %08x\n", status); 3921 RtlFreeUnicodeString(&tmpfileW); 3922 3923 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, 3924 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3925 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3926 ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n"); 3927 test_inherited_dacl(pDacl, admin_sid, user_sid, 3928 OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE, 3929 0x1f01ff, FALSE, FALSE, FALSE, __LINE__); 3930 LocalFree(pSD); 3931 CloseHandle(hTemp); 3932 3933 /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) with security descriptor */ 3934 pSD = &sd; 3935 InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); 3936 pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); 3937 bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); 3938 ok(bret, "Failed to initialize ACL\n"); 3939 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 3940 ok(bret, "Failed to add ACL to security desciptor\n"); 3941 3942 strcpy(tmpfile, tmpdir); 3943 lstrcatA(tmpfile, "/tmpdir2"); 3944 get_nt_pathW(tmpfile, &tmpfileW); 3945 3946 attr.Length = sizeof(attr); 3947 attr.RootDirectory = 0; 3948 attr.ObjectName = &tmpfileW; 3949 attr.Attributes = OBJ_CASE_INSENSITIVE; 3950 attr.SecurityDescriptor = pSD; 3951 attr.SecurityQualityOfService = NULL; 3952 3953 status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, 3954 FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0); 3955 ok(!status, "NtCreateFile failed with %08x\n", status); 3956 RtlFreeUnicodeString(&tmpfileW); 3957 HeapFree(GetProcessHeap(), 0, pDacl); 3958 3959 error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT, 3960 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3961 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3962 ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); 3963 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 3964 ok(bret, "GetAclInformation failed\n"); 3965 todo_wine 3966 ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", 3967 acl_size.AceCount); 3968 LocalFree(pSD); 3969 3970 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, 3971 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 3972 (PSID *)&owner, NULL, &pDacl, NULL, &pSD); 3973 ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error); 3974 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 3975 ok(bret, "GetAclInformation failed\n"); 3976 todo_wine 3977 ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n", 3978 acl_size.AceCount); 3979 LocalFree(pSD); 3980 CloseHandle(hTemp); 3981 3982 done: 3983 HeapFree(GetProcessHeap(), 0, user); 3984 bret = RemoveDirectoryA(tmpdir); 3985 ok(bret == TRUE, "RemoveDirectoryA should always succeed\n"); 3986 } 3987 3988 static void test_GetNamedSecurityInfoA(void) 3989 { 3990 char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user; 3991 char system_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES]; 3992 char users_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES]; 3993 SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY }; 3994 PSID admin_sid = (PSID) admin_ptr, users_sid = (PSID) users_ptr; 3995 PSID system_sid = (PSID) system_ptr, user_sid, localsys_sid; 3996 DWORD sid_size = sizeof(admin_ptr), user_size; 3997 char invalid_path[] = "/an invalid file path"; 3998 int users_ace_id = -1, admins_ace_id = -1, i; 3999 char software_key[] = "MACHINE\\Software"; 4000 char sd[SECURITY_DESCRIPTOR_MIN_LENGTH+sizeof(void*)]; 4001 SECURITY_DESCRIPTOR_CONTROL control; 4002 ACL_SIZE_INFORMATION acl_size; 4003 CHAR windows_dir[MAX_PATH]; 4004 PSECURITY_DESCRIPTOR pSD; 4005 ACCESS_ALLOWED_ACE *ace; 4006 BOOL bret = TRUE, isNT4; 4007 char tmpfile[MAX_PATH]; 4008 DWORD error, revision; 4009 BOOL owner_defaulted; 4010 BOOL group_defaulted; 4011 BOOL dacl_defaulted; 4012 HANDLE token, hTemp, h; 4013 PSID owner, group; 4014 BOOL dacl_present; 4015 PACL pDacl; 4016 BYTE flags; 4017 NTSTATUS status; 4018 4019 if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid) 4020 { 4021 win_skip("Required functions are not available\n"); 4022 return; 4023 } 4024 4025 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token)) 4026 { 4027 if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE; 4028 else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE; 4029 } 4030 if (!bret) 4031 { 4032 win_skip("Failed to get current user token\n"); 4033 return; 4034 } 4035 bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size); 4036 ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 4037 "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 4038 user = HeapAlloc(GetProcessHeap(), 0, user_size); 4039 bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size); 4040 ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 4041 CloseHandle( token ); 4042 user_sid = ((TOKEN_USER *)user)->User.Sid; 4043 4044 bret = GetWindowsDirectoryA(windows_dir, MAX_PATH); 4045 ok(bret, "GetWindowsDirectory failed with error %d\n", GetLastError()); 4046 4047 SetLastError(0xdeadbeef); 4048 error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT, 4049 OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, 4050 NULL, NULL, NULL, NULL, &pSD); 4051 if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 4052 { 4053 win_skip("GetNamedSecurityInfoA is not implemented\n"); 4054 HeapFree(GetProcessHeap(), 0, user); 4055 return; 4056 } 4057 ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); 4058 4059 bret = GetSecurityDescriptorControl(pSD, &control, &revision); 4060 ok(bret, "GetSecurityDescriptorControl failed with error %d\n", GetLastError()); 4061 ok((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == (SE_SELF_RELATIVE|SE_DACL_PRESENT) || 4062 broken((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT), /* NT4 */ 4063 "control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set\n", control); 4064 ok(revision == SECURITY_DESCRIPTOR_REVISION1, "revision was %d instead of 1\n", revision); 4065 4066 isNT4 = (control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT; 4067 4068 bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted); 4069 ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); 4070 ok(owner != NULL, "owner should not be NULL\n"); 4071 4072 bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted); 4073 ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); 4074 ok(group != NULL, "group should not be NULL\n"); 4075 LocalFree(pSD); 4076 4077 4078 /* NULL descriptor tests */ 4079 if(isNT4) 4080 { 4081 win_skip("NT4 does not support GetNamedSecutityInfo with a NULL descriptor\n"); 4082 HeapFree(GetProcessHeap(), 0, user); 4083 return; 4084 } 4085 4086 error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, 4087 NULL, NULL, NULL, NULL, NULL); 4088 ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error); 4089 4090 pDacl = NULL; 4091 error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, 4092 NULL, NULL, &pDacl, NULL, &pSD); 4093 ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); 4094 ok(pDacl != NULL, "DACL should not be NULL\n"); 4095 LocalFree(pSD); 4096 4097 error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION, 4098 NULL, NULL, &pDacl, NULL, NULL); 4099 ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error); 4100 4101 /* Test behavior of SetNamedSecurityInfo with an invalid path */ 4102 SetLastError(0xdeadbeef); 4103 error = pSetNamedSecurityInfoA(invalid_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, 4104 NULL, NULL, NULL); 4105 ok(error == ERROR_FILE_NOT_FOUND, "Unexpected error returned: 0x%x\n", error); 4106 ok(GetLastError() == 0xdeadbeef, "Expected last error to remain unchanged.\n"); 4107 4108 /* Create security descriptor information and test that it comes back the same */ 4109 pSD = &sd; 4110 pDacl = HeapAlloc(GetProcessHeap(), 0, 100); 4111 InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); 4112 pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); 4113 bret = InitializeAcl(pDacl, 100, ACL_REVISION); 4114 ok(bret, "Failed to initialize ACL.\n"); 4115 bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); 4116 ok(bret, "Failed to add Current User to ACL.\n"); 4117 bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid); 4118 ok(bret, "Failed to add Administrator Group to ACL.\n"); 4119 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 4120 ok(bret, "Failed to add ACL to security descriptor.\n"); 4121 GetTempFileNameA(".", "foo", 0, tmpfile); 4122 hTemp = CreateFileA(tmpfile, WRITE_DAC|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ, 4123 NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL); 4124 SetLastError(0xdeadbeef); 4125 error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, 4126 NULL, pDacl, NULL); 4127 HeapFree(GetProcessHeap(), 0, pDacl); 4128 if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 4129 { 4130 win_skip("SetNamedSecurityInfoA is not implemented\n"); 4131 HeapFree(GetProcessHeap(), 0, user); 4132 CloseHandle(hTemp); 4133 return; 4134 } 4135 ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error); 4136 SetLastError(0xdeadbeef); 4137 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 4138 NULL, NULL, &pDacl, NULL, &pSD); 4139 if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 4140 { 4141 win_skip("GetNamedSecurityInfoA is not implemented\n"); 4142 HeapFree(GetProcessHeap(), 0, user); 4143 CloseHandle(hTemp); 4144 return; 4145 } 4146 ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); 4147 4148 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 4149 ok(bret, "GetAclInformation failed\n"); 4150 if (acl_size.AceCount > 0) 4151 { 4152 bret = pGetAce(pDacl, 0, (VOID **)&ace); 4153 ok(bret, "Failed to get Current User ACE.\n"); 4154 bret = EqualSid(&ace->SidStart, user_sid); 4155 ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", 4156 debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); 4157 ok(((ACE_HEADER *)ace)->AceFlags == 0, 4158 "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); 4159 ok(ace->Mask == 0x1f01ff, 4160 "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); 4161 } 4162 if (acl_size.AceCount > 1) 4163 { 4164 bret = pGetAce(pDacl, 1, (VOID **)&ace); 4165 ok(bret, "Failed to get Administators Group ACE.\n"); 4166 bret = EqualSid(&ace->SidStart, admin_sid); 4167 ok(bret || broken(!bret) /* win2k */, "Administators Group ACE (%s) != Administators Group SID (%s).\n", 4168 debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); 4169 ok(((ACE_HEADER *)ace)->AceFlags == 0, 4170 "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); 4171 ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */, 4172 "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); 4173 } 4174 LocalFree(pSD); 4175 4176 /* show that setting empty DACL is not removing all file permissions */ 4177 pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL)); 4178 bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); 4179 ok(bret, "Failed to initialize ACL.\n"); 4180 error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 4181 NULL, NULL, pDacl, NULL); 4182 ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error); 4183 HeapFree(GetProcessHeap(), 0, pDacl); 4184 4185 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 4186 NULL, NULL, &pDacl, NULL, &pSD); 4187 ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); 4188 4189 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 4190 ok(bret, "GetAclInformation failed\n"); 4191 if (acl_size.AceCount > 0) 4192 { 4193 bret = pGetAce(pDacl, 0, (VOID **)&ace); 4194 ok(bret, "Failed to get ACE.\n"); 4195 ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE, 4196 "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags); 4197 } 4198 LocalFree(pSD); 4199 4200 h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, 4201 NULL, OPEN_EXISTING, 0, NULL); 4202 ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 4203 CloseHandle(h); 4204 4205 /* test setting NULL DACL */ 4206 error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, 4207 DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL); 4208 ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error); 4209 4210 error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 4211 NULL, NULL, &pDacl, NULL, &pSD); 4212 ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); 4213 todo_wine ok(!pDacl, "pDacl != NULL\n"); 4214 LocalFree(pSD); 4215 4216 h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, 4217 NULL, OPEN_EXISTING, 0, NULL); 4218 ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 4219 CloseHandle(h); 4220 4221 /* NtSetSecurityObject doesn't inherit DACL entries */ 4222 pSD = sd+sizeof(void*)-((ULONG_PTR)sd)%sizeof(void*); 4223 InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); 4224 pDacl = HeapAlloc(GetProcessHeap(), 0, 100); 4225 bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION); 4226 ok(bret, "Failed to initialize ACL.\n"); 4227 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 4228 ok(bret, "Failed to add ACL to security descriptor.\n"); 4229 status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); 4230 ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); 4231 4232 h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, 4233 NULL, OPEN_EXISTING, 0, NULL); 4234 ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 4235 CloseHandle(h); 4236 4237 pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ); 4238 status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); 4239 ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); 4240 4241 h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, 4242 NULL, OPEN_EXISTING, 0, NULL); 4243 ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 4244 CloseHandle(h); 4245 4246 pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED, 4247 SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED); 4248 status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); 4249 ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); 4250 4251 h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, 4252 NULL, OPEN_EXISTING, 0, NULL); 4253 ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 4254 CloseHandle(h); 4255 4256 /* test if DACL is properly mapped to permission */ 4257 bret = InitializeAcl(pDacl, 100, ACL_REVISION); 4258 ok(bret, "Failed to initialize ACL.\n"); 4259 bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); 4260 ok(bret, "Failed to add Current User to ACL.\n"); 4261 bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); 4262 ok(bret, "Failed to add Current User to ACL.\n"); 4263 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 4264 ok(bret, "Failed to add ACL to security descriptor.\n"); 4265 status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); 4266 ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); 4267 4268 h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, 4269 NULL, OPEN_EXISTING, 0, NULL); 4270 ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 4271 CloseHandle(h); 4272 4273 bret = InitializeAcl(pDacl, 100, ACL_REVISION); 4274 ok(bret, "Failed to initialize ACL.\n"); 4275 bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); 4276 ok(bret, "Failed to add Current User to ACL.\n"); 4277 bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); 4278 ok(bret, "Failed to add Current User to ACL.\n"); 4279 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 4280 ok(bret, "Failed to add ACL to security descriptor.\n"); 4281 status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD); 4282 ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status); 4283 4284 h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, 4285 NULL, OPEN_EXISTING, 0, NULL); 4286 ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 4287 HeapFree(GetProcessHeap(), 0, pDacl); 4288 HeapFree(GetProcessHeap(), 0, user); 4289 CloseHandle(hTemp); 4290 4291 /* Test querying the ownership of a built-in registry key */ 4292 sid_size = sizeof(system_ptr); 4293 pCreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size); 4294 error = pGetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, 4295 OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION, 4296 NULL, NULL, NULL, NULL, &pSD); 4297 ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); 4298 4299 bret = AllocateAndInitializeSid(&SIDAuthNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &localsys_sid); 4300 ok(bret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 4301 4302 bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted); 4303 ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); 4304 ok(owner != NULL, "owner should not be NULL\n"); 4305 ok(EqualSid(owner, admin_sid) || EqualSid(owner, localsys_sid), 4306 "MACHINE\\Software owner SID (%s) != Administrators SID (%s) or Local System Sid (%s).\n", 4307 debugstr_sid(owner), debugstr_sid(admin_sid), debugstr_sid(localsys_sid)); 4308 4309 bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted); 4310 ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); 4311 ok(group != NULL, "group should not be NULL\n"); 4312 ok(EqualSid(group, admin_sid) || broken(EqualSid(group, system_sid)) /* before Win7 */ 4313 || broken(((SID*)group)->SubAuthority[0] == SECURITY_NT_NON_UNIQUE) /* Vista */, 4314 "MACHINE\\Software group SID (%s) != Local System SID (%s or %s)\n", 4315 debugstr_sid(group), debugstr_sid(admin_sid), debugstr_sid(system_sid)); 4316 LocalFree(pSD); 4317 4318 /* Test querying the DACL of a built-in registry key */ 4319 sid_size = sizeof(users_ptr); 4320 pCreateWellKnownSid(WinBuiltinUsersSid, NULL, users_sid, &sid_size); 4321 error = pGetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 4322 NULL, NULL, NULL, NULL, &pSD); 4323 ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); 4324 4325 bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted); 4326 ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError()); 4327 ok(dacl_present, "DACL should be present\n"); 4328 ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n"); 4329 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 4330 ok(bret, "GetAclInformation failed\n"); 4331 ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n"); 4332 for (i=0; i<acl_size.AceCount; i++) 4333 { 4334 bret = pGetAce(pDacl, i, (VOID **)&ace); 4335 ok(bret, "Failed to get ACE %d.\n", i); 4336 bret = EqualSid(&ace->SidStart, users_sid); 4337 if (bret) users_ace_id = i; 4338 bret = EqualSid(&ace->SidStart, admin_sid); 4339 if (bret) admins_ace_id = i; 4340 } 4341 ok(users_ace_id != -1 || broken(users_ace_id == -1) /* win2k */, 4342 "Builtin Users ACE not found.\n"); 4343 if (users_ace_id != -1) 4344 { 4345 bret = pGetAce(pDacl, users_ace_id, (VOID **)&ace); 4346 ok(bret, "Failed to get Builtin Users ACE.\n"); 4347 flags = ((ACE_HEADER *)ace)->AceFlags; 4348 ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE) 4349 || broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */ 4350 || broken(flags == (CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* win 10 wow64 */ 4351 || broken(flags == CONTAINER_INHERIT_ACE), /* win 10 */ 4352 "Builtin Users ACE has unexpected flags (0x%x != 0x%x)\n", flags, 4353 INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE); 4354 ok(ace->Mask == GENERIC_READ 4355 || broken(ace->Mask == KEY_READ), /* win 10 */ 4356 "Builtin Users ACE has unexpected mask (0x%x != 0x%x)\n", 4357 ace->Mask, GENERIC_READ); 4358 } 4359 ok(admins_ace_id != -1, "Builtin Admins ACE not found.\n"); 4360 if (admins_ace_id != -1) 4361 { 4362 bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace); 4363 ok(bret, "Failed to get Builtin Admins ACE.\n"); 4364 flags = ((ACE_HEADER *)ace)->AceFlags; 4365 ok(flags == 0x0 4366 || broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */ 4367 || broken(flags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) /* win7 */ 4368 || broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE)) /* win8+ */ 4369 || broken(flags == (CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* win 10 wow64 */ 4370 || broken(flags == CONTAINER_INHERIT_ACE), /* win 10 */ 4371 "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags); 4372 ok(ace->Mask == KEY_ALL_ACCESS || broken(ace->Mask == GENERIC_ALL) /* w2k8 */, 4373 "Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, KEY_ALL_ACCESS); 4374 } 4375 4376 FreeSid(localsys_sid); 4377 LocalFree(pSD); 4378 } 4379 4380 static void test_ConvertStringSecurityDescriptor(void) 4381 { 4382 BOOL ret; 4383 PSECURITY_DESCRIPTOR pSD; 4384 static const WCHAR Blank[] = { 0 }; 4385 unsigned int i; 4386 ULONG size; 4387 ACL *acl; 4388 static const struct 4389 { 4390 const char *sidstring; 4391 DWORD revision; 4392 BOOL ret; 4393 DWORD GLE; 4394 DWORD altGLE; 4395 } cssd[] = 4396 { 4397 { "D:(A;;GA;;;WD)", 0xdeadbeef, FALSE, ERROR_UNKNOWN_REVISION }, 4398 /* test ACE string type */ 4399 { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE }, 4400 { "D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE }, 4401 { "ERROR:(D;;GA;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_PARAMETER }, 4402 /* test ACE string with spaces */ 4403 { " D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE }, 4404 { "D: (D;;GA;;;WD)", SDDL_REVISION_1, TRUE }, 4405 { "D:( D;;GA;;;WD)", SDDL_REVISION_1, TRUE }, 4406 { "D:(D ;;GA;;;WD)", SDDL_REVISION_1, FALSE, RPC_S_INVALID_STRING_UUID, ERROR_INVALID_ACL }, /* Vista+ */ 4407 { "D:(D; ;GA;;;WD)", SDDL_REVISION_1, TRUE }, 4408 { "D:(D;; GA;;;WD)", SDDL_REVISION_1, TRUE }, 4409 { "D:(D;;GA ;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL }, 4410 { "D:(D;;GA; ;;WD)", SDDL_REVISION_1, TRUE }, 4411 { "D:(D;;GA;; ;WD)", SDDL_REVISION_1, TRUE }, 4412 { "D:(D;;GA;;; WD)", SDDL_REVISION_1, TRUE }, 4413 { "D:(D;;GA;;;WD )", SDDL_REVISION_1, TRUE }, 4414 /* test ACE string access rights */ 4415 { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE }, 4416 { "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, TRUE }, 4417 { "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, TRUE }, 4418 { "D:(A;;RPWPCCDCLCSWLODTCR;;;WD)", SDDL_REVISION_1, TRUE }, 4419 { "D:(A;;FAFRFWFX;;;WD)", SDDL_REVISION_1, TRUE }, 4420 { "D:(A;;KAKRKWKX;;;WD)", SDDL_REVISION_1, TRUE }, 4421 { "D:(A;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE }, 4422 { "S:(AU;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE }, 4423 /* test ACE string access right error case */ 4424 { "D:(A;;ROB;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL }, 4425 /* test behaviour with empty strings */ 4426 { "", SDDL_REVISION_1, TRUE }, 4427 /* test ACE string SID */ 4428 { "D:(D;;GA;;;S-1-0-0)", SDDL_REVISION_1, TRUE }, 4429 { "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL, ERROR_INVALID_SID } /* W2K */ 4430 }; 4431 4432 if (!pConvertStringSecurityDescriptorToSecurityDescriptorA) 4433 { 4434 win_skip("ConvertStringSecurityDescriptorToSecurityDescriptor is not available\n"); 4435 return; 4436 } 4437 4438 for (i = 0; i < sizeof(cssd)/sizeof(cssd[0]); i++) 4439 { 4440 DWORD GLE; 4441 4442 SetLastError(0xdeadbeef); 4443 ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( 4444 cssd[i].sidstring, cssd[i].revision, &pSD, NULL); 4445 GLE = GetLastError(); 4446 ok(ret == cssd[i].ret, "(%02u) Expected %s (%d)\n", i, cssd[i].ret ? "success" : "failure", GLE); 4447 if (!cssd[i].ret) 4448 ok(GLE == cssd[i].GLE || 4449 (cssd[i].altGLE && GLE == cssd[i].altGLE), 4450 "(%02u) Unexpected last error %d\n", i, GLE); 4451 if (ret) 4452 LocalFree(pSD); 4453 } 4454 4455 /* test behaviour with NULL parameters */ 4456 SetLastError(0xdeadbeef); 4457 ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( 4458 NULL, 0xdeadbeef, &pSD, NULL); 4459 todo_wine 4460 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 4461 "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n", 4462 GetLastError()); 4463 4464 SetLastError(0xdeadbeef); 4465 ret = pConvertStringSecurityDescriptorToSecurityDescriptorW( 4466 NULL, 0xdeadbeef, &pSD, NULL); 4467 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 4468 "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n", 4469 GetLastError()); 4470 4471 SetLastError(0xdeadbeef); 4472 ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( 4473 "D:(A;;ROB;;;WD)", 0xdeadbeef, NULL, NULL); 4474 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 4475 "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n", 4476 GetLastError()); 4477 4478 SetLastError(0xdeadbeef); 4479 ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( 4480 "D:(A;;ROB;;;WD)", SDDL_REVISION_1, NULL, NULL); 4481 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 4482 "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %d\n", 4483 GetLastError()); 4484 4485 /* test behaviour with empty strings */ 4486 SetLastError(0xdeadbeef); 4487 ret = pConvertStringSecurityDescriptorToSecurityDescriptorW( 4488 Blank, SDDL_REVISION_1, &pSD, NULL); 4489 ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %d\n", GetLastError()); 4490 LocalFree(pSD); 4491 4492 SetLastError(0xdeadbeef); 4493 ret = pConvertStringSecurityDescriptorToSecurityDescriptorA( 4494 "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); 4495 ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_DATATYPE) /* win2k */, 4496 "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %u\n", GetLastError()); 4497 if (ret) LocalFree(pSD); 4498 4499 /* empty DACL */ 4500 size = 0; 4501 SetLastError(0xdeadbeef); 4502 ret = pConvertStringSecurityDescriptorToSecurityDescriptorA("D:", SDDL_REVISION_1, &pSD, &size); 4503 ok(ret, "unexpected error %u\n", GetLastError()); 4504 ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %u\n", size); 4505 acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE)); 4506 ok(acl->AclRevision == ACL_REVISION, "got %u\n", acl->AclRevision); 4507 ok(!acl->Sbz1, "got %u\n", acl->Sbz1); 4508 ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize); 4509 ok(!acl->AceCount, "got %u\n", acl->AceCount); 4510 ok(!acl->Sbz2, "got %u\n", acl->Sbz2); 4511 LocalFree(pSD); 4512 4513 /* empty SACL */ 4514 size = 0; 4515 SetLastError(0xdeadbeef); 4516 ret = pConvertStringSecurityDescriptorToSecurityDescriptorA("S:", SDDL_REVISION_1, &pSD, &size); 4517 ok(ret, "unexpected error %u\n", GetLastError()); 4518 ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %u\n", size); 4519 acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE)); 4520 ok(!acl->Sbz1, "got %u\n", acl->Sbz1); 4521 ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize); 4522 ok(!acl->AceCount, "got %u\n", acl->AceCount); 4523 ok(!acl->Sbz2, "got %u\n", acl->Sbz2); 4524 LocalFree(pSD); 4525 } 4526 4527 static void test_ConvertSecurityDescriptorToString(void) 4528 { 4529 SECURITY_DESCRIPTOR desc; 4530 SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION; 4531 LPSTR string; 4532 DWORD size; 4533 PSID psid, psid2; 4534 PACL pacl; 4535 char sid_buf[256]; 4536 char acl_buf[8192]; 4537 ULONG len; 4538 4539 if (!pConvertSecurityDescriptorToStringSecurityDescriptorA) 4540 { 4541 win_skip("ConvertSecurityDescriptorToStringSecurityDescriptor is not available\n"); 4542 return; 4543 } 4544 if (!pCreateWellKnownSid) 4545 { 4546 win_skip("CreateWellKnownSid is not available\n"); 4547 return; 4548 } 4549 4550 /* It seems Windows XP adds an extra character to the length of the string for each ACE in an ACL. We 4551 * don't replicate this feature so we only test len >= strlen+1. */ 4552 #define CHECK_RESULT_AND_FREE(exp_str) \ 4553 ok(strcmp(string, (exp_str)) == 0, "String mismatch (expected \"%s\", got \"%s\")\n", (exp_str), string); \ 4554 ok(len >= (strlen(exp_str) + 1), "Length mismatch (expected %d, got %d)\n", lstrlenA(exp_str) + 1, len); \ 4555 LocalFree(string); 4556 4557 #define CHECK_ONE_OF_AND_FREE(exp_str1, exp_str2) \ 4558 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); \ 4559 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); \ 4560 LocalFree(string); 4561 4562 InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION); 4563 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4564 CHECK_RESULT_AND_FREE(""); 4565 4566 size = 4096; 4567 pCreateWellKnownSid(WinLocalSid, NULL, sid_buf, &size); 4568 SetSecurityDescriptorOwner(&desc, sid_buf, FALSE); 4569 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4570 CHECK_RESULT_AND_FREE("O:S-1-2-0"); 4571 4572 SetSecurityDescriptorOwner(&desc, sid_buf, TRUE); 4573 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4574 CHECK_RESULT_AND_FREE("O:S-1-2-0"); 4575 4576 size = sizeof(sid_buf); 4577 pCreateWellKnownSid(WinLocalSystemSid, NULL, sid_buf, &size); 4578 SetSecurityDescriptorOwner(&desc, sid_buf, TRUE); 4579 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4580 CHECK_RESULT_AND_FREE("O:SY"); 4581 4582 pConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid); 4583 SetSecurityDescriptorGroup(&desc, psid, TRUE); 4584 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4585 CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576"); 4586 4587 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, GROUP_SECURITY_INFORMATION, &string, &len), "Conversion failed\n"); 4588 CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576"); 4589 4590 pacl = (PACL)acl_buf; 4591 InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION); 4592 SetSecurityDescriptorDacl(&desc, TRUE, pacl, TRUE); 4593 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4594 CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:"); 4595 4596 SetSecurityDescriptorDacl(&desc, TRUE, pacl, FALSE); 4597 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4598 CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:"); 4599 4600 pConvertStringSidToSidA("S-1-5-6", &psid2); 4601 pAddAccessAllowedAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, 0xf0000000, psid2); 4602 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4603 CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)"); 4604 4605 pAddAccessAllowedAceEx(pacl, ACL_REVISION, INHERIT_ONLY_ACE|INHERITED_ACE, 0x00000003, psid2); 4606 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4607 CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"); 4608 4609 pAddAccessDeniedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 0xffffffff, psid); 4610 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4611 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)"); 4612 4613 4614 pacl = (PACL)acl_buf; 4615 InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION); 4616 SetSecurityDescriptorSacl(&desc, TRUE, pacl, FALSE); 4617 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4618 CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:"); 4619 4620 /* fails in win2k */ 4621 SetSecurityDescriptorDacl(&desc, TRUE, NULL, FALSE); 4622 pAddAuditAccessAceEx(pacl, ACL_REVISION, VALID_INHERIT_FLAGS, KEY_READ|KEY_WRITE, psid2, TRUE, TRUE); 4623 if (pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len)) 4624 { 4625 CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)", /* XP */ 4626 "O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)" /* Vista */); 4627 } 4628 4629 /* fails in win2k */ 4630 pAddAuditAccessAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, FILE_GENERIC_READ|FILE_GENERIC_WRITE, psid2, TRUE, FALSE); 4631 if (pConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len)) 4632 { 4633 CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", /* XP */ 4634 "O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)" /* Vista */); 4635 } 4636 4637 LocalFree(psid2); 4638 LocalFree(psid); 4639 } 4640 4641 static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec) 4642 { 4643 SECURITY_DESCRIPTOR_CONTROL ref; 4644 SECURITY_DESCRIPTOR_CONTROL test; 4645 4646 SECURITY_DESCRIPTOR_CONTROL const mutable 4647 = SE_DACL_AUTO_INHERIT_REQ | SE_SACL_AUTO_INHERIT_REQ 4648 | SE_DACL_AUTO_INHERITED | SE_SACL_AUTO_INHERITED 4649 | SE_DACL_PROTECTED | SE_SACL_PROTECTED 4650 | 0x00000040 | 0x00000080 /* not defined in winnt.h */ 4651 ; 4652 SECURITY_DESCRIPTOR_CONTROL const immutable 4653 = SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED 4654 | SE_DACL_PRESENT | SE_DACL_DEFAULTED 4655 | SE_SACL_PRESENT | SE_SACL_DEFAULTED 4656 | SE_RM_CONTROL_VALID | SE_SELF_RELATIVE 4657 ; 4658 4659 int bit; 4660 DWORD dwRevision; 4661 LPCSTR fmt = "Expected error %s, got %u\n"; 4662 4663 GetSecurityDescriptorControl (sec, &ref, &dwRevision); 4664 4665 /* The mutable bits are mutable regardless of the truth of 4666 SE_DACL_PRESENT and/or SE_SACL_PRESENT */ 4667 4668 /* Check call barfs if any bit-of-interest is immutable */ 4669 for (bit = 0; bit < 16; ++bit) 4670 { 4671 SECURITY_DESCRIPTOR_CONTROL const bitOfInterest = 1 << bit; 4672 SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitOfInterest; 4673 4674 SECURITY_DESCRIPTOR_CONTROL ctrl; 4675 4676 DWORD dwExpect = (bitOfInterest & immutable) 4677 ? ERROR_INVALID_PARAMETER : 0xbebecaca; 4678 LPCSTR strExpect = (bitOfInterest & immutable) 4679 ? "ERROR_INVALID_PARAMETER" : "0xbebecaca"; 4680 4681 ctrl = (bitOfInterest & mutable) ? ref + bitOfInterest : ref; 4682 setOrClear ^= bitOfInterest; 4683 SetLastError (0xbebecaca); 4684 pSetSecurityDescriptorControl (sec, bitOfInterest, setOrClear); 4685 ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ()); 4686 GetSecurityDescriptorControl(sec, &test, &dwRevision); 4687 expect_eq(test, ctrl, int, "%x"); 4688 4689 setOrClear ^= bitOfInterest; 4690 SetLastError (0xbebecaca); 4691 pSetSecurityDescriptorControl (sec, bitOfInterest, setOrClear); 4692 ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ()); 4693 GetSecurityDescriptorControl (sec, &test, &dwRevision); 4694 expect_eq(test, ref, int, "%x"); 4695 } 4696 4697 /* Check call barfs if any bit-to-set is immutable 4698 even when not a bit-of-interest */ 4699 for (bit = 0; bit < 16; ++bit) 4700 { 4701 SECURITY_DESCRIPTOR_CONTROL const bitsOfInterest = mutable; 4702 SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitsOfInterest; 4703 4704 SECURITY_DESCRIPTOR_CONTROL ctrl; 4705 4706 DWORD dwExpect = ((1 << bit) & immutable) 4707 ? ERROR_INVALID_PARAMETER : 0xbebecaca; 4708 LPCSTR strExpect = ((1 << bit) & immutable) 4709 ? "ERROR_INVALID_PARAMETER" : "0xbebecaca"; 4710 4711 ctrl = ((1 << bit) & immutable) ? test : ref | mutable; 4712 setOrClear ^= bitsOfInterest; 4713 SetLastError (0xbebecaca); 4714 pSetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit)); 4715 ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ()); 4716 GetSecurityDescriptorControl(sec, &test, &dwRevision); 4717 expect_eq(test, ctrl, int, "%x"); 4718 4719 ctrl = ((1 << bit) & immutable) ? test : ref | (1 << bit); 4720 setOrClear ^= bitsOfInterest; 4721 SetLastError (0xbebecaca); 4722 pSetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit)); 4723 ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ()); 4724 GetSecurityDescriptorControl(sec, &test, &dwRevision); 4725 expect_eq(test, ctrl, int, "%x"); 4726 } 4727 } 4728 4729 static void test_PrivateObjectSecurity(void) 4730 { 4731 SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION; 4732 SECURITY_DESCRIPTOR_CONTROL ctrl; 4733 PSECURITY_DESCRIPTOR sec; 4734 DWORD dwDescSize; 4735 DWORD dwRevision; 4736 DWORD retSize; 4737 LPSTR string; 4738 ULONG len; 4739 PSECURITY_DESCRIPTOR buf; 4740 BOOL ret; 4741 4742 if (!pConvertStringSecurityDescriptorToSecurityDescriptorA) 4743 { 4744 win_skip("ConvertStringSecurityDescriptorToSecurityDescriptor is not available\n"); 4745 return; 4746 } 4747 4748 ok(pConvertStringSecurityDescriptorToSecurityDescriptorA( 4749 "O:SY" 4750 "G:S-1-5-21-93476-23408-4576" 4751 "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)" 4752 "(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)" 4753 "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", 4754 SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n"); 4755 4756 test_SetSecurityDescriptorControl(sec); 4757 4758 LocalFree(sec); 4759 4760 ok(pConvertStringSecurityDescriptorToSecurityDescriptorA( 4761 "O:SY" 4762 "G:S-1-5-21-93476-23408-4576", 4763 SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n"); 4764 4765 test_SetSecurityDescriptorControl(sec); 4766 4767 LocalFree(sec); 4768 4769 ok(pConvertStringSecurityDescriptorToSecurityDescriptorA( 4770 "O:SY" 4771 "G:S-1-5-21-93476-23408-4576" 4772 "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)" 4773 "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n"); 4774 buf = HeapAlloc(GetProcessHeap(), 0, dwDescSize); 4775 pSetSecurityDescriptorControl(sec, SE_DACL_PROTECTED, SE_DACL_PROTECTED); 4776 GetSecurityDescriptorControl(sec, &ctrl, &dwRevision); 4777 expect_eq(ctrl, 0x9014, int, "%x"); 4778 4779 ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION, buf, dwDescSize, &retSize); 4780 ok(ret, "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError()); 4781 ok(retSize <= dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize); 4782 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4783 CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576"); 4784 GetSecurityDescriptorControl(buf, &ctrl, &dwRevision); 4785 expect_eq(ctrl, 0x8000, int, "%x"); 4786 4787 ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, buf, dwDescSize, &retSize); 4788 ok(ret, "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError()); 4789 ok(retSize <= dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize); 4790 ret = pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len); 4791 ok(ret, "Conversion failed err=%u\n", GetLastError()); 4792 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)", 4793 "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 */ 4794 GetSecurityDescriptorControl(buf, &ctrl, &dwRevision); 4795 expect_eq(ctrl & (~ SE_DACL_PROTECTED), 0x8004, int, "%x"); 4796 4797 ret = GetPrivateObjectSecurity(sec, sec_info, buf, dwDescSize, &retSize); 4798 ok(ret, "GetPrivateObjectSecurity failed (err=%u)\n", GetLastError()); 4799 ok(retSize == dwDescSize, "Buffer too small (%d vs %d)\n", retSize, dwDescSize); 4800 ok(pConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n"); 4801 CHECK_ONE_OF_AND_FREE("O:SY" 4802 "G:S-1-5-21-93476-23408-4576" 4803 "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)" 4804 "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", 4805 "O:SY" 4806 "G:S-1-5-21-93476-23408-4576" 4807 "D:P(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)" 4808 "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)"); /* Win7 */ 4809 GetSecurityDescriptorControl(buf, &ctrl, &dwRevision); 4810 expect_eq(ctrl & (~ SE_DACL_PROTECTED), 0x8014, int, "%x"); 4811 4812 SetLastError(0xdeadbeef); 4813 ok(GetPrivateObjectSecurity(sec, sec_info, buf, 5, &retSize) == FALSE, "GetPrivateObjectSecurity should have failed\n"); 4814 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected error ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 4815 4816 LocalFree(sec); 4817 HeapFree(GetProcessHeap(), 0, buf); 4818 } 4819 #undef CHECK_RESULT_AND_FREE 4820 #undef CHECK_ONE_OF_AND_FREE 4821 4822 static void test_acls(void) 4823 { 4824 char buffer[256]; 4825 PACL pAcl = (PACL)buffer; 4826 BOOL ret; 4827 4828 SetLastError(0xdeadbeef); 4829 ret = InitializeAcl(pAcl, sizeof(ACL) - 1, ACL_REVISION); 4830 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 4831 { 4832 win_skip("InitializeAcl is not implemented\n"); 4833 return; 4834 } 4835 4836 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InitializeAcl with too small a buffer should have failed with ERROR_INSUFFICIENT_BUFFER instead of %d\n", GetLastError()); 4837 4838 SetLastError(0xdeadbeef); 4839 ret = InitializeAcl(pAcl, 0xffffffff, ACL_REVISION); 4840 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl with too large a buffer should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError()); 4841 4842 SetLastError(0xdeadbeef); 4843 ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION1); 4844 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(ACL_REVISION1) should have failed with ERROR_INVALID_PARAMETER instead of %d\n", GetLastError()); 4845 4846 ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION2); 4847 ok(ret, "InitializeAcl(ACL_REVISION2) failed with error %d\n", GetLastError()); 4848 4849 ret = IsValidAcl(pAcl); 4850 ok(ret, "IsValidAcl failed with error %d\n", GetLastError()); 4851 4852 ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION3); 4853 ok(ret, "InitializeAcl(ACL_REVISION3) failed with error %d\n", GetLastError()); 4854 4855 ret = IsValidAcl(pAcl); 4856 ok(ret, "IsValidAcl failed with error %d\n", GetLastError()); 4857 4858 SetLastError(0xdeadbeef); 4859 ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION4); 4860 if (GetLastError() != ERROR_INVALID_PARAMETER) 4861 { 4862 ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %d\n", GetLastError()); 4863 4864 ret = IsValidAcl(pAcl); 4865 ok(ret, "IsValidAcl failed with error %d\n", GetLastError()); 4866 } 4867 else 4868 win_skip("ACL_REVISION4 is not implemented on NT4\n"); 4869 4870 SetLastError(0xdeadbeef); 4871 ret = InitializeAcl(pAcl, sizeof(buffer), -1); 4872 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(-1) failed with error %d\n", GetLastError()); 4873 } 4874 4875 static void test_GetSecurityInfo(void) 4876 { 4877 char domain_users_ptr[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES]; 4878 char b[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES]; 4879 char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100]; 4880 PSID domain_users_sid = (PSID) domain_users_ptr, domain_sid; 4881 SID_IDENTIFIER_AUTHORITY sia = { SECURITY_NT_AUTHORITY }; 4882 int domain_users_ace_id = -1, admins_ace_id = -1, i; 4883 DWORD sid_size = sizeof(admin_ptr), l = sizeof(b); 4884 PSID admin_sid = (PSID) admin_ptr, user_sid; 4885 char sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; 4886 BOOL owner_defaulted, group_defaulted; 4887 BOOL dacl_defaulted, dacl_present; 4888 ACL_SIZE_INFORMATION acl_size; 4889 PSECURITY_DESCRIPTOR pSD; 4890 ACCESS_ALLOWED_ACE *ace; 4891 HANDLE token, obj; 4892 PSID owner, group; 4893 BOOL bret = TRUE; 4894 PACL pDacl; 4895 BYTE flags; 4896 DWORD ret; 4897 4898 if (!pGetSecurityInfo || !pSetSecurityInfo) 4899 { 4900 win_skip("[Get|Set]SecurityInfo is not available\n"); 4901 return; 4902 } 4903 4904 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token)) 4905 { 4906 if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE; 4907 else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE; 4908 } 4909 if (!bret) 4910 { 4911 win_skip("Failed to get current user token\n"); 4912 return; 4913 } 4914 bret = GetTokenInformation(token, TokenUser, b, l, &l); 4915 ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 4916 CloseHandle( token ); 4917 user_sid = ((TOKEN_USER *)b)->User.Sid; 4918 4919 /* Create something. Files have lots of associated security info. */ 4920 obj = CreateFileA(myARGV[0], GENERIC_READ|WRITE_DAC, FILE_SHARE_READ, NULL, 4921 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 4922 if (obj == INVALID_HANDLE_VALUE) 4923 { 4924 skip("Couldn't create an object for GetSecurityInfo test\n"); 4925 return; 4926 } 4927 4928 ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, 4929 OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 4930 &owner, &group, &pDacl, NULL, &pSD); 4931 if (ret == ERROR_CALL_NOT_IMPLEMENTED) 4932 { 4933 win_skip("GetSecurityInfo is not implemented\n"); 4934 CloseHandle(obj); 4935 return; 4936 } 4937 ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret); 4938 ok(pSD != NULL, "GetSecurityInfo\n"); 4939 ok(owner != NULL, "GetSecurityInfo\n"); 4940 ok(group != NULL, "GetSecurityInfo\n"); 4941 if (pDacl != NULL) 4942 ok(IsValidAcl(pDacl), "GetSecurityInfo\n"); 4943 else 4944 win_skip("No ACL information returned\n"); 4945 4946 LocalFree(pSD); 4947 4948 if (!pCreateWellKnownSid) 4949 { 4950 win_skip("NULL parameter test would crash on NT4\n"); 4951 CloseHandle(obj); 4952 return; 4953 } 4954 4955 /* If we don't ask for the security descriptor, Windows will still give us 4956 the other stuff, leaving us no way to free it. */ 4957 ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, 4958 OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 4959 &owner, &group, &pDacl, NULL, NULL); 4960 ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret); 4961 ok(owner != NULL, "GetSecurityInfo\n"); 4962 ok(group != NULL, "GetSecurityInfo\n"); 4963 if (pDacl != NULL) 4964 ok(IsValidAcl(pDacl), "GetSecurityInfo\n"); 4965 else 4966 win_skip("No ACL information returned\n"); 4967 4968 /* Create security descriptor information and test that it comes back the same */ 4969 pSD = &sd; 4970 pDacl = (PACL)&dacl; 4971 InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); 4972 pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); 4973 bret = InitializeAcl(pDacl, sizeof(dacl), ACL_REVISION); 4974 ok(bret, "Failed to initialize ACL.\n"); 4975 bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); 4976 ok(bret, "Failed to add Current User to ACL.\n"); 4977 bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid); 4978 ok(bret, "Failed to add Administrator Group to ACL.\n"); 4979 bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); 4980 ok(bret, "Failed to add ACL to security descriptor.\n"); 4981 ret = pSetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 4982 NULL, NULL, pDacl, NULL); 4983 ok(ret == ERROR_SUCCESS, "SetSecurityInfo returned %d\n", ret); 4984 ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 4985 NULL, NULL, &pDacl, NULL, &pSD); 4986 ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret); 4987 ok(pDacl && IsValidAcl(pDacl), "GetSecurityInfo returned invalid DACL.\n"); 4988 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 4989 ok(bret, "GetAclInformation failed\n"); 4990 if (acl_size.AceCount > 0) 4991 { 4992 bret = pGetAce(pDacl, 0, (VOID **)&ace); 4993 ok(bret, "Failed to get Current User ACE.\n"); 4994 bret = EqualSid(&ace->SidStart, user_sid); 4995 ok(bret, "Current User ACE (%s) != Current User SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid)); 4996 ok(((ACE_HEADER *)ace)->AceFlags == 0, 4997 "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); 4998 ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", 4999 ace->Mask); 5000 } 5001 if (acl_size.AceCount > 1) 5002 { 5003 bret = pGetAce(pDacl, 1, (VOID **)&ace); 5004 ok(bret, "Failed to get Administators Group ACE.\n"); 5005 bret = EqualSid(&ace->SidStart, admin_sid); 5006 ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); 5007 ok(((ACE_HEADER *)ace)->AceFlags == 0, 5008 "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); 5009 ok(ace->Mask == 0x1f01ff, 5010 "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); 5011 } 5012 LocalFree(pSD); 5013 CloseHandle(obj); 5014 5015 /* Obtain the "domain users" SID from the user SID */ 5016 if (!AllocateAndInitializeSid(&sia, 4, *GetSidSubAuthority(user_sid, 0), 5017 *GetSidSubAuthority(user_sid, 1), 5018 *GetSidSubAuthority(user_sid, 2), 5019 *GetSidSubAuthority(user_sid, 3), 0, 0, 0, 0, &domain_sid)) 5020 { 5021 win_skip("Failed to get current domain SID\n"); 5022 return; 5023 } 5024 sid_size = sizeof(domain_users_ptr); 5025 pCreateWellKnownSid(WinAccountDomainUsersSid, domain_sid, domain_users_sid, &sid_size); 5026 FreeSid(domain_sid); 5027 5028 /* Test querying the ownership of a process */ 5029 ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, 5030 OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION, 5031 NULL, NULL, NULL, NULL, &pSD); 5032 ok(!ret, "GetNamedSecurityInfo failed with error %d\n", ret); 5033 5034 bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted); 5035 ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); 5036 ok(owner != NULL, "owner should not be NULL\n"); 5037 ok(EqualSid(owner, admin_sid) || EqualSid(owner, user_sid), 5038 "Process owner SID != Administrators SID.\n"); 5039 5040 bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted); 5041 ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); 5042 ok(group != NULL, "group should not be NULL\n"); 5043 ok(EqualSid(group, domain_users_sid), "Process group SID != Domain Users SID.\n"); 5044 LocalFree(pSD); 5045 5046 /* Test querying the DACL of a process */ 5047 ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 5048 NULL, NULL, NULL, NULL, &pSD); 5049 ok(!ret, "GetSecurityInfo failed with error %d\n", ret); 5050 5051 bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted); 5052 ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError()); 5053 ok(dacl_present, "DACL should be present\n"); 5054 ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n"); 5055 bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); 5056 ok(bret, "GetAclInformation failed\n"); 5057 ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n"); 5058 for (i=0; i<acl_size.AceCount; i++) 5059 { 5060 bret = pGetAce(pDacl, i, (VOID **)&ace); 5061 ok(bret, "Failed to get ACE %d.\n", i); 5062 bret = EqualSid(&ace->SidStart, domain_users_sid); 5063 if (bret) domain_users_ace_id = i; 5064 bret = EqualSid(&ace->SidStart, admin_sid); 5065 if (bret) admins_ace_id = i; 5066 } 5067 ok(domain_users_ace_id != -1 || broken(domain_users_ace_id == -1) /* win2k */, 5068 "Domain Users ACE not found.\n"); 5069 if (domain_users_ace_id != -1) 5070 { 5071 bret = pGetAce(pDacl, domain_users_ace_id, (VOID **)&ace); 5072 ok(bret, "Failed to get Domain Users ACE.\n"); 5073 flags = ((ACE_HEADER *)ace)->AceFlags; 5074 ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE), 5075 "Domain Users ACE has unexpected flags (0x%x != 0x%x)\n", flags, 5076 INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE); 5077 ok(ace->Mask == GENERIC_READ, "Domain Users ACE has unexpected mask (0x%x != 0x%x)\n", 5078 ace->Mask, GENERIC_READ); 5079 } 5080 ok(admins_ace_id != -1 || broken(admins_ace_id == -1) /* xp */, 5081 "Builtin Admins ACE not found.\n"); 5082 if (admins_ace_id != -1) 5083 { 5084 bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace); 5085 ok(bret, "Failed to get Builtin Admins ACE.\n"); 5086 flags = ((ACE_HEADER *)ace)->AceFlags; 5087 ok(flags == 0x0, "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags); 5088 ok(ace->Mask == PROCESS_ALL_ACCESS || broken(ace->Mask == 0x1f0fff) /* win2k */, 5089 "Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, PROCESS_ALL_ACCESS); 5090 } 5091 LocalFree(pSD); 5092 } 5093 5094 static void test_GetSidSubAuthority(void) 5095 { 5096 PSID psid = NULL; 5097 5098 if (!pGetSidSubAuthority || !pConvertStringSidToSidA || !pIsValidSid || !pGetSidSubAuthorityCount) 5099 { 5100 win_skip("Some functions not available\n"); 5101 return; 5102 } 5103 /* Note: on windows passing in an invalid index like -1, lets GetSidSubAuthority return 0x05000000 but 5104 still GetLastError returns ERROR_SUCCESS then. We don't test these unlikely cornercases here for now */ 5105 ok(pConvertStringSidToSidA("S-1-5-21-93476-23408-4576",&psid),"ConvertStringSidToSidA failed\n"); 5106 ok(pIsValidSid(psid),"Sid is not valid\n"); 5107 SetLastError(0xbebecaca); 5108 ok(*pGetSidSubAuthorityCount(psid) == 4,"GetSidSubAuthorityCount gave %d expected 4\n",*pGetSidSubAuthorityCount(psid)); 5109 ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); 5110 SetLastError(0xbebecaca); 5111 ok(*pGetSidSubAuthority(psid,0) == 21,"GetSidSubAuthority gave %d expected 21\n",*pGetSidSubAuthority(psid,0)); 5112 ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); 5113 SetLastError(0xbebecaca); 5114 ok(*pGetSidSubAuthority(psid,1) == 93476,"GetSidSubAuthority gave %d expected 93476\n",*pGetSidSubAuthority(psid,1)); 5115 ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); 5116 SetLastError(0xbebecaca); 5117 ok(pGetSidSubAuthority(psid,4) != NULL,"Expected out of bounds GetSidSubAuthority to return a non-NULL pointer\n"); 5118 ok(GetLastError() == 0,"GetLastError returned %d instead of 0\n",GetLastError()); 5119 LocalFree(psid); 5120 } 5121 5122 static void test_CheckTokenMembership(void) 5123 { 5124 PTOKEN_GROUPS token_groups; 5125 DWORD size; 5126 HANDLE process_token, token; 5127 BOOL is_member; 5128 BOOL ret; 5129 DWORD i; 5130 5131 if (!pCheckTokenMembership) 5132 { 5133 win_skip("CheckTokenMembership is not available\n"); 5134 return; 5135 } 5136 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token); 5137 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError()); 5138 5139 ret = DuplicateToken(process_token, SecurityImpersonation, &token); 5140 ok(ret, "DuplicateToken failed with error %d\n", GetLastError()); 5141 5142 /* groups */ 5143 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size); 5144 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 5145 "GetTokenInformation(TokenGroups) %s with error %d\n", 5146 ret ? "succeeded" : "failed", GetLastError()); 5147 token_groups = HeapAlloc(GetProcessHeap(), 0, size); 5148 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size); 5149 ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n", GetLastError()); 5150 5151 for (i = 0; i < token_groups->GroupCount; i++) 5152 { 5153 if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) 5154 break; 5155 } 5156 5157 if (i == token_groups->GroupCount) 5158 { 5159 HeapFree(GetProcessHeap(), 0, token_groups); 5160 CloseHandle(token); 5161 skip("user not a member of any group\n"); 5162 return; 5163 } 5164 5165 is_member = FALSE; 5166 ret = pCheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member); 5167 ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError()); 5168 ok(is_member, "CheckTokenMembership should have detected sid as member\n"); 5169 5170 is_member = FALSE; 5171 ret = pCheckTokenMembership(NULL, token_groups->Groups[i].Sid, &is_member); 5172 ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError()); 5173 ok(is_member, "CheckTokenMembership should have detected sid as member\n"); 5174 5175 is_member = TRUE; 5176 SetLastError(0xdeadbeef); 5177 ret = pCheckTokenMembership(process_token, token_groups->Groups[i].Sid, &is_member); 5178 ok(!ret && GetLastError() == ERROR_NO_IMPERSONATION_TOKEN, 5179 "CheckTokenMembership with process token %s with error %d\n", 5180 ret ? "succeeded" : "failed", GetLastError()); 5181 ok(!is_member, "CheckTokenMembership should have cleared is_member\n"); 5182 5183 HeapFree(GetProcessHeap(), 0, token_groups); 5184 CloseHandle(token); 5185 CloseHandle(process_token); 5186 } 5187 5188 static void test_EqualSid(void) 5189 { 5190 PSID sid1, sid2; 5191 BOOL ret; 5192 SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; 5193 SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY }; 5194 5195 SetLastError(0xdeadbeef); 5196 ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, 5197 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid1); 5198 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 5199 { 5200 win_skip("AllocateAndInitializeSid is not implemented\n"); 5201 return; 5202 } 5203 ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 5204 ok(GetLastError() == 0xdeadbeef, 5205 "AllocateAndInitializeSid shouldn't have set last error to %d\n", 5206 GetLastError()); 5207 5208 ret = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 5209 0, 0, 0, 0, 0, 0, 0, &sid2); 5210 ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 5211 5212 SetLastError(0xdeadbeef); 5213 ret = EqualSid(sid1, sid2); 5214 ok(!ret, "World and domain admins sids shouldn't have been equal\n"); 5215 ok(GetLastError() == ERROR_SUCCESS || 5216 broken(GetLastError() == 0xdeadbeef), /* NT4 */ 5217 "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", 5218 GetLastError()); 5219 5220 SetLastError(0xdeadbeef); 5221 sid2 = FreeSid(sid2); 5222 ok(!sid2, "FreeSid should have returned NULL instead of %p\n", sid2); 5223 ok(GetLastError() == 0xdeadbeef, 5224 "FreeSid shouldn't have set last error to %d\n", 5225 GetLastError()); 5226 5227 ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, 5228 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid2); 5229 ok(ret, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 5230 5231 SetLastError(0xdeadbeef); 5232 ret = EqualSid(sid1, sid2); 5233 ok(ret, "Same sids should have been equal %s != %s\n", 5234 debugstr_sid(sid1), debugstr_sid(sid2)); 5235 ok(GetLastError() == ERROR_SUCCESS || 5236 broken(GetLastError() == 0xdeadbeef), /* NT4 */ 5237 "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", 5238 GetLastError()); 5239 5240 ((SID *)sid2)->Revision = 2; 5241 SetLastError(0xdeadbeef); 5242 ret = EqualSid(sid1, sid2); 5243 ok(!ret, "EqualSid with invalid sid should have returned FALSE\n"); 5244 ok(GetLastError() == ERROR_SUCCESS || 5245 broken(GetLastError() == 0xdeadbeef), /* NT4 */ 5246 "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n", 5247 GetLastError()); 5248 ((SID *)sid2)->Revision = SID_REVISION; 5249 5250 FreeSid(sid1); 5251 FreeSid(sid2); 5252 } 5253 5254 static void test_GetUserNameA(void) 5255 { 5256 char buffer[UNLEN + 1], filler[UNLEN + 1]; 5257 DWORD required_len, buffer_len; 5258 BOOL ret; 5259 5260 /* Test crashes on Windows. */ 5261 if (0) 5262 { 5263 SetLastError(0xdeadbeef); 5264 GetUserNameA(NULL, NULL); 5265 } 5266 5267 SetLastError(0xdeadbeef); 5268 required_len = 0; 5269 ret = GetUserNameA(NULL, &required_len); 5270 ok(ret == FALSE, "GetUserNameA returned %d\n", ret); 5271 ok(required_len != 0, "Outputted buffer length was %u\n", required_len); 5272 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); 5273 5274 SetLastError(0xdeadbeef); 5275 required_len = 1; 5276 ret = GetUserNameA(NULL, &required_len); 5277 ok(ret == FALSE, "GetUserNameA returned %d\n", ret); 5278 ok(required_len != 0 && required_len != 1, "Outputted buffer length was %u\n", required_len); 5279 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); 5280 5281 /* Tests crashes on Windows. */ 5282 if (0) 5283 { 5284 SetLastError(0xdeadbeef); 5285 required_len = UNLEN + 1; 5286 GetUserNameA(NULL, &required_len); 5287 5288 SetLastError(0xdeadbeef); 5289 GetUserNameA(buffer, NULL); 5290 } 5291 5292 memset(filler, 'x', sizeof(filler)); 5293 5294 /* Note that GetUserNameA on XP and newer outputs the number of bytes 5295 * required for a Unicode string, which affects a test in the next block. */ 5296 SetLastError(0xdeadbeef); 5297 memcpy(buffer, filler, sizeof(filler)); 5298 required_len = 0; 5299 ret = GetUserNameA(buffer, &required_len); 5300 ok(ret == FALSE, "GetUserNameA returned %d\n", ret); 5301 ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n"); 5302 ok(required_len != 0, "Outputted buffer length was %u\n", required_len); 5303 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); 5304 5305 SetLastError(0xdeadbeef); 5306 memcpy(buffer, filler, sizeof(filler)); 5307 buffer_len = required_len; 5308 ret = GetUserNameA(buffer, &buffer_len); 5309 ok(ret == TRUE, "GetUserNameA returned %d, last error %u\n", ret, GetLastError()); 5310 ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n"); 5311 ok(buffer_len == required_len || 5312 broken(buffer_len == required_len / sizeof(WCHAR)), /* XP+ */ 5313 "Outputted buffer length was %u\n", buffer_len); 5314 5315 /* Use the reported buffer size from the last GetUserNameA call and pass 5316 * a length that is one less than the required value. */ 5317 SetLastError(0xdeadbeef); 5318 memcpy(buffer, filler, sizeof(filler)); 5319 buffer_len--; 5320 ret = GetUserNameA(buffer, &buffer_len); 5321 ok(ret == FALSE, "GetUserNameA returned %d\n", ret); 5322 ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was untouched\n"); 5323 ok(buffer_len == required_len, "Outputted buffer length was %u\n", buffer_len); 5324 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); 5325 } 5326 5327 static void test_GetUserNameW(void) 5328 { 5329 WCHAR buffer[UNLEN + 1], filler[UNLEN + 1]; 5330 DWORD required_len, buffer_len; 5331 BOOL ret; 5332 5333 /* Test crashes on Windows. */ 5334 if (0) 5335 { 5336 SetLastError(0xdeadbeef); 5337 GetUserNameW(NULL, NULL); 5338 } 5339 5340 SetLastError(0xdeadbeef); 5341 required_len = 0; 5342 ret = GetUserNameW(NULL, &required_len); 5343 ok(ret == FALSE, "GetUserNameW returned %d\n", ret); 5344 ok(required_len != 0, "Outputted buffer length was %u\n", required_len); 5345 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); 5346 5347 SetLastError(0xdeadbeef); 5348 required_len = 1; 5349 ret = GetUserNameW(NULL, &required_len); 5350 ok(ret == FALSE, "GetUserNameW returned %d\n", ret); 5351 ok(required_len != 0 && required_len != 1, "Outputted buffer length was %u\n", required_len); 5352 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); 5353 5354 /* Tests crash on Windows. */ 5355 if (0) 5356 { 5357 SetLastError(0xdeadbeef); 5358 required_len = UNLEN + 1; 5359 GetUserNameW(NULL, &required_len); 5360 5361 SetLastError(0xdeadbeef); 5362 GetUserNameW(buffer, NULL); 5363 } 5364 5365 memset(filler, 'x', sizeof(filler)); 5366 5367 SetLastError(0xdeadbeef); 5368 memcpy(buffer, filler, sizeof(filler)); 5369 required_len = 0; 5370 ret = GetUserNameW(buffer, &required_len); 5371 ok(ret == FALSE, "GetUserNameW returned %d\n", ret); 5372 ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n"); 5373 ok(required_len != 0, "Outputted buffer length was %u\n", required_len); 5374 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); 5375 5376 SetLastError(0xdeadbeef); 5377 memcpy(buffer, filler, sizeof(filler)); 5378 buffer_len = required_len; 5379 ret = GetUserNameW(buffer, &buffer_len); 5380 ok(ret == TRUE, "GetUserNameW returned %d, last error %u\n", ret, GetLastError()); 5381 ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n"); 5382 ok(buffer_len == required_len, "Outputted buffer length was %u\n", buffer_len); 5383 5384 /* GetUserNameW on XP and newer writes a truncated portion of the username string to the buffer. */ 5385 SetLastError(0xdeadbeef); 5386 memcpy(buffer, filler, sizeof(filler)); 5387 buffer_len--; 5388 ret = GetUserNameW(buffer, &buffer_len); 5389 ok(ret == FALSE, "GetUserNameW returned %d\n", ret); 5390 ok(!memcmp(buffer, filler, sizeof(filler)) || 5391 broken(memcmp(buffer, filler, sizeof(filler)) != 0), /* XP+ */ 5392 "Output buffer was altered\n"); 5393 ok(buffer_len == required_len, "Outputted buffer length was %u\n", buffer_len); 5394 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %u\n", GetLastError()); 5395 } 5396 5397 static void test_CreateRestrictedToken(void) 5398 { 5399 TOKEN_PRIMARY_GROUP *primary_group, *primary_group2; 5400 HANDLE process_token, token, r_token; 5401 PTOKEN_GROUPS token_groups, groups2; 5402 SID_AND_ATTRIBUTES sattr; 5403 SECURITY_IMPERSONATION_LEVEL level; 5404 TOKEN_PRIVILEGES *privs; 5405 PRIVILEGE_SET privset; 5406 TOKEN_TYPE type; 5407 BOOL is_member; 5408 DWORD size; 5409 BOOL ret; 5410 DWORD i, j; 5411 5412 if (!pCreateRestrictedToken) 5413 { 5414 win_skip("CreateRestrictedToken is not available\n"); 5415 return; 5416 } 5417 5418 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token); 5419 ok(ret, "got error %d\n", GetLastError()); 5420 5421 ret = DuplicateTokenEx(process_token, TOKEN_DUPLICATE|TOKEN_ADJUST_GROUPS|TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, 5422 NULL, SecurityImpersonation, TokenImpersonation, &token); 5423 ok(ret, "got error %d\n", GetLastError()); 5424 5425 /* groups */ 5426 ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size); 5427 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 5428 "got %d with error %d\n", ret, GetLastError()); 5429 token_groups = HeapAlloc(GetProcessHeap(), 0, size); 5430 ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size); 5431 ok(ret, "got error %d\n", GetLastError()); 5432 5433 for (i = 0; i < token_groups->GroupCount; i++) 5434 { 5435 if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) 5436 break; 5437 } 5438 5439 if (i == token_groups->GroupCount) 5440 { 5441 HeapFree(GetProcessHeap(), 0, token_groups); 5442 CloseHandle(token); 5443 skip("User not a member of any group\n"); 5444 return; 5445 } 5446 5447 is_member = FALSE; 5448 ret = pCheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member); 5449 ok(ret, "got error %d\n", GetLastError()); 5450 ok(is_member, "not a member\n"); 5451 5452 privset.PrivilegeCount = 1; 5453 privset.Control = PRIVILEGE_SET_ALL_NECESSARY; 5454 ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privset.Privilege[0].Luid); 5455 ok(ret, "got error %d\n", GetLastError()); 5456 5457 is_member = FALSE; 5458 ret = PrivilegeCheck(token, &privset, &is_member); 5459 ok(ret, "got error %d\n", GetLastError()); 5460 ok(is_member, "Expected SeChangeNotifyPrivilege to be enabled\n"); 5461 5462 /* disable a SID and a privilege in new token */ 5463 sattr.Sid = token_groups->Groups[i].Sid; 5464 sattr.Attributes = 0; 5465 r_token = NULL; 5466 ret = pCreateRestrictedToken(token, 0, 1, &sattr, 1, &privset.Privilege[0], 0, NULL, &r_token); 5467 ok(ret, "got error %d\n", GetLastError()); 5468 5469 if (ret) 5470 { 5471 /* check if a SID is enabled */ 5472 is_member = TRUE; 5473 ret = pCheckTokenMembership(r_token, token_groups->Groups[i].Sid, &is_member); 5474 ok(ret, "got error %d\n", GetLastError()); 5475 ok(!is_member, "not a member\n"); 5476 5477 ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size); 5478 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", 5479 ret, GetLastError()); 5480 groups2 = HeapAlloc(GetProcessHeap(), 0, size); 5481 ret = GetTokenInformation(r_token, TokenGroups, groups2, size, &size); 5482 ok(ret, "got error %d\n", GetLastError()); 5483 5484 for (j = 0; j < groups2->GroupCount; j++) 5485 { 5486 if (EqualSid(groups2->Groups[j].Sid, token_groups->Groups[i].Sid)) 5487 break; 5488 } 5489 5490 ok(groups2->Groups[j].Attributes & SE_GROUP_USE_FOR_DENY_ONLY, 5491 "got wrong attributes\n"); 5492 ok((groups2->Groups[j].Attributes & SE_GROUP_ENABLED) == 0, 5493 "got wrong attributes\n"); 5494 5495 HeapFree(GetProcessHeap(), 0, groups2); 5496 5497 size = sizeof(type); 5498 ret = GetTokenInformation(r_token, TokenType, &type, size, &size); 5499 ok(ret, "got error %d\n", GetLastError()); 5500 ok(type == TokenImpersonation, "got type %u\n", type); 5501 5502 size = sizeof(level); 5503 ret = GetTokenInformation(r_token, TokenImpersonationLevel, &level, size, &size); 5504 ok(ret, "got error %d\n", GetLastError()); 5505 ok(level == SecurityImpersonation, "got level %u\n", type); 5506 5507 is_member = TRUE; 5508 ret = PrivilegeCheck(r_token, &privset, &is_member); 5509 ok(ret, "got error %d\n", GetLastError()); 5510 ok(!is_member, "Expected SeChangeNotifyPrivilege not to be enabled\n"); 5511 5512 ret = GetTokenInformation(r_token, TokenPrivileges, NULL, 0, &size); 5513 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", 5514 ret, GetLastError()); 5515 privs = HeapAlloc(GetProcessHeap(), 0, size); 5516 ret = GetTokenInformation(r_token, TokenPrivileges, privs, size, &size); 5517 ok(ret, "got error %d\n", GetLastError()); 5518 5519 is_member = FALSE; 5520 for (j = 0; j < privs->PrivilegeCount; j++) 5521 { 5522 if (RtlEqualLuid(&privs->Privileges[j].Luid, &privset.Privilege[0].Luid)) 5523 { 5524 is_member = TRUE; 5525 break; 5526 } 5527 } 5528 5529 ok(!is_member, "Expected not to find privilege\n"); 5530 HeapFree(GetProcessHeap(), 0, privs); 5531 } 5532 5533 HeapFree(GetProcessHeap(), 0, token_groups); 5534 CloseHandle(r_token); 5535 5536 ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &size); 5537 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", 5538 ret, GetLastError()); 5539 primary_group = HeapAlloc(GetProcessHeap(), 0, size); 5540 ret = GetTokenInformation(token, TokenPrimaryGroup, primary_group, size, &size); 5541 ok(ret, "got error %d\n", GetLastError()); 5542 5543 /* disable primary group */ 5544 sattr.Sid = primary_group->PrimaryGroup; 5545 sattr.Attributes = 0; 5546 r_token = NULL; 5547 ret = pCreateRestrictedToken(token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token); 5548 ok(ret, "got error %d\n", GetLastError()); 5549 5550 if (ret) 5551 { 5552 is_member = TRUE; 5553 ret = pCheckTokenMembership(r_token, primary_group->PrimaryGroup, &is_member); 5554 ok(ret, "got error %d\n", GetLastError()); 5555 ok(!is_member, "not a member\n"); 5556 5557 ret = GetTokenInformation(r_token, TokenPrimaryGroup, NULL, 0, &size); 5558 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", 5559 ret, GetLastError()); 5560 primary_group2 = HeapAlloc(GetProcessHeap(), 0, size); 5561 ret = GetTokenInformation(r_token, TokenPrimaryGroup, primary_group2, size, &size); 5562 ok(ret, "got error %d\n", GetLastError()); 5563 5564 ok(EqualSid(primary_group2->PrimaryGroup, primary_group->PrimaryGroup), 5565 "Expected same primary group\n"); 5566 5567 HeapFree(GetProcessHeap(), 0, primary_group2); 5568 } 5569 5570 HeapFree(GetProcessHeap(), 0, primary_group); 5571 CloseHandle(r_token); 5572 5573 CloseHandle(token); 5574 CloseHandle(process_token); 5575 } 5576 5577 static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd) 5578 { 5579 BOOL ret, present, defaulted; 5580 ACL *acl; 5581 void *sid; 5582 5583 ret = IsValidSecurityDescriptor(sd); 5584 ok(ret, "security descriptor is not valid\n"); 5585 5586 present = -1; 5587 defaulted = -1; 5588 acl = (void *)0xdeadbeef; 5589 SetLastError(0xdeadbeef); 5590 ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted); 5591 ok(ret, "GetSecurityDescriptorDacl error %d\n", GetLastError()); 5592 todo_wine 5593 ok(present == 1, "acl is not present\n"); 5594 todo_wine 5595 ok(acl != (void *)0xdeadbeef && acl != NULL, "acl pointer is not set\n"); 5596 ok(defaulted == 0, "defaulted is set to TRUE\n"); 5597 5598 defaulted = -1; 5599 sid = (void *)0xdeadbeef; 5600 SetLastError(0xdeadbeef); 5601 ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted); 5602 ok(ret, "GetSecurityDescriptorOwner error %d\n", GetLastError()); 5603 todo_wine 5604 ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n"); 5605 ok(defaulted == 0, "defaulted is set to TRUE\n"); 5606 5607 defaulted = -1; 5608 sid = (void *)0xdeadbeef; 5609 SetLastError(0xdeadbeef); 5610 ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted); 5611 ok(ret, "GetSecurityDescriptorGroup error %d\n", GetLastError()); 5612 todo_wine 5613 ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n"); 5614 ok(defaulted == 0, "defaulted is set to TRUE\n"); 5615 } 5616 5617 static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping) 5618 { 5619 DWORD ret, granted, priv_set_len; 5620 BOOL status; 5621 PRIVILEGE_SET priv_set; 5622 SECURITY_DESCRIPTOR *sd; 5623 5624 sd = test_get_security_descriptor(handle, __LINE__); 5625 validate_default_security_descriptor(sd); 5626 5627 priv_set_len = sizeof(priv_set); 5628 granted = 0xdeadbeef; 5629 status = 0xdeadbeef; 5630 SetLastError(0xdeadbeef); 5631 ret = AccessCheck(sd, token, MAXIMUM_ALLOWED, mapping, &priv_set, &priv_set_len, &granted, &status); 5632 todo_wine { 5633 ok(ret, "AccessCheck error %d\n", GetLastError()); 5634 ok(status == 1, "expected 1, got %d\n", status); 5635 ok(granted == mapping->GenericAll, "expected all access %#x, got %#x\n", mapping->GenericAll, granted); 5636 } 5637 priv_set_len = sizeof(priv_set); 5638 granted = 0xdeadbeef; 5639 status = 0xdeadbeef; 5640 SetLastError(0xdeadbeef); 5641 ret = AccessCheck(sd, token, 0, mapping, &priv_set, &priv_set_len, &granted, &status); 5642 todo_wine { 5643 ok(ret, "AccessCheck error %d\n", GetLastError()); 5644 ok(status == 0 || broken(status == 1) /* NT4 */, "expected 0, got %d\n", status); 5645 ok(granted == 0 || broken(granted == mapping->GenericRead) /* NT4 */, "expected 0, got %#x\n", granted); 5646 } 5647 priv_set_len = sizeof(priv_set); 5648 granted = 0xdeadbeef; 5649 status = 0xdeadbeef; 5650 SetLastError(0xdeadbeef); 5651 ret = AccessCheck(sd, token, ACCESS_SYSTEM_SECURITY, mapping, &priv_set, &priv_set_len, &granted, &status); 5652 todo_wine { 5653 ok(ret, "AccessCheck error %d\n", GetLastError()); 5654 ok(status == 0, "expected 0, got %d\n", status); 5655 ok(granted == 0, "expected 0, got %#x\n", granted); 5656 } 5657 priv_set_len = sizeof(priv_set); 5658 granted = 0xdeadbeef; 5659 status = 0xdeadbeef; 5660 SetLastError(0xdeadbeef); 5661 ret = AccessCheck(sd, token, mapping->GenericRead, mapping, &priv_set, &priv_set_len, &granted, &status); 5662 todo_wine { 5663 ok(ret, "AccessCheck error %d\n", GetLastError()); 5664 ok(status == 1, "expected 1, got %d\n", status); 5665 ok(granted == mapping->GenericRead, "expected read access %#x, got %#x\n", mapping->GenericRead, granted); 5666 } 5667 priv_set_len = sizeof(priv_set); 5668 granted = 0xdeadbeef; 5669 status = 0xdeadbeef; 5670 SetLastError(0xdeadbeef); 5671 ret = AccessCheck(sd, token, mapping->GenericWrite, mapping, &priv_set, &priv_set_len, &granted, &status); 5672 todo_wine { 5673 ok(ret, "AccessCheck error %d\n", GetLastError()); 5674 ok(status == 1, "expected 1, got %d\n", status); 5675 ok(granted == mapping->GenericWrite, "expected write access %#x, got %#x\n", mapping->GenericWrite, granted); 5676 } 5677 priv_set_len = sizeof(priv_set); 5678 granted = 0xdeadbeef; 5679 status = 0xdeadbeef; 5680 SetLastError(0xdeadbeef); 5681 ret = AccessCheck(sd, token, mapping->GenericExecute, mapping, &priv_set, &priv_set_len, &granted, &status); 5682 todo_wine { 5683 ok(ret, "AccessCheck error %d\n", GetLastError()); 5684 ok(status == 1, "expected 1, got %d\n", status); 5685 ok(granted == mapping->GenericExecute, "expected execute access %#x, got %#x\n", mapping->GenericExecute, granted); 5686 } 5687 HeapFree(GetProcessHeap(), 0, sd); 5688 } 5689 5690 static ACCESS_MASK get_obj_access(HANDLE obj) 5691 { 5692 OBJECT_BASIC_INFORMATION info; 5693 NTSTATUS status; 5694 5695 if (!pNtQueryObject) return 0; 5696 5697 status = pNtQueryObject(obj, ObjectBasicInformation, &info, sizeof(info), NULL); 5698 ok(!status, "NtQueryObject error %#x\n", status); 5699 5700 return info.GrantedAccess; 5701 } 5702 5703 static void test_mutex_security(HANDLE token) 5704 { 5705 DWORD ret, i, access; 5706 HANDLE mutex, dup; 5707 GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE | SYNCHRONIZE, 5708 STANDARD_RIGHTS_WRITE | MUTEX_MODIFY_STATE | SYNCHRONIZE, 5709 STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, 5710 STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS }; 5711 static const struct 5712 { 5713 int generic, mapped; 5714 } map[] = 5715 { 5716 { 0, 0 }, 5717 { GENERIC_READ, STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE }, 5718 { GENERIC_WRITE, STANDARD_RIGHTS_WRITE }, 5719 { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE }, 5720 { GENERIC_ALL, STANDARD_RIGHTS_ALL | MUTANT_QUERY_STATE } 5721 }; 5722 5723 SetLastError(0xdeadbeef); 5724 mutex = OpenMutexA(0, FALSE, "WineTestMutex"); 5725 ok(!mutex, "mutex should not exist\n"); 5726 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); 5727 5728 SetLastError(0xdeadbeef); 5729 mutex = CreateMutexA(NULL, FALSE, "WineTestMutex"); 5730 ok(mutex != 0, "CreateMutex error %d\n", GetLastError()); 5731 5732 access = get_obj_access(mutex); 5733 ok(access == MUTANT_ALL_ACCESS, "expected MUTANT_ALL_ACCESS, got %#x\n", access); 5734 5735 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 5736 { 5737 SetLastError( 0xdeadbeef ); 5738 ret = DuplicateHandle(GetCurrentProcess(), mutex, GetCurrentProcess(), &dup, 5739 map[i].generic, FALSE, 0); 5740 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 5741 5742 access = get_obj_access(dup); 5743 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 5744 5745 CloseHandle(dup); 5746 5747 SetLastError(0xdeadbeef); 5748 dup = OpenMutexA(0, FALSE, "WineTestMutex"); 5749 todo_wine 5750 ok(!dup, "OpenMutex should fail\n"); 5751 todo_wine 5752 ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError()); 5753 } 5754 5755 test_default_handle_security(token, mutex, &mapping); 5756 5757 CloseHandle (mutex); 5758 } 5759 5760 static void test_event_security(HANDLE token) 5761 { 5762 DWORD ret, i, access; 5763 HANDLE event, dup; 5764 GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | EVENT_QUERY_STATE | SYNCHRONIZE, 5765 STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE | SYNCHRONIZE, 5766 STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, 5767 STANDARD_RIGHTS_ALL | EVENT_ALL_ACCESS }; 5768 static const struct 5769 { 5770 int generic, mapped; 5771 } map[] = 5772 { 5773 { 0, 0 }, 5774 { GENERIC_READ, STANDARD_RIGHTS_READ | EVENT_QUERY_STATE }, 5775 { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE }, 5776 { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE }, 5777 { GENERIC_ALL, STANDARD_RIGHTS_ALL | EVENT_QUERY_STATE | EVENT_MODIFY_STATE } 5778 }; 5779 5780 SetLastError(0xdeadbeef); 5781 event = OpenEventA(0, FALSE, "WineTestEvent"); 5782 ok(!event, "event should not exist\n"); 5783 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); 5784 5785 SetLastError(0xdeadbeef); 5786 event = CreateEventA(NULL, FALSE, FALSE, "WineTestEvent"); 5787 ok(event != 0, "CreateEvent error %d\n", GetLastError()); 5788 5789 access = get_obj_access(event); 5790 ok(access == EVENT_ALL_ACCESS, "expected EVENT_ALL_ACCESS, got %#x\n", access); 5791 5792 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 5793 { 5794 SetLastError( 0xdeadbeef ); 5795 ret = DuplicateHandle(GetCurrentProcess(), event, GetCurrentProcess(), &dup, 5796 map[i].generic, FALSE, 0); 5797 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 5798 5799 access = get_obj_access(dup); 5800 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 5801 5802 CloseHandle(dup); 5803 5804 SetLastError(0xdeadbeef); 5805 dup = OpenEventA(0, FALSE, "WineTestEvent"); 5806 todo_wine 5807 ok(!dup, "OpenEvent should fail\n"); 5808 todo_wine 5809 ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError()); 5810 } 5811 5812 test_default_handle_security(token, event, &mapping); 5813 5814 CloseHandle(event); 5815 } 5816 5817 static void test_semaphore_security(HANDLE token) 5818 { 5819 DWORD ret, i, access; 5820 HANDLE sem, dup; 5821 GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE, 5822 STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE, 5823 STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, 5824 STANDARD_RIGHTS_ALL | SEMAPHORE_ALL_ACCESS }; 5825 static const struct 5826 { 5827 int generic, mapped; 5828 } map[] = 5829 { 5830 { 0, 0 }, 5831 { GENERIC_READ, STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE }, 5832 { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE }, 5833 { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE }, 5834 { GENERIC_ALL, STANDARD_RIGHTS_ALL | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE } 5835 }; 5836 5837 SetLastError(0xdeadbeef); 5838 sem = OpenSemaphoreA(0, FALSE, "WineTestSemaphore"); 5839 ok(!sem, "semaphore should not exist\n"); 5840 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); 5841 5842 SetLastError(0xdeadbeef); 5843 sem = CreateSemaphoreA(NULL, 0, 10, "WineTestSemaphore"); 5844 ok(sem != 0, "CreateSemaphore error %d\n", GetLastError()); 5845 5846 access = get_obj_access(sem); 5847 ok(access == SEMAPHORE_ALL_ACCESS, "expected SEMAPHORE_ALL_ACCESS, got %#x\n", access); 5848 5849 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 5850 { 5851 SetLastError( 0xdeadbeef ); 5852 ret = DuplicateHandle(GetCurrentProcess(), sem, GetCurrentProcess(), &dup, 5853 map[i].generic, FALSE, 0); 5854 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 5855 5856 access = get_obj_access(dup); 5857 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 5858 5859 CloseHandle(dup); 5860 } 5861 5862 test_default_handle_security(token, sem, &mapping); 5863 5864 CloseHandle(sem); 5865 } 5866 5867 #define WINE_TEST_PIPE "\\\\.\\pipe\\WineTestPipe" 5868 static void test_named_pipe_security(HANDLE token) 5869 { 5870 DWORD ret, i, access; 5871 HANDLE pipe, file, dup; 5872 GENERIC_MAPPING mapping = { FILE_GENERIC_READ, 5873 FILE_GENERIC_WRITE, 5874 FILE_GENERIC_EXECUTE, 5875 STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }; 5876 static const struct 5877 { 5878 int todo, generic, mapped; 5879 } map[] = 5880 { 5881 { 0, 0, 0 }, 5882 { 1, GENERIC_READ, FILE_GENERIC_READ }, 5883 { 1, GENERIC_WRITE, FILE_GENERIC_WRITE }, 5884 { 1, GENERIC_EXECUTE, FILE_GENERIC_EXECUTE }, 5885 { 1, GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS } 5886 }; 5887 static const struct 5888 { 5889 DWORD open_mode; 5890 DWORD access; 5891 } creation_access[] = 5892 { 5893 { PIPE_ACCESS_INBOUND, FILE_GENERIC_READ }, 5894 { PIPE_ACCESS_OUTBOUND, FILE_GENERIC_WRITE }, 5895 { PIPE_ACCESS_DUPLEX, FILE_GENERIC_READ|FILE_GENERIC_WRITE }, 5896 { PIPE_ACCESS_INBOUND|WRITE_DAC, FILE_GENERIC_READ|WRITE_DAC }, 5897 { PIPE_ACCESS_INBOUND|WRITE_OWNER, FILE_GENERIC_READ|WRITE_OWNER } 5898 /* ACCESS_SYSTEM_SECURITY is also valid, but will fail with ERROR_PRIVILEGE_NOT_HELD */ 5899 }; 5900 5901 /* Test the different security access options for pipes */ 5902 for (i = 0; i < sizeof(creation_access)/sizeof(creation_access[0]); i++) 5903 { 5904 SetLastError(0xdeadbeef); 5905 pipe = CreateNamedPipeA(WINE_TEST_PIPE, creation_access[i].open_mode, 5906 PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, 5907 NMPWAIT_USE_DEFAULT_WAIT, NULL); 5908 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe(0x%x) error %d\n", 5909 creation_access[i].open_mode, GetLastError()); 5910 access = get_obj_access(pipe); 5911 ok(access == creation_access[i].access, 5912 "CreateNamedPipeA(0x%x) pipe expected access 0x%x (got 0x%x)\n", 5913 creation_access[i].open_mode, creation_access[i].access, access); 5914 CloseHandle(pipe); 5915 } 5916 5917 SetLastError(0xdeadbeef); 5918 pipe = CreateNamedPipeA(WINE_TEST_PIPE, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE, 5919 PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 5920 0, 0, NMPWAIT_USE_DEFAULT_WAIT, NULL); 5921 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe error %d\n", GetLastError()); 5922 5923 test_default_handle_security(token, pipe, &mapping); 5924 5925 SetLastError(0xdeadbeef); 5926 file = CreateFileA(WINE_TEST_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0); 5927 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 5928 5929 access = get_obj_access(file); 5930 ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access); 5931 5932 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 5933 { 5934 SetLastError( 0xdeadbeef ); 5935 ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, 5936 map[i].generic, FALSE, 0); 5937 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 5938 5939 access = get_obj_access(dup); 5940 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 5941 5942 CloseHandle(dup); 5943 } 5944 5945 CloseHandle(file); 5946 CloseHandle(pipe); 5947 5948 SetLastError(0xdeadbeef); 5949 file = CreateFileA("\\\\.\\pipe\\", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); 5950 ok(file != INVALID_HANDLE_VALUE || broken(file == INVALID_HANDLE_VALUE) /* before Vista */, "CreateFile error %d\n", GetLastError()); 5951 5952 if (file != INVALID_HANDLE_VALUE) 5953 { 5954 access = get_obj_access(file); 5955 ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access); 5956 5957 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 5958 { 5959 SetLastError( 0xdeadbeef ); 5960 ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, 5961 map[i].generic, FALSE, 0); 5962 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 5963 5964 access = get_obj_access(dup); 5965 todo_wine_if (map[i].todo) 5966 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 5967 5968 CloseHandle(dup); 5969 } 5970 } 5971 5972 CloseHandle(file); 5973 } 5974 5975 static void test_file_security(HANDLE token) 5976 { 5977 DWORD ret, i, access, bytes; 5978 HANDLE file, dup; 5979 static const struct 5980 { 5981 int generic, mapped; 5982 } map[] = 5983 { 5984 { 0, 0 }, 5985 { GENERIC_READ, FILE_GENERIC_READ }, 5986 { GENERIC_WRITE, FILE_GENERIC_WRITE }, 5987 { GENERIC_EXECUTE, FILE_GENERIC_EXECUTE }, 5988 { GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS } 5989 }; 5990 char temp_path[MAX_PATH]; 5991 char file_name[MAX_PATH]; 5992 char buf[16]; 5993 5994 GetTempPathA(MAX_PATH, temp_path); 5995 GetTempFileNameA(temp_path, "tmp", 0, file_name); 5996 5997 /* file */ 5998 SetLastError(0xdeadbeef); 5999 file = CreateFileA(file_name, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, 0, NULL); 6000 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 6001 6002 access = get_obj_access(file); 6003 ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access); 6004 6005 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 6006 { 6007 SetLastError( 0xdeadbeef ); 6008 ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, 6009 map[i].generic, FALSE, 0); 6010 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 6011 6012 access = get_obj_access(dup); 6013 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6014 6015 CloseHandle(dup); 6016 } 6017 6018 CloseHandle(file); 6019 6020 SetLastError(0xdeadbeef); 6021 file = CreateFileA(file_name, 0, 0, NULL, OPEN_EXISTING, 0, NULL); 6022 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 6023 6024 access = get_obj_access(file); 6025 todo_wine 6026 ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#x\n", access); 6027 6028 bytes = 0xdeadbeef; 6029 SetLastError(0xdeadbeef); 6030 ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL); 6031 ok(!ret, "ReadFile should fail\n"); 6032 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 6033 ok(bytes == 0, "expected 0, got %u\n", bytes); 6034 6035 CloseHandle(file); 6036 6037 SetLastError(0xdeadbeef); 6038 file = CreateFileA(file_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0); 6039 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 6040 6041 access = get_obj_access(file); 6042 todo_wine 6043 ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#x\n", access); 6044 6045 bytes = 0xdeadbeef; 6046 SetLastError(0xdeadbeef); 6047 ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL); 6048 ok(!ret, "ReadFile should fail\n"); 6049 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 6050 ok(bytes == 0, "expected 0, got %u\n", bytes); 6051 6052 CloseHandle(file); 6053 DeleteFileA(file_name); 6054 6055 /* directory */ 6056 SetLastError(0xdeadbeef); 6057 file = CreateFileA(temp_path, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); 6058 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 6059 6060 access = get_obj_access(file); 6061 ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#x\n", access); 6062 6063 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 6064 { 6065 SetLastError( 0xdeadbeef ); 6066 ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup, 6067 map[i].generic, FALSE, 0); 6068 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 6069 6070 access = get_obj_access(dup); 6071 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6072 6073 CloseHandle(dup); 6074 } 6075 6076 CloseHandle(file); 6077 6078 SetLastError(0xdeadbeef); 6079 file = CreateFileA(temp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); 6080 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 6081 6082 access = get_obj_access(file); 6083 todo_wine 6084 ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#x\n", access); 6085 6086 CloseHandle(file); 6087 6088 SetLastError(0xdeadbeef); 6089 file = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); 6090 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 6091 6092 access = get_obj_access(file); 6093 todo_wine 6094 ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#x\n", access); 6095 6096 CloseHandle(file); 6097 } 6098 6099 static void test_filemap_security(void) 6100 { 6101 char temp_path[MAX_PATH]; 6102 char file_name[MAX_PATH]; 6103 DWORD ret, i, access; 6104 HANDLE file, mapping, dup, created_mapping; 6105 static const struct 6106 { 6107 int generic, mapped; 6108 BOOL open_only; 6109 } map[] = 6110 { 6111 { 0, 0 }, 6112 { GENERIC_READ, STANDARD_RIGHTS_READ | SECTION_QUERY | SECTION_MAP_READ }, 6113 { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE }, 6114 { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE }, 6115 { GENERIC_ALL, STANDARD_RIGHTS_REQUIRED | SECTION_ALL_ACCESS }, 6116 { SECTION_MAP_READ | SECTION_MAP_WRITE, SECTION_MAP_READ | SECTION_MAP_WRITE }, 6117 { SECTION_MAP_WRITE, SECTION_MAP_WRITE }, 6118 { SECTION_MAP_READ | SECTION_QUERY, SECTION_MAP_READ | SECTION_QUERY }, 6119 { SECTION_QUERY, SECTION_MAP_READ, TRUE }, 6120 { SECTION_QUERY | SECTION_MAP_READ, SECTION_QUERY | SECTION_MAP_READ } 6121 }; 6122 static const struct 6123 { 6124 int prot, mapped; 6125 } prot_map[] = 6126 { 6127 { 0, 0 }, 6128 { PAGE_NOACCESS, 0 }, 6129 { PAGE_READONLY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ }, 6130 { PAGE_READWRITE, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE }, 6131 { PAGE_WRITECOPY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ }, 6132 { PAGE_EXECUTE, 0 }, 6133 { PAGE_EXECUTE_READ, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE }, 6134 { PAGE_EXECUTE_READWRITE, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE }, 6135 { PAGE_EXECUTE_WRITECOPY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE } 6136 }; 6137 6138 GetTempPathA(MAX_PATH, temp_path); 6139 GetTempFileNameA(temp_path, "tmp", 0, file_name); 6140 6141 SetLastError(0xdeadbeef); 6142 file = CreateFileA(file_name, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, NULL, CREATE_ALWAYS, 0, 0); 6143 ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError()); 6144 SetFilePointer(file, 4096, NULL, FILE_BEGIN); 6145 SetEndOfFile(file); 6146 6147 for (i = 0; i < sizeof(prot_map)/sizeof(prot_map[0]); i++) 6148 { 6149 if (map[i].open_only) continue; 6150 6151 SetLastError(0xdeadbeef); 6152 mapping = CreateFileMappingW(file, NULL, prot_map[i].prot, 0, 4096, NULL); 6153 if (prot_map[i].mapped) 6154 { 6155 if (!mapping) 6156 { 6157 /* NT4 and win2k don't support EXEC on file mappings */ 6158 if (prot_map[i].prot == PAGE_EXECUTE_READ || prot_map[i].prot == PAGE_EXECUTE_READWRITE || prot_map[i].prot == PAGE_EXECUTE_WRITECOPY) 6159 { 6160 win_skip("CreateFileMapping doesn't support PAGE_EXECUTE protection\n"); 6161 continue; 6162 } 6163 } 6164 ok(mapping != 0, "CreateFileMapping(%04x) error %d\n", prot_map[i].prot, GetLastError()); 6165 } 6166 else 6167 { 6168 ok(!mapping, "CreateFileMapping(%04x) should fail\n", prot_map[i].prot); 6169 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 6170 continue; 6171 } 6172 6173 access = get_obj_access(mapping); 6174 ok(access == prot_map[i].mapped, "%d: expected %#x, got %#x\n", i, prot_map[i].mapped, access); 6175 6176 CloseHandle(mapping); 6177 } 6178 6179 SetLastError(0xdeadbeef); 6180 mapping = CreateFileMappingW(file, NULL, PAGE_EXECUTE_READWRITE, 0, 4096, NULL); 6181 if (!mapping) 6182 { 6183 /* NT4 and win2k don't support EXEC on file mappings */ 6184 win_skip("CreateFileMapping doesn't support PAGE_EXECUTE protection\n"); 6185 CloseHandle(file); 6186 DeleteFileA(file_name); 6187 return; 6188 } 6189 ok(mapping != 0, "CreateFileMapping error %d\n", GetLastError()); 6190 6191 access = get_obj_access(mapping); 6192 ok(access == (STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE), 6193 "expected STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, got %#x\n", access); 6194 6195 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 6196 { 6197 if (map[i].open_only) continue; 6198 6199 SetLastError( 0xdeadbeef ); 6200 ret = DuplicateHandle(GetCurrentProcess(), mapping, GetCurrentProcess(), &dup, 6201 map[i].generic, FALSE, 0); 6202 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 6203 6204 access = get_obj_access(dup); 6205 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6206 6207 CloseHandle(dup); 6208 } 6209 6210 CloseHandle(mapping); 6211 CloseHandle(file); 6212 DeleteFileA(file_name); 6213 6214 created_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000, 6215 "Wine Test Open Mapping"); 6216 ok(created_mapping != NULL, "CreateFileMapping failed with error %u\n", GetLastError()); 6217 6218 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 6219 { 6220 if (!map[i].generic) continue; 6221 6222 mapping = OpenFileMappingA(map[i].generic, FALSE, "Wine Test Open Mapping"); 6223 ok(mapping != NULL, "OpenFileMapping failed with error %d\n", GetLastError()); 6224 access = get_obj_access(mapping); 6225 ok(access == map[i].mapped, "%d: unexpected access flags %#x, expected %#x\n", 6226 i, access, map[i].mapped); 6227 CloseHandle(mapping); 6228 } 6229 6230 CloseHandle(created_mapping); 6231 } 6232 6233 static void test_thread_security(void) 6234 { 6235 DWORD ret, i, access; 6236 HANDLE thread, dup; 6237 static const struct 6238 { 6239 int generic, mapped; 6240 } map[] = 6241 { 6242 { 0, 0 }, 6243 { GENERIC_READ, STANDARD_RIGHTS_READ | THREAD_QUERY_INFORMATION | THREAD_GET_CONTEXT }, 6244 { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT | THREAD_TERMINATE | THREAD_SUSPEND_RESUME | 0x4 }, 6245 { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE }, 6246 { GENERIC_ALL, THREAD_ALL_ACCESS_NT4 } 6247 }; 6248 6249 SetLastError(0xdeadbeef); 6250 thread = CreateThread(NULL, 0, (void *)0xdeadbeef, NULL, CREATE_SUSPENDED, &ret); 6251 ok(thread != 0, "CreateThread error %d\n", GetLastError()); 6252 6253 access = get_obj_access(thread); 6254 ok(access == THREAD_ALL_ACCESS_NT4 || access == THREAD_ALL_ACCESS_VISTA, "expected THREAD_ALL_ACCESS, got %#x\n", access); 6255 6256 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 6257 { 6258 SetLastError( 0xdeadbeef ); 6259 ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup, 6260 map[i].generic, FALSE, 0); 6261 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 6262 6263 access = get_obj_access(dup); 6264 switch (map[i].generic) 6265 { 6266 case GENERIC_READ: 6267 case GENERIC_EXECUTE: 6268 ok(access == map[i].mapped || 6269 access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ || 6270 access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */, 6271 "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6272 break; 6273 case GENERIC_WRITE: 6274 todo_wine 6275 ok(access == map[i].mapped || 6276 access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION) /* Vista+ */ || 6277 access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */, 6278 "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6279 break; 6280 case GENERIC_ALL: 6281 ok(access == map[i].mapped || access == THREAD_ALL_ACCESS_VISTA, 6282 "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6283 break; 6284 default: 6285 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6286 break; 6287 } 6288 6289 CloseHandle(dup); 6290 } 6291 6292 SetLastError( 0xdeadbeef ); 6293 ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup, 6294 THREAD_QUERY_INFORMATION, FALSE, 0); 6295 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 6296 access = get_obj_access(dup); 6297 ok(access == (THREAD_QUERY_INFORMATION | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ || 6298 access == THREAD_QUERY_INFORMATION /* before Vista */, 6299 "expected THREAD_QUERY_INFORMATION|THREAD_QUERY_LIMITED_INFORMATION, got %#x\n", access); 6300 CloseHandle(dup); 6301 6302 TerminateThread(thread, 0); 6303 CloseHandle(thread); 6304 } 6305 6306 static void test_process_access(void) 6307 { 6308 DWORD ret, i, access; 6309 HANDLE process, dup; 6310 STARTUPINFOA sti; 6311 PROCESS_INFORMATION pi; 6312 char cmdline[] = "winver.exe"; 6313 static const struct 6314 { 6315 int generic, mapped; 6316 } map[] = 6317 { 6318 { 0, 0 }, 6319 { GENERIC_READ, STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ }, 6320 { GENERIC_WRITE, STANDARD_RIGHTS_WRITE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME | 6321 PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION }, 6322 { GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE }, 6323 { GENERIC_ALL, PROCESS_ALL_ACCESS_NT4 } 6324 }; 6325 6326 memset(&sti, 0, sizeof(sti)); 6327 sti.cb = sizeof(sti); 6328 SetLastError(0xdeadbeef); 6329 ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sti, &pi); 6330 ok(ret, "CreateProcess() error %d\n", GetLastError()); 6331 6332 CloseHandle(pi.hThread); 6333 process = pi.hProcess; 6334 6335 access = get_obj_access(process); 6336 ok(access == PROCESS_ALL_ACCESS_NT4 || access == PROCESS_ALL_ACCESS_VISTA, "expected PROCESS_ALL_ACCESS, got %#x\n", access); 6337 6338 for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) 6339 { 6340 SetLastError( 0xdeadbeef ); 6341 ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup, 6342 map[i].generic, FALSE, 0); 6343 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 6344 6345 access = get_obj_access(dup); 6346 switch (map[i].generic) 6347 { 6348 case GENERIC_READ: 6349 ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */, 6350 "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6351 break; 6352 case GENERIC_WRITE: 6353 ok(access == map[i].mapped || 6354 access == (map[i].mapped | PROCESS_TERMINATE) /* before Vista */ || 6355 access == (map[i].mapped | PROCESS_SET_LIMITED_INFORMATION) /* win8 */ || 6356 access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SET_LIMITED_INFORMATION) /* Win10 Anniversary Update */, 6357 "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6358 break; 6359 case GENERIC_EXECUTE: 6360 ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE) /* Vista+ */, 6361 "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6362 break; 6363 case GENERIC_ALL: 6364 ok(access == map[i].mapped || access == PROCESS_ALL_ACCESS_VISTA, 6365 "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6366 break; 6367 default: 6368 ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); 6369 break; 6370 } 6371 6372 CloseHandle(dup); 6373 } 6374 6375 SetLastError( 0xdeadbeef ); 6376 ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup, 6377 PROCESS_QUERY_INFORMATION, FALSE, 0); 6378 ok(ret, "DuplicateHandle error %d\n", GetLastError()); 6379 access = get_obj_access(dup); 6380 ok(access == (PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */ || 6381 access == PROCESS_QUERY_INFORMATION /* before Vista */, 6382 "expected PROCESS_QUERY_INFORMATION|PROCESS_QUERY_LIMITED_INFORMATION, got %#x\n", access); 6383 CloseHandle(dup); 6384 6385 TerminateProcess(process, 0); 6386 CloseHandle(process); 6387 } 6388 6389 static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type) 6390 { 6391 DWORD ret, needed; 6392 TOKEN_TYPE type; 6393 SECURITY_IMPERSONATION_LEVEL sil; 6394 6395 type = 0xdeadbeef; 6396 needed = 0; 6397 SetLastError(0xdeadbeef); 6398 ret = GetTokenInformation(token, TokenType, &type, sizeof(type), &needed); 6399 ok(ret, "GetTokenInformation error %d\n", GetLastError()); 6400 ok(needed == sizeof(type), "GetTokenInformation should return required buffer length\n"); 6401 ok(type == TokenPrimary || type == TokenImpersonation, "expected TokenPrimary or TokenImpersonation, got %d\n", type); 6402 6403 *token_type = type; 6404 if (type != TokenImpersonation) return FALSE; 6405 6406 needed = 0; 6407 SetLastError(0xdeadbeef); 6408 ret = GetTokenInformation(token, TokenImpersonationLevel, &sil, sizeof(sil), &needed); 6409 ok(ret, "GetTokenInformation error %d\n", GetLastError()); 6410 ok(needed == sizeof(sil), "GetTokenInformation should return required buffer length\n"); 6411 ok(sil == SecurityImpersonation, "expected SecurityImpersonation, got %d\n", sil); 6412 6413 needed = 0xdeadbeef; 6414 SetLastError(0xdeadbeef); 6415 ret = GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &needed); 6416 ok(!ret, "GetTokenInformation should fail\n"); 6417 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 6418 ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n"); 6419 ok(needed > sizeof(TOKEN_DEFAULT_DACL), "GetTokenInformation returned empty default DACL\n"); 6420 6421 needed = 0xdeadbeef; 6422 SetLastError(0xdeadbeef); 6423 ret = GetTokenInformation(token, TokenOwner, NULL, 0, &needed); 6424 ok(!ret, "GetTokenInformation should fail\n"); 6425 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 6426 ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n"); 6427 ok(needed > sizeof(TOKEN_OWNER), "GetTokenInformation returned empty token owner\n"); 6428 6429 needed = 0xdeadbeef; 6430 SetLastError(0xdeadbeef); 6431 ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &needed); 6432 ok(!ret, "GetTokenInformation should fail\n"); 6433 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 6434 ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n"); 6435 ok(needed > sizeof(TOKEN_PRIMARY_GROUP), "GetTokenInformation returned empty token primary group\n"); 6436 6437 return TRUE; 6438 } 6439 6440 static void test_kernel_objects_security(void) 6441 { 6442 HANDLE token, process_token; 6443 DWORD ret, token_type; 6444 6445 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token); 6446 ok(ret, "OpenProcessToken error %d\n", GetLastError()); 6447 6448 ret = validate_impersonation_token(process_token, &token_type); 6449 ok(token_type == TokenPrimary, "expected TokenPrimary, got %d\n", token_type); 6450 ok(!ret, "access token should not be an impersonation token\n"); 6451 6452 ret = DuplicateToken(process_token, SecurityImpersonation, &token); 6453 ok(ret, "DuplicateToken error %d\n", GetLastError()); 6454 6455 ret = validate_impersonation_token(token, &token_type); 6456 ok(ret, "access token should be a valid impersonation token\n"); 6457 ok(token_type == TokenImpersonation, "expected TokenImpersonation, got %d\n", token_type); 6458 6459 test_mutex_security(token); 6460 test_event_security(token); 6461 test_named_pipe_security(token); 6462 test_semaphore_security(token); 6463 test_file_security(token); 6464 test_filemap_security(); 6465 test_thread_security(); 6466 test_process_access(); 6467 /* FIXME: test other kernel object types */ 6468 6469 CloseHandle(process_token); 6470 CloseHandle(token); 6471 } 6472 6473 static void test_TokenIntegrityLevel(void) 6474 { 6475 TOKEN_MANDATORY_LABEL *tml; 6476 BYTE buffer[64]; /* using max. 28 byte in win7 x64 */ 6477 HANDLE token; 6478 DWORD size; 6479 DWORD res; 6480 static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 6481 {SECURITY_MANDATORY_HIGH_RID}}; 6482 static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 6483 {SECURITY_MANDATORY_MEDIUM_RID}}; 6484 6485 SetLastError(0xdeadbeef); 6486 res = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); 6487 ok(res, "got %d with %d (expected TRUE)\n", res, GetLastError()); 6488 6489 SetLastError(0xdeadbeef); 6490 res = GetTokenInformation(token, TokenIntegrityLevel, buffer, sizeof(buffer), &size); 6491 6492 /* not supported before Vista */ 6493 if (!res && ((GetLastError() == ERROR_INVALID_PARAMETER) || GetLastError() == ERROR_INVALID_FUNCTION)) 6494 { 6495 win_skip("TokenIntegrityLevel not supported\n"); 6496 CloseHandle(token); 6497 return; 6498 } 6499 6500 ok(res, "got %u with %u (expected TRUE)\n", res, GetLastError()); 6501 if (!res) 6502 { 6503 CloseHandle(token); 6504 return; 6505 } 6506 6507 tml = (TOKEN_MANDATORY_LABEL*) buffer; 6508 ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED), 6509 "got 0x%x (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED)); 6510 6511 ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), 6512 "got %s (expected %s or %s)\n", debugstr_sid(tml->Label.Sid), 6513 debugstr_sid(&medium_level), debugstr_sid(&high_level)); 6514 6515 CloseHandle(token); 6516 } 6517 6518 static void test_default_dacl_owner_sid(void) 6519 { 6520 HANDLE handle; 6521 BOOL ret, defaulted, present, found; 6522 DWORD size, index; 6523 SECURITY_DESCRIPTOR *sd; 6524 SECURITY_ATTRIBUTES sa; 6525 PSID owner; 6526 ACL *dacl; 6527 ACCESS_ALLOWED_ACE *ace; 6528 6529 sd = HeapAlloc( GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH ); 6530 ret = InitializeSecurityDescriptor( sd, SECURITY_DESCRIPTOR_REVISION ); 6531 ok( ret, "error %u\n", GetLastError() ); 6532 6533 sa.nLength = sizeof(SECURITY_ATTRIBUTES); 6534 sa.lpSecurityDescriptor = sd; 6535 sa.bInheritHandle = FALSE; 6536 handle = CreateEventA( &sa, TRUE, TRUE, "test_event" ); 6537 ok( handle != NULL, "error %u\n", GetLastError() ); 6538 6539 size = 0; 6540 ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &size ); 6541 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "error %u\n", GetLastError() ); 6542 6543 sd = HeapAlloc( GetProcessHeap(), 0, size ); 6544 ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, sd, size, &size ); 6545 ok( ret, "error %u\n", GetLastError() ); 6546 6547 owner = (void *)0xdeadbeef; 6548 defaulted = TRUE; 6549 ret = GetSecurityDescriptorOwner( sd, &owner, &defaulted ); 6550 ok( ret, "error %u\n", GetLastError() ); 6551 ok( owner != (void *)0xdeadbeef, "owner not set\n" ); 6552 ok( !defaulted, "owner defaulted\n" ); 6553 6554 dacl = (void *)0xdeadbeef; 6555 present = FALSE; 6556 defaulted = TRUE; 6557 ret = GetSecurityDescriptorDacl( sd, &present, &dacl, &defaulted ); 6558 ok( ret, "error %u\n", GetLastError() ); 6559 ok( present, "dacl not present\n" ); 6560 ok( dacl != (void *)0xdeadbeef, "dacl not set\n" ); 6561 ok( !defaulted, "dacl defaulted\n" ); 6562 6563 index = 0; 6564 found = FALSE; 6565 while (pGetAce( dacl, index++, (void **)&ace )) 6566 { 6567 if (EqualSid( &ace->SidStart, owner )) found = TRUE; 6568 } 6569 ok( found, "owner sid not found in dacl\n" ); 6570 6571 HeapFree( GetProcessHeap(), 0, sa.lpSecurityDescriptor ); 6572 HeapFree( GetProcessHeap(), 0, sd ); 6573 CloseHandle( handle ); 6574 } 6575 6576 static void test_AdjustTokenPrivileges(void) 6577 { 6578 TOKEN_PRIVILEGES tp; 6579 HANDLE token; 6580 DWORD len; 6581 LUID luid; 6582 BOOL ret; 6583 6584 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) 6585 return; 6586 6587 if (!LookupPrivilegeValueA(NULL, SE_BACKUP_NAME, &luid)) 6588 { 6589 CloseHandle(token); 6590 return; 6591 } 6592 6593 tp.PrivilegeCount = 1; 6594 tp.Privileges[0].Luid = luid; 6595 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 6596 6597 len = 0xdeadbeef; 6598 ret = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, &len); 6599 ok(ret, "got %d\n", ret); 6600 ok(len == 0xdeadbeef, "got length %d\n", len); 6601 6602 /* revert */ 6603 tp.PrivilegeCount = 1; 6604 tp.Privileges[0].Luid = luid; 6605 tp.Privileges[0].Attributes = 0; 6606 ret = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); 6607 ok(ret, "got %d\n", ret); 6608 6609 CloseHandle(token); 6610 } 6611 6612 static void test_AddAce(void) 6613 { 6614 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } }; 6615 6616 char acl_buf[1024], ace_buf[256]; 6617 ACCESS_ALLOWED_ACE *ace = (ACCESS_ALLOWED_ACE*)ace_buf; 6618 PACL acl = (PACL)acl_buf; 6619 BOOL ret; 6620 6621 memset(ace, 0, sizeof(ace_buf)); 6622 ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; 6623 ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)+sizeof(SID); 6624 memcpy(&ace->SidStart, &sidWorld, sizeof(sidWorld)); 6625 6626 ret = InitializeAcl(acl, sizeof(acl_buf), ACL_REVISION2); 6627 ok(ret, "InitializeAcl failed: %d\n", GetLastError()); 6628 6629 ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize); 6630 ok(ret, "AddAce failed: %d\n", GetLastError()); 6631 ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize); 6632 ok(ret, "AddAce failed: %d\n", GetLastError()); 6633 ret = AddAce(acl, ACL_REVISION3, MAXDWORD, ace, ace->Header.AceSize); 6634 ok(ret, "AddAce failed: %d\n", GetLastError()); 6635 ok(acl->AclRevision == ACL_REVISION3, "acl->AclRevision = %d\n", acl->AclRevision); 6636 ret = AddAce(acl, ACL_REVISION4, MAXDWORD, ace, ace->Header.AceSize); 6637 ok(ret, "AddAce failed: %d\n", GetLastError()); 6638 ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision); 6639 ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize); 6640 ok(ret, "AddAce failed: %d\n", GetLastError()); 6641 ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision); 6642 ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize); 6643 ok(ret, "AddAce failed: %d\n", GetLastError()); 6644 6645 ret = AddAce(acl, MIN_ACL_REVISION-1, MAXDWORD, ace, ace->Header.AceSize); 6646 ok(ret, "AddAce failed: %d\n", GetLastError()); 6647 /* next test succeededs but corrupts ACL */ 6648 ret = AddAce(acl, MAX_ACL_REVISION+1, MAXDWORD, ace, ace->Header.AceSize); 6649 ok(ret, "AddAce failed: %d\n", GetLastError()); 6650 ok(acl->AclRevision == MAX_ACL_REVISION+1, "acl->AclRevision = %d\n", acl->AclRevision); 6651 SetLastError(0xdeadbeef); 6652 ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize); 6653 ok(!ret, "AddAce succeeded\n"); 6654 ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %d\n", GetLastError()); 6655 } 6656 6657 static void test_AddMandatoryAce(void) 6658 { 6659 static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 6660 {SECURITY_MANDATORY_LOW_RID}}; 6661 static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 6662 {SECURITY_MANDATORY_MEDIUM_RID}}; 6663 static SID_IDENTIFIER_AUTHORITY sia_world = {SECURITY_WORLD_SID_AUTHORITY}; 6664 char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; 6665 SECURITY_DESCRIPTOR *sd2, *sd = (SECURITY_DESCRIPTOR *)&buffer_sd; 6666 BOOL defaulted, present, ret, found, found2; 6667 ACL_SIZE_INFORMATION acl_size_info; 6668 SYSTEM_MANDATORY_LABEL_ACE *ace; 6669 char buffer_acl[256]; 6670 ACL *acl = (ACL *)&buffer_acl; 6671 SECURITY_ATTRIBUTES sa; 6672 DWORD index, size; 6673 HANDLE handle; 6674 SID *everyone; 6675 ACL *sacl; 6676 6677 if (!pAddMandatoryAce) 6678 { 6679 win_skip("AddMandatoryAce not supported, skipping test\n"); 6680 return; 6681 } 6682 6683 ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); 6684 ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); 6685 6686 sa.nLength = sizeof(sa); 6687 sa.lpSecurityDescriptor = sd; 6688 sa.bInheritHandle = FALSE; 6689 6690 handle = CreateEventA(&sa, TRUE, TRUE, "test_event"); 6691 ok(handle != NULL, "CreateEventA failed with error %u\n", GetLastError()); 6692 6693 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 6694 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 6695 "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); 6696 6697 sd2 = HeapAlloc(GetProcessHeap(), 0, size); 6698 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); 6699 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 6700 6701 sacl = (void *)0xdeadbeef; 6702 present = TRUE; 6703 ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); 6704 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6705 ok(!present, "SACL is present\n"); 6706 ok(sacl == (void *)0xdeadbeef, "SACL is set\n"); 6707 6708 HeapFree(GetProcessHeap(), 0, sd2); 6709 CloseHandle(handle); 6710 6711 memset(buffer_acl, 0, sizeof(buffer_acl)); 6712 ret = InitializeAcl(acl, 256, ACL_REVISION); 6713 ok(ret, "InitializeAcl failed with %u\n", GetLastError()); 6714 6715 SetLastError(0xdeadbeef); 6716 ret = pAddMandatoryAce(acl, ACL_REVISION, 0, 0x1234, &low_level); 6717 ok(!ret, "AddMandatoryAce succeeded\n"); 6718 ok(GetLastError() == ERROR_INVALID_PARAMETER, 6719 "Expected ERROR_INVALID_PARAMETER got %u\n", GetLastError()); 6720 6721 ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level); 6722 ok(ret, "AddMandatoryAce failed with %u\n", GetLastError()); 6723 6724 index = 0; 6725 found = FALSE; 6726 while (pGetAce(acl, index++, (void **)&ace)) 6727 { 6728 if (ace->Header.AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue; 6729 ok(ace->Header.AceFlags == 0, "Expected flags 0, got %x\n", ace->Header.AceFlags); 6730 ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, 6731 "Expected mask SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, got %x\n", ace->Mask); 6732 ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n"); 6733 found = TRUE; 6734 } 6735 ok(found, "Could not find mandatory label ace\n"); 6736 6737 ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE); 6738 ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6739 6740 handle = CreateEventA(&sa, TRUE, TRUE, "test_event"); 6741 ok(handle != NULL, "CreateEventA failed with error %u\n", GetLastError()); 6742 6743 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 6744 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 6745 "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); 6746 6747 sd2 = HeapAlloc(GetProcessHeap(), 0, size); 6748 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); 6749 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 6750 6751 sacl = (void *)0xdeadbeef; 6752 present = FALSE; 6753 defaulted = TRUE; 6754 ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); 6755 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6756 ok(present, "SACL not present\n"); 6757 ok(sacl != (void *)0xdeadbeef, "SACL not set\n"); 6758 ok(!defaulted, "SACL defaulted\n"); 6759 ret = pGetAclInformation(sacl, &acl_size_info, sizeof(acl_size_info), AclSizeInformation); 6760 ok(ret, "GetAclInformation failed with error %u\n", GetLastError()); 6761 ok(acl_size_info.AceCount == 1, "SACL contains an unexpected ACE count %u\n", acl_size_info.AceCount); 6762 6763 ret = pGetAce(sacl, 0, (void **)&ace); 6764 ok(ret, "GetAce failed with error %u\n", GetLastError()); 6765 ok (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType); 6766 ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags); 6767 ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#x\n", ace->Mask); 6768 ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n"); 6769 6770 HeapFree(GetProcessHeap(), 0, sd2); 6771 6772 ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level); 6773 ok(ret, "AddMandatoryAce failed with error %u\n", GetLastError()); 6774 6775 ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd); 6776 ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); 6777 6778 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 6779 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 6780 "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); 6781 6782 sd2 = HeapAlloc(GetProcessHeap(), 0, size); 6783 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); 6784 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 6785 6786 sacl = (void *)0xdeadbeef; 6787 present = FALSE; 6788 defaulted = TRUE; 6789 ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); 6790 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6791 ok(present, "SACL not present\n"); 6792 ok(sacl != (void *)0xdeadbeef, "SACL not set\n"); 6793 ok(sacl->AceCount == 2, "Expected 2 ACEs, got %d\n", sacl->AceCount); 6794 ok(!defaulted, "SACL defaulted\n"); 6795 6796 index = 0; 6797 found = found2 = FALSE; 6798 while (pGetAce(sacl, index++, (void **)&ace)) 6799 { 6800 if (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE) 6801 { 6802 if (EqualSid(&ace->SidStart, &low_level)) 6803 { 6804 found = TRUE; 6805 ok(!ace->Header.AceFlags, "Expected 0 as flags, got %#x\n", ace->Header.AceFlags); 6806 ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, 6807 "Expected SYSTEM_MANDATORY_LABEL_NO_WRITE_UP as mask, got %#x\n", ace->Mask); 6808 } 6809 if (EqualSid(&ace->SidStart, &medium_level)) 6810 { 6811 found2 = TRUE; 6812 ok(!ace->Header.AceFlags, "Expected 0 as flags, got %#x\n", ace->Header.AceFlags); 6813 ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, 6814 "Expected SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP as mask, got %#x\n", ace->Mask); 6815 } 6816 } 6817 } 6818 ok(found, "Could not find low mandatory label\n"); 6819 ok(found2, "Could not find medium mandatory label\n"); 6820 6821 HeapFree(GetProcessHeap(), 0, sd2); 6822 6823 ret = SetSecurityDescriptorSacl(sd, FALSE, NULL, FALSE); 6824 ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6825 6826 ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd); 6827 ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); 6828 6829 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 6830 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 6831 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 6832 6833 sd2 = HeapAlloc(GetProcessHeap(), 0, size); 6834 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); 6835 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 6836 6837 sacl = (void *)0xdeadbeef; 6838 present = FALSE; 6839 defaulted = TRUE; 6840 ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); 6841 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6842 ok(present, "SACL not present\n"); 6843 ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n"); 6844 ok(!defaulted, "SACL defaulted\n"); 6845 ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount); 6846 6847 HeapFree(GetProcessHeap(), 0, sd2); 6848 6849 ret = InitializeAcl(acl, 256, ACL_REVISION); 6850 ok(ret, "InitializeAcl failed with error %u\n", GetLastError()); 6851 6852 ret = pAddMandatoryAce(acl, ACL_REVISION3, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level); 6853 ok(ret, "AddMandatoryAce failed with error %u\n", GetLastError()); 6854 6855 ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE); 6856 ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6857 6858 ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd); 6859 ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); 6860 6861 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 6862 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 6863 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 6864 6865 sd2 = HeapAlloc(GetProcessHeap(), 0, size); 6866 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); 6867 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 6868 6869 sacl = (void *)0xdeadbeef; 6870 present = FALSE; 6871 defaulted = TRUE; 6872 ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); 6873 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6874 ok(present, "SACL not present\n"); 6875 ok(sacl != (void *)0xdeadbeef, "SACL not set\n"); 6876 ok(sacl->AclRevision == ACL_REVISION3, "Expected revision 3, got %d\n", sacl->AclRevision); 6877 ok(!defaulted, "SACL defaulted\n"); 6878 6879 HeapFree(GetProcessHeap(), 0, sd2); 6880 6881 ret = InitializeAcl(acl, 256, ACL_REVISION); 6882 ok(ret, "InitializeAcl failed with error %u\n", GetLastError()); 6883 6884 ret = AllocateAndInitializeSid(&sia_world, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, (void **)&everyone); 6885 ok(ret, "AllocateAndInitializeSid failed with error %u\n", GetLastError()); 6886 6887 ret = AddAccessAllowedAce(acl, ACL_REVISION, KEY_READ, everyone); 6888 ok(ret, "AddAccessAllowedAce failed with error %u\n", GetLastError()); 6889 6890 ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE); 6891 ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6892 6893 ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd); 6894 ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); 6895 6896 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 6897 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 6898 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 6899 6900 sd2 = HeapAlloc(GetProcessHeap(), 0, size); 6901 ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size); 6902 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 6903 6904 sacl = (void *)0xdeadbeef; 6905 present = FALSE; 6906 defaulted = TRUE; 6907 ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted); 6908 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 6909 ok(present, "SACL not present\n"); 6910 ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n"); 6911 ok(!defaulted, "SACL defaulted\n"); 6912 ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount); 6913 6914 FreeSid(everyone); 6915 HeapFree(GetProcessHeap(), 0, sd2); 6916 CloseHandle(handle); 6917 } 6918 6919 static void test_system_security_access(void) 6920 { 6921 static const WCHAR testkeyW[] = 6922 {'S','O','F','T','W','A','R','E','\\','W','i','n','e','\\','S','A','C','L','t','e','s','t',0}; 6923 LONG res; 6924 HKEY hkey; 6925 PSECURITY_DESCRIPTOR sd; 6926 ACL *sacl; 6927 DWORD err, len = 128; 6928 TOKEN_PRIVILEGES priv, *priv_prev; 6929 HANDLE token; 6930 LUID luid; 6931 BOOL ret; 6932 6933 if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token )) return; 6934 if (!LookupPrivilegeValueA( NULL, SE_SECURITY_NAME, &luid )) 6935 { 6936 CloseHandle( token ); 6937 return; 6938 } 6939 6940 /* ACCESS_SYSTEM_SECURITY requires special privilege */ 6941 res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ|ACCESS_SYSTEM_SECURITY, NULL, &hkey, NULL ); 6942 if (res == ERROR_ACCESS_DENIED) 6943 { 6944 skip( "unprivileged user\n" ); 6945 CloseHandle( token ); 6946 return; 6947 } 6948 todo_wine ok( res == ERROR_PRIVILEGE_NOT_HELD, "got %d\n", res ); 6949 6950 priv.PrivilegeCount = 1; 6951 priv.Privileges[0].Luid = luid; 6952 priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 6953 6954 priv_prev = HeapAlloc( GetProcessHeap(), 0, len ); 6955 ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len ); 6956 ok( ret, "got %u\n", GetLastError()); 6957 6958 res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ|ACCESS_SYSTEM_SECURITY, NULL, &hkey, NULL ); 6959 if (res == ERROR_PRIVILEGE_NOT_HELD) 6960 { 6961 win_skip( "privilege not held\n" ); 6962 HeapFree( GetProcessHeap(), 0, priv_prev ); 6963 CloseHandle( token ); 6964 return; 6965 } 6966 ok( !res, "got %d\n", res ); 6967 6968 /* restore privileges */ 6969 ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL ); 6970 ok( ret, "got %u\n", GetLastError() ); 6971 HeapFree( GetProcessHeap(), 0, priv_prev ); 6972 6973 /* privilege is checked on access */ 6974 err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd ); 6975 todo_wine ok( err == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", err ); 6976 if (err == ERROR_SUCCESS) 6977 LocalFree( sd ); 6978 6979 priv.PrivilegeCount = 1; 6980 priv.Privileges[0].Luid = luid; 6981 priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 6982 6983 priv_prev = HeapAlloc( GetProcessHeap(), 0, len ); 6984 ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len ); 6985 ok( ret, "got %u\n", GetLastError()); 6986 6987 err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd ); 6988 ok( err == ERROR_SUCCESS, "got %u\n", err ); 6989 RegCloseKey( hkey ); 6990 LocalFree( sd ); 6991 6992 /* handle created without ACCESS_SYSTEM_SECURITY, privilege held */ 6993 res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL ); 6994 ok( res == ERROR_SUCCESS, "got %d\n", res ); 6995 6996 sd = NULL; 6997 err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd ); 6998 todo_wine ok( err == ERROR_SUCCESS, "got %u\n", err ); 6999 RegCloseKey( hkey ); 7000 LocalFree( sd ); 7001 7002 /* restore privileges */ 7003 ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL ); 7004 ok( ret, "got %u\n", GetLastError() ); 7005 HeapFree( GetProcessHeap(), 0, priv_prev ); 7006 7007 /* handle created without ACCESS_SYSTEM_SECURITY, privilege not held */ 7008 res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL ); 7009 ok( res == ERROR_SUCCESS, "got %d\n", res ); 7010 7011 err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd ); 7012 todo_wine ok( err == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", err ); 7013 RegCloseKey( hkey ); 7014 7015 res = RegDeleteKeyW( HKEY_LOCAL_MACHINE, testkeyW ); 7016 ok( !res, "got %d\n", res ); 7017 CloseHandle( token ); 7018 } 7019 7020 static void test_GetWindowsAccountDomainSid(void) 7021 { 7022 char *user, buffer1[SECURITY_MAX_SID_SIZE], buffer2[SECURITY_MAX_SID_SIZE]; 7023 SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY }; 7024 PSID domain_sid = (PSID *)&buffer1; 7025 PSID domain_sid2 = (PSID *)&buffer2; 7026 DWORD sid_size; 7027 PSID user_sid; 7028 HANDLE token; 7029 BOOL bret = TRUE; 7030 int i; 7031 7032 if (!pGetWindowsAccountDomainSid) 7033 { 7034 win_skip("GetWindowsAccountDomainSid not available\n"); 7035 return; 7036 } 7037 7038 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token)) 7039 { 7040 if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE; 7041 else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE; 7042 } 7043 if (!bret) 7044 { 7045 win_skip("Failed to get current user token\n"); 7046 return; 7047 } 7048 7049 bret = GetTokenInformation(token, TokenUser, NULL, 0, &sid_size); 7050 ok(!bret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7051 "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 7052 user = HeapAlloc(GetProcessHeap(), 0, sid_size); 7053 bret = GetTokenInformation(token, TokenUser, user, sid_size, &sid_size); 7054 ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError()); 7055 CloseHandle(token); 7056 user_sid = ((TOKEN_USER *)user)->User.Sid; 7057 7058 SetLastError(0xdeadbeef); 7059 bret = pGetWindowsAccountDomainSid(0, 0, 0); 7060 ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); 7061 ok(GetLastError() == ERROR_INVALID_SID, "expected ERROR_INVALID_SID, got %d\n", GetLastError()); 7062 7063 SetLastError(0xdeadbeef); 7064 bret = pGetWindowsAccountDomainSid(user_sid, 0, 0); 7065 ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); 7066 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 7067 7068 sid_size = SECURITY_MAX_SID_SIZE; 7069 SetLastError(0xdeadbeef); 7070 bret = pGetWindowsAccountDomainSid(user_sid, 0, &sid_size); 7071 ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); 7072 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 7073 ok(sid_size == GetSidLengthRequired(4), "expected size %d, got %d\n", GetSidLengthRequired(4), sid_size); 7074 7075 SetLastError(0xdeadbeef); 7076 bret = pGetWindowsAccountDomainSid(user_sid, domain_sid, 0); 7077 ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); 7078 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 7079 7080 sid_size = 1; 7081 SetLastError(0xdeadbeef); 7082 bret = pGetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size); 7083 ok(!bret, "GetWindowsAccountDomainSid succeeded\n"); 7084 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 7085 ok(sid_size == GetSidLengthRequired(4), "expected size %d, got %d\n", GetSidLengthRequired(4), sid_size); 7086 7087 sid_size = SECURITY_MAX_SID_SIZE; 7088 bret = pGetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size); 7089 ok(bret, "GetWindowsAccountDomainSid failed with error %d\n", GetLastError()); 7090 ok(sid_size == GetSidLengthRequired(4), "expected size %d, got %d\n", GetSidLengthRequired(4), sid_size); 7091 InitializeSid(domain_sid2, &domain_ident, 4); 7092 for (i = 0; i < 4; i++) 7093 *GetSidSubAuthority(domain_sid2, i) = *GetSidSubAuthority(user_sid, i); 7094 ok(EqualSid(domain_sid, domain_sid2), "unexpected domain sid %s != %s\n", 7095 debugstr_sid(domain_sid), debugstr_sid(domain_sid2)); 7096 7097 HeapFree(GetProcessHeap(), 0, user); 7098 } 7099 7100 static void test_GetSidIdentifierAuthority(void) 7101 { 7102 char buffer[SECURITY_MAX_SID_SIZE]; 7103 PSID authority_sid = (PSID *)buffer; 7104 PSID_IDENTIFIER_AUTHORITY id; 7105 BOOL ret; 7106 7107 if (!pGetSidIdentifierAuthority) 7108 { 7109 win_skip("GetSidIdentifierAuthority not available\n"); 7110 return; 7111 } 7112 7113 memset(buffer, 0xcc, sizeof(buffer)); 7114 ret = IsValidSid(authority_sid); 7115 ok(!ret, "expected FALSE, got %u\n", ret); 7116 7117 SetLastError(0xdeadbeef); 7118 id = GetSidIdentifierAuthority(authority_sid); 7119 ok(id != NULL, "got NULL pointer as identifier authority\n"); 7120 ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", GetLastError()); 7121 7122 SetLastError(0xdeadbeef); 7123 id = GetSidIdentifierAuthority(NULL); 7124 ok(id != NULL, "got NULL pointer as identifier authority\n"); 7125 ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", GetLastError()); 7126 } 7127 7128 static void test_pseudo_tokens(void) 7129 { 7130 TOKEN_STATISTICS statistics1, statistics2; 7131 HANDLE token; 7132 DWORD retlen; 7133 BOOL ret; 7134 7135 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token); 7136 ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); 7137 memset(&statistics1, 0x11, sizeof(statistics1)); 7138 ret = GetTokenInformation(token, TokenStatistics, &statistics1, sizeof(statistics1), &retlen); 7139 ok(ret, "GetTokenInformation failed with %u\n", GetLastError()); 7140 CloseHandle(token); 7141 7142 /* test GetCurrentProcessToken() */ 7143 SetLastError(0xdeadbeef); 7144 memset(&statistics2, 0x22, sizeof(statistics2)); 7145 ret = GetTokenInformation(GetCurrentProcessToken(), TokenStatistics, 7146 &statistics2, sizeof(statistics2), &retlen); 7147 ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE), 7148 "GetTokenInformation failed with %u\n", GetLastError()); 7149 if (ret) 7150 ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n"); 7151 else 7152 win_skip("CurrentProcessToken not supported, skipping test\n"); 7153 7154 /* test GetCurrentThreadEffectiveToken() */ 7155 SetLastError(0xdeadbeef); 7156 memset(&statistics2, 0x22, sizeof(statistics2)); 7157 ret = GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenStatistics, 7158 &statistics2, sizeof(statistics2), &retlen); 7159 ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE), 7160 "GetTokenInformation failed with %u\n", GetLastError()); 7161 if (ret) 7162 ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n"); 7163 else 7164 win_skip("CurrentThreadEffectiveToken not supported, skipping test\n"); 7165 7166 SetLastError(0xdeadbeef); 7167 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token); 7168 ok(!ret, "OpenThreadToken should have failed\n"); 7169 ok(GetLastError() == ERROR_NO_TOKEN, "Expected ERROR_NO_TOKEN, got %u\n", GetLastError()); 7170 7171 /* test GetCurrentThreadToken() */ 7172 SetLastError(0xdeadbeef); 7173 ret = GetTokenInformation(GetCurrentThreadToken(), TokenStatistics, 7174 &statistics2, sizeof(statistics2), &retlen); 7175 todo_wine ok(GetLastError() == ERROR_NO_TOKEN || broken(GetLastError() == ERROR_INVALID_HANDLE), 7176 "Expected ERROR_NO_TOKEN, got %u\n", GetLastError()); 7177 } 7178 7179 static void test_maximum_allowed(void) 7180 { 7181 HANDLE (WINAPI *pCreateEventExA)(SECURITY_ATTRIBUTES *, LPCSTR, DWORD, DWORD); 7182 char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH], buffer_acl[256]; 7183 SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd; 7184 SECURITY_ATTRIBUTES sa; 7185 ACL *acl = (ACL *)&buffer_acl; 7186 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll"); 7187 ACCESS_MASK mask; 7188 HANDLE handle; 7189 BOOL ret; 7190 7191 pCreateEventExA = (void *)GetProcAddress(hkernel32, "CreateEventExA"); 7192 if (!pCreateEventExA) 7193 { 7194 win_skip("CreateEventExA is not available\n"); 7195 return; 7196 } 7197 7198 ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); 7199 ok(ret, "InitializeSecurityDescriptor failed with %u\n", GetLastError()); 7200 memset(buffer_acl, 0, sizeof(buffer_acl)); 7201 ret = InitializeAcl(acl, 256, ACL_REVISION); 7202 ok(ret, "InitializeAcl failed with %u\n", GetLastError()); 7203 ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE); 7204 ok(ret, "SetSecurityDescriptorDacl failed with %u\n", GetLastError()); 7205 7206 sa.nLength = sizeof(SECURITY_ATTRIBUTES); 7207 sa.lpSecurityDescriptor = sd; 7208 sa.bInheritHandle = FALSE; 7209 7210 handle = pCreateEventExA(&sa, NULL, 0, MAXIMUM_ALLOWED | 0x4); 7211 ok(handle != NULL, "CreateEventExA failed with error %u\n", GetLastError()); 7212 mask = get_obj_access(handle); 7213 ok(mask == EVENT_ALL_ACCESS, "Expected %x, got %x\n", EVENT_ALL_ACCESS, mask); 7214 CloseHandle(handle); 7215 } 7216 7217 static void test_token_label(void) 7218 { 7219 static SID medium_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 7220 {SECURITY_MANDATORY_MEDIUM_RID}}; 7221 static SID high_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 7222 {SECURITY_MANDATORY_HIGH_RID}}; 7223 SECURITY_DESCRIPTOR_CONTROL control; 7224 SYSTEM_MANDATORY_LABEL_ACE *ace; 7225 BOOL ret, present, defaulted; 7226 SECURITY_DESCRIPTOR *sd; 7227 ACL *sacl = NULL, *dacl; 7228 DWORD size, revision; 7229 HANDLE token; 7230 char *str; 7231 SID *sid; 7232 7233 ret = OpenProcessToken(GetCurrentProcess(), READ_CONTROL | WRITE_OWNER, &token); 7234 ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); 7235 7236 ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 7237 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7238 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 7239 7240 sd = HeapAlloc(GetProcessHeap(), 0, size); 7241 ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size); 7242 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7243 7244 ret = GetSecurityDescriptorControl(sd, &control, &revision); 7245 ok(ret, "GetSecurityDescriptorControl failed with error %u\n", GetLastError()); 7246 todo_wine ok(control == (SE_SELF_RELATIVE | SE_SACL_AUTO_INHERITED | SE_SACL_PRESENT) || 7247 broken(control == SE_SELF_RELATIVE) /* WinXP, Win2003 */, 7248 "Unexpected security descriptor control %#x\n", control); 7249 ok(revision == 1, "Unexpected security descriptor revision %u\n", revision); 7250 7251 sid = (void *)0xdeadbeef; 7252 defaulted = TRUE; 7253 ret = GetSecurityDescriptorOwner(sd, (void **)&sid, &defaulted); 7254 ok(ret, "GetSecurityDescriptorOwner failed with error %u\n", GetLastError()); 7255 ok(!sid, "Owner present\n"); 7256 ok(!defaulted, "Owner defaulted\n"); 7257 7258 sid = (void *)0xdeadbeef; 7259 defaulted = TRUE; 7260 ret = GetSecurityDescriptorGroup(sd, (void **)&sid, &defaulted); 7261 ok(ret, "GetSecurityDescriptorGroup failed with error %u\n", GetLastError()); 7262 ok(!sid, "Group present\n"); 7263 ok(!defaulted, "Group defaulted\n"); 7264 7265 ret = GetSecurityDescriptorSacl(sd, &present, &sacl, &defaulted); 7266 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7267 ok(present || broken(!present) /* WinXP, Win2003 */, "No SACL in the security descriptor\n"); 7268 ok(sacl || broken(!sacl) /* WinXP, Win2003 */, "NULL SACL in the security descriptor\n"); 7269 7270 if (present) 7271 { 7272 ok(!defaulted, "SACL defaulted\n"); 7273 ok(sacl->AceCount == 1, "SACL contains an unexpected ACE count %u\n", sacl->AceCount); 7274 7275 ret = pGetAce(sacl, 0, (void **)&ace); 7276 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7277 7278 ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, 7279 "Unexpected ACE type %#x\n", ace->Header.AceType); 7280 ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags); 7281 ok(ace->Header.AceSize, "Unexpected ACE size %u\n", ace->Header.AceSize); 7282 ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#x\n", ace->Mask); 7283 7284 sid = (SID *)&ace->SidStart; 7285 ConvertSidToStringSidA(sid, &str); 7286 ok(EqualSid(sid, &medium_sid) || EqualSid(sid, &high_sid), "Got unexpected SID %s\n", str); 7287 LocalFree(str); 7288 } 7289 7290 ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted); 7291 ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); 7292 todo_wine ok(!present, "DACL present\n"); 7293 7294 HeapFree(GetProcessHeap(), 0, sd); 7295 CloseHandle(token); 7296 } 7297 7298 static void test_token_security_descriptor(void) 7299 { 7300 static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 7301 {SECURITY_MANDATORY_LOW_RID}}; 7302 static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 7303 {SECURITY_MANDATORY_MEDIUM_RID}}; 7304 static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 7305 {SECURITY_MANDATORY_HIGH_RID}}; 7306 char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; 7307 SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2, *sd3; 7308 char buffer_acl[256], buffer[MAX_PATH]; 7309 ACL *acl = (ACL *)&buffer_acl, *acl2, *acl_child, *sacl; 7310 BOOL defaulted, present, ret, found; 7311 HANDLE token, token2, token3, token4, token5, token6; 7312 EXPLICIT_ACCESSW exp_access; 7313 TOKEN_MANDATORY_LABEL *tml; 7314 BYTE buffer_integrity[64]; 7315 PROCESS_INFORMATION info; 7316 DWORD size, index, retd; 7317 ACCESS_ALLOWED_ACE *ace; 7318 SECURITY_ATTRIBUTES sa; 7319 STARTUPINFOA startup; 7320 PSID psid; 7321 7322 if (!pDuplicateTokenEx || !pConvertStringSidToSidA || !pAddAccessAllowedAceEx || !pGetAce 7323 || !pSetEntriesInAclW) 7324 { 7325 win_skip("Some functions not available\n"); 7326 return; 7327 } 7328 7329 /* Test whether we can create tokens with security descriptors */ 7330 ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); 7331 ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); 7332 7333 ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); 7334 ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); 7335 7336 memset(buffer_acl, 0, sizeof(buffer_acl)); 7337 ret = InitializeAcl(acl, 256, ACL_REVISION); 7338 ok(ret, "InitializeAcl failed with error %u\n", GetLastError()); 7339 7340 ret = pConvertStringSidToSidA("S-1-5-6", &psid); 7341 ok(ret, "ConvertStringSidToSidA failed with error %u\n", GetLastError()); 7342 7343 ret = pAddAccessAllowedAceEx(acl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, GENERIC_ALL, psid); 7344 ok(ret, "AddAccessAllowedAceEx failed with error %u\n", GetLastError()); 7345 7346 ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE); 7347 ok(ret, "SetSecurityDescriptorDacl failed with error %u\n", GetLastError()); 7348 7349 sa.nLength = sizeof(SECURITY_ATTRIBUTES); 7350 sa.lpSecurityDescriptor = sd; 7351 sa.bInheritHandle = FALSE; 7352 7353 ret = pDuplicateTokenEx(token, MAXIMUM_ALLOWED, &sa, SecurityImpersonation, TokenImpersonation, &token2); 7354 ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); 7355 7356 ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, NULL, 0, &size); 7357 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7358 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 7359 7360 sd2 = HeapAlloc(GetProcessHeap(), 0, size); 7361 ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, sd2, size, &size); 7362 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7363 7364 acl2 = (void *)0xdeadbeef; 7365 present = FALSE; 7366 defaulted = TRUE; 7367 ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted); 7368 ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); 7369 ok(present, "acl2 not present\n"); 7370 ok(acl2 != (void *)0xdeadbeef, "acl2 not set\n"); 7371 ok(acl2->AceCount == 1, "Expected 1 ACE, got %d\n", acl2->AceCount); 7372 ok(!defaulted, "acl2 defaulted\n"); 7373 7374 ret = pGetAce(acl2, 0, (void **)&ace); 7375 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7376 ok(ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType); 7377 ok(EqualSid(&ace->SidStart, psid), "Expected access allowed ACE\n"); 7378 ok(ace->Header.AceFlags == NO_PROPAGATE_INHERIT_ACE, 7379 "Expected NO_PROPAGATE_INHERIT_ACE as flags, got %x\n", ace->Header.AceFlags); 7380 7381 HeapFree(GetProcessHeap(), 0, sd2); 7382 7383 /* Duplicate token without security attributes. 7384 * Tokens do not inherit the security descriptor in DuplicateToken. */ 7385 ret = pDuplicateTokenEx(token2, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &token3); 7386 ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); 7387 7388 ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, NULL, 0, &size); 7389 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7390 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 7391 7392 sd2 = HeapAlloc(GetProcessHeap(), 0, size); 7393 ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, sd2, size, &size); 7394 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7395 7396 acl2 = (void *)0xdeadbeef; 7397 present = FALSE; 7398 defaulted = TRUE; 7399 ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted); 7400 ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); 7401 ok(present, "DACL not present\n"); 7402 7403 if (present) 7404 { 7405 ok(acl2 != (void *)0xdeadbeef, "DACL not set\n"); 7406 ok(!defaulted, "DACL defaulted\n"); 7407 7408 index = 0; 7409 found = FALSE; 7410 while (pGetAce(acl2, index++, (void **)&ace)) 7411 { 7412 if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace->SidStart, psid)) 7413 found = TRUE; 7414 } 7415 ok(!found, "Access allowed ACE was inherited\n"); 7416 } 7417 7418 HeapFree(GetProcessHeap(), 0, sd2); 7419 7420 /* When creating a child process, the process does inherit the token of 7421 * the parent but not the DACL of the token */ 7422 ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size); 7423 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7424 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 7425 7426 sd2 = HeapAlloc(GetProcessHeap(), 0, size); 7427 ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd2, size, &size); 7428 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7429 7430 acl2 = (void *)0xdeadbeef; 7431 present = FALSE; 7432 defaulted = TRUE; 7433 ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted); 7434 ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); 7435 ok(present, "DACL not present\n"); 7436 ok(acl2 != (void *)0xdeadbeef, "DACL not set\n"); 7437 ok(!defaulted, "DACL defaulted\n"); 7438 7439 exp_access.grfAccessPermissions = GENERIC_ALL; 7440 exp_access.grfAccessMode = GRANT_ACCESS; 7441 exp_access.grfInheritance = NO_PROPAGATE_INHERIT_ACE; 7442 exp_access.Trustee.pMultipleTrustee = NULL; 7443 exp_access.Trustee.TrusteeForm = TRUSTEE_IS_SID; 7444 exp_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 7445 exp_access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; 7446 exp_access.Trustee.ptstrName = (void*)psid; 7447 7448 retd = pSetEntriesInAclW(1, &exp_access, acl2, &acl_child); 7449 ok(retd == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", retd); 7450 7451 memset(sd, 0, sizeof(buffer_sd)); 7452 ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); 7453 ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); 7454 7455 ret = SetSecurityDescriptorDacl(sd, TRUE, acl_child, FALSE); 7456 ok(ret, "SetSecurityDescriptorDacl failed with error %u\n", GetLastError()); 7457 7458 ret = SetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd); 7459 ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); 7460 7461 /* The security label is also not inherited */ 7462 if (pAddMandatoryAce) 7463 { 7464 memset(buffer_integrity, 0, sizeof(buffer_integrity)); 7465 ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); 7466 ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); 7467 tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; 7468 ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), 7469 "Expected medium or high integrity level\n"); 7470 7471 if (EqualSid(tml->Label.Sid, &high_level)) 7472 { 7473 DWORD process_id; 7474 HANDLE process; 7475 HWND shell; 7476 7477 /* This test tries to get a medium token and then impersonates this token. The 7478 * idea is to check whether the sd label of a newly created token depends on the 7479 * current active token or the integrity level of the newly created token. */ 7480 7481 /* Steal process token of the explorer.exe process */ 7482 shell = GetShellWindow(); 7483 todo_wine ok(shell != NULL, "Failed to get shell window\n"); 7484 if (!shell) shell = GetDesktopWindow(); /* FIXME: Workaround for Wine */ 7485 ok(GetWindowThreadProcessId(shell, &process_id), 7486 "Failed to get process id of shell window: %u\n", GetLastError()); 7487 process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, process_id); 7488 ok(process != NULL, "Failed to open process: %u\n", GetLastError()); 7489 ok(OpenProcessToken(process, TOKEN_ALL_ACCESS, &token4), 7490 "Failed to open process token: %u\n", GetLastError()); 7491 CloseHandle(process); 7492 7493 /* Check TokenIntegrityLevel and LABEL_SECURITY_INFORMATION of explorer.exe token */ 7494 memset(buffer_integrity, 0, sizeof(buffer_integrity)); 7495 ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); 7496 ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); 7497 tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; 7498 ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n"); 7499 7500 size = 0; 7501 ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 7502 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7503 "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); 7504 7505 sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 7506 ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size); 7507 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7508 7509 sacl = NULL; 7510 ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); 7511 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7512 ok(present, "No SACL in the security descriptor\n"); 7513 ok(sacl != NULL, "NULL SACL in the security descriptor\n"); 7514 7515 if (sacl) 7516 { 7517 ret = pGetAce(sacl, 0, (void **)&ace); 7518 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7519 ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, 7520 "Unexpected ACE type %#x\n", ace->Header.AceType); 7521 ok(EqualSid(&ace->SidStart, &medium_level), 7522 "Expected medium integrity level\n"); 7523 } 7524 7525 HeapFree(GetProcessHeap(), 0, sd3); 7526 7527 /* Start child process with the explorer.exe token */ 7528 memset(&startup, 0, sizeof(startup)); 7529 startup.cb = sizeof(startup); 7530 startup.dwFlags = STARTF_USESHOWWINDOW; 7531 startup.wShowWindow = SW_SHOWNORMAL; 7532 7533 sprintf(buffer, "%s tests/security.c test_token_sd_medium", myARGV[0]); 7534 ret = CreateProcessAsUserA(token4, NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info); 7535 ok(ret || GetLastError() == ERROR_PRIVILEGE_NOT_HELD, 7536 "CreateProcess failed with error %u\n", GetLastError()); 7537 if (ret) 7538 { 7539 winetest_wait_child_process(info.hProcess); 7540 CloseHandle(info.hProcess); 7541 CloseHandle(info.hThread); 7542 } 7543 else 7544 win_skip("Skipping test for creating process with medium level token\n"); 7545 7546 ret = DuplicateTokenEx(token4, 0, NULL, SecurityImpersonation, TokenImpersonation, &token5); 7547 ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); 7548 ret = SetThreadToken(NULL, token5); 7549 ok(ret, "SetThreadToken failed with error %u\n", GetLastError()); 7550 CloseHandle(token4); 7551 7552 /* Restrict current process token while impersonating a medium integrity token */ 7553 ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token6); 7554 ok(ret, "CreateRestrictedToken failed with error %u\n", GetLastError()); 7555 7556 memset(buffer_integrity, 0, sizeof(buffer_integrity)); 7557 ret = GetTokenInformation(token6, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); 7558 ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); 7559 tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; 7560 ok(EqualSid(tml->Label.Sid, &high_level), "Expected high integrity level\n"); 7561 7562 size = 0; 7563 ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 7564 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7565 "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); 7566 7567 sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 7568 ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, sd3, size, &size); 7569 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7570 7571 sacl = NULL; 7572 ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); 7573 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7574 ok(present, "No SACL in the security descriptor\n"); 7575 ok(sacl != NULL, "NULL SACL in the security descriptor\n"); 7576 7577 if (sacl) 7578 { 7579 ret = pGetAce(sacl, 0, (void **)&ace); 7580 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7581 ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, 7582 "Unexpected ACE type %#x\n", ace->Header.AceType); 7583 ok(EqualSid(&ace->SidStart, &medium_level), 7584 "Expected medium integrity level\n"); 7585 } 7586 7587 HeapFree(GetProcessHeap(), 0, sd3); 7588 RevertToSelf(); 7589 CloseHandle(token5); 7590 7591 /* Start child process with the restricted token */ 7592 sprintf(buffer, "%s tests/security.c test_token_sd_restricted", myARGV[0]); 7593 ret = CreateProcessAsUserA(token6, NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info); 7594 ok(ret, "CreateProcess failed with error %u\n", GetLastError()); 7595 winetest_wait_child_process(info.hProcess); 7596 CloseHandle(info.hProcess); 7597 CloseHandle(info.hThread); 7598 CloseHandle(token6); 7599 7600 /* DuplicateTokenEx should assign security label even when SA points to empty SD */ 7601 memset(sd, 0, sizeof(buffer_sd)); 7602 ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); 7603 ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); 7604 7605 sa.nLength = sizeof(SECURITY_ATTRIBUTES); 7606 sa.lpSecurityDescriptor = sd; 7607 sa.bInheritHandle = FALSE; 7608 7609 ret = DuplicateTokenEx(token, 0, &sa, 0, TokenPrimary, &token6); 7610 ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); 7611 7612 size = 0; 7613 ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 7614 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7615 "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); 7616 7617 sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 7618 ret = GetKernelObjectSecurity(token6, LABEL_SECURITY_INFORMATION, sd3, size, &size); 7619 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7620 7621 sacl = NULL; 7622 ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); 7623 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7624 ok(present, "No SACL in the security descriptor\n"); 7625 ok(sacl != NULL, "NULL SACL in the security descriptor\n"); 7626 7627 if (sacl) 7628 { 7629 ret = pGetAce(sacl, 0, (void **)&ace); 7630 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7631 ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, 7632 "Unexpected ACE type %#x\n", ace->Header.AceType); 7633 ok(EqualSid(&ace->SidStart, &high_level), 7634 "Expected high integrity level\n"); 7635 } 7636 7637 HeapFree(GetProcessHeap(), 0, sd3); 7638 CloseHandle(token6); 7639 } 7640 else 7641 skip("Skipping test, running without admin rights\n"); 7642 7643 ret = InitializeAcl(acl, 256, ACL_REVISION); 7644 ok(ret, "InitializeAcl failed with error %u\n", GetLastError()); 7645 7646 ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level); 7647 ok(ret, "AddMandatoryAce failed with error %u\n", GetLastError()); 7648 7649 memset(sd, 0, sizeof(buffer_sd)); 7650 ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION); 7651 ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError()); 7652 7653 ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE); 7654 ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7655 7656 ret = SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd); 7657 ok(ret, "SetKernelObjectSecurity failed with error %u\n", GetLastError()); 7658 7659 /* changing the label of the security descriptor does not change the integrity level of the token itself */ 7660 memset(buffer_integrity, 0, sizeof(buffer_integrity)); 7661 ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); 7662 ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); 7663 tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; 7664 ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), 7665 "Expected medium or high integrity level\n"); 7666 7667 /* restricting / duplicating a token resets the mandatory sd label */ 7668 ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token4); 7669 ok(ret, "CreateRestrictedToken failed with error %u\n", GetLastError()); 7670 7671 memset(buffer_integrity, 0, sizeof(buffer_integrity)); 7672 ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); 7673 ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); 7674 tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; 7675 ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), 7676 "Expected medium or high integrity level\n"); 7677 7678 size = 0; 7679 ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 7680 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7681 "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); 7682 7683 sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 7684 ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size); 7685 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7686 7687 ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); 7688 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7689 ok(present, "No SACL in the security descriptor\n"); 7690 ok(sacl != NULL, "NULL SACL in the security descriptor\n"); 7691 7692 if (sacl) 7693 { 7694 ret = pGetAce(sacl, 0, (void **)&ace); 7695 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7696 ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, 7697 "Unexpected ACE type %#x\n", ace->Header.AceType); 7698 ok(EqualSid(&ace->SidStart, &medium_level) || EqualSid(&ace->SidStart, &high_level), 7699 "Low integrity level should not have been inherited\n"); 7700 } 7701 7702 HeapFree(GetProcessHeap(), 0, sd3); 7703 CloseHandle(token4); 7704 7705 ret = DuplicateTokenEx(token, 0, NULL, 0, TokenPrimary, &token4); 7706 ok(ret, "DuplicateTokenEx failed with error %u\n", GetLastError()); 7707 7708 memset(buffer_integrity, 0, sizeof(buffer_integrity)); 7709 ret = GetTokenInformation(token4, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); 7710 ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); 7711 tml = (TOKEN_MANDATORY_LABEL*) buffer_integrity; 7712 ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level), 7713 "Expected medium or high integrity level\n"); 7714 7715 size = 0; 7716 ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 7717 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7718 "Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError()); 7719 7720 sd3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 7721 ret = GetKernelObjectSecurity(token4, LABEL_SECURITY_INFORMATION, sd3, size, &size); 7722 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7723 7724 sacl = NULL; 7725 ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted); 7726 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7727 ok(present, "No SACL in the security descriptor\n"); 7728 ok(sacl != NULL, "NULL SACL in the security descriptor\n"); 7729 7730 if (sacl) 7731 { 7732 ret = pGetAce(sacl, 0, (void **)&ace); 7733 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7734 ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, 7735 "Unexpected ACE type %#x\n", ace->Header.AceType); 7736 ok(EqualSid(&ace->SidStart, &medium_level) || EqualSid(&ace->SidStart, &high_level), 7737 "Low integrity level should not have been inherited\n"); 7738 } 7739 7740 HeapFree(GetProcessHeap(), 0, sd3); 7741 CloseHandle(token4); 7742 } 7743 else 7744 win_skip("SYSTEM_MANDATORY_LABEL not supported\n"); 7745 7746 /* Start child process with our modified token */ 7747 memset(&startup, 0, sizeof(startup)); 7748 startup.cb = sizeof(startup); 7749 startup.dwFlags = STARTF_USESHOWWINDOW; 7750 startup.wShowWindow = SW_SHOWNORMAL; 7751 7752 sprintf(buffer, "%s tests/security.c test_token_sd", myARGV[0]); 7753 ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info); 7754 ok(ret, "CreateProcess failed with error %u\n", GetLastError()); 7755 winetest_wait_child_process(info.hProcess); 7756 CloseHandle(info.hProcess); 7757 CloseHandle(info.hThread); 7758 7759 LocalFree(acl_child); 7760 HeapFree(GetProcessHeap(), 0, sd2); 7761 LocalFree(psid); 7762 7763 CloseHandle(token3); 7764 CloseHandle(token2); 7765 CloseHandle(token); 7766 } 7767 7768 static void test_child_token_sd(void) 7769 { 7770 static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 7771 {SECURITY_MANDATORY_LOW_RID}}; 7772 SYSTEM_MANDATORY_LABEL_ACE *ace_label; 7773 BOOL ret, present, defaulted; 7774 ACCESS_ALLOWED_ACE *acc_ace; 7775 SECURITY_DESCRIPTOR *sd; 7776 DWORD size, i; 7777 HANDLE token; 7778 PSID psid; 7779 ACL *acl; 7780 7781 ret = pConvertStringSidToSidA("S-1-5-6", &psid); 7782 ok(ret, "ConvertStringSidToSidA failed with error %u\n", GetLastError()); 7783 7784 ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); 7785 ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); 7786 7787 ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size); 7788 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7789 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 7790 7791 sd = HeapAlloc(GetProcessHeap(), 0, size); 7792 ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd, size, &size); 7793 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7794 7795 acl = NULL; 7796 present = FALSE; 7797 defaulted = TRUE; 7798 ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted); 7799 ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); 7800 ok(present, "DACL not present\n"); 7801 ok(acl && acl != (void *)0xdeadbeef, "Got invalid DACL\n"); 7802 ok(!defaulted, "DACL defaulted\n"); 7803 7804 ok(acl->AceCount, "Expected at least one ACE\n"); 7805 for (i = 0; i < acl->AceCount; i++) 7806 { 7807 ok(pGetAce(acl, i, (void **)&acc_ace), "GetAce failed with error %u\n", GetLastError()); 7808 ok(acc_ace->Header.AceType != ACCESS_ALLOWED_ACE_TYPE || !EqualSid(&acc_ace->SidStart, psid), 7809 "ACE inherited from the parent\n"); 7810 } 7811 7812 LocalFree(psid); 7813 HeapFree(GetProcessHeap(), 0, sd); 7814 7815 if (!pAddMandatoryAce) 7816 { 7817 win_skip("SYSTEM_MANDATORY_LABEL not supported\n"); 7818 return; 7819 } 7820 7821 ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 7822 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7823 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 7824 7825 sd = HeapAlloc(GetProcessHeap(), 0, size); 7826 ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size); 7827 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7828 7829 acl = NULL; 7830 present = FALSE; 7831 defaulted = TRUE; 7832 ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted); 7833 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7834 ok(present, "SACL not present\n"); 7835 ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n"); 7836 ok(!defaulted, "SACL defaulted\n"); 7837 ok(acl->AceCount == 1, "Expected exactly one ACE\n"); 7838 ret = pGetAce(acl, 0, (void **)&ace_label); 7839 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7840 ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, 7841 "Unexpected ACE type %#x\n", ace_label->Header.AceType); 7842 ok(!EqualSid(&ace_label->SidStart, &low_level), 7843 "Low integrity level should not have been inherited\n"); 7844 7845 HeapFree(GetProcessHeap(), 0, sd); 7846 } 7847 7848 static void test_child_token_sd_restricted(void) 7849 { 7850 static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 7851 {SECURITY_MANDATORY_HIGH_RID}}; 7852 SYSTEM_MANDATORY_LABEL_ACE *ace_label; 7853 BOOL ret, present, defaulted; 7854 TOKEN_MANDATORY_LABEL *tml; 7855 BYTE buffer_integrity[64]; 7856 SECURITY_DESCRIPTOR *sd; 7857 HANDLE token; 7858 DWORD size; 7859 ACL *acl; 7860 7861 if (!pAddMandatoryAce) 7862 { 7863 win_skip("SYSTEM_MANDATORY_LABEL not supported\n"); 7864 return; 7865 } 7866 7867 ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); 7868 ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); 7869 7870 ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 7871 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7872 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 7873 7874 sd = HeapAlloc(GetProcessHeap(), 0, size); 7875 ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size); 7876 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7877 7878 acl = NULL; 7879 present = FALSE; 7880 defaulted = TRUE; 7881 ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted); 7882 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7883 ok(present, "SACL not present\n"); 7884 ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n"); 7885 ok(!defaulted, "SACL defaulted\n"); 7886 ok(acl->AceCount == 1, "Expected exactly one ACE\n"); 7887 ret = pGetAce(acl, 0, (void **)&ace_label); 7888 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7889 ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, 7890 "Unexpected ACE type %#x\n", ace_label->Header.AceType); 7891 ok(EqualSid(&ace_label->SidStart, &high_level), 7892 "Expected high integrity level\n"); 7893 7894 memset(buffer_integrity, 0, sizeof(buffer_integrity)); 7895 ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); 7896 ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); 7897 tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; 7898 ok(EqualSid(tml->Label.Sid, &high_level), "Expected high integrity level\n"); 7899 7900 HeapFree(GetProcessHeap(), 0, sd); 7901 } 7902 7903 static void test_child_token_sd_medium(void) 7904 { 7905 static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY}, 7906 {SECURITY_MANDATORY_MEDIUM_RID}}; 7907 SYSTEM_MANDATORY_LABEL_ACE *ace_label; 7908 BOOL ret, present, defaulted; 7909 TOKEN_MANDATORY_LABEL *tml; 7910 BYTE buffer_integrity[64]; 7911 SECURITY_DESCRIPTOR *sd; 7912 HANDLE token; 7913 DWORD size; 7914 ACL *acl; 7915 7916 if (!pAddMandatoryAce) 7917 { 7918 win_skip("SYSTEM_MANDATORY_LABEL not supported\n"); 7919 return; 7920 } 7921 7922 ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); 7923 ok(ret, "OpenProcessToken failed with error %u\n", GetLastError()); 7924 7925 ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size); 7926 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, 7927 "Unexpected GetKernelObjectSecurity return value %d, error %u\n", ret, GetLastError()); 7928 7929 sd = HeapAlloc(GetProcessHeap(), 0, size); 7930 ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size); 7931 ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError()); 7932 7933 acl = NULL; 7934 present = FALSE; 7935 defaulted = TRUE; 7936 ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted); 7937 ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError()); 7938 ok(present, "SACL not present\n"); 7939 ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n"); 7940 ok(!defaulted, "SACL defaulted\n"); 7941 ok(acl->AceCount == 1, "Expected exactly one ACE\n"); 7942 ret = pGetAce(acl, 0, (void **)&ace_label); 7943 ok(ret, "GetAce failed with error %u\n", GetLastError()); 7944 ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, 7945 "Unexpected ACE type %#x\n", ace_label->Header.AceType); 7946 ok(EqualSid(&ace_label->SidStart, &medium_level), 7947 "Expected medium integrity level\n"); 7948 7949 memset(buffer_integrity, 0, sizeof(buffer_integrity)); 7950 ret = GetTokenInformation(token, TokenIntegrityLevel, buffer_integrity, sizeof(buffer_integrity), &size); 7951 ok(ret, "GetTokenInformation failed with error %u\n", GetLastError()); 7952 tml = (TOKEN_MANDATORY_LABEL *)buffer_integrity; 7953 ok(EqualSid(tml->Label.Sid, &medium_level), "Expected medium integrity level\n"); 7954 7955 HeapFree(GetProcessHeap(), 0, sd); 7956 } 7957 7958 static void test_GetExplicitEntriesFromAclW(void) 7959 { 7960 static const WCHAR wszCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'}; 7961 SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; 7962 SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY }; 7963 PSID everyone_sid = NULL, users_sid = NULL; 7964 EXPLICIT_ACCESSW access; 7965 EXPLICIT_ACCESSW *access2; 7966 PACL new_acl, old_acl = NULL; 7967 ULONG count; 7968 DWORD res; 7969 7970 if (!pGetExplicitEntriesFromAclW) 7971 { 7972 win_skip("GetExplicitEntriesFromAclW is not available\n"); 7973 return; 7974 } 7975 7976 if (!pSetEntriesInAclW) 7977 { 7978 win_skip("SetEntriesInAclW is not available\n"); 7979 return; 7980 } 7981 7982 old_acl = HeapAlloc(GetProcessHeap(), 0, 256); 7983 res = InitializeAcl(old_acl, 256, ACL_REVISION); 7984 if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 7985 { 7986 win_skip("ACLs not implemented - skipping tests\n"); 7987 HeapFree(GetProcessHeap(), 0, old_acl); 7988 return; 7989 } 7990 ok(res, "InitializeAcl failed with error %d\n", GetLastError()); 7991 7992 res = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid); 7993 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 7994 7995 res = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, 7996 DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &users_sid); 7997 ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); 7998 7999 res = AddAccessAllowedAce(old_acl, ACL_REVISION, KEY_READ, users_sid); 8000 ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); 8001 8002 access2 = NULL; 8003 res = pGetExplicitEntriesFromAclW(old_acl, &count, &access2); 8004 ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); 8005 ok(count == 1, "Expected count == 1, got %d\n", count); 8006 ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); 8007 ok(access2[0].grfAccessPermissions == KEY_READ, "Expected KEY_READ, got %d\n", access2[0].grfAccessPermissions); 8008 ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); 8009 ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); 8010 ok(EqualSid(access2[0].Trustee.ptstrName, users_sid), "Expected equal SIDs\n"); 8011 LocalFree(access2); 8012 8013 access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; 8014 access.Trustee.pMultipleTrustee = NULL; 8015 8016 access.grfAccessPermissions = KEY_WRITE; 8017 access.grfAccessMode = GRANT_ACCESS; 8018 access.grfInheritance = NO_INHERITANCE; 8019 access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; 8020 access.Trustee.TrusteeForm = TRUSTEE_IS_SID; 8021 access.Trustee.ptstrName = everyone_sid; 8022 res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); 8023 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 8024 ok(new_acl != NULL, "returned acl was NULL\n"); 8025 8026 access2 = NULL; 8027 res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); 8028 ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); 8029 ok(count == 2, "Expected count == 2, got %d\n", count); 8030 ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); 8031 ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions); 8032 ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, 8033 "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType); 8034 ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); 8035 ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); 8036 ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n"); 8037 LocalFree(access2); 8038 LocalFree(new_acl); 8039 8040 access.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; 8041 res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); 8042 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 8043 ok(new_acl != NULL, "returned acl was NULL\n"); 8044 8045 access2 = NULL; 8046 res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); 8047 ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); 8048 ok(count == 2, "Expected count == 2, got %d\n", count); 8049 ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); 8050 ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions); 8051 ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, 8052 "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType); 8053 ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); 8054 ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); 8055 ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n"); 8056 LocalFree(access2); 8057 LocalFree(new_acl); 8058 8059 access.Trustee.TrusteeForm = TRUSTEE_IS_NAME; 8060 access.Trustee.ptstrName = (LPWSTR)wszCurrentUser; 8061 res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); 8062 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 8063 ok(new_acl != NULL, "returned acl was NULL\n"); 8064 8065 access2 = NULL; 8066 res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); 8067 ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); 8068 ok(count == 2, "Expected count == 2, got %d\n", count); 8069 ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); 8070 ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions); 8071 ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, 8072 "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType); 8073 ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); 8074 ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); 8075 LocalFree(access2); 8076 LocalFree(new_acl); 8077 8078 access.grfAccessMode = REVOKE_ACCESS; 8079 access.Trustee.TrusteeForm = TRUSTEE_IS_SID; 8080 access.Trustee.ptstrName = users_sid; 8081 res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); 8082 ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); 8083 ok(new_acl != NULL, "returned acl was NULL\n"); 8084 8085 access2 = (void *)0xdeadbeef; 8086 res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); 8087 ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); 8088 ok(count == 0, "Expected count == 0, got %d\n", count); 8089 ok(access2 == NULL, "access2 was not NULL\n"); 8090 LocalFree(new_acl); 8091 8092 FreeSid(users_sid); 8093 FreeSid(everyone_sid); 8094 HeapFree(GetProcessHeap(), 0, old_acl); 8095 } 8096 8097 static void test_BuildSecurityDescriptorW(void) 8098 { 8099 SECURITY_DESCRIPTOR old_sd, *new_sd, *rel_sd; 8100 ULONG new_sd_size; 8101 DWORD buf_size; 8102 char buf[1024]; 8103 BOOL success; 8104 DWORD ret; 8105 8106 InitializeSecurityDescriptor(&old_sd, SECURITY_DESCRIPTOR_REVISION); 8107 8108 buf_size = sizeof(buf); 8109 rel_sd = (SECURITY_DESCRIPTOR *)buf; 8110 success = MakeSelfRelativeSD(&old_sd, rel_sd, &buf_size); 8111 ok(success, "MakeSelfRelativeSD failed with %u\n", GetLastError()); 8112 8113 new_sd = NULL; 8114 new_sd_size = 0; 8115 ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, NULL, &new_sd_size, (void **)&new_sd); 8116 ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %u\n", ret); 8117 ok(new_sd != NULL, "expected new_sd != NULL\n"); 8118 ok(new_sd_size == sizeof(old_sd), "expected new_sd_size == sizeof(old_sd), got %u\n", new_sd_size); 8119 LocalFree(new_sd); 8120 8121 new_sd = (void *)0xdeadbeef; 8122 ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, &old_sd, &new_sd_size, (void **)&new_sd); 8123 ok(ret == ERROR_INVALID_SECURITY_DESCR, "expected ERROR_INVALID_SECURITY_DESCR, got %u\n", ret); 8124 ok(new_sd == (void *)0xdeadbeef, "expected new_sd == 0xdeadbeef, got %p\n", new_sd); 8125 8126 new_sd = NULL; 8127 new_sd_size = 0; 8128 ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, rel_sd, &new_sd_size, (void **)&new_sd); 8129 ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %u\n", ret); 8130 ok(new_sd != NULL, "expected new_sd != NULL\n"); 8131 ok(new_sd_size == sizeof(old_sd), "expected new_sd_size == sizeof(old_sd), got %u\n", new_sd_size); 8132 LocalFree(new_sd); 8133 } 8134 8135 START_TEST(security) 8136 { 8137 init(); 8138 if (!hmod) return; 8139 8140 if (myARGC >= 3) 8141 { 8142 if (!strcmp(myARGV[2], "test_token_sd")) 8143 test_child_token_sd(); 8144 else if (!strcmp(myARGV[2], "test_token_sd_restricted")) 8145 test_child_token_sd_restricted(); 8146 else if (!strcmp(myARGV[2], "test_token_sd_medium")) 8147 test_child_token_sd_medium(); 8148 else 8149 test_process_security_child(); 8150 return; 8151 } 8152 test_kernel_objects_security(); 8153 test_sid(); 8154 test_trustee(); 8155 test_luid(); 8156 test_CreateWellKnownSid(); 8157 test_FileSecurity(); 8158 test_AccessCheck(); 8159 test_token_attr(); 8160 test_GetTokenInformation(); 8161 test_LookupAccountSid(); 8162 test_LookupAccountName(); 8163 test_security_descriptor(); 8164 test_process_security(); 8165 test_impersonation_level(); 8166 test_SetEntriesInAclW(); 8167 test_SetEntriesInAclA(); 8168 test_CreateDirectoryA(); 8169 test_GetNamedSecurityInfoA(); 8170 test_ConvertStringSecurityDescriptor(); 8171 test_ConvertSecurityDescriptorToString(); 8172 test_PrivateObjectSecurity(); 8173 test_acls(); 8174 test_GetWindowsAccountDomainSid(); 8175 test_GetSecurityInfo(); 8176 test_GetSidSubAuthority(); 8177 test_CheckTokenMembership(); 8178 test_EqualSid(); 8179 test_GetUserNameA(); 8180 test_GetUserNameW(); 8181 test_CreateRestrictedToken(); 8182 test_TokenIntegrityLevel(); 8183 test_default_dacl_owner_sid(); 8184 test_AdjustTokenPrivileges(); 8185 test_AddAce(); 8186 test_AddMandatoryAce(); 8187 test_system_security_access(); 8188 test_GetSidIdentifierAuthority(); 8189 test_pseudo_tokens(); 8190 test_maximum_allowed(); 8191 test_token_label(); 8192 test_GetExplicitEntriesFromAclW(); 8193 test_BuildSecurityDescriptorW(); 8194 8195 /* Must be the last test, modifies process token */ 8196 test_token_security_descriptor(); 8197 } 8198