From 6946d78ed9e88536951357ae5574e251f0007006 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 22 Sep 2020 17:31:16 -0500 Subject: [PATCH] kernelbase: Implement CreateRestrictedToken(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on a patch by Michael Müller. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/advapi32/tests/security.c | 26 ++++++++--------- dlls/kernelbase/security.c | 51 +++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 957ebc3036a..6919ea64ce9 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -5237,7 +5237,7 @@ static void test_CreateRestrictedToken(void) is_member = TRUE; ret = pCheckTokenMembership(r_token, removed_sid, &is_member); ok(ret, "got error %d\n", GetLastError()); - todo_wine ok(!is_member, "not a member\n"); + ok(!is_member, "not a member\n"); ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size); ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", @@ -5251,8 +5251,8 @@ static void test_CreateRestrictedToken(void) if (EqualSid(groups2->Groups[i].Sid, removed_sid)) { DWORD attr = groups2->Groups[i].Attributes; - todo_wine ok(attr & SE_GROUP_USE_FOR_DENY_ONLY, "got wrong attributes %#x\n", attr); - todo_wine ok(!(attr & SE_GROUP_ENABLED), "got wrong attributes %#x\n", attr); + ok(attr & SE_GROUP_USE_FOR_DENY_ONLY, "got wrong attributes %#x\n", attr); + ok(!(attr & SE_GROUP_ENABLED), "got wrong attributes %#x\n", attr); break; } } @@ -5307,7 +5307,7 @@ static void test_CreateRestrictedToken(void) priv_set.Privilege[0].Attributes = 0; ret = PrivilegeCheck(r_token, &priv_set, &is_member); ok(ret, "got error %u\n", GetLastError()); - todo_wine ok(!is_member, "privilege should not be enabled\n"); + ok(!is_member, "privilege should not be enabled\n"); ret = GetTokenInformation(r_token, TokenPrivileges, privs, sizeof(privs_buffer), &size); ok(ret, "got error %u\n", GetLastError()); @@ -5318,7 +5318,7 @@ static void test_CreateRestrictedToken(void) if (!memcmp(&privs->Privileges[i].Luid, &luid, sizeof(luid))) is_member = TRUE; } - todo_wine ok(!is_member, "disabled privilege should not be present\n"); + ok(!is_member, "disabled privilege should not be present\n"); CloseHandle(r_token); @@ -7679,8 +7679,8 @@ static void test_duplicate_handle_access(void) SetLastError(0xdeadbeef); event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup"); - todo_wine ok(!event2, "expected failure\n"); - todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); + ok(!event2, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); ok(ret, "got error %u\n", GetLastError()); @@ -7688,8 +7688,8 @@ static void test_duplicate_handle_access(void) SetLastError(0xdeadbeef); ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); - todo_wine ok(!ret, "expected failure\n"); - todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); ret = RevertToSelf(); ok(ret, "got error %u\n", GetLastError()); @@ -7751,13 +7751,13 @@ static void test_duplicate_handle_access_child(void) SetLastError(0xdeadbeef); ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0); - todo_wine ok(!ret, "expected failure\n"); - todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); SetLastError(0xdeadbeef); ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); - todo_wine ok(!ret, "expected failure\n"); - todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); + ok(!ret, "expected failure\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); ret = RevertToSelf(); ok(ret, "failed to revert, error %u\n", GetLastError()); diff --git a/dlls/kernelbase/security.c b/dlls/kernelbase/security.c index 72bb5892d3b..97943048b01 100644 --- a/dlls/kernelbase/security.c +++ b/dlls/kernelbase/security.c @@ -646,27 +646,46 @@ exit: * CreateRestrictedToken (kernelbase.@) */ BOOL WINAPI CreateRestrictedToken( HANDLE token, DWORD flags, - DWORD disable_count, PSID_AND_ATTRIBUTES disable_sids, - DWORD delete_count, PLUID_AND_ATTRIBUTES delete_privs, - DWORD restrict_count, PSID_AND_ATTRIBUTES restrict_sids, PHANDLE ret ) + DWORD disable_sid_count, SID_AND_ATTRIBUTES *disable_sids, + DWORD delete_priv_count, LUID_AND_ATTRIBUTES *delete_privs, + DWORD restrict_sid_count, SID_AND_ATTRIBUTES *restrict_sids, HANDLE *ret ) { - TOKEN_TYPE type; - SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous; - DWORD size; + TOKEN_PRIVILEGES *nt_privs = NULL; + TOKEN_GROUPS *nt_disable_sids = NULL, *nt_restrict_sids = NULL; + NTSTATUS status = STATUS_NO_MEMORY; - FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n", - token, flags, disable_count, disable_sids, delete_count, delete_privs, - restrict_count, restrict_sids, ret ); + TRACE("token %p, flags %#x, disable_sids %u %p, delete_privs %u %p, restrict_sids %u %p, ret %p\n", + token, flags, disable_sid_count, disable_sids, delete_priv_count, delete_privs, + restrict_sid_count, restrict_sids, ret); - size = sizeof(type); - if (!GetTokenInformation( token, TokenType, &type, size, &size )) return FALSE; - if (type == TokenImpersonation) + if (disable_sid_count) { - size = sizeof(level); - if (!GetTokenInformation( token, TokenImpersonationLevel, &level, size, &size )) - return FALSE; + if (!(nt_disable_sids = heap_alloc( offsetof( TOKEN_GROUPS, Groups[disable_sid_count] ) ))) goto out; + nt_disable_sids->GroupCount = disable_sid_count; + memcpy( nt_disable_sids->Groups, disable_sids, disable_sid_count * sizeof(SID_AND_ATTRIBUTES) ); } - return DuplicateTokenEx( token, MAXIMUM_ALLOWED, NULL, level, type, ret ); + + if (delete_priv_count) + { + if (!(nt_privs = heap_alloc( offsetof( TOKEN_GROUPS, Groups[delete_priv_count] ) ))) goto out; + nt_privs->PrivilegeCount = delete_priv_count; + memcpy( nt_privs->Privileges, delete_privs, delete_priv_count * sizeof(SID_AND_ATTRIBUTES) ); + } + + if (restrict_sid_count) + { + if (!(nt_restrict_sids = heap_alloc( offsetof( TOKEN_GROUPS, Groups[restrict_sid_count] ) ))) goto out; + nt_restrict_sids->GroupCount = restrict_sid_count; + memcpy( nt_restrict_sids->Groups, restrict_sids, restrict_sid_count * sizeof(SID_AND_ATTRIBUTES) ); + } + + status = NtFilterToken(token, flags, nt_disable_sids, nt_privs, nt_restrict_sids, ret); + +out: + heap_free(nt_disable_sids); + heap_free(nt_privs); + heap_free(nt_restrict_sids); + return set_ntstatus( status ); } /******************************************************************************