// // Retrieves the 'negotiate' AuthPackage from the LSA. In this case, Kerberos // For more information on auth packages see this msdn page: // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthn/security/msv1_0_lm20_logon.asp // HRESULT RetrieveNegotiateAuthPackage(ULONG * pulAuthPackage) { HRESULT hr; HANDLE hLsa; NTSTATUS status = LsaConnectUntrusted(&hLsa); if (SUCCEEDED(HRESULT_FROM_NT(status))) { ULONG ulAuthPackage; LSA_STRING lsaszKerberosName; LsaInitString(&lsaszKerberosName, NEGOSSP_NAME); status = LsaLookupAuthenticationPackage(hLsa, &lsaszKerberosName, &ulAuthPackage); if (SUCCEEDED(HRESULT_FROM_NT(status))) { *pulAuthPackage = ulAuthPackage; hr = S_OK; } else { hr = HRESULT_FROM_NT(status); } LsaDeregisterLogonProcess(hLsa); } else { hr= HRESULT_FROM_NT(status); } return hr; }
int __cdecl wmain( int argc, wchar_t *argv[] ) { HANDLE LogonHandle = NULL; ULONG PackageId; if (argc < 2) { printf("Usage: %S <tickets | tgt | purge | get> [service principal name(for get)]\n",argv[0]); return FALSE; } // // Get the logon handle and package ID from the // Kerberos package // if(!PackageConnectLookup(&LogonHandle, &PackageId)) return FALSE; if(!_wcsicmp(argv[1],L"tickets")) { ShowTickets(LogonHandle, PackageId, 0); } else if(!_wcsicmp(argv[1],L"tgt")) { ShowTgt(LogonHandle, PackageId); } else if(!_wcsicmp(argv[1],L"purge")) { ShowTickets(LogonHandle, PackageId, INTERACTIVE_PURGE); } else if(!_wcsicmp(argv[1],L"get")) { if(argc < 3) { printf("Provide service principal name (SPN) of encoded ticket to retrieve\n"); } else GetEncodedTicket(LogonHandle, PackageId, argv[2]); } else { printf("Usage: %S <tickets | tgt | purge | get> [service principal name(for get)]\n",argv[0]); } if (LogonHandle != NULL) { LsaDeregisterLogonProcess(LogonHandle); } return TRUE; }
static NTSTATUS OpenLogonLsaHandle(VOID) { LSA_STRING LogonProcessName; LSA_STRING PackageName; LSA_OPERATIONAL_MODE SecurityMode = 0; NTSTATUS Status; RtlInitAnsiString((PANSI_STRING)&LogonProcessName, "User32LogonProcess"); Status = LsaRegisterLogonProcess(&LogonProcessName, &LsaHandle, &SecurityMode); if (!NT_SUCCESS(Status)) { TRACE("LsaRegisterLogonProcess failed (Status 0x%08lx)\n", Status); goto done; } RtlInitAnsiString((PANSI_STRING)&PackageName, MSV1_0_PACKAGE_NAME); Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage); if (!NT_SUCCESS(Status)) { TRACE("LsaLookupAuthenticationPackage failed (Status 0x%08lx)\n", Status); goto done; } TRACE("AuthenticationPackage: 0x%08lx\n", AuthenticationPackage); done: if (!NT_SUCCESS(Status)) { if (LsaHandle != NULL) { Status = LsaDeregisterLogonProcess(LsaHandle); if (!NT_SUCCESS(Status)) { TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status); } } } return Status; }
NTSTATUS CloseLogonLsaHandle(VOID) { NTSTATUS Status = STATUS_SUCCESS; if (LsaHandle != NULL) { Status = LsaDeregisterLogonProcess(LsaHandle); if (!NT_SUCCESS(Status)) { TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status); } } return Status; }
static BOOL GetLSAPrincipalName(char * pszUser, DWORD dwUserSize) { KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; ULONG ResponseSize; PKERB_EXTERNAL_NAME pClientName = NULL; PUNICODE_STRING pDomainName = NULL; LSA_STRING Name; HANDLE hLogon = INVALID_HANDLE_VALUE; ULONG PackageId; NTSTATUS ntStatus; NTSTATUS ntSubStatus = 0; WCHAR * wchUser = NULL; DWORD dwSize; SHORT sCount; BOOL bRet = FALSE; ntStatus = LsaConnectUntrusted( &hLogon); if (FAILED(ntStatus)) goto cleanup; Name.Buffer = MICROSOFT_KERBEROS_NAME_A; Name.Length = (USHORT)(sizeof(MICROSOFT_KERBEROS_NAME_A) - sizeof(char)); Name.MaximumLength = Name.Length; ntStatus = LsaLookupAuthenticationPackage( hLogon, &Name, &PackageId); if (FAILED(ntStatus)) goto cleanup; memset(&CacheRequest, 0, sizeof(KERB_QUERY_TKT_CACHE_REQUEST)); CacheRequest.MessageType = KerbRetrieveTicketMessage; CacheRequest.LogonId.LowPart = 0; CacheRequest.LogonId.HighPart = 0; ntStatus = LsaCallAuthenticationPackage( hLogon, PackageId, &CacheRequest, sizeof(CacheRequest), &pTicketResponse, &ResponseSize, &ntSubStatus); if (FAILED(ntStatus) || FAILED(ntSubStatus)) goto cleanup; /* We have a ticket in the response */ pClientName = pTicketResponse->Ticket.ClientName; pDomainName = &pTicketResponse->Ticket.DomainName; /* We want to return ClientName @ DomainName */ dwSize = 0; for ( sCount = 0; sCount < pClientName->NameCount; sCount++) { dwSize += pClientName->Names[sCount].Length; } dwSize += pDomainName->Length + sizeof(WCHAR); if ( dwSize / sizeof(WCHAR) > dwUserSize ) goto cleanup; wchUser = malloc(dwSize); if (wchUser == NULL) goto cleanup; for ( sCount = 0, wchUser[0] = L'\0'; sCount < pClientName->NameCount; sCount++) { StringCbCatNW( wchUser, dwSize, pClientName->Names[sCount].Buffer, pClientName->Names[sCount].Length); } StringCbCatNW( wchUser, dwSize, pDomainName->Buffer, pDomainName->Length); if ( !UnicodeToANSI( wchUser, pszUser, dwUserSize) ) goto cleanup; bRet = TRUE; cleanup: if (wchUser) free(wchUser); if ( hLogon != INVALID_HANDLE_VALUE) LsaDeregisterLogonProcess(hLogon); if ( pTicketResponse ) { SecureZeroMemory(pTicketResponse,ResponseSize); LsaFreeReturnBuffer(pTicketResponse); } return bRet; }
NTSTATUS kuhl_m_kerberos_clean() { return LsaDeregisterLogonProcess(g_hLSA); }
int LsaLogon(HANDLE *hToken, char homeDir[MAX_PATH], char *user, char *pkBlob, int pkBlobSize, char *sign, int signSize, char *data, int dataSize, int dataFellow) { int exitCode = 1; NTSTATUS ntStat = 0; LSA_STRING logonProcName; LSA_STRING originName; LSA_STRING authPckgName; HANDLE hLsa = NULL; LSA_OPERATIONAL_MODE securityMode; /* * Impersonation, "weak" token returned from network logon. * We can't create process as other user via this token. */ HANDLE hWeakToken = NULL; /* * Login data. */ LsaAuth *lsaAuth = NULL; ULONG lsaAuthSize = 0; ULONG authPckgId = 0; TOKEN_SOURCE srcToken; PVOID profile = NULL; ULONG profileSize; LUID logonId; QUOTA_LIMITS quotas; NTSTATUS loginStat; debug("-> LsaLogon()..."); /* * We check only hToken arg, becouse other args are tested in AllocLsaAuth(). */ debug("Checking args..."); FAIL(hToken == NULL); /* * Setup lsa strings. */ debug("Setting up LSA Strings..."); FAIL(InitLsaString(&logonProcName, "sshd-logon")); FAIL(InitLsaString(&originName, "NTLM")); FAIL(InitLsaString(&authPckgName, "SSH-LSA")); /* * Enable needed privilege to current running process. */ EnablePrivilege("SeTcbPrivilege", 1); /* * Register new logon process. */ debug("LsaRegisterLogonProcess()..."); NTFAIL(LsaRegisterLogonProcess(&logonProcName, &hLsa, &securityMode)); /* * Retrieve Authenticated Package ID. */ debug("Retrieving Authentification Package ID..."); NTFAIL(LsaLookupAuthenticationPackage(hLsa, &authPckgName, &authPckgId)); /* * Allocate LsaAuth struct. */ debug("Allocating LsaAuth struct..."); FAIL(AllocLsaAuth(&lsaAuth, user, pkBlob, pkBlobSize, sign, signSize, data, dataSize, dataFellow)); lsaAuthSize = lsaAuth -> totalSize_; /* * Create TOKEN_SOURCE part */ debug("Setting up TOKEN_SOURCE..."); FAIL(AllocateLocallyUniqueId(&srcToken.SourceIdentifier) == FALSE); memcpy(srcToken.SourceName, "**sshd**", 8); /* * Try to login using LsaAuth struct. */ debug("Login attemp..."); NTFAIL(LsaLogonUser(hLsa, &originName, Network, authPckgId, lsaAuth, lsaAuthSize, NULL, &srcToken, &profile, &profileSize, &logonId, &hWeakToken, "as, &loginStat)); debug("login status: %x...", loginStat); //FAIL(WideCharToMultiByte( CP_UTF8, 0, profile, -1, homeDir, MAX_PATH, NULL, NULL)==0); //memcpy(homeDir, profile, MAX_PATH*sizeof(wchar_t)); lstrcpyW(homeDir, profile); debug("homedir = [%ls]", (char *) homeDir); //strcpy(homeDir, profile); //PrintToken(hToken); /* * Duplicate 'weak' impersonation token into Primary Key token. * We can create process using duplicated token. */ debug("Duplicating token..."); FAIL(DuplicateTokenEx(hWeakToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, hToken) == 0); exitCode = 0; fail: if (exitCode) { switch(ntStat) { case STATUS_LOGON_FAILURE: { debug("SSH-LSA authorization failed. " "(err = %u, ntStat = %x).", GetLastError(), ntStat); exitCode = 0; break; } case STATUS_NO_SUCH_PACKAGE: { debug("SSH-LSA package not found. " "(err = %u, ntStat = %x).", GetLastError(), ntStat); break; } default: { debug("Cannot logon using LSA package (err = %u, ntStat = %x).", GetLastError(), ntStat); } } hToken = NULL; } else { debug("LsaLogon : OK."); } /* * Clean up. */ CloseHandle(hWeakToken); LsaFreeReturnBuffer(profile); EnablePrivilege("SeTcbPrivilege", 0); LsaDeregisterLogonProcess(hLsa); ClearLsaString(&logonProcName); ClearLsaString(&originName); ClearLsaString(&authPckgName); debug("<- LsaLogon()..."); return exitCode; }
int _tmain(int argc, _TCHAR* argv[]) { int result = -1; HANDLE lsa = 0; //wchar_t unlock[MAX_GROUPNAME] = L""; TRACE(L"-------------------------\n"); //EnablePrivilege(L"SeTcbPrivilege"); if(!RegisterLogonProcess(LOGON_PROCESS_NAME, &lsa)) TRACEMSG(GetLastError()); if(IsWindowsServer()) { TRACE(L"Windows Server\n"); } else { TRACE(L"Windows pas Server\n"); } /* if(GetGroupName(gUnlockGroupName, unlock, sizeof unlock / sizeof *unlock) == S_OK) { wchar_t caption[512]; wchar_t text[2048]; OutputDebugString(L"Group name "); OutputDebugString(unlock); OutputDebugString(L"\n"); if((GetNoticeText(L"Caption", caption, sizeof caption / sizeof *caption) == S_OK) && (GetNoticeText(L"Text", text, sizeof text / sizeof *text) == S_OK)) { wchar_t message[MAX_USERNAME + sizeof text / sizeof *text]; wchar_t *read = text; wchar_t *write = text; while(*read) { if((*read == '\\') && (*(read+1) == 'n')) { *write++ = '\n'; read += 2; } else { *write++ = *read++; } } *write = 0; wsprintf(message, text, unlock); //Will insert group name if there is a %s in the message MessageBox(0, message, caption, MB_YESNOCANCEL|MB_ICONEXCLAMATION); } } */ if(argc > 1) for(int i=1; i<argc; ++i) { // wchar_t user[MAX_USERNAME]; // wchar_t domain[MAX_DOMAIN]; wchar_t passwd[MAX_PASSWORD]; wchar_t username[512]; wchar_t domain[512]; HANDLE current_user = 0; OpenProcessToken(GetCurrentProcess(), TOKEN_READ, ¤t_user); GetUsernameAndDomainFromToken(current_user, username, sizeof username / sizeof *username, domain, sizeof domain / sizeof *domain); if(ShouldHookUnlockPasswordDialog(current_user)) { TRACE(L"Should hook.\n"); } if (_getws_s(passwd, MAX_PASSWORD) == passwd) { result = ShouldUnlockForUser(lsa, current_user, L".", argv[i], passwd); switch(result) { case eLetMSGINAHandleIt: TRACE(L"TEST result is eLetMSGINAHandleIt\n"); wprintf(L"Actual result : eLetMSGINAHandleIt\n"); break; case eUnlock: TRACE(L"TEST result is eUnlock\n"); wprintf(L"Actual result : eUnlock\n"); break; case eForceLogoff: TRACE(L"TEST result is eForceLogoff\n"); wprintf(L"Actual result : eForceLogoff\n"); break; } } else { TRACE(L"Unable to read password\n"); break; } CloseHandle(current_user); } LsaDeregisterLogonProcess(lsa); //DisablePrivilege(L"SeTcbPrivilege"); return result; }
int WINAPI WinMain( IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd) { #if 0 LSA_STRING ProcessName, PackageName; HANDLE LsaHandle; LSA_OPERATIONAL_MODE Mode; BOOLEAN Old; ULONG AuthenticationPackage; NTSTATUS Status; #endif ULONG HardErrorResponse; MSG Msg; UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(nShowCmd); hAppInstance = hInstance; /* Make us critical */ RtlSetProcessIsCritical(TRUE, NULL, FALSE); RtlSetThreadIsCritical(TRUE, NULL, FALSE); if (!RegisterLogonProcess(GetCurrentProcessId(), TRUE)) { ERR("WL: Could not register logon process\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } WLSession = (PWLSESSION)HeapAlloc(GetProcessHeap(), 0, sizeof(WLSESSION)); if (!WLSession) { ERR("WL: Could not allocate memory for winlogon instance\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } ZeroMemory(WLSession, sizeof(WLSESSION)); WLSession->DialogTimeout = 120; /* 2 minutes */ /* Initialize the dialog tracking list */ InitDialogListHead(); if (!CreateWindowStationAndDesktops(WLSession)) { ERR("WL: Could not create window station and desktops\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } LockWorkstation(WLSession); /* Load default keyboard layouts */ if (!InitKeyboardLayouts()) { ERR("WL: Could not preload keyboard layouts\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } if (!StartRpcServer()) { ERR("WL: Could not start the RPC server\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } if (!StartServicesManager()) { ERR("WL: Could not start services.exe\n"); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } if (!StartLsass()) { ERR("WL: Failed to start lsass.exe service (error %lu)\n", GetLastError()); NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 0, 0, NULL, OptionOk, &HardErrorResponse); ExitProcess(1); } /* Wait for the LSA server */ WaitForLsass(); /* Init Notifications */ InitNotifications(); /* Load and initialize gina */ if (!GinaInit(WLSession)) { ERR("WL: Failed to initialize Gina\n"); // FIXME: Retrieve the real name of the GINA DLL we were trying to load. // It is known only inside the GinaInit function... DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_GINALOADFAILED), GetDesktopWindow(), GinaLoadFailedWindowProc, (LPARAM)L"msgina.dll"); HandleShutdown(WLSession, WLX_SAS_ACTION_SHUTDOWN_REBOOT); ExitProcess(1); } DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP); #if 0 /* Connect to NetLogon service (lsass.exe) */ /* Real winlogon uses "Winlogon" */ RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"Winlogon"); Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); if (Status == STATUS_PORT_CONNECTION_REFUSED) { /* Add the 'SeTcbPrivilege' privilege and try again */ Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, TRUE, &Old); if (!NT_SUCCESS(Status)) { ERR("RtlAdjustPrivilege() failed with error %lu\n", LsaNtStatusToWinError(Status)); return 1; } Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode); } if (!NT_SUCCESS(Status)) { ERR("LsaRegisterLogonProcess() failed with error %lu\n", LsaNtStatusToWinError(Status)); return 1; } RtlInitUnicodeString((PUNICODE_STRING)&PackageName, MICROSOFT_KERBEROS_NAME_W); Status = LsaLookupAuthenticationPackage(LsaHandle, &PackageName, &AuthenticationPackage); if (!NT_SUCCESS(Status)) { ERR("LsaLookupAuthenticationPackage() failed with error %lu\n", LsaNtStatusToWinError(Status)); LsaDeregisterLogonProcess(LsaHandle); return 1; } #endif CallNotificationDlls(WLSession, StartupHandler); /* Create a hidden window to get SAS notifications */ if (!InitializeSAS(WLSession)) { ERR("WL: Failed to initialize SAS\n"); ExitProcess(2); } // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_PREPARENETWORKCONNECTIONS); // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGCOMPUTERSETTINGS); /* Display logged out screen */ WLSession->LogonState = STATE_INIT; RemoveStatusMessage(WLSession); /* Check for pending setup */ if (GetSetupType() != 0) { /* Run setup and reboot when done */ TRACE("WL: Setup mode detected\n"); RunSetup(); } else { PostMessageW(WLSession->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_CTRL_ALT_DEL, 0); } (void)LoadLibraryW(L"sfc_os.dll"); /* Tell kernel that CurrentControlSet is good (needed * to support Last good known configuration boot) */ NtInitializeRegistry(CM_BOOT_FLAG_ACCEPTED | 1); /* Message loop for the SAS window */ while (GetMessageW(&Msg, WLSession->SASWindow, 0, 0)) { TranslateMessage(&Msg); DispatchMessageW(&Msg); } CleanupNotifications(); /* We never go there */ return 0; }