Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

505 lines
14 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
msvlogon.cxx
Abstract:
logon
Author:
Larry Zhu (LZhu) December 1, 2001 Created
Environment:
User Mode
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
#include "msvlogon.hxx"
VOID
Usage(
IN PCSTR pszApp
)
{
DebugPrintf(SSPI_ERROR, "\n\nUsage: %s [-p<ParameterControl>] -s<server> -S<server domain> "
"-c<client name> -C<client realm> -k<password> -h<LogonId.highpart> -l<LognId.LowPart> "
"-H<challeng HighPart> -L<challenge LowPart> -w<Workstation> -a<application>\n\n",
pszApp);
exit(-1);
}
NTSTATUS
GetMsvLogonInfo(
IN HANDLE hLogonHandle,
IN ULONG PackageId,
IN LUID* pLogonId,
IN ULONG ParameterControl,
IN UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH],
IN UNICODE_STRING* pUserName,
IN UNICODE_STRING* pUserDomain,
IN UNICODE_STRING* pPassword,
IN UNICODE_STRING* pServerName,
IN UNICODE_STRING* pServerDomain,
IN UNICODE_STRING* pWorkstation,
OUT ULONG* pcbLogonInfo,
OUT MSV1_0_LM20_LOGON** ppLogonInfo
)
{
TNtStatus Status;
NTSTATUS AuthPackageStatus = STATUS_UNSUCCESSFUL;
MSV1_0_GETCHALLENRESP_REQUEST* pRequest = NULL;
MSV1_0_GETCHALLENRESP_RESPONSE* pResponse = NULL;
ULONG cbResponse = 0;
ULONG cbRequest = 0;
WCHAR* pWhere = NULL;
UNICODE_STRING NtlmServerName = {0};
ULONG cbLogonInfo = 0;
MSV1_0_LM20_LOGON* pLogonInfo = NULL;
NtlmServerName.Length = (pServerDomain->Length ? pServerDomain->Length + sizeof(WCHAR) : 0)
+ pServerName->Length;
NtlmServerName.MaximumLength = NtlmServerName.Length + sizeof(WCHAR);
NtlmServerName.Buffer = (PWSTR) new CHAR[NtlmServerName.MaximumLength];
Status DBGCHK = NtlmServerName.Buffer ? STATUS_SUCCESS : STATUS_NO_MEMORY;
if (NT_SUCCESS(Status))
{
RtlZeroMemory(NtlmServerName.Buffer, NtlmServerName.MaximumLength);
if (pServerDomain->Length)
{
RtlCopyMemory(NtlmServerName.Buffer, pServerDomain->Buffer, pServerDomain->Length);
RtlCopyMemory(NtlmServerName.Buffer + (pServerDomain->Length / sizeof(WCHAR)) + 1,
pServerName->Buffer, pServerName->Length);
}
else
{
RtlCopyMemory(NtlmServerName.Buffer, pServerName->Buffer, pServerName->Length);
}
cbRequest = ROUND_UP_COUNT(sizeof(MSV1_0_GETCHALLENRESP_REQUEST), sizeof(ULONG_PTR))
+ pUserName->Length + sizeof(WCHAR)
+ pUserDomain->Length + sizeof(WCHAR)
+ NtlmServerName.Length + sizeof(WCHAR)
+ pPassword->Length + sizeof(WCHAR);
pRequest = (MSV1_0_GETCHALLENRESP_REQUEST*) new CHAR[cbRequest];
Status DBGCHK = pRequest ? STATUS_SUCCESS : STATUS_NO_MEMORY;
}
if (NT_SUCCESS(Status))
{
RtlZeroMemory(pRequest, cbRequest);
pWhere = (WCHAR*) (pRequest + 1);
pRequest->MessageType = MsV1_0Lm20GetChallengeResponse;
pRequest->ParameterControl = ParameterControl;
pRequest->LogonId = *pLogonId;
RtlCopyMemory(pRequest->ChallengeToClient, ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
PackUnicodeStringAsUnicodeStringZ(pUserName, &pWhere, &pRequest->UserName);
PackUnicodeStringAsUnicodeStringZ(pUserDomain, &pWhere, &pRequest->LogonDomainName);
PackUnicodeStringAsUnicodeStringZ(&NtlmServerName, &pWhere, &pRequest->ServerName);
PackUnicodeStringAsUnicodeStringZ(pPassword, &pWhere, &pRequest->Password);
DebugPrintf(SSPI_LOG, "MsvLsaLogonUser PackageId %#x, "
"UserName %wZ, DomainName %wZ, Password %wZ, "
"ParameterControl %#x, LogonId %#x:%#x\n",
PackageId, &pRequest->UserName, &pRequest->LogonDomainName, &pRequest->Password,
pRequest->ParameterControl, pRequest->LogonId.HighPart,
pRequest->LogonId.LowPart);
DebugPrintHex(SSPI_LOG, "pRequest->ServerName:", pRequest->ServerName.MaximumLength, pRequest->ServerName.Buffer);
DebugPrintHex(SSPI_LOG, "ChallengeToClient:", MSV1_0_CHALLENGE_LENGTH, pRequest->ChallengeToClient);
Status DBGCHK = LsaCallAuthenticationPackage(
hLogonHandle,
PackageId,
pRequest,
cbRequest,
(VOID**) &pResponse,
&cbResponse,
&AuthPackageStatus
);
}
if (NT_SUCCESS(Status))
{
Status DBGCHK = AuthPackageStatus;
}
if (NT_SUCCESS(Status))
{
DebugPrintf(SSPI_LOG, "GetMsvLogonInfo response LogonDomain %wZ, UserName %wZ\n",
pResponse->LogonDomainName, pResponse->UserName);
DebugPrintHex(SSPI_LOG, "CaseSensitiveChallengeResponse:",
pResponse->CaseSensitiveChallengeResponse.Length,
pResponse->CaseSensitiveChallengeResponse.Buffer);
DebugPrintHex(SSPI_LOG, "CaseInsensitiveChallengeResponse:",
pResponse->CaseInsensitiveChallengeResponse.Length,
pResponse->CaseInsensitiveChallengeResponse.Buffer);
DebugPrintHex(SSPI_LOG, "UserSessionKey:", MSV1_0_USER_SESSION_KEY_LENGTH, pResponse->UserSessionKey);
DebugPrintHex(SSPI_LOG, "LanmanSessionKey:", MSV1_0_USER_SESSION_KEY_LENGTH, pResponse->LanmanSessionKey);
cbLogonInfo = ROUND_UP_COUNT(sizeof(MSV1_0_LM20_LOGON), sizeof(ULONG_PTR))
+ pUserDomain->Length + sizeof(WCHAR)
+ pWorkstation->Length + sizeof(WCHAR)
+ pUserName->Length + sizeof(WCHAR)
+ pResponse->CaseSensitiveChallengeResponse.Length + sizeof(WCHAR)
+ pResponse->CaseInsensitiveChallengeResponse.Length + sizeof(WCHAR);
pLogonInfo = (MSV1_0_LM20_LOGON*) new CHAR[cbLogonInfo];
Status DBGCHK = pLogonInfo ? STATUS_SUCCESS : STATUS_NO_MEMORY;
}
if (NT_SUCCESS(Status))
{
RtlZeroMemory(pLogonInfo, cbLogonInfo);
pLogonInfo->MessageType = MsV1_0NetworkLogon;
pLogonInfo->ParameterControl = ParameterControl;
RtlCopyMemory(pLogonInfo->ChallengeToClient, ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
pWhere = (PWSTR) (pLogonInfo + 1);
PackUnicodeStringAsUnicodeStringZ(pUserDomain, &pWhere, &pLogonInfo->LogonDomainName);
PackUnicodeStringAsUnicodeStringZ(pUserName, &pWhere, &pLogonInfo->UserName);
PackUnicodeStringAsUnicodeStringZ(pWorkstation, &pWhere, &pLogonInfo->Workstation);
PackString(
&pResponse->CaseSensitiveChallengeResponse,
(CHAR**) &pWhere,
&pLogonInfo->CaseSensitiveChallengeResponse
);
PackString(
&pResponse->CaseSensitiveChallengeResponse,
(CHAR**) &pWhere,
&pLogonInfo->CaseSensitiveChallengeResponse
);
DebugPrintf(SSPI_LOG, "pLogonInfo ParameterControl %#x, LogonDomain %wZ, UserName %wZ, Workstation %wZ\n",
pLogonInfo->ParameterControl,
&pLogonInfo->LogonDomainName,
&pLogonInfo->UserName,
&pLogonInfo->Workstation);
DebugPrintHex(SSPI_LOG, "ChallengeToClient:", MSV1_0_CHALLENGE_LENGTH, pLogonInfo->ChallengeToClient);
DebugPrintHex(SSPI_LOG, "CaseSensitiveChallengeResponse:",
pLogonInfo->CaseSensitiveChallengeResponse.Length,
pLogonInfo->CaseSensitiveChallengeResponse.Buffer);
DebugPrintHex(SSPI_LOG, "CaseInsensitiveChallengeResponse:",
pLogonInfo->CaseInsensitiveChallengeResponse.Length,
pLogonInfo->CaseInsensitiveChallengeResponse.Buffer);
*ppLogonInfo = pLogonInfo;
pLogonInfo = NULL;
*pcbLogonInfo = cbLogonInfo;
}
if (pRequest)
{
delete [] pRequest;
}
if (pLogonInfo)
{
delete [] pLogonInfo;
}
if (pResponse)
{
LsaFreeReturnBuffer(pResponse);
}
return Status;
}
NTSTATUS
MsvLsaLogon(
IN HANDLE hLogonHandle,
IN ULONG PackageId,
IN LUID* pLogonId,
IN ULONG ParameterControl,
IN UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH],
IN UNICODE_STRING* pUserName,
IN UNICODE_STRING* pUserDomain,
IN UNICODE_STRING* pPassword,
IN UNICODE_STRING* pServerName,
IN UNICODE_STRING* pServerDomain,
IN UNICODE_STRING* pWorkstation,
OUT HANDLE* pTokenHandle
)
{
TNtStatus Status;
NTSTATUS SubStatus = STATUS_UNSUCCESSFUL;
MSV1_0_LM20_LOGON* pLogonInfo = NULL;
ULONG cbLogonInfoSize = 0;
LSA_STRING Name = {0};
TOKEN_SOURCE SourceContext = {0};
VOID* pProfile = NULL;
ULONG cbProfileSize = 0;
LUID LogonId = {0};
QUOTA_LIMITS Quotas = {0};
Status DBGCHK = GetMsvLogonInfo(
hLogonHandle,
PackageId,
pLogonId,
ParameterControl,
ChallengeToClient,
pUserName,
pUserDomain,
pPassword,
pServerName,
pServerDomain,
pWorkstation,
&cbLogonInfoSize,
&pLogonInfo
);
if (NT_SUCCESS(Status))
{
strncpy(
SourceContext.SourceName,
"ssptest",
sizeof(SourceContext.SourceName)
);
NtAllocateLocallyUniqueId(&SourceContext.SourceIdentifier);
//
// Now call LsaLogonUser
//
RtlInitString(
&Name,
"ssptest"
);
Status DBGCHK = LsaLogonUser(
hLogonHandle,
&Name,
Network,
PackageId,
pLogonInfo,
cbLogonInfoSize,
NULL, // no token groups
&SourceContext,
(VOID**) &pProfile,
&cbProfileSize,
&LogonId,
pTokenHandle,
&Quotas,
&SubStatus
);
}
if (NT_SUCCESS(Status))
{
Status DBGCHK = SubStatus;
}
if (NT_SUCCESS(Status))
{
DebugPrintf(SSPI_LOG, "LogonId %#x:%#x\n", LogonId.HighPart, LogonId.LowPart);
DebugPrintf(SSPI_LOG, "TokenHandle %p\n", *pTokenHandle);
DebugPrintProfileAndQuotas(SSPI_LOG, pProfile, &Quotas);
}
if (pProfile)
{
LsaFreeReturnBuffer(pProfile);
}
if (pLogonInfo)
{
delete [] pLogonInfo;
}
return Status;
}
VOID __cdecl
main(
IN INT argc,
IN PSTR argv[]
)
{
TNtStatus Status = STATUS_SUCCESS;
UNICODE_STRING UserName = {0};
UNICODE_STRING UserDomain = {0};
UNICODE_STRING Password = {0};
UNICODE_STRING Application = {0};
UNICODE_STRING ServerName = {0};
UNICODE_STRING ServerDomain = {0};
UNICODE_STRING Workstation = {0};
ULONG ParameterControl = 0;
LUID LogonId = {0};
LUID ChallengeToClient = {0};
C_ASSERT(MSV1_0_CHALLENGE_LENGTH == sizeof(LUID));
HANDLE hToken = NULL;
HANDLE hLogonHandle = NULL;
ULONG PackageId = 0;
RtlGenRandom(&ChallengeToClient, sizeof(ChallengeToClient));
for (INT i = 1; NT_SUCCESS(Status) && (i < argc); i++)
{
if ((*argv[i] == '-') || (*argv[i] == '/'))
{
switch (argv[i][1])
{
case 'c':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &UserName);
break;
case 'C':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &UserDomain);
break;
case 'a':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &Application);
break;
case 'k':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &Password);
break;
case 'p':
ParameterControl = strtol(argv[i] + 2, NULL, 0);
break;
case 'h':
LogonId.HighPart = strtol(argv[i] + 2, NULL, 0);
break;
case 'l':
LogonId.LowPart = strtol(argv[i] + 2, NULL, 0);
break;
case 'H':
ChallengeToClient.HighPart = strtol(argv[i] + 2, NULL, 0);
break;
case 'L':
ChallengeToClient.LowPart = strtol(argv[i] + 2, NULL, 0);
break;
case 's':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &ServerName);
break;
case 'S':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &ServerDomain);
break;
case 'w':
Status DBGCHK = CreateUnicodeStringFromAsciiz(argv[i] + 2, &Workstation);
break;
case '?':
default:
Usage(argv[0]);
break;
}
}
else
{
Usage(argv[0]);
}
}
DebugLogOpen(NULL, SSPI_LOG | SSPI_WARN | SSPI_ERROR);
if (NT_SUCCESS(Status))
{
Status DBGCHK = GetLsaHandleAndPackageId(
NTLMSP_NAME_A,
&hLogonHandle,
&PackageId
);
}
if (NT_SUCCESS(Status))
{
Status DBGCHK = MsvLsaLogon(
hLogonHandle,
PackageId,
&LogonId,
ParameterControl,
(UCHAR*) &ChallengeToClient,
&UserName,
&UserDomain,
&Password,
&ServerName,
&ServerDomain,
&Workstation,
&hToken
);
}
if (NT_SUCCESS(Status))
{
Status DBGCHK = CheckUserToken(hToken);
}
if (NT_SUCCESS(Status) && Application.Length && Application.Buffer)
{
Status DBGCHK = StartInteractiveClientProcessAsUser(hToken, Application.Buffer);
}
if (NT_SUCCESS(Status))
{
DebugPrintf(SSPI_LOG, "Operation succeeded\n");
}
else
{
DebugPrintf(SSPI_ERROR, "Operation failed\n");
}
if (hLogonHandle)
{
LsaDeregisterLogonProcess(hLogonHandle);
}
if (hToken)
{
CloseHandle(hToken);
}
RtlFreeUnicodeString(&UserName);
RtlFreeUnicodeString(&UserDomain);
RtlFreeUnicodeString(&Password);
RtlFreeUnicodeString(&ServerName);
RtlFreeUnicodeString(&ServerDomain);
RtlFreeUnicodeString(&Application);
RtlFreeUnicodeString(&Workstation);
}