eResult CSecRunAsUser::RestartAsUser(){
	USES_CONVERSION;

	if (m_bRunningRestricted || m_bRunningAsEmule)
		return RES_OK;
	if (!LoadAPI())
		return RES_FAILED;

	ASSERT ( !m_strPassword.IsEmpty() );
	BOOL bResult;
	try{
		PROCESS_INFORMATION ProcessInfo = {0};
		TCHAR szAppPath[MAX_PATH];
		GetModuleFileName(NULL, szAppPath, MAX_PATH);
		CString strAppName;
		strAppName.Format(_T("\"%s\""),szAppPath);
		
		STARTUPINFOW StartInf = {0};
		StartInf.cb = sizeof(StartInf);
		StartInf.dwFlags = STARTF_USESHOWWINDOW;
		StartInf.wShowWindow = SW_NORMAL;

		// remove the current mutex, so that the restart emule can create its own without problems
		// in the rare case CreateProcessWithLogonW fails, this will allow mult. instances, but if that function fails we have other problems anyway
		//MODIFIED by fengwen on 2007/03/05	<begin> :
		//::CloseHandle(theApp.m_hMutexOneInstance);
		if (NULL != theApp.m_pSingleInst)
			theApp.m_pSingleInst->AppEnd();
		//MODIFIED by fengwen on 2007/03/05	<end> :
		if (NULL != theApp.m_pSingleInst2Loader)
			theApp.m_pSingleInst2Loader->AppEnd();
		
		bResult = CreateProcessWithLogonW(EMULEACCOUNTW, m_strDomain, m_strPassword,
			LOGON_WITH_PROFILE, NULL, (LPWSTR)T2CW(strAppName), 0, NULL, NULL, &StartInf, &ProcessInfo);
		CloseHandle(ProcessInfo.hProcess);
		CloseHandle(ProcessInfo.hThread);

	}
	catch(...){
		CGlobalVariable::QueueDebugLogLine(false, _T("Run as unpriveleged user: Error: Unexpected exception while loading advapi32.dll"));
		FreeAPI();
		return RES_FAILED;
	}
	FreeAPI();
	if (!bResult)
		CGlobalVariable::QueueDebugLogLine(false, _T("Run as unpriveleged user: Error: Failed to restart eMule as different user! Error Code: %i"),GetLastError());
	
	if (bResult)
		return RES_OK_NEED_RESTART;
	else
		return RES_FAILED;
}
Exemple #2
0
// Initializes the PCANLight for a specific hardware
// "HWType" = Hardware to be used
//
bool PCANLight::InitializeAPI(HardwareType HWType)
{
	// Unloads the current DLL
	//
	UnloadAPI();
	// Sets the new Hardware
	//
	hwType = HWType;
	// Loads the API for the new Hardware
	//
	LoadAPI();

	return bWasLoaded;
}
Exemple #3
0
eResult CSecRunAsUser::RestartAsUser(){

	if (m_bRunningRestricted || m_bRunningAsEmule)
		return RES_OK;
	if (!LoadAPI())
		return RES_FAILED;

	TCHAR szAppPath[MAX_PATH];
	DWORD dwModPathLen = GetModuleFileName(NULL, szAppPath, _countof(szAppPath));
	if (dwModPathLen == 0 || dwModPathLen == _countof(szAppPath))
		return RES_FAILED;

	ASSERT ( !m_strPassword.IsEmpty() );
	BOOL bResult;
	try{
		PROCESS_INFORMATION ProcessInfo = {0};
		CString strAppName;
		strAppName.Format(_T("\"%s\""),szAppPath);
		
		STARTUPINFOW StartInf = {0};
		StartInf.cb = sizeof(StartInf);
		StartInf.dwFlags = STARTF_USESHOWWINDOW;
		StartInf.wShowWindow = SW_NORMAL;

		// remove the current mutex, so that the restart emule can create its own without problems
		// in the rare case CreateProcessWithLogonW fails, this will allow mult. instances, but if that function fails we have other problems anyway
		::CloseHandle(theApp.m_hMutexOneInstance);
		
		bResult = CreateProcessWithLogonW(EMULEACCOUNTW, m_strDomain, m_strPassword,
			LOGON_WITH_PROFILE, NULL, const_cast<LPWSTR>((LPCWSTR)strAppName), 0, NULL, NULL, &StartInf, &ProcessInfo);
		CloseHandle(ProcessInfo.hProcess);
		CloseHandle(ProcessInfo.hThread);

	}
	catch(...){
		theApp.QueueDebugLogLine(false, _T("Run as unpriveleged user: Error: Unexpected exception while loading advapi32.dll"));
		FreeAPI();
		return RES_FAILED;
	}
	FreeAPI();
	if (!bResult)
		theApp.QueueDebugLogLine(false, _T("Run as unpriveleged user: Error: Failed to restart eMule as different user! Error Code: %i"),GetLastError());
	
	if (bResult)
		return RES_OK_NEED_RESTART;
	else
		return RES_FAILED;
}
Exemple #4
0
eResult CSecRunAsUser::RestartAsRestricted(){
	if (m_bRunningRestricted || m_bRunningAsEmule)
		return RES_OK;
	if (!LoadAPI())
		return RES_FAILED;

	HANDLE hProcessToken = NULL;
	HANDLE hRestrictedToken = NULL;
	PTOKEN_USER pstructUserToken = NULL;

	try{
		// get our access token from the process
		if(!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_READ, &hProcessToken)){
			throw(CString(_T("Failed to retrieve access token from process")));
		}
		
		// there is no easy way to check if we have already restircted token when not using the restricted sid list
		// so just check if we set the SANDBOX_INERT flag and hope noone else did
		// (which isunlikely tho because afaik you would only set it when using CreateRestirctedToken) :)
		DWORD dwLen = 0;
		DWORD dwInertFlag;
		if (!GetTokenInformation(hProcessToken, TokenSandBoxInert, &dwInertFlag, sizeof(dwInertFlag), &dwLen)){
			throw(CString(_T("Failed to Flag-Status from AccessToken")));
		}
		if (dwInertFlag != 0){
			m_bRunningRestricted = true;
			throw(CString(_T("Already using a restricted Token it seems (everything is fine!)")));
		}

		// get the user account SID to disable it in our new token
		dwLen = 0;
		while (!GetTokenInformation(hProcessToken, TokenUser, pstructUserToken, dwLen, &dwLen)){
			if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && pstructUserToken == NULL){
				pstructUserToken = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLen);
				continue;
			}
			throw(CString(_T("Failed to retrieve UserSID from AccessToken")));
		}
		if (pstructUserToken == NULL)
			throw(CString(_T("Failed to retrieve UserSID from AccessToken")));

		// disabling our primary token would make sense from an Security POV, but this would cause file acces conflicts
		// in the default settings (since we cannot access files we created ourself if they don't have the write flag for the group "users")
		// so it stays enabled for now and we only reduce privileges

		// create the new token
		if(!CreateRestrictedToken(hProcessToken, DISABLE_MAX_PRIVILEGE | SANDBOX_INERT, 0 /*disabled*/, &pstructUserToken->User, 0, NULL, 0, NULL, &hRestrictedToken ) ){
			throw(CString(_T("Failed to create Restricted Token")));
		}

		// do the starting job
		PROCESS_INFORMATION ProcessInfo = {0};
		TCHAR szAppPath[MAX_PATH];
		DWORD dwModPathLen = GetModuleFileName(NULL, szAppPath, _countof(szAppPath));
		if (dwModPathLen == 0 || dwModPathLen == _countof(szAppPath))
			throw CString(_T("Failed to get module file path"));
		CString strAppName;
		strAppName.Format(_T("\"%s\""),szAppPath);
		
		STARTUPINFO StartInf = {0};
		StartInf.cb = sizeof(StartInf);
		StartInf.dwFlags = STARTF_USESHOWWINDOW;
		StartInf.wShowWindow = SW_NORMAL;

		// remove the current mutex, so that the restart emule can create its own without problems
		// in the rare case CreateProcessWithLogonW fails, this will allow mult. instances, but if that function fails we have other problems anyway
		::CloseHandle(theApp.m_hMutexOneInstance);
		
		if(!CreateProcessAsUser(hRestrictedToken, NULL, strAppName.GetBuffer(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartInf, &ProcessInfo) ){
			CString e;
			GetErrorMessage(GetLastError(), e, 0);
			throw(CString(_T("CreateProcessAsUser failed")));
		}
		strAppName.ReleaseBuffer();
		CloseHandle(ProcessInfo.hProcess);
		CloseHandle(ProcessInfo.hThread);

		// cleanup
		HeapFree(GetProcessHeap(), 0, (LPVOID)pstructUserToken);
		pstructUserToken = NULL;
		CloseHandle(hRestrictedToken);
		CloseHandle(hProcessToken);
	}
	catch(CString strError){
		if (hProcessToken != NULL)
			CloseHandle(hProcessToken);
		if (hRestrictedToken != NULL)
			CloseHandle(hRestrictedToken);
		if (pstructUserToken != NULL)
			HeapFree(GetProcessHeap(), 0, (LPVOID)pstructUserToken);


		theApp.QueueDebugLogLine(false, _T("SecureShellExecute exception: %s!"), strError);
		if (m_bRunningRestricted)
			return RES_OK;
		else
			return RES_FAILED;
	}
	return RES_OK_NEED_RESTART;
}
Exemple #5
0
eResult CSecRunAsUser::PrepareUser(){
	CoInitialize(NULL);
	bool bResult = false;
	if (!LoadAPI())
		return RES_FAILED;

	try{
		IADsContainerPtr pUsers;
		try{
			IADsWinNTSystemInfoPtr pNTsys;
			if (CoCreateInstance(CLSID_WinNTSystemInfo,NULL,CLSCTX_INPROC_SERVER,IID_IADsWinNTSystemInfo,(void**)&pNTsys) != S_OK)
			    throw CString(_T("Failed to create IADsWinNTSystemInfo"));
			// check if we are already running on our eMule Account
			// todo: check if the current account is an administrator
			
			CComBSTR bstrUserName;
			pNTsys->get_UserName(&bstrUserName);
			m_strCurrentUser = bstrUserName;

			if (m_strCurrentUser == EMULEACCOUNTW){ 
				m_bRunningAsEmule = true;
			    throw CString(_T("Already running as eMule_Secure Account (everything is fine)"));
			}
			CComBSTR bstrCompName;
			pNTsys->get_ComputerName(&bstrCompName);
			CStringW cscompName = bstrCompName;

			CComBSTR bstrDomainName;
			pNTsys->get_DomainName(&bstrDomainName);
			m_strDomain = bstrDomainName;
		
			ADSPath.Format(L"WinNT://%s,computer",cscompName);
			if ( !SUCCEEDED(ADsGetObject(ADSPath.AllocSysString(),IID_IADsContainer,(void **)&pUsers)) )
			    throw CString(_T("Failed ADsGetObject()"));

			IEnumVARIANTPtr pEnum; 
			ADsBuildEnumerator (pUsers,&pEnum);

			IADsUserPtr pChild;
			_variant_t vChild;			  
			while( ADsEnumerateNext (pEnum,1,&vChild,NULL) == S_OK )
			{	
				if (vChild.pdispVal->QueryInterface(IID_IADsUser,(void **)&pChild) != S_OK)
					continue;
				//If the object in the container is user then get properties
				CComBSTR bstrName; 
				pChild->get_Name(&bstrName);
				CStringW csName= bstrName;
				
				// find the emule user account if possible
				if ( csName == EMULEACCOUNTW ){
					// account found, set new random password and save it
					m_strPassword = CreateRandomPW();
					if ( !SUCCEEDED(pChild->SetPassword(m_strPassword.AllocSysString())) )
					    throw CString(_T("Failed to set password"));

					bResult = true;
					break;
				}
			}

		}
		catch(CString error){
			// clean up and abort
			theApp.QueueDebugLogLine(false, _T("Run as unpriveleged user: Exception while preparing user account: %s!"), error);
			CoUninitialize();
			if (m_bRunningAsEmule)
				return RES_OK;
			else
				return RES_FAILED;
		}
		if (bResult || CreateEmuleUser(pUsers) ){
			bResult = SetDirectoryPermissions();
		}
	}
	catch(...){
		// clean up and abort
		theApp.QueueDebugLogLine(false, _T("Run as unpriveleged user: Unexpected fatal error while preparing user account!"));
		CoUninitialize();
		return RES_FAILED;
	}



	CoUninitialize();
	FreeAPI();
	if (bResult)
		return RES_OK_NEED_RESTART;
	else
		return RES_FAILED;
}