static int windowsfunc(struct clientparam *param){ char *dom; HANDLE h; DWORD dw, sidlen, i; char tokenbuf[4096]; PTOKEN_GROUPS ptg = (PTOKEN_GROUPS)tokenbuf; if(!param->username || !param->password || param->pwtype != 0) return 4; dom = strchr((char *)param->username, '\\'); if(dom)*dom++=0; if(!LogonUser( dom?dom:(char *)param->username, dom?(char *)param->username:NULL, param->password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h))return 5; if(dom)*(dom-1)='\\'; if(!GetTokenInformation(h, TokenGroups, ptg, sizeof(tokenbuf), &dw)) return 6; CloseHandle(h); sidlen = GetLengthSid(psid); for(i=0; i < ptg->GroupCount; i++){ if(GetLengthSid(ptg->Groups[i].Sid)==sidlen){ if(!memcmp((void *)ptg->Groups[i].Sid, (void *)psid, sidlen)) { setlocale(LC_CTYPE, ".ACP"); _strlwr(param->username); return 0; } } } return 7; }
bool ProcessObject::start() { if(m_pProcInfo.hProcess) return true; //Pre-Process preProcess(); // start a process with given index STARTUPINFO startUpInfo = { sizeof(STARTUPINFO),NULL,_T(""),NULL,0,0,0,0,0,0,0,STARTF_USESHOWWINDOW,0,0,NULL,0,0,0}; if(m_isUserInterface) startUpInfo.wShowWindow = SW_SHOW; else startUpInfo.wShowWindow = SW_HIDE; startUpInfo.lpDesktop = NULL; // set the correct desktop for the process to be started if(m_isImpersonate==false) { // create the process if(CreateProcess(NULL, const_cast<TCHAR*>(m_commandLine.GetString()),NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS, NULL,NULL,&startUpInfo,&m_pProcInfo)) { Sleep(m_delayStartTime); return true; } else { TCHAR pTemp[256]; long nError = GetLastError(); _stprintf(pTemp,_T("Failed to start program '%s', error code = %d"), m_commandLine.GetString(), nError); LOG_WRITER_INSTANCE.WriteLog( pTemp); return false; } } else { HANDLE hToken = NULL; if(LogonUser(m_userName.GetString(),(m_domainName.GetLength()==0)?_T("."):m_domainName.GetString(),m_userPassword.GetString(),LOGON32_LOGON_SERVICE,LOGON32_PROVIDER_DEFAULT,&hToken)) { if(CreateProcessAsUser(hToken,NULL,const_cast<TCHAR*>(m_commandLine.GetString()),NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&startUpInfo,&m_pProcInfo)) { Sleep(m_delayStartTime); return true; } long nError = GetLastError(); TCHAR pTemp[256]; _stprintf(pTemp,_T("Failed to start program '%s' as user '%s', error code = %d"), m_commandLine.GetString(), m_userName.GetString(), nError); LOG_WRITER_INSTANCE.WriteLog( pTemp); return false; } long nError = GetLastError(); TCHAR pTemp[256]; _stprintf(pTemp,_T("Failed to logon as user '%s', error code = %d"), m_userName.GetString(), nError); LOG_WRITER_INSTANCE.WriteLog( pTemp); return false; } }
BOOL Cnet_demoApp::InitInstance() { // 如果一个运行在 Windows XP 上的应用程序清单指定要 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, //则需要 InitCommonControlsEx()。否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // 将它设置为包括所有要在应用程序中使用的 // 公共控件类。 InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); AfxEnableControlContainer(); // 标准初始化 // 如果未使用这些功能并希望减小 // 最终可执行文件的大小,则应移除下列 // 不需要的特定初始化例程 // 更改用于存储设置的注册表项 // TODO: 应适当修改该字符串, // 例如修改为公司或组织名 SetRegistryKey(_T("应用程序向导生成的本地应用程序")); HANDLE hUser; if(LogonUser ("test",".","test",LOGON32_LOGON_NEW_CREDENTIALS,LOGON32_PROVIDER_DEFAULT,&hUser)){ TRACE("授权1成功"); } if ( 0 == ImpersonateLoggedOnUser(hUser)){ TRACE("授权2不成功"); } //CKaoqing dlg1; CAMainDlg dlg1; Cnet_demoDlg dlg2; INT_PTR nResponse; if (1 || IDOK == AfxMessageBox(_T("选择"),MB_OKCANCEL )){ m_pMainWnd = &dlg1; nResponse = dlg1.DoModal(); } else{ m_pMainWnd = &dlg2; nResponse = dlg2.DoModal(); } if (nResponse == IDOK) { // TODO: 在此放置处理何时用 // “确定”来关闭对话框的代码 } else if (nResponse == IDCANCEL) { // TODO: 在此放置处理何时用 // “取消”来关闭对话框的代码 } // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序, // 而不是启动应用程序的消息泵。 return FALSE; }
void sys_LogonUser(PA_PluginParameters params) { HANDLE hToken = NULL; BOOL bStatus = FALSE; char chUserID[MAXBUF] = ""; // String to hold the username char chDomain[MAXBUF] = ""; // String to hold the domain char chPassword[MAXBUF] = ""; // String to hold the password // Make sure that we've cleared out any previous errors SetLastError(0); // Get our parameters PA_GetTextParameter(params, 1, chUserID); PA_GetTextParameter(params, 2, chDomain); PA_GetTextParameter(params, 3, chPassword); // Authenticate the user bStatus = LogonUser(chUserID, chDomain, chPassword, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken); if(bStatus) { // Authenticated // Close the handle if (hToken != NULL) { CloseHandle(hToken); hToken = NULL; } } PA_ReturnLong(params, (LONG_PTR)bStatus); }
int logon_checkpass(char *user, char *pass, char *domain, char *errbuf, int errlen) { HANDLE h=0; int i, err=-1; char *p; do { *errbuf = 0; p = strchr(user, '@'); if( !p ) { domain = "."; } i = LogonUser(user, domain, pass, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &h); if( !i ) { syserr2str(syserr(), errbuf, errlen); } debug(DEBUG_INFO, ("LogonUser user=%s pass=%s domain=%s i=%d err=%s\n", user, pass, domain, i, errbuf)); err = i == 1 ? 0 : -1; } while(0); if( h ) CloseHandle(h); return err; }
AUTHADMIN_API BOOL CUGP(char * userin,char *password,char *machine,char *groupin,int locdom) { DWORD dwLogonType; DWORD dwLogonProvider; HANDLE hToken; bool returnvalue=false; dwLogonType = LOGON32_LOGON_INTERACTIVE; dwLogonProvider = LOGON32_PROVIDER_DEFAULT; byte *buf = 0; byte *buf2 = 0; char domain[MAXLEN * sizeof(wchar_t)]; DWORD rcdomain = NetGetDCName( 0, 0, &buf ); NetApiBufferFree( buf ); printf("Logonuser: % s %s \n", userin, "."); if (LogonUser(userin, ".", password, dwLogonType, dwLogonProvider, &hToken)) if (ImpersonateLoggedOnUser(hToken)) { returnvalue=IsAdmin(); RevertToSelf(); CloseHandle(hToken); } if (returnvalue==true) return returnvalue; if (!rcdomain) { DWORD result=NetWkstaGetInfo( 0 , 100 , &buf2 ) ; if (!result) { wcstombs( domain, ((WKSTA_INFO_100_NT *) buf2)->wki100_langroup, MAXLEN ); NetApiBufferFree( buf2 ); printf("Logonuser: % s %s \n", userin, domain); if (LogonUser(userin, domain, password, dwLogonType, dwLogonProvider, &hToken)) if (ImpersonateLoggedOnUser(hToken)) { returnvalue=IsAdmin(); RevertToSelf(); CloseHandle(hToken); } } } return returnvalue; }
/** * 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; }
/* static */ bool User::LocalLoginForUser(const wchar_t *username, const wchar_t *password) { std::wstring domainName = pGina::Helpers::GetMachineName(); Log::Debug(L"Using LogonUser(%s, %s, *****)", username, domainName.c_str()); HANDLE token = NULL; if(LogonUser(username, domainName.c_str(), password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &token) == TRUE) { CloseHandle(token); return true; } return false; }
static int get_token(connection_context *c) { int res = 0; int wres; HANDLE token; if (c->runas) { credentials crd; if (!prepare_credentials(c->runas, &crd)) { hprintf(c->pipe, "error Incorrect runas credentials\n"); goto finish; } wres = LogonUser(crd.user, crd.domain, crd.password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &c->token); if (!wres) { hprintf(c->pipe, "error Cannot LogonUser(%s,%s,%s) %d\n", crd.user, crd.domain, crd.password, GetLastError()); goto finish; } res = 1; goto finish; } else if (c->system) { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) { hprintf(c->pipe, "error Cannot OpenProcessToken %d\n", GetLastError()); goto finish; } } else { if (!ImpersonateNamedPipeClient(c->pipe->h)) { hprintf(c->pipe, "error Cannot ImpersonateNamedPipeClient %d\n", GetLastError()); goto finish; } if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &token)) { hprintf(c->pipe, "error Cannot OpenThreadToken %d\n", GetLastError()); goto finishRevertToSelf; } } if (!DuplicateTokenEx(token, MAXIMUM_ALLOWED, 0, c->implevel, TokenPrimary, &c->token)) { hprintf(c->pipe, "error Cannot Duplicate Token %d\n", GetLastError()); goto finishCloseToken; } res = 1; finishCloseToken: CloseHandle(token); finishRevertToSelf: if (!c->system) { if (!RevertToSelf()) { hprintf(c->pipe, "error Cannot RevertToSelf %d\n", GetLastError()); res = 0; } } finish: return res; }
void CUser::LogonNewUser(void) { CTrace::CEnter Enter(CTrace::Layer::KERNEL, L"User::LogonNewUser()"); BOOL bRet; HANDLE hToken; bRet = LogonUser(const_cast<PWSTR>(m_Username.c_str()), NULL, const_cast<PWSTR>(m_Password.c_str()), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken); if (bRet == 0) { wcerr << L"Username: "******" Password: " << m_Password.c_str() << endl; throw CCodineException(CError::GetErrorMessage(GetLastError()), __FILE__, __LINE__); } else { SetHandle(hToken); } }
HANDLE RConStartArgs::CheckUserToken() { //SafeFree(pszUserProfile); HANDLE hLogonToken = NULL; BOOL lbRc = LogonUser(pszUserName, pszDomain, szUserPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hLogonToken); //if (szUserPassword[0]) SecureZeroMemory(szUserPassword, sizeof(szUserPassword)); if (!lbRc || !hLogonToken) { //MessageBox(GetParent(hPwd), L"Invalid user name or password specified!", L"ConEmu", MB_OK|MB_ICONSTOP); return NULL; } return hLogonToken; ////HRESULT hr; //wchar_t szPath[MAX_PATH+1] = {}; ////OSVERSIONINFO osv = {sizeof(osv)}; //// Windows 2000 - hLogonToken - not supported ////if (!GetVersionEx(&osv) || (osv.dwMajorVersion <= 5 && osv.dwMinorVersion == 0)) ////{ //if (ImpersonateLoggedOnUser(hLogonToken)) //{ // //hr = SHGetFolderPath(NULL, CSIDL_PROFILE, hLogonToken, SHGFP_TYPE_CURRENT, szPath); // if (GetEnvironmentVariable(L"USERPROFILE", szPath, countof(szPath))) // { // pszUserProfile = lstrdup(szPath); // } // RevertToSelf(); //} ////} ////else ////{ //// hr = SHGetFolderPath(NULL, CSIDL_PROFILE, hLogonToken, SHGFP_TYPE_CURRENT, szPath); ////} ////if (SUCCEEDED(hr) && *szPath) ////{ //// pszUserProfile = lstrdup(szPath); ////} //CloseHandle(hLogonToken); ////hLogonToken may be used for CreateProcessAsUser //return TRUE; }
void logonu(HANDLE & server_user,char * user,char * password, int & error_code) { char usr[100],srv[100]; char *us=user,*sr=0; item(usr,sizeof(usr),user,"\\\n\t",1,FALSE); if (usr[0]) { item(srv,sizeof(srv),user,"\\\n\t",0,FALSE); us=usr; sr=srv; } if (!LogonUser(us,sr,password,LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&server_user)) { error_code=GetLastError(); if (sr) logfile("LogonUser failed %s %s %u \r\n",us,sr,error_code); else logfile("LogonUser failed %s %u \r\n",us,error_code); server_user=NULL; } }
HANDLE RConStartArgs::CheckUserToken() { HANDLE hLogonToken = NULL; // Empty password? Really? Security hole? Are you sure? // aka: code 1327 (ERROR_ACCOUNT_RESTRICTION) // gpedit.msc - Конфигурация компьютера - Конфигурация Windows - Локальные политики - Параметры безопасности - Учетные записи // Ограничить использование пустых паролей только для консольного входа -> "Отключить". LPWSTR pszPassword = (UseEmptyPassword == crb_On) ? NULL : szUserPassword; DWORD nFlags = LOGON32_LOGON_INTERACTIVE; BOOL lbRc = LogonUser(pszUserName, pszDomain, pszPassword, nFlags, LOGON32_PROVIDER_DEFAULT, &hLogonToken); if (!lbRc || !hLogonToken) { return NULL; } return hLogonToken; }
HANDLE GetUserHandle(char *account, char *domain, char *password, int *pError) { HANDLE hUser; int error; int num_tries = 3; // attempt to get a cached handle hUser = GetCachedUser(account, domain, password); if (hUser != INVALID_HANDLE_VALUE) return hUser; // logon the user while (!LogonUser( account, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hUser)) { error = GetLastError(); if (error == ERROR_NO_LOGON_SERVERS) { if (num_tries) Sleep(250); else { *pError = error; return INVALID_HANDLE_VALUE; } num_tries--; } else { *pError = error; return INVALID_HANDLE_VALUE; } } // cache the user handle CacheUserHandle(account, domain, password, hUser); return hUser; }
void CreatProc(int argc, WCHAR *argv[]) { DWORD dwSize; HANDLE hToken; LPVOID lpvEnv; PROCESS_INFORMATION pi = {0}; STARTUPINFO si = {0}; WCHAR szUserProfile[256] = L""; si.cb = sizeof(STARTUPINFO); // // TO DO: change NULL to '.' to use local account database // if (!LogonUser(argv[1], NULL, argv[2], LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken)) DisplayError(L"LogonUser"); //if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE)) DisplayError(L"CreateEnvironmentBlock"); // dwSize = sizeof(szUserProfile)/sizeof(WCHAR); //if (!GetUserProfileDirectory(hToken, szUserProfile, &dwSize)) DisplayError(L"GetUserProfileDirectory"); // // TO DO: change NULL to '.' to use local account database // int bResult; bResult = CreateProcessWithLogonW(argv[1], NULL, argv[2], LOGON_WITH_PROFILE, NULL, argv[3], CREATE_UNICODE_ENVIRONMENT, /*lpvEnv*/ NULL, szUserProfile, &si, &pi); DWORD dwError; dwError = ::GetLastError(); DisplayError(L"CreateProcessWithLogonW"); // if (!DestroyEnvironmentBlock(lpvEnv)) DisplayError(L"DestroyEnvironmentBlock"); CloseHandle(hToken); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); }
JSBool win32_impersonateuser(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval) { JSString * username, * password, *domain = NULL; DWORD logonType = LOGON32_LOGON_INTERACTIVE; JS_BeginRequest(cx); if(!JS_ConvertArguments(cx, argc, argv, "S S /S u", &username, &password, &domain, &logonType)) { JS_ReportError(cx, "Unable to parse arguments in ImpersonateUser"); JS_EndRequest(cx); return JS_FALSE; } if(logonType == LOGON32_LOGON_NETWORK) { *rval = JSVAL_FALSE; JS_EndRequest(cx); return JS_TRUE; } LPWSTR domainName = NULL; if(domain != NULL) domainName = (LPWSTR)JS_GetStringChars(domain); HANDLE newToken = NULL; JS_YieldRequest(cx); if(!LogonUser((LPWSTR)JS_GetStringChars(username), domainName, (LPWSTR)JS_GetStringChars(password), logonType, LOGON32_PROVIDER_DEFAULT, &newToken)) { *rval = JSVAL_FALSE; JS_EndRequest(cx); return JS_TRUE; } if(!ImpersonateLoggedOnUser(newToken)) *rval = JSVAL_FALSE; else *rval = JSVAL_TRUE; CloseHandle(newToken); JS_EndRequest(cx); return JS_TRUE; }
//***************************************************************************** // Benutzt das Logon-API, um Usernamen und Password (unter NT Betriebssystemen) // zu überprüfen. Liefert ERROR_SUCCESS, wenn die Überprüfung erfolgreich war, // oder den entsprechenden Fehlercode. // //***************************************************************************** long WINAPI CheckUserCredentials(long lusername,long lpassword) { HANDLE hToken = INVALID_HANDLE_VALUE; TCHAR* UserName = (TCHAR*)lusername; TCHAR* PassWord = (TCHAR*)lpassword; BOOLEAN bRes = LogonUser(UserName,NULL,PassWord,LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hToken); if(bRes == FALSE) { DWORD dwErr = GetLastError(); return GetLastError(); } else { CloseHandle(hToken); return ERROR_SUCCESS; }; return 0; };
ULONG kernel_createproc(PKERNEL_ENV pKernelEnv,PWCHAR pExeName){ ULONG rl; HANDLE hUserToken; STARTUPINFO stInfo; PROCESS_INFORMATION procInfo; PPROCESS_ENV pProcEnv; LogonUser(pKernelEnv->UserName, NULL, L"1234%^&*910", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hUserToken); memset(&stInfo,0,sizeof(STARTUPINFO)); stInfo.cb=sizeof(STARTUPINFO); rl=CreateProcessAsUser(hUserToken, pExeName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED | CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &stInfo, &procInfo); pProcEnv=(PPROCESS_ENV)malloc(sizeof(PROCESS_ENV)); pProcEnv->hProc=procInfo.hProcess; pProcEnv->hMainThread=procInfo.hThread; kernel_addproc(pKernelEnv,pProcEnv); return 0; }
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()); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % H t t p E x t e n s i o n P r o c % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % HttpExtensionProc - ISAPI / Win32 API method. This method is % required by IIS. It is called once per client request. This % is where the extension accomplishes its purpose in life. See % Microsofts ISAPI API documentation for all the gory details. % */ DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB) { char **argv, **argv_hw, *errmsg; int argc, argc_hw, i; unsigned int impersonating, status; CHAR *lpszQuery, *lpszHeader=NULL, *lpszTemp=NULL; BOOL Success=FALSE; DWORD dwTotalBytes=0, dwLen=0; impersonating=False; pECB->dwHttpStatusCode=0; // 0 Failure if (!stricmp(pECB->lpszMethod, "get")) { lpszQuery = pECB->lpszQueryString; dwTotalBytes = lstrlen(lpszQuery); Success=TRUE; } else if (!stricmp(pECB->lpszMethod, "post")) { if(pECB->cbTotalBytes > 0) { DWORD cbQuery; dwTotalBytes=pECB->cbTotalBytes; lpszTemp = (char*)LocalAlloc(LPTR, dwTotalBytes+1); if (!lpszTemp) return HSE_STATUS_ERROR; cbQuery = pECB->cbTotalBytes - pECB->cbAvailable; if (cbQuery > 0) { pECB->ReadClient(pECB->ConnID, (LPVOID) (lpszTemp + pECB->cbAvailable),&cbQuery); } strncpy(lpszTemp, pECB->lpbData, pECB->cbAvailable); lpszTemp[dwTotalBytes]='\0'; lpszQuery = lpszTemp; Success=TRUE; } } if (Success) { status=CGIToArgv(lpszQuery,&argc,&argv); if (status == True) { char szMimeType[MaxTextExtent], szPathTranslated[MaxTextExtent]; DWORD dwBuffSize; HSE_SEND_HEADER_EX_INFO HeaderExInfo; dwBuffSize = MaxTextExtent; szPathTranslated[0] = '\0'; if (pECB->GetServerVariable(pECB->ConnID, "PATH_TRANSLATED",szPathTranslated,&dwBuffSize)) { GetFileMimeType(szPathTranslated, szMimeType,MaxTextExtent); } else strcpy(szMimeType,"application/ocetet-stream"); for (argc_hw=1; argc_hw < argc; argc_hw++) { char *blob_data, szHeaders[MaxTextExtent]; size_t blob_length; Image *image; ImageInfo *image_info; int mode=0; argv_hw = &argv[argc_hw]; if (LocaleNCompare("-login",argv[argc_hw],8) == 0) { for (i=argc_hw; i < argc; i++) { if (LocaleNCompare("login-",argv[i],8) == 0) break; } #if defined(WIN32) if ((i-argc_hw)>3) { char *domain=argv_hw[1], *userid=argv_hw[2], *passwd=argv_hw[3]; HANDLE hToken; BOOL status; status = LogonUser(userid,domain,passwd, LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hToken); if (status) { status = ImpersonateLoggedOnUser(hToken); if (status) impersonating=True; else errmsg = NTGetLastError(); } else errmsg = NTGetLastError(); } #endif argc_hw = i+1; argv_hw = &argv[argc_hw]; } if (LocaleNCompare("-convert",argv[argc_hw],8) == 0) { for (i=argc_hw; i < argc; i++) { if (LocaleNCompare("-xbdat",argv[i],6) == 0) { argv[i+1]=(char *)(&blob_data); mode=1; } else if (LocaleNCompare("-xblen",argv[i],6) == 0) { argv[i+1]=(char *)(&blob_length); mode=1; } else if (LocaleNCompare("-xfunc",argv[i],6) == 0) { argv[i+1]=(char *)CGIFifo; mode=2; } else if (LocaleNCompare("-xctxt",argv[i],6) == 0) { argv[i+1]=(char *)pECB; mode=2; } else if (LocaleNCompare("-xinfo",argv[i],6) == 0) { argv[i+1]=(char *)(&image_info); mode=3; } else if (LocaleNCompare("-ximag",argv[i],6) == 0) { argv[i+1]=(char *)(&image); mode=3; } else if (LocaleNCompare("convert-",argv[i],8) == 0) break; } if (mode==0) { convert_main(i-argc_hw,argv_hw); } if (mode==1) { blob_length=8192; convert_main(i-argc_hw,argv_hw); dwLen=blob_length; sprintf(szHeaders, "Content-Length: %u\r\nContent-Type: %s\r\n\r\n", dwLen,szMimeType); HeaderExInfo.pszStatus = "200 OK"; HeaderExInfo.pszHeader = szHeaders; HeaderExInfo.cchStatus = strlen( HeaderExInfo.pszStatus ); HeaderExInfo.cchHeader = strlen( szHeaders ); HeaderExInfo.fKeepConn = FALSE; if (!pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX,&HeaderExInfo,NULL,NULL)) return HSE_STATUS_ERROR; if (!pECB->WriteClient( pECB->ConnID, blob_data, &dwLen, 0)) return HSE_STATUS_ERROR; } if (mode==2) { sprintf(szHeaders,"Content-Type: %s\r\n\r\n",szMimeType); HeaderExInfo.pszStatus = "200 OK"; HeaderExInfo.pszHeader = szHeaders; HeaderExInfo.cchStatus = strlen( HeaderExInfo.pszStatus ); HeaderExInfo.cchHeader = strlen( szHeaders ); HeaderExInfo.fKeepConn = FALSE; if (!pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX,&HeaderExInfo,NULL,NULL)) return HSE_STATUS_ERROR; convert_main(i-argc_hw,argv_hw); } if (mode==3) { convert_main(i-argc_hw,argv_hw); } argc_hw = i+1; argv_hw = &argv[argc_hw]; } if (LocaleNCompare("-combine",argv[argc_hw],8) == 0) { for (i=argc_hw; i < argc; i++) { if (LocaleNCompare("-xbdat",argv[i],6) == 0) { argv[i+1]=(char *)(&blob_data); mode=1; } else if (LocaleNCompare("-xblen",argv[i],6) == 0) { argv[i+1]=(char *)(&blob_length); mode=1; } else if (LocaleNCompare("-xfunc",argv[i],6) == 0) { argv[i+1]=(char *)CGIFifo; mode=2; } else if (LocaleNCompare("-xctxt",argv[i],6) == 0) { argv[i+1]=(char *)pECB; mode=2; } else if (LocaleNCompare("-xinfo",argv[i],6) == 0) { argv[i+1]=(char *)(&image_info); mode=3; } else if (LocaleNCompare("-ximag",argv[i],6) == 0) { argv[i+1]=(char *)(&image); mode=3; } else if (LocaleNCompare("combine-",argv[i],8) == 0) break; } if (mode==0) { combine_main(i-argc_hw,argv_hw); } if (mode==1) { blob_length=8192; combine_main(i-argc_hw,argv_hw); dwLen=blob_length; sprintf(szHeaders, "Content-Length: %u\r\nContent-Type: %s\r\n\r\n", dwLen,szMimeType); HeaderExInfo.pszStatus = "200 OK"; HeaderExInfo.pszHeader = szHeaders; HeaderExInfo.cchStatus = strlen( HeaderExInfo.pszStatus ); HeaderExInfo.cchHeader = strlen( szHeaders ); HeaderExInfo.fKeepConn = FALSE; if (!pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX,&HeaderExInfo,NULL,NULL)) return HSE_STATUS_ERROR; if (!pECB->WriteClient( pECB->ConnID, blob_data, &dwLen, 0)) return HSE_STATUS_ERROR; } if (mode==2) { sprintf(szHeaders,"Content-Type: %s\r\n\r\n",szMimeType); HeaderExInfo.pszStatus = "200 OK"; HeaderExInfo.pszHeader = szHeaders; HeaderExInfo.cchStatus = strlen( HeaderExInfo.pszStatus ); HeaderExInfo.cchHeader = strlen( szHeaders ); HeaderExInfo.fKeepConn = FALSE; if (!pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX,&HeaderExInfo,NULL,NULL)) return HSE_STATUS_ERROR; combine_main(i-argc_hw,argv_hw); } if (mode==3) { combine_main(i-argc_hw,argv_hw); } argc_hw = i+1; argv_hw = &argv[argc_hw]; } } } // BUG: must free all the strings pointed to by argv not just argv LiberateMemory((void **) &argv); } if (impersonating==True) { #if defined(WIN32) status = RevertToSelf(); if (status) impersonating=False; else errmsg = NTGetLastError(); #endif } pECB->dwHttpStatusCode=200; // 200 OK if (lpszTemp) LocalFree(lpszTemp); return HSE_STATUS_SUCCESS; }
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); }
int init_user_ids(const char username[], const char domain[]) { int retval = 0; if (!username || !domain) { dprintf(D_ALWAYS, "WARNING: init_user_ids() called with" " NULL arguments!\n"); return 0; } // we have to be very careful calling dprintf in this function, because dprintf // will try and _set_priv to root and then back to what it was. so we need to // make sure that our global variables are always in a state where that doesn't // except. // TJ:2010: Can't do this here, UserIdsInited must never be true // while CurrUserHandle is NULL or dprintf will EXCEPT. // UserIdsInited = true; // see if we already have a user handle for the requested user. // if so, just return 1. // TODO: cache multiple user handles to save time. dprintf(D_FULLDEBUG, "init_user_ids: want user '%s@%s', " "current is '%s@%s'\n", username, domain, UserLoginName, UserDomainName); if ( CurrUserHandle = cached_tokens.getToken(username, domain)) { UserIdsInited = true; // do this before we call dprintf // when we uninit_user_ids we can end up CurrUserHandle in the cache // but UserLoginName and UserDomainName not set, if that happens // we need to set them here. if ( ! UserLoginName) UserLoginName = strdup(username); if ( ! UserDomainName) UserDomainName = strdup(domain); dprintf(D_FULLDEBUG, "init_user_ids: Already have handle for %s@%s," " so returning.\n", username, domain); return 1; } else { char* myusr = my_username(); char* mydom = my_domainname(); // we cleared CurrUserHandle, so we aren't inited. UserIdsInited = false; // see if our calling thread matches the user and domain // we want a token for. This happens if we're submit for example. if ( strcmp( myusr, username ) == 0 && strcasecmp( mydom, domain ) == 0 ) { // domain is case insensitive dprintf(D_FULLDEBUG, "init_user_ids: Calling thread has token " "we want, so returning.\n"); CurrUserHandle = my_usertoken(); if (CurrUserHandle) { UserIdsInited = true; } else { dprintf(D_FULLDEBUG, "init_user_ids: handle is null!\n"); } if (UserLoginName) { free(UserLoginName); UserLoginName = NULL; } if (UserDomainName) { free(UserDomainName); UserDomainName = NULL; } // these are strdup'ed, so we can just stash their pointers UserLoginName = myusr; UserDomainName = mydom; // don't forget to drop it in the cache too cached_tokens.storeToken(UserLoginName, UserDomainName, CurrUserHandle); return 1; } } // at this point UserIdsInited should be false. ASSERT( ! UserIdsInited); // anything beyond this requires user switching if (!can_switch_ids()) { dprintf(D_ALWAYS, "init_user_ids: failed because user switching is disabled\n"); return 0; } if ( strcmp(username,"nobody") != 0 ) { // here we call routines to deal with passwords. Hopefully we're // running as LocalSystem here, otherwise we can't get at the // password stash. lsa_mgr lsaMan; char pw[255]; char user[255]; char dom[255]; wchar_t w_fullname[255]; wchar_t *w_pw; bool got_password = false; bool got_password_from_credd = false; // these should probably be snprintfs swprintf(w_fullname, L"%S@%S", username, domain); sprintf(user, "%s", username); sprintf(dom, "%s", domain); // make sure we're SYSTEM when we do this w_pw = lsaMan.query(w_fullname); if ( w_pw ) { // copy password into a char buffer sprintf(pw, "%S", w_pw); // we don't need the wide char pw anymore, so clean it up SecureZeroMemory(w_pw, wcslen(w_pw)*sizeof(wchar_t)); delete[](w_pw); w_pw = NULL; // now that we got a password, see if it is good. retval = LogonUser( user, // user name dom, // domain or server - local for now pw, // password LOGON32_LOGON_INTERACTIVE, // type of logon operation. // LOGON_BATCH doesn't seem to work right here. LOGON32_PROVIDER_DEFAULT, // logon provider &CurrUserHandle // receive tokens handle ); if ( !retval ) { dprintf(D_FULLDEBUG,"Locally stored credential for %s@%s is stale\n", user,dom); // Set handle to NULL to make certain we recall LogonUser again below CurrUserHandle = NULL; } else { got_password = true; // so we don't bother going to a credd } } // if we don't have the password from our local stash, try to fetch // it from a credd. this tiny function is in a separate file so // that we don't pull in all of daemon core when we link to the utils library. char *credd_host = param("CREDD_HOST"); if (credd_host && got_password==false) { #if 1 got_password = get_password_from_credd( credd_host, username, domain, pw, sizeof(pw)); got_password_from_credd = got_password; #else dprintf(D_FULLDEBUG, "trying to fetch password from credd: %s\n", credd_host); Daemon credd(DT_CREDD); Sock * credd_sock = credd.startCommand(CREDD_GET_PASSWD,Stream::reli_sock,10); if ( credd_sock ) { credd_sock->put((char*)username); // send user credd_sock->put((char*)domain); // send domain credd_sock->end_of_message(); credd_sock->decode(); pw[0] = '\0'; int my_stupid_sizeof_int_for_damn_cedar = sizeof(pw); char *my_buffer = pw; if ( credd_sock->code(my_buffer,my_stupid_sizeof_int_for_damn_cedar) && pw[0] ) { got_password = true; got_password_from_credd = true; } else { dprintf(D_FULLDEBUG, "credd (%s) did not have info for %s@%s\n", credd_host, username,domain); } delete credd_sock; credd_sock = NULL; } else { dprintf(D_FULLDEBUG,"Failed to contact credd %s: %s\n", credd_host,credd.error() ? credd.error() : ""); } #endif } if (credd_host) free(credd_host); if ( ! got_password ) { dprintf(D_ALWAYS, "ERROR: Could not locate valid credential for user " "'%s@%s'\n", username, domain); return 0; } else { dprintf(D_FULLDEBUG, "Found credential for user '%s'\n", username); // If we have not yet called LogonUser, then CurrUserHandle is NULL, // and we need to call it here. if ( CurrUserHandle == NULL ) { retval = LogonUser( user, // user name dom, // domain or server - local for now pw, // password LOGON32_LOGON_INTERACTIVE, // type of logon operation. // LOGON_BATCH doesn't seem to work right here. LOGON32_PROVIDER_DEFAULT, // logon provider &CurrUserHandle // receive tokens handle ); } else { // we already have a good user handle from calling LogonUser to check to // see if our stashed credential was stale or not, so set retval to success retval = 1; // LogonUser returns nonzero value on success } dprintf(D_FULLDEBUG, "LogonUser completed.\n"); if (UserLoginName) { free(UserLoginName); UserDomainName = NULL; } if (UserDomainName) { free(UserDomainName); UserDomainName = NULL; } UserLoginName = strdup(username); UserDomainName = strdup(domain); if ( !retval ) { dprintf(D_ALWAYS, "init_user_ids: LogonUser failed with NT Status %ld\n", GetLastError()); retval = 0; // return of 0 means FAILURE } else { // stash the new token in our cache cached_tokens.storeToken(UserLoginName, UserDomainName, CurrUserHandle); UserIdsInited = true; // if we got the password from the credd, and the admin wants passwords stashed // locally on this machine, then do it. if ( got_password_from_credd && param_boolean("CREDD_CACHE_LOCALLY",false) ) { cache_credd_locally(username, domain, pw); } retval = 1; // return of 1 means SUCCESS } // clear pw from memory SecureZeroMemory(pw, 255); return retval; } } else { /// // Here's where we use a nobody account // dprintf(D_FULLDEBUG, "Using dynamic user account.\n"); myDynuser->reset(); // at this point, we know we want a user nobody, so // generate a dynamic user and stash the handle if ( !myDynuser->init_user() ) { // This is indicative of a serious problem. EXCEPT("Failed to create a user nobody"); } if (UserLoginName) { free(UserLoginName); UserDomainName = NULL; } if (UserDomainName) { free(UserDomainName); UserDomainName = NULL; } UserLoginName = strdup( myDynuser->get_accountname() ); UserDomainName = strdup( "." ); // we created a new user, now just stash the token CurrUserHandle = myDynuser->get_token(); // drop the handle in our cache too cached_tokens.storeToken(UserLoginName, UserDomainName, CurrUserHandle); UserIdsInited = true; return 1; } }
/* Return token for test user with required privileges to execute * programs as that user. Note that for this to work, some system * configuration is required: * - you must have a local user account with name "test" and * password "test" * - you must run "secpol.msc", and in the Local Policies > * User Rights Assignment section, give your test user the right to * "Replace a process level token" */ void get_test_user_token (HANDLE *p_token) { BOOL success; DWORD result; success = LogonUser ("test", ".", "test", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, p_token); if (! success) { result = GetLastError (); if (result == ERROR_LOGON_FAILURE) { rpc_log_error (test_user_logon_failure_error_message); } else { printf ("tester: Unable to log on second user: "******"SeIncreaseQuotaPrivilege", &se_increase_quota_privilege); if (! success) rpc_log_error_from_status (GetLastError ()); success = LookupPrivilegeValue (NULL, "SeTakeOwnershipPrivilege", &se_take_ownership_privilege); if (! success) rpc_log_error_from_status (GetLastError ()); success = LookupPrivilegeValue (NULL, "SeAssignPrimaryTokenPrivilege", &se_assign_primary_token_privilege); if (! success) rpc_log_error_from_status (GetLastError ()); new_privileges->PrivilegeCount = 3; new_privileges->Privileges[0].Luid = se_increase_quota_privilege; new_privileges->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; new_privileges->Privileges[1].Luid = se_take_ownership_privilege; new_privileges->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; new_privileges->Privileges[2].Luid = se_assign_primary_token_privilege; new_privileges->Privileges[2].Attributes = SE_PRIVILEGE_ENABLED; /* If SeAssignPrimaryToken isn't present in the token (which it * won't be if it's not been enabled in secpol.msc) this function * will succeed anyway and just not enable the privilege. Then * CreateProcessAsUser() will fail because "A required privilege is * not held by the client." */ success = AdjustTokenPrivileges (*p_token, FALSE, new_privileges, length, NULL, NULL); if (! success) rpc_log_error_from_status (GetLastError ()); free (new_privileges); }
int daemon_AuthUserPwd(char *username, char *password, char *errbuf) { #ifdef WIN32 /* Warning: the user which launches the process must have the SE_TCB_NAME right. This corresponds to have the "Act as part of the Operating System" turined on (administrative tools, local security settings, local policies, user right assignment) However, it seems to me that if you run it as a service, this right should be provided by default. */ HANDLE Token; if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0) { int error; error = GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, PCAP_ERRBUF_SIZE, NULL); return -1; } // This call should change the current thread to the selected user. // I didn't test it. if (ImpersonateLoggedOnUser(Token) == 0) { int error; error = GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, PCAP_ERRBUF_SIZE, NULL); CloseHandle(Token); return -1; } CloseHandle(Token); return 0; #else /* Standard user authentication: http://www.unixpapa.com/incnote/passwd.html Problem: it is not able to merge the standard pwd file with the shadow one Shadow user authentication: http://www.tldp.org/HOWTO/Shadow-Password-HOWTO-8.html Problem: the program must either (1) run as root, or (2) run as user, but it must be owned by root and must be SUID root (chmod u+s rpcapd) */ struct passwd *user; #ifdef linux struct spwd *usersp; #endif // This call is needed to get the uid if ((user= getpwnam(username)) == NULL) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user"); return -1; } #ifdef linux // This call is needed to get the password; otherwise 'x' is returned if ((usersp= getspnam(username)) == NULL) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user"); return -1; } if (strcmp(usersp->sp_pwdp, (char *) crypt(password, usersp->sp_pwdp) ) != 0) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: password incorrect"); return -1; } #endif #ifdef bsd if (strcmp(user->pw_passwd, (char *) crypt(password, user->pw_passwd) ) != 0) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: password incorrect"); return -1; } #endif if (setuid(user->pw_uid) ) { snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s", pcap_strerror(errno) ); return -1; } /* if (setgid(user->pw_gid) ) { SOCK_ASSERT("setgid failed", 1); snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s", pcap_strerror(errno) ); return -1; } */ return 0; #endif }
void CmdService::Run() { CLog* log=LogManager::OpenLog(m_szLogFile,CLog::LL_INFO); int i; DWORD nBufferSize=GetFileSize(m_szConfigFile); if(!nBufferSize) { nBufferSize = 32767; } PEXECPARAM tmpExecParam=NULL,ptrExecParam; PTCHAR pBuffer= (PTCHAR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(TCHAR)*nBufferSize),ptrBuffer,tmpBuffer; DWORD ret = GetPrivateProfileSection("Command", pBuffer, nBufferSize, m_szConfigFile); // ¶ÁÈ¡ËùÓÐÅäÖõÄÃüÁî if(ret>0) { TCHAR *p; TCHAR tmpDirectory[MAX_PATH]={0}; TCHAR configFileDirectory[MAX_PATH]={0}; strncpy(configFileDirectory,m_szConfigFile,strrchr(m_szConfigFile,'\\')-m_szConfigFile+1); for(ptrBuffer=pBuffer;*ptrBuffer;ptrBuffer+=strlen(ptrBuffer)+1) { ptrExecParam = (PEXECPARAM)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(EXECPARAM)); tmpBuffer=strchr(ptrBuffer,'='); strcpy(ptrExecParam->cmdLine,tmpBuffer+1); *tmpBuffer='\0'; strcpy(ptrExecParam->keyName,ptrBuffer); sprintf(ptrExecParam->logFile, "%s-%s", m_szLogFile, ptrExecParam->keyName); GetPrivateProfileString("Directory", ptrExecParam->keyName, ".\\", tmpDirectory, MAX_PATH-1,m_szConfigFile); p=tmpDirectory; while(*p) { if(*p == '/') { *p='\\'; } p++; } PathCombine(ptrExecParam->curDirectory,configFileDirectory, tmpDirectory); #ifdef _DEBUG log->WriteLog(CLog::LL_INFO,"keyName(%s), curDirectory(%s), cmdLine(%s), logFile(%s)", ptrExecParam->keyName, ptrExecParam->curDirectory, ptrExecParam->cmdLine, ptrExecParam->logFile); #endif ptrExecParam->next = NULL; if(tmpExecParam) { tmpExecParam->next = ptrExecParam; } else { pHeadExecParam = ptrExecParam; } tmpExecParam = ptrExecParam; nCmdSize++; ptrBuffer=strchr(tmpBuffer+1,'\0'); } } else { log->WriteLog("Not found [Command] section in config file."); log->CloseLogFile(); return; } TCHAR domain[100], userName[100], passWord[100]; HANDLE hToken = NULL; GetPrivateProfileString("Account", "Domain", ".", domain, sizeof(domain)-1, m_szConfigFile); GetPrivateProfileString("Account", "User", "Administrator", userName, sizeof(userName)-1, m_szConfigFile); GetPrivateProfileString("Account", "Password", "", passWord, sizeof(passWord)-1, m_szConfigFile); ret = LogonUser(userName, domain, passWord, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken); if(ret) { log->WriteLog(CLog::LL_INFO, "Login success(Domain=%s, User=%s, Password=%s)", domain, userName, passWord); } else { log->WriteLog(CLog::LL_WARN, "Login fail(Domain=%s, User=%s, Password=%s)", domain, userName, passWord); } dwThreadId = (PDWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(DWORD)*nCmdSize); hThread = (PHANDLE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(HANDLE)*nCmdSize); m_bRunning = true; while (m_bRunning) { if (m_bPaused) { Sleep(200); continue; } ptrExecParam=pHeadExecParam; i=0; while(ptrExecParam) { ptrExecParam->hToken = hToken; hThread[i]=CreateThread(NULL, 0, ThreadProc, ptrExecParam, 0, &dwThreadId[i]); if(hThread[i]==NULL) { log->WriteLog(CLog::LL_ERROR, "[%s] create thread fail", ptrExecParam->keyName); } else { #ifdef _DEBUG log->WriteLog(CLog::LL_INFO, "[%d] = %s", i, ptrExecParam->keyName); #endif i++; } ptrExecParam = ptrExecParam->next; } WaitForMultipleObjects(i, hThread, TRUE, INFINITE); ptrExecParam=pHeadExecParam; i = 0; while(ptrExecParam) { CloseHandle(hThread[i]); i++; ptrExecParam = ptrExecParam->next; } Sleep(1000); } log->CloseLogFile(); }
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; }
BOOL StartInteractiveClientProcess ( LPTSTR lpszUsername, // client to log on LPTSTR lpszDomain, // domain of client's account LPTSTR lpszPassword, // client's password LPTSTR lpCommandLine // command line to execute ) { HANDLE hToken; HDESK hdesk = NULL; HWINSTA hwinsta = NULL, hwinstaSave = NULL; PROCESS_INFORMATION pi; PSID pSid = NULL; STARTUPINFO si; BOOL bResult = FALSE; // Log the client on to the local computer. if (!LogonUser( lpszUsername, lpszDomain, lpszPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken) ) { goto Cleanup; } // Save a handle to the caller's current window station. if ( (hwinstaSave = GetProcessWindowStation() ) == NULL) goto Cleanup; // Get a handle to the interactive window station. hwinsta = OpenWindowStation( _T("winsta0"), // the interactive window station FALSE, // handle is not inheritable READ_CONTROL | WRITE_DAC); // rights to read/write the DACL if (hwinsta == NULL) goto Cleanup; // To get the correct default desktop, set the caller's // window station to the interactive window station. if (!SetProcessWindowStation(hwinsta)) goto Cleanup; // Get a handle to the interactive desktop. hdesk = OpenDesktop( _T("default"), // the interactive window station 0, // no interaction with other desktop processes FALSE, // handle is not inheritable READ_CONTROL | // request the rights to read and write the DACL WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS); // Restore the caller's window station. if (!SetProcessWindowStation(hwinstaSave)) goto Cleanup; if (hdesk == NULL) goto Cleanup; // Get the SID for the client's logon session. if (!GetLogonSID(hToken, &pSid)) goto Cleanup; // Allow logon SID full access to interactive window station. if (! AddAceToWindowStation(hwinsta, pSid) ) goto Cleanup; // Allow logon SID full access to interactive desktop. if (! AddAceToDesktop(hdesk, pSid) ) goto Cleanup; // Impersonate client to ensure access to executable file. if (! ImpersonateLoggedOnUser(hToken) ) goto Cleanup; // Initialize the STARTUPINFO structure. // Specify that the process runs in the interactive desktop. ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb= sizeof(STARTUPINFO); si.lpDesktop = TEXT("winsta0\\default"); // Launch the process in the client's logon session. bResult = CreateProcessAsUser( hToken, // client's access token NULL, // file to execute lpCommandLine, // command line NULL, // pointer to process SECURITY_ATTRIBUTES NULL, // pointer to thread SECURITY_ATTRIBUTES FALSE, // handles are not inheritable NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, // creation flags NULL, // pointer to new environment block NULL, // name of current directory &si, // pointer to STARTUPINFO structure &pi // receives information about new process ); // End impersonation of client. RevertToSelf(); if (bResult && pi.hProcess != INVALID_HANDLE_VALUE) { WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); } if (pi.hThread != INVALID_HANDLE_VALUE) CloseHandle(pi.hThread); Cleanup: if (hwinstaSave != NULL) SetProcessWindowStation (hwinstaSave); // Free the buffer for the logon SID. if (pSid) FreeLogonSID(&pSid); // Close the handles to the interactive window station and desktop. if (hwinsta) CloseWindowStation(hwinsta); if (hdesk) CloseDesktop(hdesk); // Close the handle to the client's access token. if (hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken); return bResult; }
//Authentication bool UserUtilities::LoginUser(CString userName, CString userPass, HANDLE &hToken) { BOOL res = LogonUser(userName, TEXT("."), userPass, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken); return res; }
LDAPWAStatus WindowsAuthentication( struct backentry *e, struct berval *cred ) { Slapi_Attr *a; Slapi_Value *sval = NULL; int iStatus; char szNTDomain[MAX_PATH], szNTUsername[MAX_PATH]; HANDLE hToken = NULL; BOOL bLogonStatus = FALSE; int i= -1; /* Get the NT Domain and username - if the entry has such an attribute */ if( !e || !e->ep_entry || slapi_entry_attr_find( e->ep_entry, "ntuserdomainid", &a ) != 0) { return( LDAPWA_NoDomainAttr ); } i= slapi_attr_first_value( a, &sval ); if(sval==NULL) { return( LDAPWA_NoDomainAttr ); } while(i != -1) { const struct berval *val = slapi_value_get_berval(sval); char * colon = NULL; if (!val->bv_val || (strlen(val->bv_val) > (MAX_PATH<<1))) { LDAPDebug( LDAP_DEBUG_TRACE, "WindowsAuthentication => validation FAILED for \"%s\" on NT Domain : " "ntuserdomainid attr value too long\n", val->bv_val, 0, 0); i= slapi_attr_next_value(a, i, &sval); continue; } colon = strchr( val->bv_val, ':' ); if (!colon || ((colon - val->bv_val)/sizeof(char) > MAX_PATH)) { if (!colon) { LDAPDebug( LDAP_DEBUG_TRACE, "WindowsAuthentication => validation FAILED for \"%s\" on NT Domain : " "a colon is missing in ntuserdomainid attr value\n", val->bv_val, 0, 0); } else { LDAPDebug( LDAP_DEBUG_TRACE, "WindowsAuthentication => validation FAILED for \"%s\" on NT Domain : " "domain in ntuserdomainid attr value too long\n", val->bv_val, 0, 0); } i= slapi_attr_next_value(a, i, &sval); continue; } if(( iStatus = GetDomainUsername( val->bv_val, szNTDomain, szNTUsername )) != 0) { i= slapi_attr_next_value(a, i, &sval); continue; } #if !defined( LOGON32_LOGON_NETWORK ) /* This is specified in the WIn32 LogonUser() documentation, but not defined in the Visual C++ 4.2 include file winbase.h. A search of the lastest version of this file at www.microsoft.com finds that LOGON32_LOGON_NETWORK == 3. */ #define LOGON32_LOGON_NETWORK 3 #endif /* Now do the Logon attempt */ bLogonStatus = LogonUser( szNTUsername, // string that specifies the user name szNTDomain, // string that specifies the domain or server cred->bv_val, // string that specifies the password LOGON32_LOGON_NETWORK, // the type of logon operation, LOGON32_PROVIDER_DEFAULT, // specifies the logon provider &hToken ); // pointer to variable to receive token handle if( bLogonStatus && hToken ) CloseHandle( hToken ); if( bLogonStatus ) { // Successful validation LDAPDebug( LDAP_DEBUG_TRACE, "WindowsAuthentication => validated \"%s\" on NT Domain \"%s\"\n", szNTUsername, szNTDomain, 0 ); return( LDAPWA_Success ); } else { LDAPDebug( LDAP_DEBUG_TRACE, "WindowsAuthentication => validation FAILED for \"%s\" on NT Domain \"%s\", reason %d\n", szNTUsername, szNTDomain, GetLastError() ); return( LDAPWA_InvalidCredentials ); } i= slapi_attr_next_value(a, i, &sval); } return( LDAPWA_Failure ); }
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); } } }