api: elevate to SYSTEM in WintunEnumAdapters()

The WintunEnumAdapters() requires namespace mutex. However,
NamespaceTakePoolMutex() works as SYSTEM user only.

WireGuard is using the WintunEnumAdapters() in its manager service to
cleanup stale adapters. As the WireGuard manager service is running as
SYSTEM, this requirement was not apparent before.

This commit also extends the example project to list its existing
adapters at start.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2021-03-08 13:48:29 +01:00
parent bc5cde8916
commit cef7922556
2 changed files with 21 additions and 3 deletions

View File

@ -1983,13 +1983,18 @@ cleanupToken:
_Return_type_success_(return != FALSE) BOOL WINAPI _Return_type_success_(return != FALSE) BOOL WINAPI
WintunEnumAdapters(_In_z_ const WCHAR *Pool, _In_ WINTUN_ENUM_CALLBACK Func, _In_ LPARAM Param) WintunEnumAdapters(_In_z_ const WCHAR *Pool, _In_ WINTUN_ENUM_CALLBACK Func, _In_ LPARAM Param)
{ {
HANDLE Mutex = NamespaceTakePoolMutex(Pool); if (!ElevateToSystem())
if (!Mutex)
{ {
LOG(WINTUN_LOG_ERR, L"Failed to take %s pool mutex", Pool); LOG(WINTUN_LOG_ERR, L"Failed to impersonate SYSTEM user");
return FALSE; return FALSE;
} }
DWORD LastError = ERROR_SUCCESS; DWORD LastError = ERROR_SUCCESS;
HANDLE Mutex = NamespaceTakePoolMutex(Pool);
if (!Mutex)
{
LastError = LOG(WINTUN_LOG_ERR, L"Failed to take %s pool mutex", Pool);
goto cleanupToken;
}
HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); HDEVINFO DevInfo = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
if (DevInfo == INVALID_HANDLE_VALUE) if (DevInfo == INVALID_HANDLE_VALUE)
{ {
@ -2022,5 +2027,7 @@ _Return_type_success_(return != FALSE) BOOL WINAPI
SetupDiDestroyDeviceInfoList(DevInfo); SetupDiDestroyDeviceInfoList(DevInfo);
cleanupMutex: cleanupMutex:
NamespaceReleaseMutex(Mutex); NamespaceReleaseMutex(Mutex);
cleanupToken:
RevertToSelf();
return RET_ERROR(TRUE, LastError); return RET_ERROR(TRUE, LastError);
} }

View File

@ -293,6 +293,16 @@ SendPackets(_Inout_ DWORD_PTR SessionPtr)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static BOOL CALLBACK
PrintAdapter(_In_ WINTUN_ADAPTER_HANDLE Adapter, _In_ LPARAM Param)
{
UNREFERENCED_PARAMETER(Param);
WCHAR szAdapterName[MAX_ADAPTER_NAME];
if (WintunGetAdapterName(Adapter, szAdapterName))
Log(WINTUN_LOG_INFO, L"Existing Wintun adapter: %s", szAdapterName);
return TRUE;
}
int int
main(void) main(void)
{ {
@ -301,6 +311,7 @@ main(void)
return LogError(L"Failed to initialize Wintun", GetLastError()); return LogError(L"Failed to initialize Wintun", GetLastError());
WintunSetLogger(ConsoleLogger); WintunSetLogger(ConsoleLogger);
Log(WINTUN_LOG_INFO, L"Wintun library loaded"); Log(WINTUN_LOG_INFO, L"Wintun library loaded");
WintunEnumAdapters(L"Example", PrintAdapter, 0);
DWORD LastError; DWORD LastError;
HaveQuit = FALSE; HaveQuit = FALSE;