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