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;
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());

View File

@ -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 );
}
/******************************************************************************