【发布时间】:2017-05-13 03:51:31
【问题描述】:
这是我试图模拟用户然后创建互斥锁的代码。未创建互斥锁。我收到 ERROR_ACCESS_DENIED 错误。
void Impersonate()
{
DWORD logonType = LOGON32_LOGON_INTERACTIVE;
DWORD logonProvider = LOGON32_PROVIDER_DEFAULT;
HANDLE userToken;
HANDLE hMutex;
DWORD err;
LPSTR user = "zoom"; // the user I created myself on my machine.
// It has Administrator privileges, and my account,
// from which I start the app, is Admin too
LPSTR password = "zoom";
LPSTR domain = ".";
hMutex = NULL;
LogonUserA(user, domain, password, logonType, logonProvider,&userToken);
// just to make sure that mutexes are created fine before impersonation
hMutex = CreateMutexA( NULL, FALSE, "mutex_good" );
ImpersonateLoggedOnUser(userToken);
hMutex = CreateMutexA( NULL, FALSE, "mutex_797" ); // I can set any
// random name, no difference
if( hMutex == NULL )
{
err = GetLastError();
// here err is ERROR_ACCESS_DENIED
}
CloseHandle(userToken);
}
我发现了几个类似的主题,但他们都在讨论从两个不同的用户上下文创建同名互斥锁,即在模拟之前已经创建了一个互斥锁“MUTEX_1”,并尝试使用相同的名称调用 CreateMutex 但由于缺乏权限,来自模拟用户的请求失败。
这里不是这种情况,因为我很确定在此代码之前没有创建同名的互斥锁(或任何互斥锁)。
我想我应该将一些非空值传递给 CreateMutex,但究竟是什么?
我在 Windows 安全方面不是很好。我理解将 NULL 作为 CreateMutex 的第一个参数传递意味着将使用“默认”安全属性。在这种情况下,它将是与线程相关联的安全参数,即与模拟用户。
我的假设是否正确?
【问题讨论】:
-
RbMm 的回答解释了这不起作用的技术原因,并提供了一种解决方法(尽管不受支持)。由于两个帐户都是管理员,并且假设您以提升的权限运行程序,更好的解决方法是指定
LOGON32_LOGON_BATCH(而不是交互式),以便模拟令牌具有管理员权限。 -
但是,最好还是退后一步,问问你为什么一开始就在模拟时尝试创建互斥锁。这是一件相当奇怪的事情。你想达到什么目标?
-
@HarryJohnston - “尽管不受支持” - 实际上我们不需要使用
Restricted子文件夹。我们可以简单地使用带有“Global\\”前缀的CreateMutexA(0, 0, "Global\\mutex_797");,仅记录在案 - msdn.microsoft.com/en-us/library/windows/desktop/… 。我最初将\BaseNamedObjects与\GLOBAL??混淆了,忘记了Everyone对\BaseNamedObjects有写访问权。对不起 -
@RbMm:嗯。我认为您需要管理员权限才能在全局命名空间中创建任何对象;我不知道这只适用于文件映射对象。谢谢!我同意创建全局互斥锁至少与使用管理员权限一样好,但我仍然怀疑 OP 在模拟时创建互斥锁是否有意义。另见blogs.msdn.microsoft.com/oldnewthing/20110928-00/?p=9533
-
啊。对我来说,这听起来像是一个不合理的客户要求,但无论如何,迎合它当然是你的特权。 :-) RbMm 关于创建全局互斥锁的建议绝对是您最好的选择,但请确保您已经考虑过如果不止一个人登录并运行您的代码的后果。您可能还想查看我上面提到的博客文章,我相信它提到了您可能需要注意的许多其他潜在的假冒问题。
标签: c++ windows mutex impersonation