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.
 
 
 
 
 
 

1046 lines
25 KiB

/*--
Copyright (c) 1987-1993 Microsoft Corporation
Module Name:
ssptest.c
Abstract:
Test program for the NtLmSsp service.
Author:
28-Jun-1993 (cliffv)
Environment:
User mode only.
Contains NT-specific code.
Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
--*/
#ifndef UNICODE
#define UNICODE
#endif // UNICODE
#include <ntos.h>
#include <ntlsa.h>
#include <ntsam.h>
#ifndef SECURITY_WIN32
#define SECURITY_WIN32
#endif // SECURITY_WIN32
#define SECURITY_KERNEL
#define SECURITY_PACKAGE
#define SECURITY_KERBEROS
#include <security.h>
#include <zwapi.h>
BOOLEAN QuietMode = FALSE;
ULONG DoTests = FALSE;
VOID
DumpBuffer(
PVOID Buffer,
DWORD BufferSize
)
/*++
Routine Description:
Dumps the buffer content on to the debugger output.
Arguments:
Buffer: buffer pointer.
BufferSize: size of the buffer.
Return Value:
none
--*/
{
#define NUM_CHARS 16
DWORD i, limit;
CHAR TextBuffer[NUM_CHARS + 1];
PUCHAR BufferPtr = Buffer;
DbgPrint("------------------------------------\n");
//
// Hex dump of the bytes
//
limit = ((BufferSize - 1) / NUM_CHARS + 1) * NUM_CHARS;
for (i = 0; i < limit; i++) {
if (i < BufferSize) {
DbgPrint("%02x ", BufferPtr[i]);
if (BufferPtr[i] < 31 ) {
TextBuffer[i % NUM_CHARS] = '.';
} else if (BufferPtr[i] == '\0') {
TextBuffer[i % NUM_CHARS] = ' ';
} else {
TextBuffer[i % NUM_CHARS] = (CHAR) BufferPtr[i];
}
} else {
DbgPrint(" ");
TextBuffer[i % NUM_CHARS] = ' ';
}
if ((i + 1) % NUM_CHARS == 0) {
TextBuffer[NUM_CHARS] = 0;
DbgPrint(" %s\n", TextBuffer);
}
}
DbgPrint("------------------------------------\n");
}
VOID
PrintTime(
LPSTR Comment,
TimeStamp ConvertTime
)
/*++
Routine Description:
Print the specified time
Arguments:
Comment - Comment to print in front of the time
Time - Local time to print
Return Value:
None
--*/
{
LARGE_INTEGER LocalTime;
LocalTime.HighPart = ConvertTime.HighPart;
LocalTime.LowPart = ConvertTime.LowPart;
DbgPrint( "%s", Comment );
//
// If the time is infinite,
// just say so.
//
if ( LocalTime.HighPart == 0x7FFFFFFF && LocalTime.LowPart == 0xFFFFFFFF ) {
DbgPrint( "Infinite\n" );
//
// Otherwise print it more clearly
//
} else {
TIME_FIELDS TimeFields;
RtlTimeToTimeFields( &LocalTime, &TimeFields );
DbgPrint( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
TimeFields.Month,
TimeFields.Day,
TimeFields.Year,
TimeFields.Hour,
TimeFields.Minute,
TimeFields.Second );
}
}
VOID
PrintStatus(
ULONG NetStatus
)
/*++
Routine Description:
Print a net status code.
Arguments:
NetStatus - The net status code to print.
Return Value:
None
--*/
{
DbgPrint( "Status = %lu 0x%lx", NetStatus, NetStatus );
switch (NetStatus) {
case SEC_E_NO_SPM:
DbgPrint( " SEC_E_NO_SPM" );
break;
case SEC_E_BAD_PKGID:
DbgPrint( " SEC_E_BAD_PKGID" ); break;
case SEC_E_NOT_OWNER:
DbgPrint( " SEC_E_NOT_OWNER" ); break;
case SEC_E_CANNOT_INSTALL:
DbgPrint( " SEC_E_CANNOT_INSTALL" ); break;
case SEC_E_INVALID_TOKEN:
DbgPrint( " SEC_E_INVALID_TOKEN" ); break;
case SEC_E_CANNOT_PACK:
DbgPrint( " SEC_E_CANNOT_PACK" ); break;
case SEC_E_QOP_NOT_SUPPORTED:
DbgPrint( " SEC_E_QOP_NOT_SUPPORTED" ); break;
case SEC_E_NO_IMPERSONATION:
DbgPrint( " SEC_E_NO_IMPERSONATION" ); break;
case SEC_E_LOGON_DENIED:
DbgPrint( " SEC_E_LOGON_DENIED" ); break;
case SEC_E_UNKNOWN_CREDENTIALS:
DbgPrint( " SEC_E_UNKNOWN_CREDENTIALS" ); break;
case SEC_E_NO_CREDENTIALS:
DbgPrint( " SEC_E_NO_CREDENTIALS" ); break;
case SEC_E_MESSAGE_ALTERED:
DbgPrint( " SEC_E_MESSAGE_ALTERED" ); break;
case SEC_E_OUT_OF_SEQUENCE:
DbgPrint( " SEC_E_OUT_OF_SEQUENCE" ); break;
case SEC_E_INSUFFICIENT_MEMORY:
DbgPrint( " SEC_E_INSUFFICIENT_MEMORY" ); break;
case SEC_E_INVALID_HANDLE:
DbgPrint( " SEC_E_INVALID_HANDLE" ); break;
case SEC_E_NOT_SUPPORTED:
DbgPrint( " SEC_E_NOT_SUPPORTED" ); break;
}
DbgPrint( "\n" );
}
//+-------------------------------------------------------------------------
//
// Function: SecAllocate
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
VOID * SEC_ENTRY
SspAlloc(ULONG Flags, ULONG cbMemory)
{
NTSTATUS scRet;
PVOID Buffer = NULL;
scRet = ZwAllocateVirtualMemory(
NtCurrentProcess(),
&Buffer,
0L,
&cbMemory,
MEM_COMMIT,
PAGE_READWRITE
);
if (!NT_SUCCESS(scRet))
{
return(NULL);
}
return(Buffer);
UNREFERENCED_PARAMETER(Flags);
}
//+-------------------------------------------------------------------------
//
// Function: SecFree
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
void SEC_ENTRY
SspFree(PVOID pvMemory)
{
ULONG Length = 0;
(VOID) ZwFreeVirtualMemory(
NtCurrentProcess(),
&pvMemory,
&Length,
MEM_RELEASE
);
}
VOID
TestSspRoutine(
)
/*++
Routine Description:
Test base SSP functionality
Arguments:
None
Return Value:
None
--*/
{
SECURITY_STATUS SecStatus;
SECURITY_STATUS AcceptStatus;
SECURITY_STATUS InitStatus;
CredHandle ServerCredHandle;
CredHandle ClientCredentialHandle;
CtxtHandle ClientContextHandle;
CtxtHandle ServerContextHandle;
TimeStamp Lifetime;
ULONG ContextAttributes;
ULONG PackageCount, Index;
PSecPkgInfo PackageInfo = NULL;
HANDLE Token = NULL;
static int Calls;
ULONG ClientFlags;
ULONG ServerFlags;
LPWSTR DomainName = NULL;
LPWSTR UserName = NULL;
LPWSTR TargetName = NULL;
UNICODE_STRING TargetString;
UNICODE_STRING PackageName;
SecBufferDesc NegotiateDesc;
SecBuffer NegotiateBuffer;
SecBufferDesc ChallengeDesc;
SecBuffer ChallengeBuffer;
SecBufferDesc AuthenticateDesc;
SecBuffer AuthenticateBuffer;
SecPkgContext_Sizes ContextSizes;
SecPkgContext_Names ContextNames;
SecPkgContext_Lifespan ContextLifespan;
PSecPkgCredentials_Names CredNames;
SecBufferDesc SignMessage;
SecBuffer SigBuffers[2];
UCHAR bDataBuffer[20];
UCHAR bSigBuffer[100];
//
// Allow tests to be disabled
//
if (!DoTests)
{
return;
}
NegotiateBuffer.pvBuffer = NULL;
ChallengeBuffer.pvBuffer = NULL;
AuthenticateBuffer.pvBuffer = NULL;
SigBuffers[1].pvBuffer = bSigBuffer;
SigBuffers[1].cbBuffer = sizeof(bSigBuffer);
SigBuffers[1].BufferType = SECBUFFER_TOKEN;
SigBuffers[0].pvBuffer = bDataBuffer;
SigBuffers[0].cbBuffer = sizeof(bDataBuffer);
SigBuffers[0].BufferType = SECBUFFER_DATA;
memset(bDataBuffer,0xeb,sizeof(bDataBuffer));
SignMessage.pBuffers = SigBuffers;
SignMessage.cBuffers = 2;
SignMessage.ulVersion = 0;
DomainName = L"makalu";
UserName = L"mikesw";
PackageName.Buffer = (LPWSTR) SspAlloc(0,100);
if (PackageName.Buffer == NULL)
{
return;
}
wcscpy(
PackageName.Buffer,
L"Kerberos"
);
RtlInitUnicodeString(
&PackageName,
PackageName.Buffer
);
//
// Get info about the security packages.
//
SecStatus = EnumerateSecurityPackages( &PackageCount, &PackageInfo );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "EnumerateSecurityPackages failed:" );
PrintStatus( SecStatus );
return;
}
DbgPrint( "PackageCount: %ld\n", PackageCount );
for (Index = 0; Index < PackageCount ; Index++ )
{
DbgPrint( "Package %d:\n",Index);
DbgPrint( "Name: %ws Comment: %ws\n", PackageInfo[Index].Name, PackageInfo[Index].Comment );
DbgPrint( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
PackageInfo[Index].fCapabilities,
PackageInfo[Index].wVersion,
PackageInfo[Index].wRPCID,
PackageInfo[Index].cbMaxToken );
}
#ifdef notdef
//
// Get info about the security packages.
//
SecStatus = QuerySecurityPackageInfo( &PackageName, &PackageInfo );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "QuerySecurityPackageInfo failed:" );
PrintStatus( SecStatus );
return;
}
if ( !QuietMode ) {
DbgPrint( "Name: %ws Comment: %ws\n", PackageInfo->Name, PackageInfo->Comment );
DbgPrint( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
PackageInfo->fCapabilities,
PackageInfo->wVersion,
PackageInfo->wRPCID,
PackageInfo->cbMaxToken );
}
FreeContextBuffer(PackageInfo);
#endif
//
// Acquire a credential handle for the server side
//
SecStatus = AcquireCredentialsHandle(
NULL, // New principal
&PackageName, // Package Name
SECPKG_CRED_INBOUND,
NULL,
NULL,
NULL,
NULL,
&ServerCredHandle,
&Lifetime );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "AcquireCredentialsHandle failed: ");
PrintStatus( SecStatus );
return;
}
if ( !QuietMode ) {
DbgPrint( "ServerCredHandle: 0x%lx 0x%lx ",
ServerCredHandle.dwLower, ServerCredHandle.dwUpper );
PrintTime( "Lifetime: ", Lifetime );
}
//
// Acquire a credential handle for the client side
//
SecStatus = AcquireCredentialsHandle(
NULL, // New principal
&PackageName, // Package Name
SECPKG_CRED_OUTBOUND,
NULL,
NULL,
NULL,
NULL,
&ClientCredentialHandle,
&Lifetime );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "AcquireCredentialsHandle failed: " );
PrintStatus( SecStatus );
return;
}
if ( !QuietMode ) {
DbgPrint( "ClientCredentialHandle: 0x%lx 0x%lx ",
ClientCredentialHandle.dwLower, ClientCredentialHandle.dwUpper );
PrintTime( "Lifetime: ", Lifetime );
}
//
// Query some cred attributes
//
CredNames = SspAlloc(0, sizeof(*CredNames));
if (CredNames == NULL)
{
DbgPrint("Failed to allocate CredNames\n");
return;
}
SecStatus = QueryCredentialsAttributes(
&ClientCredentialHandle,
SECPKG_CRED_ATTR_NAMES,
CredNames );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "QueryCredentialsAttributes (Client) (names): " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
DbgPrint("Client credential names: %ws\n",CredNames->sUserName);
FreeContextBuffer(CredNames->sUserName);
//
// Do the same for the client
//
SecStatus = QueryCredentialsAttributes(
&ServerCredHandle,
SECPKG_CRED_ATTR_NAMES,
CredNames );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "QueryCredentialsAttributes (Server) (names): " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
DbgPrint("Server credential names: %ws\n",CredNames->sUserName);
FreeContextBuffer(CredNames->sUserName);
SspFree(CredNames);
//
// Get the NegotiateMessage (ClientSide)
//
NegotiateDesc.ulVersion = 0;
NegotiateDesc.cBuffers = 1;
NegotiateDesc.pBuffers = &NegotiateBuffer;
NegotiateBuffer.cbBuffer = PackageInfo->cbMaxToken;
NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
NegotiateBuffer.pvBuffer = SspAlloc( 0, NegotiateBuffer.cbBuffer );
if ( NegotiateBuffer.pvBuffer == NULL ) {
DbgPrint( "Allocate NegotiateMessage failed\n" );
return;
}
ClientFlags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_MUTUAL_AUTH; // | ISC_REQ_USE_DCE_STYLE | ISC_REQ_DATAGRAM; // | ISC_REQ_DELEGATE;
TargetName = (LPWSTR) SspAlloc(0,100);
if (TargetName == NULL)
{
return;
}
wcscpy(
TargetName,
DomainName
);
wcscat(
TargetName,
L"\\"
);
wcscat(
TargetName,
UserName
);
RtlInitUnicodeString(
&TargetString,
TargetName
);
InitStatus = InitializeSecurityContext(
&ClientCredentialHandle,
NULL, // No Client context yet
&TargetString, // Faked target name
ClientFlags,
0, // Reserved 1
SECURITY_NATIVE_DREP,
NULL, // No initial input token
0, // Reserved 2
&ClientContextHandle,
&NegotiateDesc,
&ContextAttributes,
&Lifetime );
if ( InitStatus != STATUS_SUCCESS ) {
if ( !QuietMode || !NT_SUCCESS(InitStatus) ) {
DbgPrint( "InitializeSecurityContext (negotiate): " );
PrintStatus( InitStatus );
}
if ( !NT_SUCCESS(InitStatus) ) {
return;
}
}
if ( !QuietMode ) {
DbgPrint( "\n\nNegotiate Message:\n" );
DbgPrint( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
ContextAttributes );
PrintTime( "Lifetime: ", Lifetime );
// DumpBuffer( NegotiateBuffer.pvBuffer, NegotiateBuffer.cbBuffer );
}
//
// Get the ChallengeMessage (ServerSide)
//
NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
ChallengeDesc.ulVersion = 0;
ChallengeDesc.cBuffers = 1;
ChallengeDesc.pBuffers = &ChallengeBuffer;
ChallengeBuffer.cbBuffer = PackageInfo->cbMaxToken;
ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
ChallengeBuffer.pvBuffer = SspAlloc( 0, ChallengeBuffer.cbBuffer );
if ( ChallengeBuffer.pvBuffer == NULL ) {
DbgPrint( "Allocate ChallengeMessage failed\n");
return;
}
ServerFlags = 0;
AcceptStatus = AcceptSecurityContext(
&ServerCredHandle,
NULL, // No Server context yet
&NegotiateDesc,
ServerFlags,
SECURITY_NATIVE_DREP,
&ServerContextHandle,
&ChallengeDesc,
&ContextAttributes,
&Lifetime );
if ( AcceptStatus != STATUS_SUCCESS ) {
if ( !QuietMode || !NT_SUCCESS(AcceptStatus) ) {
DbgPrint( "AcceptSecurityContext (Challenge): " );
PrintStatus( AcceptStatus );
}
if ( !NT_SUCCESS(AcceptStatus) ) {
return;
}
}
if ( !QuietMode ) {
DbgPrint( "\n\nChallenge Message:\n" );
DbgPrint( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
ContextAttributes );
PrintTime( "Lifetime: ", Lifetime );
// DumpBuffer( ChallengeBuffer.pvBuffer, ChallengeBuffer.cbBuffer );
}
if (InitStatus != STATUS_SUCCESS)
{
//
// Get the AuthenticateMessage (ClientSide)
//
ChallengeBuffer.BufferType |= SECBUFFER_READONLY;
AuthenticateDesc.ulVersion = 0;
AuthenticateDesc.cBuffers = 1;
AuthenticateDesc.pBuffers = &AuthenticateBuffer;
AuthenticateBuffer.cbBuffer = PackageInfo->cbMaxToken;
AuthenticateBuffer.BufferType = SECBUFFER_TOKEN;
AuthenticateBuffer.pvBuffer = SspAlloc( 0, AuthenticateBuffer.cbBuffer );
if ( AuthenticateBuffer.pvBuffer == NULL ) {
DbgPrint( "Allocate AuthenticateMessage failed: \n" );
return;
}
SecStatus = InitializeSecurityContext(
NULL,
&ClientContextHandle,
NULL,
0,
0, // Reserved 1
SECURITY_NATIVE_DREP,
&ChallengeDesc,
0, // Reserved 2
&ClientContextHandle,
&AuthenticateDesc,
&ContextAttributes,
&Lifetime );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "InitializeSecurityContext (Authenticate): " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
if ( !QuietMode ) {
DbgPrint( "\n\nAuthenticate Message:\n" );
DbgPrint( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
ContextAttributes );
PrintTime( "Lifetime: ", Lifetime );
// DumpBuffer( AuthenticateBuffer.pvBuffer, AuthenticateBuffer.cbBuffer );
}
if (AcceptStatus != STATUS_SUCCESS)
{
//
// Finally authenticate the user (ServerSide)
//
AuthenticateBuffer.BufferType |= SECBUFFER_READONLY;
SecStatus = AcceptSecurityContext(
NULL,
&ServerContextHandle,
&AuthenticateDesc,
0,
SECURITY_NATIVE_DREP,
&ServerContextHandle,
NULL,
&ContextAttributes,
&Lifetime );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "AcceptSecurityContext (Challenge): " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
if ( !QuietMode ) {
DbgPrint( "\n\nFinal Authentication:\n" );
DbgPrint( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
ContextAttributes );
PrintTime( "Lifetime: ", Lifetime );
DbgPrint(" \n" );
}
}
}
SecStatus = QueryContextAttributes(
&ServerContextHandle,
SECPKG_ATTR_NAMES,
&ContextNames );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "QueryContextAttributes (Server) (names): " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
DbgPrint("Server Context names: %ws\n",ContextNames.sUserName);
FreeContextBuffer(ContextNames.sUserName);
//
// Impersonate the client (ServerSide)
//
SecStatus = ImpersonateSecurityContext( &ServerContextHandle );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "ImpersonateSecurityContext: " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
SecStatus = RevertSecurityContext( &ServerContextHandle );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "RevertSecurityContext: " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
#ifdef notdef
//
// Impersonate the client manually
//
SecStatus = QuerySecurityContextToken( &ServerContextHandle,&Token );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "ImpersonateSecurityContext: " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
NtClose(Token);
#endif
#ifdef notdef
//
// Sign a message
//
SecStatus = MakeSignature(
&ClientContextHandle,
0,
&SignMessage,
0 );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "MakeSignature: " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
if ( !QuietMode ) {
DbgPrint("\n Signature: \n");
// DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
}
//
// Verify the signature
//
SecStatus = VerifySignature(
&ServerContextHandle,
&SignMessage,
0,
0 );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "VerifySignature: " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
//
// Sign a message, this time to check if it can detect a change in the
// message
//
SecStatus = MakeSignature(
&ClientContextHandle,
0,
&SignMessage,
0 );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "MakeSignature: " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
if ( !QuietMode ) {
DbgPrint("\n Signature: \n");
// DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
}
//
// Mess up the message to see if VerifySignature works
//
bDataBuffer[10] = 0xec;
//
// Verify the signature
//
SecStatus = VerifySignature(
&ServerContextHandle,
&SignMessage,
0,
0 );
if ( SecStatus != SEC_E_MESSAGE_ALTERED ) {
DbgPrint( "VerifySignature: " );
PrintStatus( SecStatus );
if ( !NT_SUCCESS(SecStatus) ) {
return;
}
}
#endif
//
// Delete both contexts.
//
SecStatus = DeleteSecurityContext( &ClientContextHandle );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "DeleteSecurityContext failed: " );
PrintStatus( SecStatus );
return;
}
SecStatus = DeleteSecurityContext( &ServerContextHandle );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "DeleteSecurityContext failed: " );
PrintStatus( SecStatus );
return;
}
//
// Free both credential handles
//
SecStatus = FreeCredentialsHandle( &ServerCredHandle );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "FreeCredentialsHandle failed: " );
PrintStatus( SecStatus );
return;
}
SecStatus = FreeCredentialsHandle( &ClientCredentialHandle );
if ( SecStatus != STATUS_SUCCESS ) {
DbgPrint( "FreeCredentialsHandle failed: " );
PrintStatus( SecStatus );
return;
}
//
// Final Cleanup
//
if (PackageInfo != NULL)
{
FreeContextBuffer(PackageInfo);
}
if (PackageName.Buffer != NULL)
{
SspFree(PackageName.Buffer);
}
if ( NegotiateBuffer.pvBuffer != NULL ) {
(VOID) SspFree( NegotiateBuffer.pvBuffer );
}
if ( ChallengeBuffer.pvBuffer != NULL ) {
(VOID) SspFree( ChallengeBuffer.pvBuffer );
}
if ( AuthenticateBuffer.pvBuffer != NULL ) {
(VOID) SspFree( AuthenticateBuffer.pvBuffer );
}
if (TargetName != NULL)
{
SspFree(TargetName);
}
}