kernelbase: Implement CreateRestrictedToken().

Based on a patch by Michael Müller.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2020-09-22 17:31:16 -05:00 committed by Alexandre Julliard
parent 8c5638aa5e
commit 6946d78ed9
2 changed files with 48 additions and 29 deletions

View File

@ -5237,7 +5237,7 @@ static void test_CreateRestrictedToken(void)
is_member = TRUE; is_member = TRUE;
ret = pCheckTokenMembership(r_token, removed_sid, &is_member); ret = pCheckTokenMembership(r_token, removed_sid, &is_member);
ok(ret, "got error %d\n", GetLastError()); 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); ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size);
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n", 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)) if (EqualSid(groups2->Groups[i].Sid, removed_sid))
{ {
DWORD attr = groups2->Groups[i].Attributes; DWORD attr = groups2->Groups[i].Attributes;
todo_wine ok(attr & SE_GROUP_USE_FOR_DENY_ONLY, "got wrong attributes %#x\n", attr); 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_ENABLED), "got wrong attributes %#x\n", attr);
break; break;
} }
} }
@ -5307,7 +5307,7 @@ static void test_CreateRestrictedToken(void)
priv_set.Privilege[0].Attributes = 0; priv_set.Privilege[0].Attributes = 0;
ret = PrivilegeCheck(r_token, &priv_set, &is_member); ret = PrivilegeCheck(r_token, &priv_set, &is_member);
ok(ret, "got error %u\n", GetLastError()); 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); ret = GetTokenInformation(r_token, TokenPrivileges, privs, sizeof(privs_buffer), &size);
ok(ret, "got error %u\n", GetLastError()); 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))) if (!memcmp(&privs->Privileges[i].Luid, &luid, sizeof(luid)))
is_member = TRUE; 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); CloseHandle(r_token);
@ -7679,8 +7679,8 @@ static void test_duplicate_handle_access(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup"); event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
todo_wine ok(!event2, "expected failure\n"); ok(!event2, "expected failure\n");
todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
ok(ret, "got error %u\n", GetLastError()); ok(ret, "got error %u\n", GetLastError());
@ -7688,8 +7688,8 @@ static void test_duplicate_handle_access(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
todo_wine ok(!ret, "expected failure\n"); ok(!ret, "expected failure\n");
todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
ret = RevertToSelf(); ret = RevertToSelf();
ok(ret, "got error %u\n", GetLastError()); ok(ret, "got error %u\n", GetLastError());
@ -7751,13 +7751,13 @@ static void test_duplicate_handle_access_child(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0); ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0);
todo_wine ok(!ret, "expected failure\n"); ok(!ret, "expected failure\n");
todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0); ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
todo_wine ok(!ret, "expected failure\n"); ok(!ret, "expected failure\n");
todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError()); ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %u\n", GetLastError());
ret = RevertToSelf(); ret = RevertToSelf();
ok(ret, "failed to revert, error %u\n", GetLastError()); ok(ret, "failed to revert, error %u\n", GetLastError());

View File

@ -646,27 +646,46 @@ exit:
* CreateRestrictedToken (kernelbase.@) * CreateRestrictedToken (kernelbase.@)
*/ */
BOOL WINAPI CreateRestrictedToken( HANDLE token, DWORD flags, BOOL WINAPI CreateRestrictedToken( HANDLE token, DWORD flags,
DWORD disable_count, PSID_AND_ATTRIBUTES disable_sids, DWORD disable_sid_count, SID_AND_ATTRIBUTES *disable_sids,
DWORD delete_count, PLUID_AND_ATTRIBUTES delete_privs, DWORD delete_priv_count, LUID_AND_ATTRIBUTES *delete_privs,
DWORD restrict_count, PSID_AND_ATTRIBUTES restrict_sids, PHANDLE ret ) DWORD restrict_sid_count, SID_AND_ATTRIBUTES *restrict_sids, HANDLE *ret )
{ {
TOKEN_TYPE type; TOKEN_PRIVILEGES *nt_privs = NULL;
SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous; TOKEN_GROUPS *nt_disable_sids = NULL, *nt_restrict_sids = NULL;
DWORD size; NTSTATUS status = STATUS_NO_MEMORY;
FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n", TRACE("token %p, flags %#x, disable_sids %u %p, delete_privs %u %p, restrict_sids %u %p, ret %p\n",
token, flags, disable_count, disable_sids, delete_count, delete_privs, token, flags, disable_sid_count, disable_sids, delete_priv_count, delete_privs,
restrict_count, restrict_sids, ret ); restrict_sid_count, restrict_sids, ret);
size = sizeof(type); if (disable_sid_count)
if (!GetTokenInformation( token, TokenType, &type, size, &size )) return FALSE;
if (type == TokenImpersonation)
{ {
size = sizeof(level); if (!(nt_disable_sids = heap_alloc( offsetof( TOKEN_GROUPS, Groups[disable_sid_count] ) ))) goto out;
if (!GetTokenInformation( token, TokenImpersonationLevel, &level, size, &size )) nt_disable_sids->GroupCount = disable_sid_count;
return FALSE; 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 );
} }
/****************************************************************************** /******************************************************************************