/**
 * Does not closeHandle on the session handle, nor does it perform UnloadUserProfile
 * on the profile handle. The profile handle cannot be unloaded, that would unload
 * the registry keys that we just got the root to. These cleanup flaws are probably acceptable
 * for the Polarizer, which runs for a few minutes before shutting down.
 **/
RegKey getUserRegistryRoot(std::wstring accountName, std::wstring password) {
    HANDLE session;
	if (!LogonUser(accountName.c_str(), NULL, password.c_str(),
				LOGON32_LOGON_INTERACTIVE,
				LOGON32_PROVIDER_DEFAULT,
				&session)) {
        DWORD error = GetLastError();
        printf("LogonUser() failed: %d", error);
        logtools.log(L"LogonUser() failed", error);
        return RegKey::INVALID;
	}
    // Load the pet account's registry hive.
    wchar_t account[128] = {};
    wcsncat(account, accountName.c_str(), 128);
	PROFILEINFO profile = { sizeof(PROFILEINFO), 0, account };
	if (!LoadUserProfile(session, &profile)) {
        printf("LoadUserProfile() failed: %d", GetLastError());
        logtools.log(L"LoadUserProfile() failed", GetLastError());
        return RegKey::INVALID;
	}
    // now the pet hive is loaded, compute the SID so I
    // can get a name for the key that I can use to make a RegKey
    // Can't use the session handle I just got back because it
    // can't be converted to a regkey, either get the name or 
    // give up on using our regkey abstraction.
    BYTE sid[10000];
    DWORD sidSize = 10000;
    DWORD domainSize = 1000;
    wchar_t domain[1000];
    SID_NAME_USE peUse;
    BOOL lookupWorked = LookupAccountName(NULL,accountName.c_str(), sid, 
        &sidSize, domain, &domainSize, &peUse);
    if (lookupWorked) {

        LPTSTR sidNameChars;
        BOOL converted = ConvertSidToStringSidW(sid, &sidNameChars);
        if (converted) {
            std::wstring sidName = sidNameChars;
            RegKey key = RegKey::HKU.open(sidName);
            LocalFree(sidNameChars);
            return key;
        } else {
            logtools.log(L"convert sid to string failed", GetLastError());
            return RegKey::INVALID;
        }
    } else {
        int err = GetLastError();
        logtools.log(L"lookupAccountName failed", err);
        return RegKey::INVALID;
    }
    
    return RegKey::INVALID;
}
ActivePet::ActivePet(wchar_t* user_password,
                     std::wstring petname,
                     FileEventLoop* files) : m_petname(petname),
                                             m_files(files),
                                             m_session(INVALID_HANDLE_VALUE),
                                             m_profile(INVALID_HANDLE_VALUE),
                                             m_job(CreateJobObject(NULL, NULL)),
                                             m_next_editable_name(1),
                                             m_ticks_while_invisible(0)
{
    // Create a new logon session for the pet.
    std::wstring petRegistryPath = Constants::registryPets() + L"\\" + m_petname;
	RegKey petkey = RegKey::HKCU.open(petRegistryPath);
	std::wstring accountName = petkey.getValue(L"accountName");
    std::wstring accountRegistryPath = Constants::registryAccounts() + L"\\" + accountName;
	RegKey accountKey = RegKey::HKCU.open(accountRegistryPath);	
	std::wstring password = accountKey.getValue(L"password");
	if (!LogonUser(accountName.c_str(), NULL, password.c_str(),
				   LOGON32_LOGON_INTERACTIVE,
				   LOGON32_PROVIDER_DEFAULT,
				   &m_session)) {
        printf("LogonUser() failed: %d\n", GetLastError());
        return;
	}

    // Tweak the Winsta0 and desktop ACLs to allow the pet to create windows.
    auto_buffer<PSID> logon_sid = GetLogonSID(m_session.get());
    if (NULL == logon_sid.get()) {
        return;
    }
    auto_close<HWINSTA, &::CloseWindowStation> winsta0(OpenWindowStation(L"winsta0", FALSE, READ_CONTROL | WRITE_DAC));
	if (NULL == winsta0.get()) {
        printf("OpenWindowStation() failed: %d\n", GetLastError());
        return;
	}
	if (!AddAceToWindowStation(winsta0.get(), logon_sid.get())) {
        printf("AddAceToWindowStation() failed: %d", GetLastError());
		return;
	}
    auto_close<HDESK, &::CloseDesktop> desktop(OpenDesktop(L"default", 0, FALSE,
                                                           READ_CONTROL | WRITE_DAC |
                                                           DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS));
	if (NULL == desktop.get()) {
        printf("OpenDesktop() failed: %d\n", GetLastError());
		return;
	}
    if (!AddAceToDesktop(desktop.get(), logon_sid.get())) {
        printf("AddAceToDesktop() failed: %d\n", GetLastError());
		return;
	}

    // Load the pet account's registry hive.
    wchar_t account[128] = {};
    wcsncpy(account, accountName.c_str(), 128);
	PROFILEINFO profile = { sizeof(PROFILEINFO), 0, account };
	if (!LoadUserProfile(m_session.get(), &profile)) {
        printf("LoadUserProfile() failed: %d\n", GetLastError());
		return;
	}
    m_profile = profile.hProfile;

    // Initialize the pet job.
	if (NULL == m_job.get()) {
        printf("CreateJobObject() failed: %d\n", GetLastError());
		return;
	}
    JOBOBJECT_BASIC_UI_RESTRICTIONS buir = { JOB_OBJECT_UILIMIT_HANDLES };
	if (!SetInformationJobObject(m_job.get(), JobObjectBasicUIRestrictions, &buir, sizeof buir)) {
        printf("SetInformationJobObject() failed: %d\n", GetLastError());
	}

    // Some apps fail to launch without access to the desktop window.
	if (!UserHandleGrantAccess(GetDesktopWindow(), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}

    // Give apps access to all the standard cursors.
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_ARROW), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_IBEAM), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_WAIT), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_CROSS), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_UPARROW), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZE), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_ICON), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZENWSE), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZENESW), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZEWE), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZENS), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZEALL), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_NO), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_HAND), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_APPSTARTING), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_HELP), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}

    // Setup the use records for the printers.
    std::set<std::wstring> servers;
    RegKey printers = RegKey::HKCU.open(L"Printers\\Connections");
    for (int i = 0; true; ++i) {
        RegKey printer = printers.getSubKey(i);
        if (!printer.isGood()) {
            break;
        }
        std::wstring server = printer.getValue(L"Server");
        if (servers.count(server) == 0) {

            std::wstring resource = server + L"\\IPC$";
            auto_array<wchar_t> remote(resource.length() + 1);
            lstrcpy(remote.get(), resource.c_str());

            USE_INFO_2 use = {};
            use.ui2_remote = remote.get();
            use.ui2_domainname = _wgetenv(L"USERDOMAIN");
            use.ui2_username = _wgetenv(L"USERNAME");;
            use.ui2_password = user_password;
            use.ui2_asg_type = USE_WILDCARD;

            auto_impersonation impersonate(m_session.get());

            DWORD arg_error;
            NET_API_STATUS error = NetUseAdd(NULL, 2, (BYTE*)&use, &arg_error);
            if (error) {
                printf("NetUseAdd() failed: %d\n", error);
            } else {
                servers.insert(server);
            }
        }
    }

    // Add the message handlers.
    //m_requestFolderPath = accountKey.getValue(Constants::petDataPathName()) + Constants::requestPath();
    m_requestFolderPath = Constants::requestsPath(Constants::polarisDataPath(Constants::userProfilePath(accountName)));
    m_dispatcher = new MessageDispatcher(m_requestFolderPath);
    m_files->watch(m_requestFolderPath, m_dispatcher);
    m_dispatcher->add("sendmail",makeSendMailHandler());
