我现在正在查看wininetd的来源:http://4coder.org/c-c-source-code/27/wininetd-0.7/wininetd.c.html,第408行。看起来奇怪的是CreateProcessAsUserA()参数:lpEnvironment,si.hStdInput等在调用ImpersonateLoggedOnUser()之后被填充,创建不需要的代码重复。
它有什么特别的意义吗?例如,影响句柄继承还是破坏安全性?
if (!ImpersonateLoggedOnUser(husr)) {
winet_log(WINET_LOG_ERROR, "[%s] unable to impersonate user: user='%s' err='%s'\n",
WINET_APPNAME, pm->user, emsg = winet_get_syserror());
free(emsg);
CloseHandle(husr);
return -1;
}
if (winet_create_stdhandles(asock, &si.hStdInput, &si.hStdOutput, &si.hStdError) < 0) {
RevertToSelf();
CloseHandle(husr);
return -1;
}
if (!(env = winet_prepare_env(pm, asock, saddr))) {
RevertToSelf();
CloseHandle(husr);
CloseHandle(si.hStdError);
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdInput);
return -1;
}
if (!CreateProcessAsUserA(husr, NULL, pm->cmdline, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS,
env, NULL, &si, &pi)) {
winet_log(WINET_LOG_ERROR, "[%s] unable to create process as user: cmdln='%s' user='%s' err='%s'\n",
WINET_APPNAME, pm->cmdline, pm->user, emsg = winet_get_syserror());
free(emsg);
FreeEnvironmentStrings(env);
RevertToSelf();
CloseHandle(husr);
CloseHandle(si.hStdError);
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdInput);
return -1;
}
RevertToSelf();
CloseHandle(husr);
答案 0 :(得分:0)
管道和环境块的创建对调用线程的当前用户很敏感,因此需要首先进行模拟。此外,代码正在调用CreateProcess()
vs CreateProcessAsUser()
,具体取决于是否正在使用模拟。所以有意义的是部分代码是重复的。另一方面,代码当然可以用这种方式编写,以减少代码的重复,而不会改变原始代码的整体含义,例如:
static int winet_serve_client(portmap_t *pm, SOCKET asock, struct sockaddr_in *saddr) {
HANDLE husr = NULL;
char *emsg;
LPVOID env;
STARTUPINFOA si;
PROCESS_INFORMATION pi;
BOOL impersonating = FALSE;
BOOL created;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.lpDesktop = "";
si.dwFlags = STARTF_USESTDHANDLES;
if (winet_user_handle(pm, &husr) >= 0) {
if (!ImpersonateLoggedOnUser(husr)) {
winet_log(WINET_LOG_ERROR, "[%s] unable to impersonate user: user='%s' err='%s'\n", WINET_APPNAME, pm->user, emsg = winet_get_syserror());
free(emsg);
CloseHandle(husr);
return -1;
}
impersonating = TRUE;
}
if (winet_create_stdhandles(asock, &si.hStdInput, &si.hStdOutput, &si.hStdError) < 0) {
if (impersonating) RevertToSelf();
if (husr) CloseHandle(husr);
return -1;
}
if (!(env = winet_prepare_env(pm, asock, saddr))) {
if (impersonating) RevertToSelf();
if (husr) CloseHandle(husr);
CloseHandle(si.hStdError);
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdInput);
return -1;
}
if (husr) {
created = CreateProcessAsUserA(husr, NULL, pm->cmdline, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, env, NULL, &si, &pi));
} else {
created = CreateProcessA(NULL, pm->cmdline, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, env, NULL, &si, &pi));
}
if (!created) {
emsg = winet_get_syserror();
if (husr) {
winet_log(WINET_LOG_ERROR, "[%s] unable to create process as user: cmdln='%s' user='%s' err='%s'\n", WINET_APPNAME, pm->cmdline, pm->user, emsg);
} else {
winet_log(WINET_LOG_ERROR, "[%s] unable to create process: cmdln='%s' err='%s'\n", WINET_APPNAME, pm->cmdline, emsg);
}
free(emsg);
FreeEnvironmentStrings(env);
if (impersonating) RevertToSelf();
if (husr) CloseHandle(husr);
CloseHandle(si.hStdError);
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdInput);
return -1;
}
if (impersonating) RevertToSelf();
if (husr) CloseHandle(husr);
if (impersonating) {
winet_log(WINET_LOG_MESSAGE, "[%s] process created: user='%s' cmdln='%s'\n", WINET_APPNAME, pm->user, pm->cmdline);
} else {
winet_log(WINET_LOG_MESSAGE, "[%s] process created: cmdln='%s'\n", WINET_APPNAME, pm->cmdline);
}
WaitForSingleObject(pi.hProcess, INFINITE);
FreeEnvironmentStrings(env);
CloseHandle(si.hStdError);
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdInput);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}