[PATCH] kernelbase: Implement EqualDomainSid.

Dmitry Timoshkov dmitry at baikal.ru
Fri Nov 8 00:12:52 CST 2019


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/advapi32/advapi32.spec     |  2 +-
 dlls/advapi32/tests/security.c  | 78 +++++++++++++++++++++++++++++++++
 dlls/kernelbase/kernelbase.spec |  2 +-
 dlls/kernelbase/security.c      | 55 +++++++++++++++++++++++
 include/winbase.h               |  1 +
 include/winerror.h              |  2 +
 6 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index 54b479dc5d..5a4344852e 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 5f65ed385d..938a0b9e76 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/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index a86a3fe252..5b2c5ef2e0 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 327172c236..d1736e61b8 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 90179b3d85..2d9fafa52d 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 40dd6d9efa..73027c4189 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
-- 
2.20.1




More information about the wine-devel mailing list