CEF sometimes uses that during sandbox initialization.
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/sec.c | 10 ++++++++++ include/winternl.h | 1 + 3 files changed, 12 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 293a0ab290e..9975f709116 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -614,6 +614,7 @@ @ stdcall RtlDeleteTimerQueueEx(ptr ptr) @ stdcall RtlDeregisterWait(ptr) @ stdcall RtlDeregisterWaitEx(ptr ptr) +@ stdcall RtlDeriveCapabilitySidsFromName(ptr ptr ptr) @ stdcall RtlDestroyAtomTable(ptr) @ stdcall RtlDestroyEnvironment(ptr) @ stdcall RtlDestroyHandleTable(ptr) diff --git a/dlls/ntdll/sec.c b/dlls/ntdll/sec.c index 4188faafb4b..36b613d53e7 100644 --- a/dlls/ntdll/sec.c +++ b/dlls/ntdll/sec.c @@ -1812,3 +1812,13 @@ NTSTATUS WINAPI RtlDefaultNpAcl(PACL *pAcl) *pAcl = NULL; return STATUS_SUCCESS; } + +/****************************************************************************** + * RtlDeriveCapabilitySidsFromName (NTDLL.@) + */ +NTSTATUS WINAPI RtlDeriveCapabilitySidsFromName( UNICODE_STRING *cap_name, PSID cap_group_sid, PSID cap_sid ) +{ + FIXME( "cap_name %s, cap_group_sid %p, cap_sid %p.\n", debugstr_us(cap_name), cap_group_sid, cap_sid ); + + return STATUS_NOT_SUPPORTED; +} diff --git a/include/winternl.h b/include/winternl.h index d3537cc774d..2e01c308435 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -4671,6 +4671,7 @@ NTSYSAPI NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE, HANDLE); NTSYSAPI PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams(RTL_USER_PROCESS_PARAMETERS*); NTSYSAPI NTSTATUS WINAPI RtlDeregisterWait(HANDLE); NTSYSAPI NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE,HANDLE); +NTSYSAPI NTSTATUS WINAPI RtlDeriveCapabilitySidsFromName(UNICODE_STRING *cap_name, PSID cap_group_sid, PSID cap_sid); NTSYSAPI NTSTATUS WINAPI RtlDestroyAtomTable(RTL_ATOM_TABLE); NTSYSAPI NTSTATUS WINAPI RtlDestroyEnvironment(PWSTR); NTSYSAPI NTSTATUS WINAPI RtlDestroyHandleTable(RTL_HANDLE_TABLE *);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/tests/rtl.c | 66 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 117d9eed067..86e634daad8 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -98,6 +98,7 @@ static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, U static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *); static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **); static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *); +static NTSTATUS (WINAPI *pRtlDeriveCapabilitySidsFromName)(UNICODE_STRING *, PSID, PSID);
static HMODULE hkernel32 = 0; static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); @@ -140,6 +141,7 @@ static void InitFunctionPtrs(void) pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules"); pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification"); pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification"); + pRtlDeriveCapabilitySidsFromName = (void *)GetProcAddress(hntdll, "RtlDeriveCapabilitySidsFromName"); } hkernel32 = LoadLibraryA("kernel32.dll"); ok(hkernel32 != 0, "LoadLibrary failed\n"); @@ -3649,6 +3651,69 @@ static void test_RtlValidSecurityDescriptor(void) free(sd); }
+static void test_RtlDeriveCapabilitySidsFromName(void) +{ + static const SID_IDENTIFIER_AUTHORITY app_authority = { SECURITY_APP_PACKAGE_AUTHORITY }; + static SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY }; + struct + { + const WCHAR *name; + DWORD hash[8]; + } + tests[] = + { + { NULL, { 0x42c4b0e3, 0x141cfc98, 0xc8f4fb9a, 0x24b96f99, 0xe441ae27, 0x4c939b64, 0x1b9995a4, 0x55b85278, }}, + { L"__AB", { 0xddd798eb, 0x367bd9d0, 0x1c9e610a, 0x0c43dc7e, 0xe91d8625, 0x395e7cf8, 0xe6e7c3d2, 0x2661e620 }}, + { L"__ab", { 0xddd798eb, 0x367bd9d0, 0x1c9e610a, 0x0c43dc7e, 0xe91d8625, 0x395e7cf8, 0xe6e7c3d2, 0x2661e620 }}, + { L"0123456789012345678901234567890123456789", + { 0x3c45e3e6, 0xa598e751, 0x2eb11e4c, 0x04e073fd, 0xb7c331a3, 0x07b1214d, 0xd8dee260, 0xa0966ecf }}, + }; + UNICODE_STRING cap_name; + SID *group_sid, *sid; + unsigned int i, size; + NTSTATUS status; + + if (!pRtlDeriveCapabilitySidsFromName) + { + win_skip( "RtlDeriveCapabilitySidsFromName is not available.\n" ); + return; + } + + size = RtlLengthRequiredSid( 10 ); + sid = malloc( size ); + group_sid = malloc( size ); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context( "%s", debugstr_w(tests[i].name) ); + memset( sid, 0, size ); + memset( group_sid, 0, size ); + RtlInitUnicodeString( &cap_name, tests[i].name ); + todo_wine + { + status = pRtlDeriveCapabilitySidsFromName( &cap_name, group_sid, sid ); + ok( !status, "got %#lx.\n", status ); + + ok( sid->Revision == SID_REVISION, "got %u.\n", sid->Revision ); + ok( !memcmp( &sid->IdentifierAuthority, &app_authority, sizeof(app_authority) ), "mismatch.\n" ); + ok( sid->SubAuthorityCount == 10, "got %u.\n", sid->SubAuthorityCount ); + ok ( sid->SubAuthority[0] == SECURITY_BATCH_RID, "got %lu.\n", sid->SubAuthority[0] ); + ok ( sid->SubAuthority[1] == SECURITY_CAPABILITY_APP_RID, "got %lu.\n", sid->SubAuthority[1] ); + ok( !memcmp( sid->SubAuthority + 2, tests[i].hash, sizeof(tests[i].hash) ), "mismatch.\n" ); + + ok( group_sid->Revision == SID_REVISION, "got %u.\n", group_sid->Revision ); + ok( !memcmp( &group_sid->IdentifierAuthority, &nt_authority, sizeof(nt_authority) ), "mismatch.\n" ); + ok( group_sid->SubAuthorityCount == 9, "got %u.\n", group_sid->SubAuthorityCount ); + ok ( group_sid->SubAuthority[0] == SECURITY_BUILTIN_DOMAIN_RID, "got %lu.\n", group_sid->SubAuthority[0] ); + ok( !memcmp( group_sid->SubAuthority + 1, tests[i].hash, sizeof(tests[i].hash) ), "mismatch.\n" ); + } + winetest_pop_context(); + } + + free( sid ); + free( group_sid ); +} + START_TEST(rtl) { InitFunctionPtrs(); @@ -3695,4 +3760,5 @@ START_TEST(rtl) test_RtlFirstFreeAce(); test_RtlInitializeSid(); test_RtlValidSecurityDescriptor(); + test_RtlDeriveCapabilitySidsFromName(); }
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/Makefile.in | 1 + dlls/ntdll/ntdll_misc.h | 11 +++ dlls/ntdll/sec.c | 33 +++++++- dlls/ntdll/sha256.c | 169 ++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/tests/rtl.c | 3 - 5 files changed, 212 insertions(+), 5 deletions(-) create mode 100644 dlls/ntdll/sha256.c
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in index 2e862c68b7e..59b8c86f271 100644 --- a/dlls/ntdll/Makefile.in +++ b/dlls/ntdll/Makefile.in @@ -35,6 +35,7 @@ C_SRCS = \ rtlbitmap.c \ rtlstr.c \ sec.c \ + sha256.c \ signal_arm.c \ signal_arm64.c \ signal_i386.c \ diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index ad8e2691224..d23c92e7c1a 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -131,4 +131,15 @@ static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len ) extern TEB_FLS_DATA *fls_alloc_data(void) DECLSPEC_HIDDEN; extern void heap_thread_detach(void) DECLSPEC_HIDDEN;
+typedef struct +{ + ULONG64 len; + DWORD h[8]; + UCHAR buf[64]; +} SHA256_CTX; + +void sha256_init(SHA256_CTX *ctx) DECLSPEC_HIDDEN; +void sha256_update(SHA256_CTX *ctx, const UCHAR *buffer, ULONG len) DECLSPEC_HIDDEN; +void sha256_finalize(SHA256_CTX *ctx, UCHAR *buffer) DECLSPEC_HIDDEN; + #endif diff --git a/dlls/ntdll/sec.c b/dlls/ntdll/sec.c index 36b613d53e7..a4f788d2054 100644 --- a/dlls/ntdll/sec.c +++ b/dlls/ntdll/sec.c @@ -1818,7 +1818,36 @@ NTSTATUS WINAPI RtlDefaultNpAcl(PACL *pAcl) */ NTSTATUS WINAPI RtlDeriveCapabilitySidsFromName( UNICODE_STRING *cap_name, PSID cap_group_sid, PSID cap_sid ) { - FIXME( "cap_name %s, cap_group_sid %p, cap_sid %p.\n", debugstr_us(cap_name), cap_group_sid, cap_sid ); + static const SID_IDENTIFIER_AUTHORITY app_authority = { SECURITY_APP_PACKAGE_AUTHORITY }; + static const SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY }; + UNICODE_STRING cap_upcase; + SHA256_CTX hash_ctx; + NTSTATUS status; + ULONG hash[8]; + SID *sid; + + TRACE( "cap_name %s, cap_group_sid %p, cap_sid %p.\n", debugstr_us(cap_name), cap_group_sid, cap_sid ); + + if ((status = RtlUpcaseUnicodeString( &cap_upcase, cap_name, TRUE ))) return status; + sha256_init( &hash_ctx ); + sha256_update( &hash_ctx, (UCHAR *)cap_upcase.Buffer, cap_upcase.Length ); + sha256_finalize( &hash_ctx, (UCHAR *)hash ); + RtlFreeUnicodeString( &cap_upcase ); + + sid = cap_sid; + sid->Revision = SID_REVISION; + sid->IdentifierAuthority = app_authority; + sid->SubAuthorityCount = 2 + ARRAY_SIZE(hash); + sid->SubAuthority[0] = SECURITY_BATCH_RID; + sid->SubAuthority[1] = SECURITY_CAPABILITY_APP_RID; + memcpy( sid->SubAuthority + 2, hash, sizeof(hash) ); + + sid = cap_group_sid; + sid->Revision = SID_REVISION; + sid->IdentifierAuthority = nt_authority; + sid->SubAuthorityCount = 1 + ARRAY_SIZE(hash); + sid->SubAuthority[0] = SECURITY_BUILTIN_DOMAIN_RID; + memcpy( sid->SubAuthority + 1, hash, sizeof(hash) );
- return STATUS_NOT_SUPPORTED; + return STATUS_SUCCESS; } diff --git a/dlls/ntdll/sha256.c b/dlls/ntdll/sha256.c new file mode 100644 index 00000000000..da97e810070 --- /dev/null +++ b/dlls/ntdll/sha256.c @@ -0,0 +1,169 @@ +/* + * Copyright 2016 Michael Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +/* Based on public domain implementation from + https://git.musl-libc.org/cgit/musl/tree/src/crypt/crypt_sha256.c */ + +#include "ntdll_misc.h" + +static DWORD ror(DWORD n, int k) { return (n >> k) | (n << (32-k)); } +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) ((x & y) | (z & (x | y))) +#define S0(x) (ror(x,2) ^ ror(x,13) ^ ror(x,22)) +#define S1(x) (ror(x,6) ^ ror(x,11) ^ ror(x,25)) +#define R0(x) (ror(x,7) ^ ror(x,18) ^ (x>>3)) +#define R1(x) (ror(x,17) ^ ror(x,19) ^ (x>>10)) + +static const DWORD K[64] = +{ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static void processblock(SHA256_CTX *ctx, const UCHAR *buffer) +{ + DWORD W[64], t1, t2, a, b, c, d, e, f, g, h; + int i; + + for (i = 0; i < 16; i++) + { + W[i] = (DWORD)buffer[4*i]<<24; + W[i] |= (DWORD)buffer[4*i+1]<<16; + W[i] |= (DWORD)buffer[4*i+2]<<8; + W[i] |= buffer[4*i+3]; + } + + for (; i < 64; i++) + W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16]; + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + for (i = 0; i < 64; i++) + { + t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i]; + t2 = S0(a) + Maj(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; +} + +static void pad(SHA256_CTX *ctx) +{ + ULONG64 r = ctx->len % 64; + + ctx->buf[r++] = 0x80; + + if (r > 56) + { + memset(ctx->buf + r, 0, 64 - r); + r = 0; + processblock(ctx, ctx->buf); + } + + memset(ctx->buf + r, 0, 56 - r); + ctx->len *= 8; + ctx->buf[56] = ctx->len >> 56; + ctx->buf[57] = ctx->len >> 48; + ctx->buf[58] = ctx->len >> 40; + ctx->buf[59] = ctx->len >> 32; + ctx->buf[60] = ctx->len >> 24; + ctx->buf[61] = ctx->len >> 16; + ctx->buf[62] = ctx->len >> 8; + ctx->buf[63] = ctx->len; + + processblock(ctx, ctx->buf); +} + +void sha256_init(SHA256_CTX *ctx) +{ + ctx->len = 0; + ctx->h[0] = 0x6a09e667; + ctx->h[1] = 0xbb67ae85; + ctx->h[2] = 0x3c6ef372; + ctx->h[3] = 0xa54ff53a; + ctx->h[4] = 0x510e527f; + ctx->h[5] = 0x9b05688c; + ctx->h[6] = 0x1f83d9ab; + ctx->h[7] = 0x5be0cd19; +} + +void sha256_update(SHA256_CTX *ctx, const UCHAR *buffer, ULONG len) +{ + const UCHAR *p = buffer; + ULONG64 r = ctx->len % 64; + + ctx->len += len; + if (r) + { + if (len < 64 - r) + { + memcpy(ctx->buf + r, p, len); + return; + } + memcpy(ctx->buf + r, p, 64 - r); + len -= 64 - r; + p += 64 - r; + processblock(ctx, ctx->buf); + } + for (; len >= 64; len -= 64, p += 64) + processblock(ctx, p); + memcpy(ctx->buf, p, len); +} + +void sha256_finalize(SHA256_CTX *ctx, UCHAR *buffer) +{ + int i; + + pad(ctx); + for (i = 0; i < 8; i++) + { + buffer[4*i] = ctx->h[i] >> 24; + buffer[4*i+1] = ctx->h[i] >> 16; + buffer[4*i+2] = ctx->h[i] >> 8; + buffer[4*i+3] = ctx->h[i]; + } +} diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 86e634daad8..060d7a4fde9 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -3689,8 +3689,6 @@ static void test_RtlDeriveCapabilitySidsFromName(void) memset( sid, 0, size ); memset( group_sid, 0, size ); RtlInitUnicodeString( &cap_name, tests[i].name ); - todo_wine - { status = pRtlDeriveCapabilitySidsFromName( &cap_name, group_sid, sid ); ok( !status, "got %#lx.\n", status );
@@ -3706,7 +3704,6 @@ static void test_RtlDeriveCapabilitySidsFromName(void) ok( group_sid->SubAuthorityCount == 9, "got %u.\n", group_sid->SubAuthorityCount ); ok ( group_sid->SubAuthority[0] == SECURITY_BUILTIN_DOMAIN_RID, "got %lu.\n", group_sid->SubAuthority[0] ); ok( !memcmp( group_sid->SubAuthority + 1, tests[i].hash, sizeof(tests[i].hash) ), "mismatch.\n" ); - } winetest_pop_context(); }
From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernelbase/kernelbase.spec | 1 + dlls/kernelbase/security.c | 46 +++++++++++++++++++++++++++++++++ include/winbase.h | 1 + 3 files changed, 48 insertions(+)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 104dd99d619..9c096d1b003 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -241,6 +241,7 @@ @ stdcall CtrlRoutine(ptr) # @ stub CveEventWrite @ stdcall DeactivateActCtx(long long) +@ stdcall DeriveCapabilitySidsFromName(ptr ptr ptr ptr ptr) @ stdcall DebugActiveProcess(long) @ stdcall DebugActiveProcessStop(long) @ stdcall DebugBreak() diff --git a/dlls/kernelbase/security.c b/dlls/kernelbase/security.c index 4434a59a53a..c432d8eacd3 100644 --- a/dlls/kernelbase/security.c +++ b/dlls/kernelbase/security.c @@ -1512,3 +1512,49 @@ BOOL WINAPI SetCachedSigningLevel( PHANDLE source, ULONG count, ULONG flags, HAN FIXME( "%p %lu %lu %p - stub\n", source, count, flags, file ); return TRUE; } + +/****************************************************************************** + * DeriveCapabilitySidsFromName (kernelbase.@) + */ +BOOL WINAPI DeriveCapabilitySidsFromName( const WCHAR *cap_name, PSID **cap_group_sids, DWORD *cap_group_sid_count, + PSID **cap_sids, DWORD *cap_sid_count ) +{ + NTSTATUS status = STATUS_NO_MEMORY; + UNICODE_STRING name_us; + DWORD size; + + TRACE( "cap_name %s, cap_group_sids %p, cap_group_sid_count %p, cap_sids %p, cap_sid_count %p.\n", + debugstr_w(cap_name), cap_group_sids, cap_group_sid_count, cap_sids, cap_sid_count ); + + *cap_group_sid_count = 1; + *cap_sid_count = 1; + *cap_group_sids = NULL; + *cap_sids = NULL; + + if (!(*cap_group_sids = RtlAllocateHeap( GetProcessHeap(), 0, *cap_group_sid_count * sizeof(**cap_group_sids) ))) + goto done; + if (!(*cap_sids = RtlAllocateHeap( GetProcessHeap(), 0, *cap_sid_count * sizeof(**cap_sids) ))) + goto done; + + /* There is no obvious way to query returned subauthority count for RtlDeriveCapabilitySidsFromName, + * so let's reserve a bit more. */ + size = RtlLengthRequiredSid( 16 ); + if (!(**cap_group_sids = RtlAllocateHeap( GetProcessHeap(), 0, size ))) goto done; + if (!(**cap_sids = RtlAllocateHeap( GetProcessHeap(), 0, size ))) goto done; + RtlInitUnicodeString( &name_us, cap_name ); + status = RtlDeriveCapabilitySidsFromName( &name_us, **cap_group_sids, **cap_sids ); + +done: + if (!status) return TRUE; + if (*cap_group_sids) + { + RtlFreeHeap( GetProcessHeap(), 0, **cap_group_sids ); + RtlFreeHeap( GetProcessHeap(), 0, *cap_group_sids ); + } + if (*cap_sids) + { + RtlFreeHeap( GetProcessHeap(), 0, **cap_sids ); + RtlFreeHeap( GetProcessHeap(), 0, *cap_sids ); + } + return set_ntstatus( status ); +} diff --git a/include/winbase.h b/include/winbase.h index 135c2603a70..f656c302317 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -2002,6 +2002,7 @@ WINBASEAPI BOOL WINAPI DeleteVolumeMountPointW(LPCWSTR); #define DeleteVolumeMountPoint WINELIB_NAME_AW(DeleteVolumeMountPoint) WINBASEAPI BOOL WINAPI DequeueUmsCompletionListItems(void *, DWORD, PUMS_CONTEXT *); WINADVAPI BOOL WINAPI DeregisterEventSource(HANDLE); +WINADVAPI BOOL WINAPI DeriveCapabilitySidsFromName(const WCHAR *, PSID **, DWORD *, PSID **, DWORD *); WINADVAPI BOOL WINAPI DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR*); WINBASEAPI BOOL WINAPI DeviceIoControl(HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPDWORD,LPOVERLAPPED); WINBASEAPI BOOL WINAPI DisableThreadLibraryCalls(HMODULE);
From: Paul Gofman pgofman@codeweavers.com
--- dlls/kernelbase/tests/Makefile.in | 1 + dlls/kernelbase/tests/security.c | 99 +++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 dlls/kernelbase/tests/security.c
diff --git a/dlls/kernelbase/tests/Makefile.in b/dlls/kernelbase/tests/Makefile.in index b51eaefcd13..88a86b70094 100644 --- a/dlls/kernelbase/tests/Makefile.in +++ b/dlls/kernelbase/tests/Makefile.in @@ -4,6 +4,7 @@ C_SRCS = \ file.c \ path.c \ process.c \ + security.c \ sync.c
RC_SRCS = \ diff --git a/dlls/kernelbase/tests/security.c b/dlls/kernelbase/tests/security.c new file mode 100644 index 00000000000..e5f1ab93b01 --- /dev/null +++ b/dlls/kernelbase/tests/security.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2023 Paul Gofman for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> +#include <stdlib.h> + +#include <ntstatus.h> +#define WIN32_NO_STATUS +#include <windef.h> +#include <winbase.h> +#include <winerror.h> +#include <winternl.h> + +#include "wine/test.h" + +static BOOL (WINAPI *pDeriveCapabilitySidsFromName)(const WCHAR *, PSID **, DWORD *, PSID **, DWORD *); + +static NTSTATUS (WINAPI *pRtlDeriveCapabilitySidsFromName)(UNICODE_STRING *, PSID, PSID); + +static void test_DeriveCapabilitySidsFromName(void) +{ + BYTE auth_count_sid, auth_count_group_sid; + PSID *check_group_sid, *check_sid; + DWORD sid_count, group_sid_count; + PSID *group_sids, *sids; + UNICODE_STRING name_us; + NTSTATUS status; + DWORD size; + BOOL bret; + + if (!pDeriveCapabilitySidsFromName) + { + win_skip ("DeriveCapabilitySidsFromName is not available.\n"); + return; + } + + if (0) + { + /* Crashes on Windows. */ + pDeriveCapabilitySidsFromName(L"test", NULL, &group_sid_count, NULL, &sid_count); + } + + sid_count = group_sid_count = 0xdeadbeef; + SetLastError(0xdeadbeef); + bret = pDeriveCapabilitySidsFromName(L"test", &group_sids, &group_sid_count, &sids, &sid_count); + ok(bret && GetLastError() == 0xdeadbeef, "got bret %d, err %lu.\n", bret, GetLastError()); + ok(group_sid_count == 1, "got %lu.\n", group_sid_count); + ok(sid_count == 1, "got %lu.\n", sid_count); + + auth_count_sid = *RtlSubAuthorityCountSid(sids[0]); + auth_count_group_sid = *RtlSubAuthorityCountSid(group_sids[0]); + + size = RtlLengthRequiredSid(auth_count_sid); + check_sid = malloc( size ); + size = RtlLengthRequiredSid(auth_count_group_sid); + check_group_sid = malloc( size ); + + RtlInitUnicodeString(&name_us, L"test"); + status = pRtlDeriveCapabilitySidsFromName(&name_us, check_group_sid, check_sid); + ok(!status, "failed, status %#lx.\n", status); + ok(!memcmp(sids[0], check_sid, RtlLengthRequiredSid(auth_count_sid)), "mismatch.\n"); + ok(!memcmp(group_sids[0], check_group_sid, RtlLengthRequiredSid(auth_count_group_sid)), "mismatch.\n"); + + free(check_sid); + free(check_group_sid); + + LocalFree(group_sids[0]); + LocalFree(group_sids); + LocalFree(sids[0]); + LocalFree(sids); +} + +START_TEST(security) +{ + HMODULE hmod; + + hmod = LoadLibraryA("kernelbase.dll"); + pDeriveCapabilitySidsFromName = (void *)GetProcAddress(hmod, "DeriveCapabilitySidsFromName"); + + hmod = LoadLibraryA("ntdll.dll"); + pRtlDeriveCapabilitySidsFromName = (void *)GetProcAddress(hmod, "RtlDeriveCapabilitySidsFromName"); + + test_DeriveCapabilitySidsFromName(); +}
Even though MS docs [1] say that DeriveCapabilitySidsFromName is in advapi32 or kernel32 I could not find it there (the docs also say that it is available since Windows Server 2003 for desktop apps which also seems to be not the case).
1. https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-secur...