⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 secrunasuser.cpp

📁 非常难得的eMule(电骡) V0.45b 源码下载 值得研究
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//this file is part of eMule
//Copyright (C)2004 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "StdAfx.h"
#include "emule.h"
#include "secrunasuser.h"
#include "Preferences.h"
#include "emuledlg.h"
#include "otherfunctions.h"
#include "Log.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


CSecRunAsUser::CSecRunAsUser(void)
{
	bRunningAsEmule = false;
	m_hADVAPI32_DLL = 0;
	m_hACTIVEDS_DLL = 0;
}

CSecRunAsUser::~CSecRunAsUser(void)
{
	FreeAPI();
}

bool CSecRunAsUser::PrepareUser(){

	USES_CONVERSION;
	CoInitialize(NULL);
	bool bResult = false;
	if (!LoadAPI())
		return false;

	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){
				theApp.QueueLogLine(false, GetResString(IDS_RAU_RUNNING), EMULEACCOUNT); 
				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();
			return false;
		}
		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 false;
	}



	CoUninitialize();
	FreeAPI();
	return bResult;
}

bool CSecRunAsUser::CreateEmuleUser(IADsContainerPtr pUsers){

	IDispatchPtr pDisp=NULL;
	if ( !SUCCEEDED(pUsers->Create(L"user",CString(EMULEACCOUNT).AllocSysString() ,&pDisp )) )
		return false;

	IADsUserPtr pUser;
	if (!SUCCEEDED(pDisp->QueryInterface(&pUser)) )
		return false;

	VARIANT_BOOL bAccountDisabled=FALSE;
	VARIANT_BOOL bIsLocked=FALSE;
	VARIANT_BOOL bPwRequired=TRUE;
	pUser->put_AccountDisabled(bAccountDisabled);
	pUser->put_IsAccountLocked(bIsLocked);
	pUser->put_PasswordRequired(bPwRequired);
	pUser->put_Description(CString(_T("Account used to run eMule with additional security")).AllocSysString() );
	pUser->SetInfo();
	m_strPassword = CreateRandomPW();
	if ( !SUCCEEDED(pUser->SetPassword(m_strPassword.AllocSysString())) )
		return false;
	return true;
}

CStringW CSecRunAsUser::CreateRandomPW(){
	CStringW strResult;
	while (strResult.GetLength() < 10){
		char chRnd=48 + (rand() % 74);
		if( (chRnd > 97 && chRnd < 122) || (chRnd > 65 && chRnd < 90)
			|| (chRnd >48 && chRnd < 57) ||(chRnd==95) ){
				strResult.AppendChar(chRnd);
		}
	}
	return strResult;
}

bool CSecRunAsUser::SetDirectoryPermissions(){
#define FULLACCESS ADS_RIGHT_GENERIC_ALL
	// shared files list: read permission only
	// we odnt check for success here, for emule will also run if one dir fails for some reason
	// if there is a dir which is also an incoming dir, rights will be overwritten below
	for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition();pos != 0;)
	{
		VERIFY( SetObjectPermission(thePrefs.shareddir_list.GetNext(pos), (DWORD)ADS_RIGHT_GENERIC_READ) );
	}

	// set special permission for emule account on needed folders
	bool bSucceeded = true;
	bSucceeded = bSucceeded && SetObjectPermission(thePrefs.GetAppDir(), FULLACCESS);
	bSucceeded = bSucceeded && SetObjectPermission(thePrefs.GetConfigDir(), FULLACCESS);
	bSucceeded = bSucceeded && SetObjectPermission(thePrefs.GetTempDir(), FULLACCESS);
	bSucceeded = bSucceeded && SetObjectPermission(thePrefs.GetIncomingDir(), FULLACCESS);

	uint16 cCats = thePrefs.GetCatCount();
	for (int i= 0; i!= cCats; i++){
		if (!CString(thePrefs.GetCatPath(i)).IsEmpty())
			bSucceeded = bSucceeded && SetObjectPermission(thePrefs.GetCatPath(i), FULLACCESS);
	}
	if (!bSucceeded)
		theApp.QueueDebugLogLine(false, _T("Run as unpriveleged user: Error: Failed to set directoy permissions!"));
	
	return bSucceeded;
}

bool CSecRunAsUser::SetObjectPermission(CString strDirFile, DWORD lGrantedAccess){
	USES_CONVERSION;
	if (!m_hADVAPI32_DLL){
		ASSERT ( false );
		return false;
	}
	if ( strDirFile.IsEmpty() )
		return true;

	SID_NAME_USE   snuType;
	TCHAR* szDomain = NULL;
	LPVOID pUserSID = NULL;
	PACL pNewACL = NULL;
	PSECURITY_DESCRIPTOR pSD = NULL;
	bool fAPISuccess;
	
	try {
		// get user sid
		DWORD cbDomain = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -