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.
655 lines
19 KiB
655 lines
19 KiB
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sspicli.cxx
|
|
|
|
Abstract:
|
|
|
|
sspicli
|
|
|
|
Author:
|
|
|
|
Larry Zhu (LZhu) January 1, 2002 Created
|
|
|
|
Environment:
|
|
|
|
User Mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include "sspicli.hxx"
|
|
|
|
TSspiClientParam::TSspiClientParam(
|
|
VOID
|
|
) : pszTargetName(NULL),
|
|
pszPrincipal(NULL),
|
|
pCredLogonID(NULL),
|
|
pszPackageName(NTLMSP_NAME_A),
|
|
pAuthData(NULL),
|
|
ClientFlags(ISC_REQ_MUTUAL_AUTH | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY),
|
|
TargetDataRep(SECURITY_NATIVE_DREP),
|
|
ClientActionFlags(0),
|
|
ProcessIdTokenUsedByClient(-1),
|
|
pszS4uClientUpn(NULL),
|
|
pszS4uClientRealm(NULL),
|
|
S4u2SelfFlags(0)
|
|
{
|
|
}
|
|
|
|
HRESULT
|
|
GetClientSecurityContextHandle(
|
|
IN TSspiClientParam* pCliParam,
|
|
IN SOCKET ServerSocket,
|
|
IN SOCKET ClientSocket,
|
|
IN PCredHandle phClientCred,
|
|
IN ULONG cbInBuf,
|
|
IN CHAR* pInBuf,
|
|
IN ULONG cbOutBuf,
|
|
IN CHAR* pOutBuf,
|
|
OUT PCtxtHandle phClientCtxt
|
|
)
|
|
{
|
|
THResult hRetval = S_OK;
|
|
|
|
SECURITY_STATUS ProtocolStatus;
|
|
THResult hProtocolStatus;
|
|
|
|
ULONG ContextAttributes = 0;
|
|
TimeStamp Lifetime = {0};
|
|
CtxtHandle hClientCtxt;
|
|
ULONG cbRead = 0;
|
|
|
|
SecBufferDesc OutBuffDesc = {0};
|
|
SecBuffer OutSecBuff = {0};
|
|
SecBufferDesc InBuffDesc = {0};
|
|
SecBuffer InSecBuff = {0};
|
|
|
|
BOOL bIsContinueNeeded = FALSE;
|
|
|
|
SecInvalidateHandle(phClientCtxt);
|
|
SecInvalidateHandle(&hClientCtxt);
|
|
|
|
//
|
|
// prepare output buffer
|
|
//
|
|
|
|
OutBuffDesc.ulVersion = 0;
|
|
OutBuffDesc.cBuffers = 1;
|
|
OutBuffDesc.pBuffers = &OutSecBuff;
|
|
|
|
OutSecBuff.cbBuffer = cbOutBuf;
|
|
OutSecBuff.BufferType = SECBUFFER_TOKEN;
|
|
OutSecBuff.pvBuffer = pOutBuf;
|
|
|
|
//
|
|
// prepare input buffer
|
|
//
|
|
|
|
InBuffDesc.ulVersion = 0;
|
|
InBuffDesc.cBuffers = 1;
|
|
InBuffDesc.pBuffers = &InSecBuff;
|
|
|
|
InSecBuff.cbBuffer = cbRead;
|
|
InSecBuff.BufferType = SECBUFFER_TOKEN;
|
|
InSecBuff.pvBuffer = pInBuf;
|
|
|
|
DebugPrintf(SSPI_LOG, "GetClientSecurityContextHandle calling InitializeSecurityContextA "
|
|
"pszTargetName %s, ClientFlags %#x, TargetDataRep %#x, CredHandle %#x:%#x\n",
|
|
pCliParam->pszTargetName, pCliParam->ClientFlags, pCliParam->TargetDataRep,
|
|
phClientCred->dwUpper, phClientCred->dwLower);
|
|
|
|
hRetval DBGCHK = InitializeSecurityContextA(
|
|
phClientCred,
|
|
NULL, // No Client context yet
|
|
pCliParam->pszTargetName,
|
|
pCliParam->ClientFlags,
|
|
0, // Reserved 1
|
|
pCliParam->TargetDataRep,
|
|
NULL, // No initial input token
|
|
0, // Reserved 2
|
|
&hClientCtxt,
|
|
&OutBuffDesc,
|
|
&ContextAttributes,
|
|
&Lifetime
|
|
);
|
|
|
|
bIsContinueNeeded = (S_OK == IsContinueNeeded(hRetval));
|
|
|
|
DebugPrintf(SSPI_LOG, "GetClientSecurityContextHandle ISC bIsContinueNeeded %#x, hRetval %#x\n", bIsContinueNeeded, (HRESULT) hRetval);
|
|
|
|
if (S_OK == IsCompleteNeeded(hRetval))
|
|
{
|
|
THResult hr;
|
|
|
|
hr DBGCHK = CompleteAuthToken(&hClientCtxt, &OutBuffDesc);
|
|
|
|
if (FAILED(hr)) // retain continue needed info
|
|
{
|
|
hRetval DBGNOCHK = hr;
|
|
}
|
|
}
|
|
|
|
ProtocolStatus = (HRESULT) hRetval;
|
|
hProtocolStatus DBGCHK = WriteMessage(ServerSocket,
|
|
sizeof(ProtocolStatus),
|
|
&ProtocolStatus);
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = hProtocolStatus;
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = WriteMessage(ServerSocket,
|
|
OutSecBuff.cbBuffer,
|
|
OutSecBuff.pvBuffer);
|
|
}
|
|
|
|
while (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = ReadMessage(ClientSocket,
|
|
sizeof(ProtocolStatus),
|
|
&ProtocolStatus,
|
|
&cbRead);
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = ProtocolStatus;
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = ReadMessage(ClientSocket,
|
|
cbInBuf,
|
|
pInBuf,
|
|
&cbRead);
|
|
}
|
|
else
|
|
{
|
|
break; // break out
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval) && !bIsContinueNeeded)
|
|
{
|
|
hRetval DBGCHK = (S_OK != IsContinueNeeded(ProtocolStatus)) ? S_OK : E_ACCESSDENIED;
|
|
break;
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
InSecBuff.cbBuffer = cbRead;
|
|
OutSecBuff.cbBuffer = cbOutBuf;
|
|
|
|
DebugPrintf(SSPI_LOG, "GetClientSecurityContextHandle calling InitializeSecurityContextA "
|
|
"pszTargetName %s, ClientFlags %#x, TargetDataRep %#x, hClientCtxt %#x:%#x\n",
|
|
pCliParam->pszTargetName, pCliParam->ClientFlags, pCliParam->TargetDataRep,
|
|
hClientCtxt.dwUpper, hClientCtxt.dwLower);
|
|
|
|
hRetval DBGCHK = InitializeSecurityContextA(
|
|
NULL, // no cred handle
|
|
&hClientCtxt,
|
|
pCliParam->pszTargetName,
|
|
pCliParam->ClientFlags,
|
|
0,
|
|
pCliParam->TargetDataRep,
|
|
&InBuffDesc,
|
|
0,
|
|
&hClientCtxt,
|
|
&OutBuffDesc,
|
|
&ContextAttributes,
|
|
&Lifetime
|
|
);
|
|
}
|
|
|
|
bIsContinueNeeded = (S_OK == IsContinueNeeded(hRetval));
|
|
|
|
DebugPrintf(SSPI_LOG, "GetClientSecurityContextHandle ISC bIsContinueNeeded %#x, hRetval %#x\n", bIsContinueNeeded, (HRESULT) hRetval);
|
|
|
|
if (S_OK == IsCompleteNeeded(hRetval))
|
|
{
|
|
THResult hr;
|
|
|
|
hr DBGCHK = CompleteAuthToken(&hClientCtxt, &OutBuffDesc);
|
|
|
|
if (FAILED(hr)) // retain continue needed info
|
|
{
|
|
hRetval DBGNOCHK = hr;
|
|
}
|
|
}
|
|
|
|
//
|
|
// is server listening?
|
|
//
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
if (S_OK != IsContinueNeeded(ProtocolStatus)) // no
|
|
{
|
|
hRetval DBGCHK = (SEC_E_OK == (HRESULT) hRetval) ? S_OK : E_ACCESSDENIED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ProtocolStatus = (HRESULT) hRetval;
|
|
hProtocolStatus DBGCHK = WriteMessage(ServerSocket,
|
|
sizeof(ProtocolStatus),
|
|
&ProtocolStatus);
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = hProtocolStatus;
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = WriteMessage(ServerSocket,
|
|
OutSecBuff.cbBuffer,
|
|
OutSecBuff.pvBuffer);
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
TimeStamp CurrentTime = {0};
|
|
|
|
DebugPrintf(SSPI_LOG, "***********Client authentication succeeded:**********\n");
|
|
|
|
DebugPrintf(SSPI_LOG, "ClientContextHandle: %#x:%#x, ContextAttributes: %#x\n",
|
|
hClientCtxt.dwUpper, hClientCtxt.dwLower, ContextAttributes);
|
|
DebugPrintLocalTime(SSPI_LOG, "Lifetime", &Lifetime);
|
|
|
|
GetSystemTimeAsFileTime((PFILETIME) &CurrentTime);
|
|
DebugPrintSysTimeAsLocalTime(SSPI_LOG, "Current Time", &CurrentTime);
|
|
|
|
*phClientCtxt = hClientCtxt;
|
|
SecInvalidateHandle(&hClientCtxt)
|
|
}
|
|
|
|
THResult hr;
|
|
|
|
if (SecIsValidHandle(&hClientCtxt))
|
|
{
|
|
hr DBGCHK = DeleteSecurityContext(&hClientCtxt);
|
|
}
|
|
|
|
return hRetval;
|
|
}
|
|
|
|
HRESULT
|
|
GetClientImpToken(
|
|
IN ULONG ProcessId,
|
|
IN PCSTR pszPackageName,
|
|
IN OPTIONAL PCSTR pszS4uClientUpn,
|
|
IN OPTIONAL PCSTR pszS4uClientRealm,
|
|
IN ULONG S4u2SelfFlags,
|
|
OUT HANDLE* phToken
|
|
)
|
|
{
|
|
THResult hRetval = S_OK;
|
|
|
|
UNICODE_STRING ClientUpn = {0};
|
|
UNICODE_STRING ClientRealm = {0};
|
|
UNICODE_STRING Password = {0}; // ignored
|
|
ULONG PackageId = 0;
|
|
HANDLE hLsa = NULL;
|
|
HANDLE hImpToken = NULL;
|
|
|
|
TPrivilege* pPriv = NULL;
|
|
|
|
*phToken = NULL;
|
|
|
|
if (ProcessId != -1)
|
|
{
|
|
hRetval DBGCHK = GetProcessTokenByProcessId(ProcessId, &hImpToken);
|
|
}
|
|
else if (pszS4uClientRealm || pszS4uClientUpn)
|
|
{
|
|
hRetval DBGCHK = !_stricmp(pszPackageName, MICROSOFT_KERBEROS_NAME_A) ? S_OK : E_INVALIDARG;
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = CreateUnicodeStringFromAsciiz(pszS4uClientRealm, &ClientRealm);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = CreateUnicodeStringFromAsciiz(pszS4uClientUpn, &ClientUpn);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
pPriv = new TPrivilege(SE_TCB_PRIVILEGE, TRUE);
|
|
hRetval DBGCHK = pPriv ? pPriv->Validate() : E_OUTOFMEMORY;
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = GetLsaHandleAndPackageId(
|
|
pszPackageName,
|
|
&hLsa,
|
|
&PackageId
|
|
);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = KrbLsaLogonUser(
|
|
hLsa,
|
|
PackageId,
|
|
Network, // this would cause S4u2self to be used
|
|
&ClientUpn,
|
|
&ClientRealm,
|
|
&Password, // ignored for s4u2self
|
|
S4u2SelfFlags, // Flags for s4u2self
|
|
&hImpToken
|
|
);
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
*phToken = hImpToken;
|
|
hImpToken = NULL;
|
|
}
|
|
|
|
THResult hr;
|
|
|
|
if (hImpToken)
|
|
{
|
|
hr DBGCHK = CloseHandle(hImpToken) ? S_OK : GetLastErrorAsHResult();
|
|
}
|
|
|
|
if (pPriv)
|
|
{
|
|
delete pPriv;
|
|
}
|
|
|
|
if (hLsa)
|
|
{
|
|
hr DBGCHK = LsaDeregisterLogonProcess(hLsa);
|
|
}
|
|
|
|
RtlFreeUnicodeString(&ClientRealm);
|
|
RtlFreeUnicodeString(&ClientUpn);
|
|
|
|
return hRetval;
|
|
}
|
|
|
|
HRESULT
|
|
SspiClientStart(
|
|
IN TSspiClientThreadParam* pParameter, // thread data
|
|
IN SOCKET ServerSocket,
|
|
IN SOCKET ClientSocket
|
|
)
|
|
{
|
|
THResult hRetval = S_OK;
|
|
|
|
TSspiClientParam* pCliParam = NULL;
|
|
CredHandle hClientCred;
|
|
CtxtHandle hClientCtxt;
|
|
CtxtHandle hServerCtxt;
|
|
|
|
ULONG cbInBuf = 0;
|
|
CHAR* pInBuf = NULL;
|
|
ULONG cbOutBuf = 0;
|
|
CHAR* pOutBuf = NULL;
|
|
|
|
TImpersonation* pImpersonation = NULL;
|
|
HANDLE hImpToken = NULL;
|
|
|
|
ULONG cPackages = 0;
|
|
PSecPkgInfoA pPackageInfo = NULL;
|
|
HANDLE hImportToken = NULL;
|
|
HANDLE hExportToken = NULL;
|
|
SecBuffer MarshalledContext = {0};
|
|
SecPkgContext_PackageInfoA ContextPackageInfo = {0};
|
|
|
|
DebugPrintf(SSPI_LOG, "SspiClientStart entering\n");
|
|
|
|
SecInvalidateHandle(&hClientCred);
|
|
SecInvalidateHandle(&hClientCtxt);
|
|
SecInvalidateHandle(&hServerCtxt);
|
|
|
|
pCliParam = dynamic_cast<TSspiClientParam*>(pParameter);
|
|
hRetval DBGCHK = pCliParam ? S_OK : E_INVALIDARG;
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = GetClientImpToken(
|
|
pCliParam->ProcessIdTokenUsedByClient,
|
|
pCliParam->pszPackageName,
|
|
pCliParam->pszS4uClientUpn,
|
|
pCliParam->pszS4uClientRealm,
|
|
pCliParam->S4u2SelfFlags,
|
|
&hImpToken
|
|
);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval) && hImpToken)
|
|
{
|
|
pImpersonation = new TImpersonation(hImpToken);
|
|
|
|
hRetval DBGCHK = pImpersonation ? pImpersonation->Validate() : E_OUTOFMEMORY;
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
DebugPrintf(SSPI_LOG, "************** check client token data %p ******\n", hImpToken);
|
|
hRetval DBGCHK = CheckUserData();
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
hRetval DBGCHK = AcquireCredHandle(
|
|
pCliParam->pszPrincipal,
|
|
pCliParam->pCredLogonID,
|
|
pCliParam->pszPackageName,
|
|
pCliParam->pAuthData,
|
|
SECPKG_CRED_OUTBOUND,
|
|
&hClientCred
|
|
);
|
|
}
|
|
|
|
if (pImpersonation)
|
|
{
|
|
delete pImpersonation;
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
DebugPrintf(SSPI_LOG, "SspiClientStart QuerySecurityPackageInfoA \"%s\"\n", pCliParam->pszPackageName);
|
|
|
|
hRetval DBGCHK = QuerySecurityPackageInfoA(pCliParam->pszPackageName, &pPackageInfo);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
pInBuf = new CHAR[pPackageInfo->cbMaxToken + sizeof(ULONG_PTR)]; // allow length prefix
|
|
hRetval DBGCHK = pInBuf ? S_OK : E_OUTOFMEMORY;
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
cbInBuf = pPackageInfo->cbMaxToken + sizeof(ULONG_PTR);
|
|
RtlZeroMemory(pInBuf, cbInBuf);
|
|
|
|
pOutBuf = new CHAR[pPackageInfo->cbMaxToken + sizeof(ULONG_PTR)]; // allow length prefix
|
|
hRetval DBGCHK = pOutBuf ? S_OK : E_OUTOFMEMORY;
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
cbOutBuf = pPackageInfo->cbMaxToken + sizeof(ULONG_PTR);
|
|
RtlZeroMemory(pOutBuf, cbOutBuf);
|
|
|
|
hRetval DBGCHK = GetClientSecurityContextHandle(
|
|
pCliParam,
|
|
ServerSocket,
|
|
ClientSocket,
|
|
&hClientCred,
|
|
cbInBuf,
|
|
pInBuf,
|
|
cbOutBuf,
|
|
pOutBuf,
|
|
&hClientCtxt
|
|
);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
DebugPrintf(SSPI_LOG, "SspiClientStart Writing ClientActionFlags %#x\n", pCliParam->ClientActionFlags);
|
|
hRetval DBGCHK = WriteMessage(ServerSocket,
|
|
sizeof(pCliParam->ClientActionFlags),
|
|
&pCliParam->ClientActionFlags);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval) && ((pCliParam->ClientActionFlags & SSPI_ACTION_NO_QCA) == 0))
|
|
{
|
|
hRetval DBGCHK = CheckSecurityContextHandle(&hClientCtxt);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval) && ((pCliParam->ClientActionFlags & SSPI_ACTION_NO_MESSAGES) == 0))
|
|
{
|
|
hRetval DBGCHK = DoSspiClientWork(
|
|
&hClientCtxt,
|
|
ServerSocket,
|
|
ClientSocket
|
|
);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval) && ((pCliParam->ClientActionFlags & SSPI_ACTION_NO_IMPORT_EXPORT) == 0))
|
|
{
|
|
DebugPrintf(SSPI_LOG, "*********Client Export/Import security contexts***********");
|
|
|
|
hRetval DBGCHK = QueryContextAttributesA(
|
|
&hClientCtxt, // assuming client and server having the same package
|
|
SECPKG_ATTR_PACKAGE_INFO,
|
|
&ContextPackageInfo
|
|
);
|
|
|
|
MarshalledContext.cbBuffer = cbInBuf;
|
|
MarshalledContext.pvBuffer = pInBuf;
|
|
|
|
hRetval DBGCHK = ReadMessage(ClientSocket,
|
|
MarshalledContext.cbBuffer,
|
|
MarshalledContext.pvBuffer,
|
|
&MarshalledContext.cbBuffer);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval) && ((pCliParam->ClientActionFlags & SSPI_ACTION_NO_IMPORT_EXPORT) == 0))
|
|
{
|
|
DebugPrintf(SSPI_LOG, "SspiClientStart calling ImportSecurityContextA pszPackageName %s\n",
|
|
(ContextPackageInfo.PackageInfo ?
|
|
ContextPackageInfo.PackageInfo->Name : pCliParam->pszPackageName));
|
|
|
|
hRetval DBGCHK = ImportSecurityContextA(
|
|
(ContextPackageInfo.PackageInfo ?
|
|
ContextPackageInfo.PackageInfo->Name : pCliParam->pszPackageName),
|
|
&MarshalledContext,
|
|
NULL, // hImportToken
|
|
&hServerCtxt
|
|
);
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval) && ((pCliParam->ClientActionFlags & SSPI_ACTION_NO_IMPORT_EXPORT) == 0))
|
|
{
|
|
RtlZeroMemory(&MarshalledContext, sizeof(MarshalledContext));
|
|
|
|
DebugPrintf(SSPI_LOG, "SspiClientStart calling ExportSecurityContext\n");
|
|
|
|
hRetval DBGCHK = ExportSecurityContext(
|
|
&hClientCtxt,
|
|
SECPKG_CONTEXT_EXPORT_DELETE_OLD,
|
|
&MarshalledContext,
|
|
&hExportToken
|
|
);
|
|
|
|
if (SUCCEEDED(hRetval))
|
|
{
|
|
SecInvalidateHandle(&hClientCtxt);
|
|
|
|
hRetval DBGCHK = WriteMessage(ServerSocket,
|
|
MarshalledContext.cbBuffer,
|
|
MarshalledContext.pvBuffer);
|
|
}
|
|
|
|
if (MarshalledContext.pvBuffer)
|
|
{
|
|
FreeContextBuffer(MarshalledContext.pvBuffer);
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hRetval) && ((pCliParam->ClientActionFlags & (SSPI_ACTION_NO_IMPORT_EXPORT | SSPI_ACTION_NO_IMPORT_EXPORT_MSG)) == 0))
|
|
{
|
|
hRetval DBGCHK = DoSspiServerWork(
|
|
&hServerCtxt,
|
|
ServerSocket,
|
|
ClientSocket
|
|
);
|
|
}
|
|
|
|
THResult hr;
|
|
|
|
if (pPackageInfo)
|
|
{
|
|
hr DBGCHK = FreeContextBuffer(pPackageInfo);
|
|
}
|
|
|
|
if (SecIsValidHandle(&hClientCred))
|
|
{
|
|
hr DBGCHK = FreeCredentialsHandle(&hClientCred);
|
|
}
|
|
|
|
if (SecIsValidHandle(&hClientCtxt))
|
|
{
|
|
hr DBGCHK = DeleteSecurityContext(&hClientCtxt);
|
|
}
|
|
|
|
if (SecIsValidHandle(&hServerCtxt))
|
|
{
|
|
hr DBGCHK = DeleteSecurityContext(&hServerCtxt);
|
|
}
|
|
|
|
if (ContextPackageInfo.PackageInfo)
|
|
{
|
|
hr DBGCHK = FreeContextBuffer(ContextPackageInfo.PackageInfo);
|
|
}
|
|
|
|
if (pOutBuf)
|
|
{
|
|
delete [] pOutBuf;
|
|
}
|
|
|
|
if (pInBuf)
|
|
{
|
|
delete [] pInBuf;
|
|
}
|
|
|
|
if (hExportToken)
|
|
{
|
|
hr DBGCHK = CloseHandle(hExportToken) ? S_OK : GetLastErrorAsHResult();
|
|
}
|
|
|
|
if (hImportToken)
|
|
{
|
|
hr DBGCHK = CloseHandle(hImportToken) ? S_OK : GetLastErrorAsHResult();
|
|
}
|
|
|
|
if (hImpToken)
|
|
{
|
|
hr DBGCHK = CloseHandle(hImpToken) ? S_OK : GetLastErrorAsHResult();
|
|
}
|
|
|
|
DebugPrintf(SSPI_LOG, "SspiClientStart leaving %#x\n", (HRESULT) hRetval);
|
|
|
|
return hRetval;
|
|
}
|