我正在创建一个侦听端口的应用程序,当客户端发出请求时,它将使用LogonUser,CreateProcessAsUser与其他用户生成一个新进程。
我已经使用CreateEvent()函数设置了2个事件,以向子进程发出信号,通知WSADuplicateSocket准备通过内存映射文件将SOCKADD_STORAGEW结构传递给子进程。
子进程中的OpenEvent()从应用程序中产生时,始终失败并显示错误5(拒绝访问)。
如果我使用(Shift +右键单击,运行方式)手动运行子级/客户端,则OpenEvent函数将成功管理打开事件。
该事件在全局名称空间(Global \ myevent)中创建,并且出于测试目的,我创建了一个空的Dacl(我已使用winobj验证了对Event的权限)并传递给CreateEvent()函数。
我看不到我想念的东西。
有关代码段:
服务器:
SECURITY_ATTRIBUTES sa;
CreateNullDacl(&sa);
if ((ghParentFileMappingEvent = CreateEvent(&sa, TRUE, FALSE, szParentEventName)) == NULL) {
fprintf(stderr, "CreateEvent() failed: %d\n", GetLastError());
return false;
}
if ((ghChildFileMappingEvent = CreateEvent(&sa, TRUE, FALSE, szChildEventName)) == NULL) {
fprintf(stderr, "CreateEvent() failed: %d\n", GetLastError());
CloseHandle(ghParentFileMappingEvent);
return false;
}
PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
SECURITY_ATTRIBUTES procSa;
CreateNullDacl(&procSa);
HANDLE htok;
if (!LogonUser(chall->user, ".", chall->pass, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &htok)) {
fprintf(stderr, "LogonUser() failed: %d\n", GetLastError());
return false;
}
if(CreateProcessAsUser(htok, 0, szChildComandLineBuf, &procSa, 0, FALSE, NULL, NULL, "C:\\Users\\ch99", &si, &pi)) {
//...
}
从CreateProcessAsUser()产生的客户端
if ((ghParentFileMappingEvent = OpenEventA(SYNCHRONIZE, FALSE, szParentEventName)) == 0) // return 5 , access denied
{
fprintf(fp, "OpenParentEvent failed: %d\n", GetLastError());
return INVALID_SOCKET;
}
if ((ghChildFileMappingEvent = OpenEventA(SYNCHRONIZE, FALSE, szChildEventName)) == 0) { // return 5 access denied
fprintf(fp, "OpenChildEvent failed: %d\n", GetLastError());
CloseHandle(ghParentFileMappingEvent);
ghParentFileMappingEvent = NULL;
return INVALID_SOCKET;
}
感谢您的回复。
答案 0 :(得分:1)
尝试了很多不同的事情后,CreateEvent()继续拒绝返回访问。
我发现了一个丑陋的解决方法:在传递给CreateEvent()的SECURITY_ATTRIBUTES中,我将bInheritHandle设置为TRUE,并将handle值传递给arguments中的子进程。
这时我可以在handle上使用WaitForSingleObject()了。
我真的很想知道为什么它不如我的第一个问题所述...
答案 1 :(得分:0)
基于CreateProcessAsUser
的文档:
代表用户的主要令牌的句柄。手柄必须 具有 TOKEN_QUERY , TOKEN_DUPLICATE 和 TOKEN_ASSIGN_PRIMARY 的访问权限 权利。
以下代码对我有用:
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &htok))
printf("OpenProcessToken() failed: %d\n", GetLastError());
if (!CreateProcessAsUser(htok, L"childProc.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
printf("CreateProcessAsUser() failed: %d\n", GetLastError());
}
或者您也可以使用CreateProcessWithToken
(这需要以管理员身份运行):
HANDLE htok;
if (!LogonUser(L"userName", L"domain", L"password", LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &htok)) {
printf("LogonUser() failed: %d\n", GetLastError());
return false;
}
if (!CreateProcessWithTokenW(htok, LOGON_WITH_PROFILE,L"childProc.exe", NULL, 0, NULL, NULL, &si, &pi)) {
printf("CreateProcessAsUser() failed: %d\n", GetLastError());
}
使用上述两种方法,子进程可以成功打开事件。
对于您的代码,我在调用CreateProcessAsUser
时收到错误代码1314(客户端没有所需的特权。)。指出我缺少的内容,并重现您的问题的步骤。