CreateProcessAsUser 和 createevent 权限
CreateProcessAsUser and createevent permissions
我正在创建一个侦听端口的应用程序,当客户端发出请求时,它会使用不同的用户生成一个新进程 LogonUser,CreateProcessAsUser 。
我已经使用 CreateEvent() 函数设置了 2 个事件,以向子进程发出 WSADuplicateSocket 已准备好通过内存映射文件将 SOCKADD_STORAGEW 结构传递给子进程的信号。
从应用程序生成时,子进程中的 OpenEvent() 一直失败并显示错误 5(访问被拒绝)。
如果我手动 运行 a child/client 使用(shift + 右键单击,运行 as)OpenEvent 函数成功地打开事件。
事件是在全局命名空间 (Global\myevent) 中创建的,出于测试目的,我创建了一个空 Dacl(我已经使用 winobj 验证了事件的权限)传递给 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() 生成的 CLient
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;
}
感谢您的回复。
基于 CreateProcessAsUser
的文档:
A handle to the primary token that represents a user. The handle must
have the TOKEN_QUERY, TOKEN_DUPLICATE, and TOKEN_ASSIGN_PRIMARY access
rights.
以下代码适用于我:
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(客户端未持有所需的权限。)。指出我遗漏了什么并针对您的问题重现步骤。
在尝试了很多不同的东西之后,CreateEvent() 一直返回访问被拒绝。
我发现了一个丑陋的解决方法:在传递给 CreateEvent() 的 SECURITY_ATTRIBUTES 中,我将 bInheritHandle 设置为 TRUE,并将句柄值传递给参数中的子进程。
此时我可以在句柄上使用 WaitForSingleObject()。
我真的很想知道为什么它没有像我第一个问题中描述的那样工作...
我正在创建一个侦听端口的应用程序,当客户端发出请求时,它会使用不同的用户生成一个新进程 LogonUser,CreateProcessAsUser 。
我已经使用 CreateEvent() 函数设置了 2 个事件,以向子进程发出 WSADuplicateSocket 已准备好通过内存映射文件将 SOCKADD_STORAGEW 结构传递给子进程的信号。
从应用程序生成时,子进程中的 OpenEvent() 一直失败并显示错误 5(访问被拒绝)。
如果我手动 运行 a child/client 使用(shift + 右键单击,运行 as)OpenEvent 函数成功地打开事件。
事件是在全局命名空间 (Global\myevent) 中创建的,出于测试目的,我创建了一个空 Dacl(我已经使用 winobj 验证了事件的权限)传递给 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() 生成的 CLient
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;
}
感谢您的回复。
基于 CreateProcessAsUser
的文档:
A handle to the primary token that represents a user. The handle must have the TOKEN_QUERY, TOKEN_DUPLICATE, and TOKEN_ASSIGN_PRIMARY access rights.
以下代码适用于我:
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(客户端未持有所需的权限。)。指出我遗漏了什么并针对您的问题重现步骤。
在尝试了很多不同的东西之后,CreateEvent() 一直返回访问被拒绝。
我发现了一个丑陋的解决方法:在传递给 CreateEvent() 的 SECURITY_ATTRIBUTES 中,我将 bInheritHandle 设置为 TRUE,并将句柄值传递给参数中的子进程。
此时我可以在句柄上使用 WaitForSingleObject()。
我真的很想知道为什么它没有像我第一个问题中描述的那样工作...