로컬 관리자 계정으로 실행되는 Windows 서비스에서 프로세스를 실행하려고합니다. 컴퓨터는 Windows 7이고 그 컴퓨터는 Remote Desktop/Terminal Service APIs입니다.다른 사용자의 프로세스 실행
코드는
5. 먼저 내가 모두 SE_DEBUG_NAME
및 SE_TCB_NAME
권한을 사용할 수 있도록 SetPrivilege
를 호출 한 후, 현재 스레드에서 토큰을 얻기 위해 시도 = 오류 코드로 WTSQueryUserToken
에 실패했습니다. WTSQueryUserToken
으로 전화를 걸지만 오류가 발생하면
서비스가 로컬 시스템 (localSystem) 아래에있을 때이 코드는 SetPrivilege를 호출 할 필요없이 완벽하게 작동합니다. 이제 문제는 로컬 관리자 권한으로 실행되도록 서비스를 이동해야한다는 것입니다. !!!!
내가 무엇을 놓치고 있는지 알 수 있습니까?
코드 :
BOOL T_Ex_RunProgram (DWORD sessionId, LPCWSTR targetPath)
{
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("T_Ex_RunProgram: sessionId = %d, targetPath = \"%S\"\n", sessionId, targetPath);
}
#endif
HANDLE htoken;
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &htoken))
{
if (GetLastError() == ERROR_NO_TOKEN)
{
if (!ImpersonateSelf(SecurityImpersonation))
{
DWORD dwErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("ImpersonateSelf::RunProgram: dwErr = %d\n", dwErr);
}
#endif
SetLastError(dwErr);
return FALSE;
}
if(!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &htoken))
{
DWORD dwErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("OpenThreadToken::RunProgram: dwErr = %d\n", dwErr);
}
#endif
SetLastError(dwErr);
return FALSE;
}
}
else{
DWORD dwErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("OpenThreadToken::RunProgram: GetLastError return unexpected dwErr = %d\n", dwErr);
}
#endif
SetLastError(dwErr);
return FALSE;
}
}
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("Before SetPrivilege(SE_DEBUG_NAME)::RunProgram\n");
}
#endif
// enable SeDebugPrivilege
if(!SetPrivilege(htoken, SE_DEBUG_NAME, TRUE))
{
// close token handle
CloseHandle(htoken);
DWORD dwErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("SetPrivilege::RunProgram((SE_DEBUG_NAME): dwErr = %d\n", dwErr);
}
#endif
SetLastError(dwErr);
return FALSE;
}
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("Before SetPrivilege(SE_TCB_NAME)::RunProgram\n");
}
#endif
// enable SeDebugPrivilege
if(!SetPrivilege(htoken, SE_TCB_NAME, TRUE))
{
// close token handle
CloseHandle(htoken);
DWORD dwErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("SetPrivilege(SE_TCB_NAME)::RunProgram: dwErr = %d\n", dwErr);
}
#endif
SetLastError(dwErr);
return FALSE;
}
BOOL b = WTSQueryUserToken (sessionId, &htoken);
if (!b)
{
DWORD dwErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("T_Ex_RunProgram: WTSQueryUserToken failed. dwErr = %d\n", dwErr);
}
#endif
SetLastError(dwErr);
return FALSE;
}
LPWSTR userName, userName1;
DWORD userNameLength;
b = WTSQuerySessionInformationW (WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, &userName, &userNameLength);
if (b)
{
userName1 = _wcsdup (userName);
WTSFreeMemory (userName);
}
else
{
DWORD dwErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("T_Ex_RunProgram: WTSQuerySessionInformation failed: dwErr = %d\n", dwErr);
}
#endif
SetLastError(dwErr);
return FALSE;
}
b = RunProgramWithToken (htoken, userName1, targetPath,sessionId);
DWORD dwreturnErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("Before SetPrivilege(SE_DEBUG_NAME,FALSE)::RunProgram\n");
}
#endif
// enable SeDebugPrivilege
if(!SetPrivilege(htoken, SE_DEBUG_NAME, FALSE))
{
// close token handle
CloseHandle(htoken);
DWORD dwErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("SetPrivilege::RunProgram((SE_DEBUG_NAME,FALSE): dwErr = %d\n", dwErr);
}
#endif
SetLastError(dwErr);
}
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("Before SetPrivilege(SE_TCB_NAME,FALSE)::RunProgram\n");
}
#endif
// enable SeDebugPrivilege
if(!SetPrivilege(htoken, SE_TCB_NAME, FALSE))
{
// close token handle
CloseHandle(htoken);
DWORD dwErr = GetLastError();
#ifdef DEBUG
if(g_pLog)
{
g_pLog->Format ("SetPrivilege(SE_TCB_NAME,FALSE)::RunProgram: dwErr = %d\n", dwErr);
}
#endif
SetLastError(dwErr);
}
free (userName1);
CloseHandle (htoken);
if (!b)
SetLastError (dwreturnErr);
return b;
}
BOOL SetPrivilege(HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError());
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL))
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError());
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
일반적으로 'SE_DEBUG_NAME' 또는'SE_TCB_NAME' 중 하나만 필요합니다. 그러나'SE_ASSIGNPRIMARYTOKEN_NAME'을 활성화해야 할 수도 있습니다. 그것이 기본 프로세스 토큰을 대체 할 수있는 것이며, "프로세스로 원하는 모든 것을하십시오."라는 거룩한 삼위 일체에서 세 번째 프로세스 토큰입니다. MSDN에서 [Privilege Constants] (http://msdn.microsoft.com/en-us/library/windows/desktop/bb530716%28v=vs.85%29.aspx)를 참조하십시오. – jww
대상 사용자 계정에 필요한 일부 로그온 권한이 있습니다. 이벤트 로그 ('eventvwr')에는 자세한 정보가있는 자세한 정보가 있어야합니다. 또한 처음에는 기술 자료 문서 [NTRights 유틸리티를 사용하여 로그온 사용자 권한을 설정하는 방법] (http://support.microsoft.com/kb/315276)을 참조하십시오. 더 많은 정보를 얻으려면 발끝을 잡아야합니다. – jww
또한 사용중인 Windows 버전은 무엇입니까? 이 서버 2008입니까? 터미널 서비스는 XP 및 2003 (및 다른 경우)에서 약간 다르게 작동하며 다른 사용자를 지원할 때 도움이 될 수 있습니다. – jww