From d4fa0262315bb1f15e673878a936a294cfcf65be Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 29 Aug 2016 02:51:46 +0200 Subject: [PATCH] Added patch to implement semi-stub for advapi32.GetExplicitEntriesFromAclW. --- ...Implement-GetExplicitEntriesFromAclW.patch | 277 ++++++++++++++++++ .../definition | 1 + patches/patchinstall.sh | 16 + 3 files changed, 294 insertions(+) create mode 100644 patches/advapi32-GetExplicitEntriesFromAclW/0001-advapi32-Implement-GetExplicitEntriesFromAclW.patch create mode 100644 patches/advapi32-GetExplicitEntriesFromAclW/definition diff --git a/patches/advapi32-GetExplicitEntriesFromAclW/0001-advapi32-Implement-GetExplicitEntriesFromAclW.patch b/patches/advapi32-GetExplicitEntriesFromAclW/0001-advapi32-Implement-GetExplicitEntriesFromAclW.patch new file mode 100644 index 00000000..7d53f382 --- /dev/null +++ b/patches/advapi32-GetExplicitEntriesFromAclW/0001-advapi32-Implement-GetExplicitEntriesFromAclW.patch @@ -0,0 +1,277 @@ +From cb383abcb7d36d739092a93c1f276895622b6806 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sun, 28 Aug 2016 21:56:41 +0200 +Subject: advapi32: Implement GetExplicitEntriesFromAclW. + +--- + dlls/advapi32/security.c | 81 ++++++++++++++++++++++- + dlls/advapi32/tests/security.c | 142 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 221 insertions(+), 2 deletions(-) + +diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c +index 92a1789..c60aa4e 100644 +--- a/dlls/advapi32/security.c ++++ b/dlls/advapi32/security.c +@@ -4202,8 +4202,85 @@ DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntr + DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries, + PEXPLICIT_ACCESSW* pListOfExplicitEntries) + { +- FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries); +- return ERROR_CALL_NOT_IMPLEMENTED; ++ ACL_SIZE_INFORMATION sizeinfo; ++ EXPLICIT_ACCESSW* entries; ++ MAX_SID *sid_entries; ++ ACE_HEADER *ace; ++ NTSTATUS status; ++ int i; ++ ++ FIXME("%p %p %p: semi-stub\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries); ++ ++ if (!pcCountOfExplicitEntries || !pListOfExplicitEntries) ++ return ERROR_INVALID_PARAMETER; ++ ++ status = RtlQueryInformationAcl(pacl, &sizeinfo, sizeof(sizeinfo), AclSizeInformation); ++ if (status) return RtlNtStatusToDosError(status); ++ ++ if (!sizeinfo.AceCount) ++ { ++ *pcCountOfExplicitEntries = 0; ++ *pListOfExplicitEntries = NULL; ++ return ERROR_SUCCESS; ++ } ++ ++ entries = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (sizeof(EXPLICIT_ACCESSW) + sizeof(MAX_SID)) * sizeinfo.AceCount); ++ if (!entries) return ERROR_OUTOFMEMORY; ++ sid_entries = (MAX_SID*)((char*)entries + sizeof(EXPLICIT_ACCESSW) * sizeinfo.AceCount); ++ ++ for (i = 0; i < sizeinfo.AceCount; i++) ++ { ++ status = RtlGetAce(pacl, i, (void**)&ace); ++ if (status) goto error; ++ ++ switch (ace->AceType) ++ { ++ case ACCESS_ALLOWED_ACE_TYPE: ++ { ++ ACCESS_ALLOWED_ACE *allow = (ACCESS_ALLOWED_ACE *)ace; ++ entries[i].grfAccessMode = GRANT_ACCESS; ++ entries[i].grfInheritance = ace->AceFlags; ++ entries[i].grfAccessPermissions = allow->Mask; ++ ++ CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&allow->SidStart); ++ entries[i].Trustee.pMultipleTrustee = NULL; ++ entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; ++ entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID; ++ entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; ++ entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i]; ++ break; ++ } ++ ++ case ACCESS_DENIED_ACE_TYPE: ++ { ++ ACCESS_DENIED_ACE *deny = (ACCESS_DENIED_ACE *)ace; ++ entries[i].grfAccessMode = DENY_ACCESS; ++ entries[i].grfInheritance = ace->AceFlags; ++ entries[i].grfAccessPermissions = deny->Mask; ++ ++ CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&deny->SidStart); ++ entries[i].Trustee.pMultipleTrustee = NULL; ++ entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; ++ entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID; ++ entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; ++ entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i]; ++ break; ++ } ++ ++ default: ++ FIXME("Unhandled ace type %d\n", ace->AceType); ++ entries[i].grfAccessMode = NOT_USED_ACCESS; ++ continue; ++ } ++ } ++ ++ *pcCountOfExplicitEntries = sizeinfo.AceCount; ++ *pListOfExplicitEntries = entries; ++ return ERROR_SUCCESS; ++ ++error: ++ LocalFree(entries); ++ return RtlNtStatusToDosError(status); + } + + /****************************************************************************** +diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c +index cf104ab..2bcb108 100644 +--- a/dlls/advapi32/tests/security.c ++++ b/dlls/advapi32/tests/security.c +@@ -133,6 +133,7 @@ static BOOL (WINAPI *pGetWindowsAccountDomainSid)(PSID,PSID,DWORD*); + static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ); + static NTSTATUS (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); + static PSID_IDENTIFIER_AUTHORITY (WINAPI *pGetSidIdentifierAuthority)(PSID); ++static DWORD (WINAPI *pGetExplicitEntriesFromAclW)(PACL,PULONG,PEXPLICIT_ACCESSW*); + + static HMODULE hmod; + static int myARGC; +@@ -227,6 +228,7 @@ static void init(void) + pGetAce = (void *)GetProcAddress(hmod, "GetAce"); + pGetWindowsAccountDomainSid = (void *)GetProcAddress(hmod, "GetWindowsAccountDomainSid"); + pGetSidIdentifierAuthority = (void *)GetProcAddress(hmod, "GetSidIdentifierAuthority"); ++ pGetExplicitEntriesFromAclW = (void *)GetProcAddress(hmod, "GetExplicitEntriesFromAclW"); + + myARGC = winetest_get_mainargs( &myARGV ); + } +@@ -6378,6 +6380,145 @@ static void test_pseudo_tokens(void) + "Expected ERROR_NO_TOKEN, got %u\n", GetLastError()); + } + ++static void test_GetExplicitEntriesFromAclW(void) ++{ ++ static const WCHAR wszCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'}; ++ SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; ++ SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY }; ++ PSID everyone_sid = NULL, users_sid = NULL; ++ EXPLICIT_ACCESSW access; ++ EXPLICIT_ACCESSW *access2; ++ PACL new_acl, old_acl = NULL; ++ ULONG count; ++ DWORD res; ++ ++ if (!pGetExplicitEntriesFromAclW) ++ { ++ win_skip("GetExplicitEntriesFromAclW is not available\n"); ++ return; ++ } ++ ++ if (!pSetEntriesInAclW) ++ { ++ win_skip("SetEntriesInAclW is not available\n"); ++ return; ++ } ++ ++ old_acl = HeapAlloc(GetProcessHeap(), 0, 256); ++ res = InitializeAcl(old_acl, 256, ACL_REVISION); ++ if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) ++ { ++ win_skip("ACLs not implemented - skipping tests\n"); ++ HeapFree(GetProcessHeap(), 0, old_acl); ++ return; ++ } ++ ok(res, "InitializeAcl failed with error %d\n", GetLastError()); ++ ++ res = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid); ++ ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); ++ ++ res = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, ++ DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &users_sid); ++ ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); ++ ++ res = AddAccessAllowedAce(old_acl, ACL_REVISION, KEY_READ, users_sid); ++ ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); ++ ++ access2 = NULL; ++ res = pGetExplicitEntriesFromAclW(old_acl, &count, &access2); ++ ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); ++ ok(count == 1, "Expected count == 1, got %d\n", count); ++ ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); ++ ok(access2[0].grfAccessPermissions == KEY_READ, "Expected KEY_READ, got %d\n", access2[0].grfAccessPermissions); ++ ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); ++ ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); ++ ok(EqualSid(access2[0].Trustee.ptstrName, users_sid), "Expected equal SIDs\n"); ++ LocalFree(access2); ++ ++ access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; ++ access.Trustee.pMultipleTrustee = NULL; ++ ++ access.grfAccessPermissions = KEY_WRITE; ++ access.grfAccessMode = GRANT_ACCESS; ++ access.grfInheritance = NO_INHERITANCE; ++ access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ++ access.Trustee.TrusteeForm = TRUSTEE_IS_SID; ++ access.Trustee.ptstrName = everyone_sid; ++ res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); ++ ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); ++ ok(new_acl != NULL, "returned acl was NULL\n"); ++ ++ access2 = NULL; ++ res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); ++ ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); ++ ok(count == 2, "Expected count == 2, got %d\n", count); ++ ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); ++ ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions); ++ ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, ++ "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType); ++ ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); ++ ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); ++ ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n"); ++ LocalFree(access2); ++ LocalFree(new_acl); ++ ++ access.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; ++ res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); ++ ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); ++ ok(new_acl != NULL, "returned acl was NULL\n"); ++ ++ access2 = NULL; ++ res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); ++ ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); ++ ok(count == 2, "Expected count == 2, got %d\n", count); ++ ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); ++ ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions); ++ ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, ++ "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType); ++ ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); ++ ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); ++ ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n"); ++ LocalFree(access2); ++ LocalFree(new_acl); ++ ++ access.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ++ access.Trustee.ptstrName = (LPWSTR)wszCurrentUser; ++ res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); ++ ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); ++ ok(new_acl != NULL, "returned acl was NULL\n"); ++ ++ access2 = NULL; ++ res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); ++ ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); ++ ok(count == 2, "Expected count == 2, got %d\n", count); ++ ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode); ++ ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %d\n", access2[0].grfAccessPermissions); ++ ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, ++ "Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType); ++ ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm); ++ ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %x\n", access2[0].grfInheritance); ++ LocalFree(access2); ++ LocalFree(new_acl); ++ ++ access.grfAccessMode = REVOKE_ACCESS; ++ access.Trustee.TrusteeForm = TRUSTEE_IS_SID; ++ access.Trustee.ptstrName = users_sid; ++ res = pSetEntriesInAclW(1, &access, old_acl, &new_acl); ++ ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res); ++ ok(new_acl != NULL, "returned acl was NULL\n"); ++ ++ access2 = (void *)0xdeadbeef; ++ res = pGetExplicitEntriesFromAclW(new_acl, &count, &access2); ++ ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %d\n", GetLastError()); ++ ok(count == 0, "Expected count == 0, got %d\n", count); ++ ok(access2 == NULL, "access2 was not NULL\n"); ++ LocalFree(new_acl); ++ ++ FreeSid(users_sid); ++ FreeSid(everyone_sid); ++ HeapFree(GetProcessHeap(), 0, old_acl); ++} ++ + START_TEST(security) + { + init(); +@@ -6424,4 +6565,5 @@ START_TEST(security) + test_system_security_access(); + test_GetSidIdentifierAuthority(); + test_pseudo_tokens(); ++ test_GetExplicitEntriesFromAclW(); + } +-- +2.9.0 + diff --git a/patches/advapi32-GetExplicitEntriesFromAclW/definition b/patches/advapi32-GetExplicitEntriesFromAclW/definition new file mode 100644 index 00000000..8d58f7bc --- /dev/null +++ b/patches/advapi32-GetExplicitEntriesFromAclW/definition @@ -0,0 +1 @@ +Fixes: Implement semi-stub for advapi32.GetExplicitEntriesFromAclW diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 755df8ec..0be7c236 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -86,6 +86,7 @@ patch_enable_all () enable_Coverity="$1" enable_Pipelight="$1" enable_Staging="$1" + enable_advapi32_GetExplicitEntriesFromAclW="$1" enable_advapi32_LsaLookupSids="$1" enable_advapi32_SetSecurityInfo="$1" enable_api_ms_win_Stub_DLLs="$1" @@ -428,6 +429,9 @@ patch_enable () Staging) enable_Staging="$2" ;; + advapi32-GetExplicitEntriesFromAclW) + enable_advapi32_GetExplicitEntriesFromAclW="$2" + ;; advapi32-LsaLookupSids) enable_advapi32_LsaLookupSids="$2" ;; @@ -2428,6 +2432,18 @@ if test "$enable_Staging" -eq 1; then ) >> "$patchlist" fi +# Patchset advapi32-GetExplicitEntriesFromAclW +# | +# | Modified files: +# | * dlls/advapi32/security.c, dlls/advapi32/tests/security.c +# | +if test "$enable_advapi32_GetExplicitEntriesFromAclW" -eq 1; then + patch_apply advapi32-GetExplicitEntriesFromAclW/0001-advapi32-Implement-GetExplicitEntriesFromAclW.patch + ( + echo '+ { "Michael Müller", "advapi32: Implement GetExplicitEntriesFromAclW.", 1 },'; + ) >> "$patchlist" +fi + # Patchset server-CreateProcess_ACLs # | # | This patchset fixes the following Wine bugs: