From fde235da03de45c8520c069cd7c27ca1f7b6167c Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Fri, 8 Nov 2019 14:12:52 +0800 Subject: [PATCH] kernelbase: Implement EqualDomainSid. Signed-off-by: Dmitry Timoshkov Signed-off-by: Alexandre Julliard --- dlls/advapi32/advapi32.spec | 2 +- dlls/advapi32/tests/security.c | 78 +++++++++++++++++++ .../api-ms-win-downlevel-advapi32-l1-1-0.spec | 2 +- .../api-ms-win-security-base-l1-1-0.spec | 2 +- .../api-ms-win-security-base-l1-2-0.spec | 2 +- dlls/kernelbase/kernelbase.spec | 2 +- dlls/kernelbase/security.c | 55 +++++++++++++ include/winbase.h | 1 + include/winerror.h | 2 + 9 files changed, 141 insertions(+), 5 deletions(-) diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index 54b479dc5d2..5a4344852ee 100644 --- a/dlls/advapi32/advapi32.spec +++ b/dlls/advapi32/advapi32.spec @@ -281,7 +281,7 @@ @ stdcall EnumServicesStatusW (long long long ptr long ptr ptr ptr) @ stdcall EnumerateTraceGuids(ptr long ptr) # @ stub EnumerateTraceGuidsEx -# @ stub EqualDomainSid +@ stdcall -import EqualDomainSid(ptr ptr ptr) @ stdcall -import EqualPrefixSid(ptr ptr) @ stdcall -import EqualSid(ptr ptr) # @ stub EventAccessControl diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 5f65ed385dd..bddcdef6bb8 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -130,6 +130,7 @@ static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,P static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*); static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_STRING,BOOLEAN); static BOOL (WINAPI *pGetWindowsAccountDomainSid)(PSID,PSID,DWORD*); +static BOOL (WINAPI *pEqualDomainSid)(PSID,PSID,BOOL*); static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ); static NTSTATUS (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); static PSID_IDENTIFIER_AUTHORITY (WINAPI *pGetSidIdentifierAuthority)(PSID); @@ -218,6 +219,7 @@ static void init(void) pGetAclInformation = (void *)GetProcAddress(hmod, "GetAclInformation"); pGetAce = (void *)GetProcAddress(hmod, "GetAce"); pGetWindowsAccountDomainSid = (void *)GetProcAddress(hmod, "GetWindowsAccountDomainSid"); + pEqualDomainSid = (void *)GetProcAddress(hmod, "EqualDomainSid"); pGetSidIdentifierAuthority = (void *)GetProcAddress(hmod, "GetSidIdentifierAuthority"); pDuplicateTokenEx = (void *)GetProcAddress(hmod, "DuplicateTokenEx"); pGetExplicitEntriesFromAclW = (void *)GetProcAddress(hmod, "GetExplicitEntriesFromAclW"); @@ -7570,6 +7572,81 @@ static void test_BuildSecurityDescriptorW(void) LocalFree(new_sd); } +static void test_EqualDomainSid(void) +{ + SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY }; + char sid_buffer[SECURITY_MAX_SID_SIZE], sid_buffer2[SECURITY_MAX_SID_SIZE]; + PSID domainsid, sid = sid_buffer, sid2 = sid_buffer2; + DWORD size; + BOOL ret, equal; + unsigned int i; + + if (!pEqualDomainSid) + { + win_skip("EqualDomainSid not available\n"); + return; + } + + if (!pCreateWellKnownSid) + { + win_skip("CreateWellKnownSid not available\n"); + return; + } + + ret = AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid); + ok(ret, "AllocateAndInitializeSid error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = pEqualDomainSid(NULL, NULL, NULL); + ok(!ret, "got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_SID, "got %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = pEqualDomainSid(domainsid, domainsid, NULL); + ok(!ret, "got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError()); + + for (i = 0; i < ARRAY_SIZE(well_known_sid_values); i++) + { + SID *pisid = sid; + + size = sizeof(sid_buffer); + if (!pCreateWellKnownSid(i, NULL, sid, &size)) + { + trace("Well known SID %u not supported\n", i); + continue; + } + + equal = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = pEqualDomainSid(sid, domainsid, &equal); + if (pisid->SubAuthority[0] != SECURITY_BUILTIN_DOMAIN_RID) + { + ok(!ret, "%u: got %d\n", i, ret); + ok(GetLastError() == ERROR_NON_DOMAIN_SID, "%u: got %u\n", i, GetLastError()); + ok(equal == 0xdeadbeef, "%u: got %d\n", i, equal); + continue; + } + + ok(ret, "%u: got %d\n", i, ret); + ok(GetLastError() == 0, "%u: got %u\n", i, GetLastError()); + ok(equal == 0, "%u: got %d\n", i, equal); + + size = sizeof(sid_buffer2); + ret = pCreateWellKnownSid(i, well_known_sid_values[i].without_domain ? NULL : domainsid, sid2, &size); + ok(ret, "%u: CreateWellKnownSid error %u\n", i, GetLastError()); + + equal = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = pEqualDomainSid(sid, sid2, &equal); + ok(ret, "%u: got %d\n", i, ret); + ok(GetLastError() == 0, "%u: got %u\n", i, GetLastError()); + ok(equal == 1, "%u: got %d\n", i, equal); + } + + FreeSid(domainsid); +} + START_TEST(security) { init(); @@ -7606,6 +7683,7 @@ START_TEST(security) test_PrivateObjectSecurity(); test_acls(); test_GetWindowsAccountDomainSid(); + test_EqualDomainSid(); test_GetSecurityInfo(); test_GetSidSubAuthority(); test_CheckTokenMembership(); diff --git a/dlls/api-ms-win-downlevel-advapi32-l1-1-0/api-ms-win-downlevel-advapi32-l1-1-0.spec b/dlls/api-ms-win-downlevel-advapi32-l1-1-0/api-ms-win-downlevel-advapi32-l1-1-0.spec index 1d581876275..8891ed26a46 100644 --- a/dlls/api-ms-win-downlevel-advapi32-l1-1-0/api-ms-win-downlevel-advapi32-l1-1-0.spec +++ b/dlls/api-ms-win-downlevel-advapi32-l1-1-0/api-ms-win-downlevel-advapi32-l1-1-0.spec @@ -35,7 +35,7 @@ @ stdcall DestroyPrivateObjectSecurity(ptr) advapi32.DestroyPrivateObjectSecurity @ stdcall DuplicateToken(long long ptr) advapi32.DuplicateToken @ stdcall DuplicateTokenEx(long long ptr long long ptr) advapi32.DuplicateTokenEx -@ stub EqualDomainSid +@ stdcall EqualDomainSid(ptr ptr ptr) advapi32.EqualDomainSid @ stdcall EqualPrefixSid(ptr ptr) advapi32.EqualPrefixSid @ stdcall EqualSid(ptr ptr) advapi32.EqualSid @ stdcall EventActivityIdControl(long ptr) advapi32.EventActivityIdControl diff --git a/dlls/api-ms-win-security-base-l1-1-0/api-ms-win-security-base-l1-1-0.spec b/dlls/api-ms-win-security-base-l1-1-0/api-ms-win-security-base-l1-1-0.spec index 097c313303f..2170f69d568 100644 --- a/dlls/api-ms-win-security-base-l1-1-0/api-ms-win-security-base-l1-1-0.spec +++ b/dlls/api-ms-win-security-base-l1-1-0/api-ms-win-security-base-l1-1-0.spec @@ -34,7 +34,7 @@ @ stdcall DestroyPrivateObjectSecurity(ptr) advapi32.DestroyPrivateObjectSecurity @ stdcall DuplicateToken(long long ptr) advapi32.DuplicateToken @ stdcall DuplicateTokenEx(long long ptr long long ptr) advapi32.DuplicateTokenEx -@ stub EqualDomainSid +@ stdcall EqualDomainSid(ptr ptr ptr) advapi32.EqualDomainSid @ stdcall EqualPrefixSid(ptr ptr) advapi32.EqualPrefixSid @ stdcall EqualSid(ptr ptr) advapi32.EqualSid @ stdcall FindFirstFreeAce(ptr ptr) advapi32.FindFirstFreeAce diff --git a/dlls/api-ms-win-security-base-l1-2-0/api-ms-win-security-base-l1-2-0.spec b/dlls/api-ms-win-security-base-l1-2-0/api-ms-win-security-base-l1-2-0.spec index b80ce693607..fc9af375db6 100644 --- a/dlls/api-ms-win-security-base-l1-2-0/api-ms-win-security-base-l1-2-0.spec +++ b/dlls/api-ms-win-security-base-l1-2-0/api-ms-win-security-base-l1-2-0.spec @@ -38,7 +38,7 @@ @ stdcall DestroyPrivateObjectSecurity(ptr) advapi32.DestroyPrivateObjectSecurity @ stdcall DuplicateToken(long long ptr) advapi32.DuplicateToken @ stdcall DuplicateTokenEx(long long ptr long long ptr) advapi32.DuplicateTokenEx -@ stub EqualDomainSid +@ stdcall EqualDomainSid(ptr ptr ptr) advapi32.EqualDomainSid @ stdcall EqualPrefixSid(ptr ptr) advapi32.EqualPrefixSid @ stdcall EqualSid(ptr ptr) advapi32.EqualSid @ stdcall FindFirstFreeAce(ptr ptr) advapi32.FindFirstFreeAce diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index a86a3fe2524..5b2c5ef2e0c 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -323,7 +323,7 @@ @ stdcall EnumUILanguagesW(ptr long long) # @ stub EnumerateStateAtomValues # @ stub EnumerateStateContainerItems -@ stub EqualDomainSid +@ stdcall EqualDomainSid(ptr ptr ptr) @ stdcall EqualPrefixSid(ptr ptr) @ stdcall EqualSid(ptr ptr) @ stdcall EscapeCommFunction(long long) diff --git a/dlls/kernelbase/security.c b/dlls/kernelbase/security.c index 327172c236b..d1736e61b80 100644 --- a/dlls/kernelbase/security.c +++ b/dlls/kernelbase/security.c @@ -274,6 +274,61 @@ BOOL WINAPI EqualSid( PSID sid1, PSID sid2 ) return ret; } +/****************************************************************************** + * EqualDomainSid (kernelbase.@) + */ +BOOL WINAPI EqualDomainSid( PSID sid1, PSID sid2, BOOL *equal ) +{ + MAX_SID builtin_sid, domain_sid1, domain_sid2; + DWORD size; + + TRACE( "(%p,%p,%p)\n", sid1, sid2, equal ); + + if (!IsValidSid( sid1 ) || !IsValidSid( sid2 )) + { + SetLastError( ERROR_INVALID_SID ); + return FALSE; + } + + if (!equal) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + size = sizeof(domain_sid1); + if (GetWindowsAccountDomainSid( sid1, &domain_sid1, &size )) + { + size = sizeof(domain_sid2); + if (GetWindowsAccountDomainSid( sid2, &domain_sid2, &size )) + { + *equal = EqualSid( &domain_sid1, &domain_sid2 ); + SetLastError( 0 ); + return TRUE; + } + } + + size = sizeof(builtin_sid); + if (!CreateWellKnownSid( WinBuiltinDomainSid, NULL, &builtin_sid, &size )) + return FALSE; + + if (!memcmp(GetSidIdentifierAuthority( sid1 )->Value, builtin_sid.IdentifierAuthority.Value, sizeof(builtin_sid.IdentifierAuthority.Value)) && + !memcmp(GetSidIdentifierAuthority( sid2 )->Value, builtin_sid.IdentifierAuthority.Value, sizeof(builtin_sid.IdentifierAuthority.Value))) + { + if (*GetSidSubAuthorityCount( sid1 ) != 0 && *GetSidSubAuthorityCount( sid2 ) != 0 && + (*GetSidSubAuthority( sid1, 0 ) == SECURITY_BUILTIN_DOMAIN_RID || + *GetSidSubAuthority( sid2, 0 ) == SECURITY_BUILTIN_DOMAIN_RID)) + { + *equal = EqualSid( sid1, sid2 ); + SetLastError( 0 ); + return TRUE; + } + } + + SetLastError( ERROR_NON_DOMAIN_SID ); + return FALSE; +} + /****************************************************************************** * FreeSid (kernelbase.@) */ diff --git a/include/winbase.h b/include/winbase.h index 90179b3d857..2d9fafa52d4 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -2002,6 +2002,7 @@ WINBASEAPI BOOL WINAPI EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG_P WINBASEAPI BOOL WINAPI EnumResourceTypesExA(HMODULE,ENUMRESTYPEPROCA,LONG_PTR,DWORD,LANGID); WINBASEAPI BOOL WINAPI EnumResourceTypesExW(HMODULE,ENUMRESTYPEPROCW,LONG_PTR,DWORD,LANGID); #define EnumResourceTypesEx WINELIB_NAME_AW(EnumResourceTypesEx) +WINADVAPI BOOL WINAPI EqualDomainSid(PSID,PSID,BOOL*); WINADVAPI BOOL WINAPI EqualSid(PSID, PSID); WINADVAPI BOOL WINAPI EqualPrefixSid(PSID,PSID); WINBASEAPI DWORD WINAPI EraseTape(HANDLE,DWORD,BOOL); diff --git a/include/winerror.h b/include/winerror.h index 40dd6d9efa9..73027c4189e 100644 --- a/include/winerror.h +++ b/include/winerror.h @@ -762,6 +762,8 @@ static inline HRESULT HRESULT_FROM_WIN32(unsigned int x) #define ERROR_NOT_SUPPORTED_ON_SBS 1254 #define ERROR_SERVER_SHUTDOWN_IN_PROGRESS 1255 #define ERROR_HOST_DOWN 1256 +#define ERROR_NON_ACCOUNT_SID 1257 +#define ERROR_NON_DOMAIN_SID 1258 #define ERROR_ACCESS_DISABLED_BY_POLICY 1260 #define ERROR_REG_NAT_CONSUMPTION 1261 #define ERROR_PKINIT_FAILURE 1263