Signed-off-by: Dmitry Timoshkov <dmitry(a)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