// TODO    m_dispatcher->add("GetOpenFileNameA", makeGetOpenFileNameAHandler(this));
    m_dispatcher->add("GetOpenFileNameW", makeGetOpenFileNameWHandler(this));
	m_dispatcher->add("GetClipboardData", makeGetClipboardDataHandler());
}
Exemple #3
0
Result<ExitCode> ProcessAsUser::Run(const Settings& settings, ProcessTracker& processTracker) const
{
	Trace trace(settings.GetLogLevel());
	trace < L"ProcessAsUser::Attempt to log a user on to the local computer";
	StringBuffer userName(settings.GetUserName());
	StringBuffer domain(settings.GetDomain());
	StringBuffer password(settings.GetPassword());
	StringBuffer workingDirectory(settings.GetWorkingDirectory());
	StringBuffer commandLine(settings.GetCommandLine());

	SecurityManager securityManager;
	auto setPrivilegesResult = securityManager.SetPrivileges(trace, { SE_TCB_NAME, SE_ASSIGNPRIMARYTOKEN_NAME }, true);
	if(setPrivilegesResult.HasError())
	{
		return setPrivilegesResult.GetError();
	}

	auto newUserSecurityTokenHandle = Handle(L"New user security token");
	unsigned long logonTypeCount = sizeof(allLogonTypes) / sizeof(allLogonTypes[0]);
	for (unsigned long logonTypeIndex = 0; logonTypeIndex < logonTypeCount; logonTypeIndex++)
	{
		auto logonType = allLogonTypes[logonTypeIndex];
		trace < L"::LogonUser using logon type ";
		switch (logonType)
		{
			case LOGON32_LOGON_INTERACTIVE:
				trace << L"LOGON32_LOGON_INTERACTIVE";
				break;

			case LOGON32_LOGON_NETWORK:
				trace << L"LOGON32_LOGON_NETWORK";
				break;

			case LOGON32_LOGON_BATCH:
				trace << L"LOGON32_LOGON_BATCH";
				break;

			case LOGON32_LOGON_SERVICE:
				trace << L"LOGON32_LOGON_SERVICE";
				break;
		}

		if (LogonUser(
			userName.GetPointer(),
			domain.GetPointer(),
			password.GetPointer(),
			logonType,
			LOGON32_PROVIDER_DEFAULT,
			&newUserSecurityTokenHandle))
		{
			break;
		}
		
		auto error = Error(L"LogonUser");
		trace << L" - ";
		trace << error.GetDescription();

		if(logonTypeIndex == logonTypeCount -1)
		{
			return error;
		}
	}

	trace < L"ProcessAsUser::InitializeConsoleRedirection a new security descriptor";
	trace < L"::InitializeSecurityDescriptor";
	SECURITY_DESCRIPTOR securityDescriptor = {};
	if (!InitializeSecurityDescriptor(
		&securityDescriptor,
		SECURITY_DESCRIPTOR_REVISION))
	{
		return Error(L"InitializeSecurityDescriptor");
	}

	trace < L"::SetSecurityDescriptorDacl";
	if (!SetSecurityDescriptorDacl(
		&securityDescriptor,
		true,
		nullptr,
		false))
	{
		return Error(L"SetSecurityDescriptorDacl");
	}

	trace < L"ProcessAsUser::Creates a new access primary token that duplicates new process's token";
	auto primaryNewUserSecurityTokenHandle = Handle(L"Primary new user security token");
	SECURITY_ATTRIBUTES processSecAttributes = {};
	processSecAttributes.lpSecurityDescriptor = &securityDescriptor;
	processSecAttributes.nLength = sizeof(SECURITY_DESCRIPTOR);
	processSecAttributes.bInheritHandle = true;
	trace < L"::DuplicateTokenEx";
	if (!DuplicateTokenEx(
		newUserSecurityTokenHandle,
		0, // MAXIMUM_ALLOWED
		&processSecAttributes,
		SecurityImpersonation,
		TokenPrimary,
		&primaryNewUserSecurityTokenHandle))
	{
		return Error(L"DuplicateTokenEx");
	}	

	SECURITY_ATTRIBUTES threadSecAttributes = {};
	threadSecAttributes.lpSecurityDescriptor = nullptr;
	threadSecAttributes.nLength = 0;
	threadSecAttributes.bInheritHandle = false;	
	STARTUPINFO startupInfo = {};	

	trace < L"ProcessTracker::InitializeConsoleRedirection";
	auto error = processTracker.InitializeConsoleRedirection(processSecAttributes, startupInfo);
	if(error.HasError())
	{
		return Result<ExitCode>(error.GetError());
	}

	trace < L"::LoadUserProfile";
	PROFILEINFO profileInfo = {};
	profileInfo.dwSize = sizeof(PROFILEINFO);
	profileInfo.lpUserName = userName.GetPointer();
	if (!LoadUserProfile(primaryNewUserSecurityTokenHandle, &profileInfo))
	{
		return Error(L"LoadUserProfile");
	}

	auto newProcessEnvironmentResult = GetEnvironment(settings, primaryNewUserSecurityTokenHandle, settings.GetInheritanceMode(), trace);
	if (newProcessEnvironmentResult.HasError())
	{
		UnloadUserProfile(primaryNewUserSecurityTokenHandle, profileInfo.hProfile);
		return Result<ExitCode>(newProcessEnvironmentResult.GetError());
	}

	auto setIntegrityLevelResult = securityManager.SetIntegrityLevel(settings.GetIntegrityLevel(), primaryNewUserSecurityTokenHandle, trace);
	if (setIntegrityLevelResult.HasError())
	{
		return Result<ExitCode>(setIntegrityLevelResult.GetError());
	}

	trace < L"ProcessAsUser::Create a new process and its primary thread. The new process runs in the security context of the user represented by the specified token.";
	PROCESS_INFORMATION processInformation = {};
	startupInfo.dwFlags = STARTF_USESHOWWINDOW;
	startupInfo.wShowWindow = ShowModeConverter::ToShowWindowFlag(settings.GetShowMode());
	auto cmdLine = settings.GetCommandLine();
	trace < L"::CreateProcessAsUser";	
	if (!CreateProcessAsUser(
		primaryNewUserSecurityTokenHandle,
		nullptr,
		commandLine.GetPointer(),
		&processSecAttributes,
		&threadSecAttributes,
		true,
		CREATE_UNICODE_ENVIRONMENT,
		newProcessEnvironmentResult.GetResultValue().CreateEnvironment(),
		workingDirectory.GetPointer(),
		&startupInfo,
		&processInformation))
	{		
		auto result = Error(L"CreateProcessAsUser");
		UnloadUserProfile(primaryNewUserSecurityTokenHandle, profileInfo.hProfile);
		return result;
	}

	// ReSharper disable CppInitializedValueIsAlwaysRewritten
	// ReSharper disable CppEntityAssignedButNoRead
	
	auto processHandle = Handle(L"Service Process");
	processHandle = processInformation.hProcess;
	
	auto threadHandle = Handle(L"Thread");
	threadHandle = processInformation.hThread;

	auto exitCode = processTracker.WaiteForExit(processInformation.hProcess, trace);
	UnloadUserProfile(primaryNewUserSecurityTokenHandle, profileInfo.hProfile);	

	return exitCode;
}
Exemple #4
0
/* returns TRUE if the user profile is loaded; otherwise, 
FALSE.  This is a simple helper that does all the initialization
required to do the loading of a profile. */
BOOL 
OwnerProfile::loadProfile () {

    dprintf ( D_FULLDEBUG, "In OwnerProfile::loadProfile()\n" );

    priv_state  priv;
    BOOL        profile_loaded = FALSE,
                ok             = FALSE;

    __try {

        /* we must do the following as Condor, because, presumably,
        the account we are running as, does not have admin rights*/
        priv = set_condor_priv ();
        
        /* initialize profile information */
        ZeroMemory ( 
            &user_profile_, 
            sizeof ( PROFILEINFO ) );
        user_profile_.dwSize = sizeof ( PROFILEINFO );

        /* The PI_NOUI flag avoids the "I'm going to make a temporary 
        profile for you... blah, blah, blah" dialog from being 
        displayed in the case when a roaming profile is inaccessible 
        because of a network outage, among other reasons. */
        user_profile_.dwFlags    = PI_NOUI;
        user_profile_.lpUserName = (char*)user_name_;
        
        /* load the user's profile for the first time-- this will 
        effectively create it "for free", using the local "default"
        account as a template. */
        profile_loaded = LoadUserProfile ( 
            user_token_, 
            &user_profile_ );

        dprintf ( 
            D_FULLDEBUG, 
            "OwnerProfile::loadProfile: Loading the %s's "
            "profile %s. (last-error = %u)\n",
            user_profile_.lpUserName,
            profile_loaded ? "succeeded" : "failed", 
            profile_loaded ? 0 : GetLastError () );

        if ( !profile_loaded ) {
            __leave;
        }

        /* if we get here then we've managed to create the profile */
        ok = TRUE;

    }  
    __finally { 
    
        /* return to previous privilege level */
        set_priv ( priv );

    }

    return ok;

}
Exemple #5
0
bool GetUserHandle(Settings& settings, BOOL& bLoadedProfile, PROFILEINFO& profile, HANDLE hCmdPipe)
{
	DWORD gle = 0;

	if(settings.bUseSystemAccount) 
	{
		if(BAD_HANDLE(settings.hUser)) //might already have hUser from a previous call
		{
			EnablePrivilege(SE_DEBUG_NAME); //helps with OpenProcess, required for GetLocalSystemProcessToken
			settings.hUser = GetLocalSystemProcessToken();
			if(BAD_HANDLE(settings.hUser))
			{
				Log(L"Not able to get Local System token", true);
				return false;
			}
			else
				Log(L"Got Local System handle", false);

			Duplicate(settings.hUser, __FILE__, __LINE__);
		}
		return true;
	}
	else
	{
		//not Local System, so either as specified user, or as current user
		if(FALSE == settings.user.IsEmpty())
		{
			CString user, domain;
			GetUserDomain(settings.user, user, domain);

			BOOL bLoggedIn = LogonUser(user, domain.IsEmpty() ? NULL : domain, settings.password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_WINNT50, &settings.hUser);
			gle = GetLastError();
#ifdef _DEBUG
			Log(L"DEBUG: LogonUser", gle);
#endif
			if((FALSE == bLoggedIn) || BAD_HANDLE(settings.hUser))
			{
				Log(StrFormat(L"Error logging in as %s", settings.user), gle);
				return false;
			}
			else
				Duplicate(settings.hUser, __FILE__, __LINE__); //gives max rights

			if(!BAD_HANDLE(settings.hUser) && (false == settings.bDontLoadProfile))
			{
				EnablePrivilege(SE_RESTORE_NAME);
				EnablePrivilege(SE_BACKUP_NAME);
				bLoadedProfile = LoadUserProfile(settings.hUser, &profile);
#ifdef _DEBUG
				gle = GetLastError();
				Log(L"DEBUG: LoadUserProfile", gle);
#endif
			}
			return true;
		}
		else
		{
			//run as current user
			
			if(NULL != hCmdPipe)
			{
				BOOL b = ImpersonateNamedPipeClient(hCmdPipe);
				DWORD gle = GetLastError();
				if(FALSE == b)
					Log(L"Failed to impersonate client user", gle);
				else
					Log(L"Impersonated caller", false);
			}

			HANDLE hThread = GetCurrentThread();
			BOOL bDupe = DuplicateHandle(GetCurrentProcess(), hThread, GetCurrentProcess(), &hThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
			DWORD gle = GetLastError();

			BOOL bOpen = OpenThreadToken(hThread, TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &settings.hUser);
			gle = GetLastError();
			if(1008 == gle) //no thread token
			{
				bOpen = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &settings.hUser);
				gle = GetLastError();
			}

			if(FALSE == bOpen)
				Log(L"Failed to open current user token", GetLastError());

			Duplicate(settings.hUser, __FILE__, __LINE__); //gives max rights
			RevertToSelf();
			return !BAD_HANDLE(settings.hUser);
		}
	}
}
Exemple #6
0
Result<ExitCode> ProcessWithLogon::RunInternal(Trace& trace, const Settings& settings, ProcessTracker& processTracker, Environment& environment, bool changeIntegrityLevel) const
{
	SECURITY_ATTRIBUTES securityAttributes = {};
	securityAttributes.nLength = sizeof(SECURITY_DESCRIPTOR);
	securityAttributes.bInheritHandle = true;

	STARTUPINFO startupInfo = {};
	startupInfo.dwFlags = STARTF_USESHOWWINDOW;
	startupInfo.wShowWindow = ShowModeConverter::ToShowWindowFlag(settings.GetShowMode());	
	PROCESS_INFORMATION processInformation = {};

	trace < L"ProcessTracker::InitializeConsoleRedirection";
	processTracker.InitializeConsoleRedirection(securityAttributes, startupInfo);	

	StringBuffer userName(settings.GetUserName());
	StringBuffer domain(settings.GetDomain());
	StringBuffer password(settings.GetPassword());
	StringBuffer workingDirectory(settings.GetWorkingDirectory());
	StringBuffer commandLine(settings.GetCommandLine());

	if (changeIntegrityLevel)
	{
		trace < L"::LogonUser";
		auto newUserSecurityTokenHandle = Handle(L"New user security token");
		if (!LogonUser(
			userName.GetPointer(),
			domain.GetPointer(),
			password.GetPointer(),
			LOGON32_LOGON_BATCH,
			LOGON32_PROVIDER_DEFAULT,
			&newUserSecurityTokenHandle))
		{
			return Error(L"LogonUser");
		}

		trace < L"::LoadUserProfile";
		PROFILEINFO profileInfo = {};
		profileInfo.dwSize = sizeof(PROFILEINFO);
		profileInfo.lpUserName = userName.GetPointer();
		if (!LoadUserProfile(newUserSecurityTokenHandle, &profileInfo))
		{
			return Error(L"LoadUserProfile");
		}

		SecurityManager securityManager;
		auto setIntegrityLevelResult = securityManager.SetIntegrityLevel(settings.GetIntegrityLevel(), newUserSecurityTokenHandle, trace);
		if (setIntegrityLevelResult.HasError())
		{
			return Result<ExitCode>(setIntegrityLevelResult.GetError());
		}

		trace < L"::CreateProcessWithTokenW";		
		if (!CreateProcessWithTokenW(
			newUserSecurityTokenHandle,
			LOGON_WITH_PROFILE,
			nullptr,
			commandLine.GetPointer(),
			CREATE_UNICODE_ENVIRONMENT,
			environment.CreateEnvironment(),
			workingDirectory.GetPointer(),
			&startupInfo,
			&processInformation))
		{
			return Error(L"CreateProcessWithLogonW");
		}
	}
	else
	{
		trace < L"::CreateProcessWithLogonW";		
		if (!CreateProcessWithLogonW(
			userName.GetPointer(),
			domain.GetPointer(),
			password.GetPointer(),
			LOGON_WITH_PROFILE,
			nullptr,
			commandLine.GetPointer(),
			CREATE_UNICODE_ENVIRONMENT,
			environment.CreateEnvironment(),
			workingDirectory.GetPointer(),
			&startupInfo,
			&processInformation))
		{
			return Error(L"CreateProcessWithLogonW");
		}
	}

	// ReSharper disable once CppInitializedValueIsAlwaysRewritten
	auto processHandle = Handle(L"Process");
	processHandle = processInformation.hProcess;

	// ReSharper disable once CppInitializedValueIsAlwaysRewritten
	auto threadHandle = Handle(L"Thread");
	threadHandle = processInformation.hThread;

	return processTracker.WaiteForExit(processInformation.hProcess, trace);
}
Exemple #7
0
wchar_t *gethomedir_w(char *pUserName, char *pDomainName)
{
  HANDLE token;

  PROFILEINFOW profileInfo;
  
  wchar_t szPathW[MAX_PATH] = {0};
  
  wchar_t pUserName_w[UNLEN + 1] = {0};
  
  static wchar_t username_w[UNLEN + 1] = {0}; 
  
  DWORD usernamelen = UNLEN + 1;
  
  wchar_t pDomainName_w[UNLEN + 1] = {0};
  
  wchar_t *userprofile_w;
  
  /*
   * If there is home dir from lsa return it.
   */
  
  if (HomeDirLsaW[0] != L'\0')
  {
    debug("Using LSA HomeDirW.");
    
    return _wcsdup(HomeDirLsaW);
  }

  szPathW[0] = '\0';
  
  if (MultiByteToWideChar(CP_UTF8, 0, pUserName, -1, pUserName_w, UNLEN) == 0)
  {
    return NULL;
  }  
  
  if (pDomainName && 
          MultiByteToWideChar(CP_UTF8, 0, pDomainName,
                                  -1, pDomainName_w, UNLEN) == 0)
  {
    return NULL;
  }  

  debug3("gethomedir: pUserName [%s]", pUserName);

  GetUserNameW(username_w, &usernamelen);

  debug3("gethomedir: username [%ls]", username_w);

  if (wcscmp(pUserName_w, username_w) == 0)
  {
    /*
     * User query his own home dir, we can take it from env.
     */
    
    debug3("gethomedir: getenv");
  
    userprofile_w = _wgetenv(L"USERPROFILE");
    
    if (userprofile_w)
    {
      debug3("gethomedir: userprofile [%ls]", userprofile_w);
      
      /*
       * We have a %USERPROFILE% and we can return it
       */
      
      return _wcsdup(userprofile_w);
    }
    
    /*
     * Env not set, let's try to take it from token
     */
  }

  /*
   * If all above fail try to create user token manually
   * and get homedir using this token.
   */
  
  #ifdef USE_NTCREATETOKEN
  
  token = CreateUserTokenW(pUserName_w, pDomainName_w, L"sshd");
  
  if (token == NULL)
  {
    debug("gethomedir: create token failed");

    return NULL;
  }

  debug2("setting up profile info...");
  
  /*
   * Become the user
   */
  
  memset(&profileInfo, 0, sizeof(profileInfo));

  profileInfo.dwSize = sizeof(profileInfo);
  profileInfo.lpUserName = pUserName_w;
  profileInfo.lpServerName = pDomainName_w;

  debug2("LoadUserProfile()...");
  
  if (!LoadUserProfile(token, &profileInfo))
  {
    DWORD dwLast = GetLastError();
  
    debug("gethomedir: load profile failed [%d]", dwLast);
    
    return NULL;
  }

  /*
   * Get user's home directory
   */
  
  //if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, token, 0, szPath)))
  
  debug2("SGGetFolderPath()...");
  
  if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, token, 0, szPathW)))
  {
    debug("gethomedir: get folder failed");

    /*
     * Become self again.
     */

    UnloadUserProfile(token, profileInfo.hProfile);

    RevertToSelf();

    CloseHandle(token);

    return NULL;
  }

  debug3("gethomedir: szPathW [%ls]", szPathW);

  /*
   * Become self again.
   */
  
  UnloadUserProfile(token, profileInfo.hProfile);

  RevertToSelf();
  
  CloseHandle(token);

  debug2("<- gethomedir()...");
  
  return _wcsdup(szPathW);
  
  #else
  
  return NULL;
  
  #endif
}
Exemple #8
0
char *GetHomeDirFromToken(char *userName, HANDLE token)
{
  UCHAR domain[200];
  wchar_t pw_buf[MAX_PATH] = { L'\0' };
  
  debug("-> GetHomeDirFromToken()...");
  
  PROFILEINFO profileInfo;

  // find the server name of the domain controller which created this token
  GetDomainFromToken ( &token, domain, sizeof(domain));
  //if (MultiByteToWideChar(CP_UTF8, 0, domain, -1, domainW, sizeof(domainW)) == 0)
  //{
    //debug("DomainServerName encoding conversion failure");
    //return NULL;
  //}

  profileInfo.dwFlags = PI_NOUI;
  profileInfo.lpProfilePath = NULL;
  profileInfo.lpUserName = userName;
  profileInfo.lpDefaultPath = NULL;
  profileInfo.lpServerName = domain;
  profileInfo.lpPolicyPath = NULL;
  profileInfo.hProfile = NULL;
  profileInfo.dwSize = sizeof(profileInfo);


  
  if (LoadUserProfile(token, &profileInfo) == FALSE)
  {
    debug("<- GetHomeDirFromToken()...");
    debug("LoadUserProfile failure: %d", GetLastError());
    
    return NULL;
  }

  /*
   * And retrieve homedir from profile.
   */
        
  if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, token, 0, pw_homedir)))
  {
    debug("<- GetHomeDirFromToken()...");
    debug("SHGetFolderPath failed");
    
    return NULL;
  }

  // update APPDATA user's env variable
  if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA, token, 0, pw_buf)))
  {
	  SetEnvironmentVariableW(L"APPDATA", pw_buf);
  }

  // update LOCALAPPDATA user's env variable
  if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, token, 0, pw_buf)))
  {
	  SetEnvironmentVariableW(L"LOCALAPPDATA", pw_buf);
  }

  /*
   * Unload user profile.
   */
       
  if (UnloadUserProfile(token, profileInfo.hProfile) == FALSE)
  {
    debug("WARNING. Cannot unload user profile (%u).", GetLastError());
  }
  
  debug("<- GetHomeDirFromToken()...");
  
  return pw_homedir;
}