···11+/*
22+ * PROJECT: ReactOS API tests
33+ * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
44+ * PURPOSE: Tests for the NtImpersonateAnonymousToken API
55+ * COPYRIGHT: Copyright 2021 George Bișoc <george.bisoc@reactos.org>
66+ */
77+88+#include "precomp.h"
99+#include <winreg.h>
1010+1111+#define TOKEN_WITH_EVERYONE_GROUP 1
1212+#define TOKEN_WITHOUT_EVERYONE_GROUP 0
1313+1414+static
1515+HANDLE
1616+GetThreadFromCurrentProcess(_In_ DWORD DesiredAccess)
1717+{
1818+ HANDLE Thread;
1919+2020+ Thread = OpenThread(DesiredAccess, FALSE, GetCurrentThreadId());
2121+ if (!Thread)
2222+ {
2323+ skip("OpenThread() has failed to open the current process' thread (error code: %lu)\n", GetLastError());
2424+ return NULL;
2525+ }
2626+2727+ return Thread;
2828+}
2929+3030+static
3131+VOID
3232+ImpersonateTokenWithEveryoneOrWithout(_In_ DWORD Value)
3333+{
3434+ LONG Result;
3535+ HKEY Key;
3636+3737+ Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
3838+ L"SYSTEM\\CurrentControlSet\\Control\\Lsa",
3939+ 0,
4040+ KEY_SET_VALUE,
4141+ &Key);
4242+ if (Result != ERROR_SUCCESS)
4343+ {
4444+ skip("RegOpenKeyExW() has failed to open the key (error code: %li)\n", Result);
4545+ return;
4646+ }
4747+4848+ Result = RegSetValueExW(Key,
4949+ L"EveryoneIncludesAnonymous",
5050+ 0,
5151+ REG_DWORD,
5252+ (PBYTE)&Value,
5353+ sizeof(Value));
5454+ if (Result != ERROR_SUCCESS)
5555+ {
5656+ skip("RegSetValueExW() has failed to set the value (error code: %li)\n", Result);
5757+ RegCloseKey(Key);
5858+ return;
5959+ }
6060+6161+ RegCloseKey(Key);
6262+}
6363+6464+START_TEST(NtImpersonateAnonymousToken)
6565+{
6666+ NTSTATUS Status;
6767+ BOOL Success;
6868+ HANDLE ThreadHandle;
6969+7070+ ThreadHandle = GetThreadFromCurrentProcess(THREAD_IMPERSONATE);
7171+7272+ /* We give an invalid thread handle */
7373+ Status = NtImpersonateAnonymousToken(NULL);
7474+ ok_hex(Status, STATUS_INVALID_HANDLE);
7575+7676+ /* We want to impersonate the token including Everyone Group SID */
7777+ ImpersonateTokenWithEveryoneOrWithout(TOKEN_WITH_EVERYONE_GROUP);
7878+7979+ /* Impersonate the anonymous logon token */
8080+ Status = NtImpersonateAnonymousToken(ThreadHandle);
8181+ ok_hex(Status, STATUS_SUCCESS);
8282+8383+ /* Now revert to the previous security properties */
8484+ Success = RevertToSelf();
8585+ ok(Success == TRUE, "We should have terminated the impersonation but we couldn't (error code: %lu)\n", GetLastError());
8686+8787+ /* Return to default setting -- token without Everyone Group SID */
8888+ ImpersonateTokenWithEveryoneOrWithout(TOKEN_WITHOUT_EVERYONE_GROUP);
8989+9090+ /* Impersonate the anonymous logon token again */
9191+ Status = NtImpersonateAnonymousToken(ThreadHandle);
9292+ ok_hex(Status, STATUS_SUCCESS);
9393+9494+ /* Now revert to the previous security properties */
9595+ Success = RevertToSelf();
9696+ ok(Success == TRUE, "We should have terminated the impersonation but we couldn't (error code: %lu)\n", GetLastError());
9797+9898+ /*
9999+ * Invalidate the handle and open a new one. This time
100100+ * with the wrong access right mask, the function will
101101+ * outright fail on impersonating the token.
102102+ */
103103+ CloseHandle(ThreadHandle);
104104+ ThreadHandle = GetThreadFromCurrentProcess(SYNCHRONIZE);
105105+106106+ /* The thread handle has incorrect right access */
107107+ Status = NtImpersonateAnonymousToken(ThreadHandle);
108108+ ok_hex(Status, STATUS_ACCESS_DENIED);
109109+110110+ /* We're done with the tests */
111111+ CloseHandle(ThreadHandle);
112112+}