Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

980 lines
26 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995.
//
// File:
// remact.cxx
//
// Contents:
//
// Implementation of binding handle cache to remote activation services.
//
// History:
//
//--------------------------------------------------------------------------
#include <headers.cxx>
#pragma hdrstop
#include "scm.hxx"
#include "port.hxx"
#include "cls.hxx"
#include "remact.hxx"
#include "or.hxx"
#include "remact.h"
extern "C" {
extern PROTSEQ_INFO gaProtseqInfo[];
}
CRITICAL_SECTION RemoteServerCS;
void
LogRemoteSideUnavailable(
ACTIVATION_PARAMS * pActParams,
WCHAR * pwszServerName )
{
// %1 is the remote machine name
HANDLE LogHandle;
LPTSTR Strings[1]; // array of message strings.
Strings[0] = pwszServerName;
// Get the log handle, then report then event.
LogHandle = RegisterEventSource( NULL,
SCM_EVENT_SOURCE );
if ( LogHandle )
{
ReportEvent( LogHandle,
EVENTLOG_ERROR_TYPE,
0, // event category
EVENT_RPCSS_REMOTE_SIDE_UNAVAILABLE,
pActParams->pToken->GetSid(), // SID
1, // 1 strings passed
0, // 0 bytes of binary
(LPCTSTR *)Strings, // array of strings
NULL ); // no raw data
// clean up the event log handle
DeregisterEventSource(LogHandle);
}
}
void
LogRemoteSideFailure(
ACTIVATION_PARAMS * pActParams,
WCHAR * pwszServerName,
WCHAR * pwszPathForServer,
HRESULT hr )
{
// %1 is the error number
// %2 is the remote machine name
// %3 is the clsid
// %4 is the PathForServer
HANDLE LogHandle;
LPTSTR Strings[4]; // array of message strings.
WCHAR wszClsid[GUIDSTR_MAX];
WCHAR wszErrnum[20];
// Save the error number
wsprintf(wszErrnum, L"%lu",hr );
Strings[0] = wszErrnum;
Strings[1] = pwszServerName;
// Get the clsid
wStringFromGUID2(*(pActParams->Clsid), wszClsid, sizeof(wszClsid));
Strings[2] = wszClsid;
Strings[3] = pwszPathForServer;
// Get the log handle, then report then event.
LogHandle = RegisterEventSource( NULL,
SCM_EVENT_SOURCE );
if ( LogHandle )
{
if ( pwszPathForServer )
{
ReportEvent( LogHandle,
EVENTLOG_ERROR_TYPE,
0, // event category
EVENT_RPCSS_REMOTE_SIDE_ERROR_WITH_FILE,
pActParams->pToken->GetSid(), // SID
4, // 4 strings passed
0, // 0 bytes of binary
(LPCTSTR *)Strings, // array of strings
NULL ); // no raw data
}
else
{
ReportEvent( LogHandle,
EVENTLOG_ERROR_TYPE,
0, // event category
EVENT_RPCSS_REMOTE_SIDE_ERROR,
pActParams->pToken->GetSid(), // SID
3, // 3 strings passed
0, // 0 bytes of binary
(LPCTSTR *)Strings, // array of strings
NULL ); // no raw data
}
// clean up the event log handle
DeregisterEventSource(LogHandle);
}
}
//
// Entry point for outgoing remote activation calls.
//
HRESULT
RemoteActivationCall(
ACTIVATION_PARAMS * pActParams,
WCHAR * pwszServerName,
WCHAR * pwszPathForServer )
{
CRemoteServer * pRemoteServer;
BOOL NoEndpoint;
HRESULT hr;
RPC_STATUS Status;
Win4Assert( pwszServerName );
EnterCriticalSection( &RemoteServerCS );
pRemoteServer = gpCRemSrvList->Add( pwszServerName, hr );
LeaveCriticalSection( &RemoteServerCS );
if ( FAILED(hr) )
return hr;
if ( (Status = RpcImpersonateClient(NULL)) != ERROR_SUCCESS )
return HRESULT_FROM_WIN32(Status);
// try a secure activation
hr = pRemoteServer->Activate( &Status,pActParams,pwszPathForServer,pwszServerName,TRUE );
// if we have don't have authinfo, try an unsecure activation
if( (Status != RPC_S_OK) && !(pActParams->pAuthInfo) )
{
hr = pRemoteServer->Activate( &Status,pActParams,pwszPathForServer,pwszServerName,FALSE );
}
RpcRevertToSelf();
return hr;
}
HRESULT
CRemoteServer::Activate(
RPC_STATUS* pStatus,
ACTIVATION_PARAMS* pActParams,
WCHAR* pwszPathForServer,
WCHAR* pwszServerName,
BOOL Secure )
{
COAUTHINFO* pAuthInfo = pActParams->pAuthInfo;
handle_t hRemoteSCM = NULL;
WCHAR* pStringBinding = NULL;
RPC_SECURITY_QOS Qos;
HRESULT hr;
BOOL NoEndpoint;
hRemoteSCM = NULL;
pStringBinding = NULL;
// try to use a cached handle
hRemoteSCM = LookupHandle( pActParams->pToken,pAuthInfo,Secure );
if ( hRemoteSCM )
{
*pStatus = CallRemoteSCM( hRemoteSCM,
GetProtseqId( hRemoteSCM ),
pActParams,
pwszPathForServer,
&hr );
ReleaseHandle( hRemoteSCM );
//
// Check if call completed OK. The overall activation may still have
// failed.
//
if ( *pStatus == RPC_S_OK )
{
return hr;
}
// if we get an unexpected failure, get rid of this handle
if (!(FNonFatalRpcError(*pStatus)) )
{
InvalidateHandle( hRemoteSCM );
}
else
{
//
// if its an expected failure, don't bother creating a new handle
//
return HRESULT_FROM_WIN32( *pStatus );
}
hRemoteSCM = 0;
}
//
// using cached handle failed, now we need to create a new binding
// handle and try it
//
Qos.Version = RPC_C_SECURITY_QOS_VERSION;
if ( pAuthInfo )
{
Qos.Capabilities = pAuthInfo->dwCapabilities;
Qos.ImpersonationType = pAuthInfo->dwImpersonationLevel;
Qos.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
}
else
{
Qos.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
Qos.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
Qos.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
}
//
// try creating a new binding handle for each protocol sequence
// that we support
//
for ( int ProtseqIndex = 0; ProtseqIndex < cMyProtseqs; ProtseqIndex++ )
{
*pStatus = RpcStringBindingCompose(
NULL,
gaProtseqInfo[aMyProtseqs[ProtseqIndex]].pwstrProtseq,
pwszServerName,
gaProtseqInfo[aMyProtseqs[ProtseqIndex]].pwstrEndpoint,
NULL,
&pStringBinding );
// This is most likely an out of memory condition, so we'll give up.
if ( *pStatus != RPC_S_OK )
return HRESULT_FROM_WIN32(*pStatus);
*pStatus = RpcBindingFromStringBinding( pStringBinding, &hRemoteSCM );
RpcStringFree( &pStringBinding );
pStringBinding = 0;
// This could be a protocol specific problem, so we'll continue.
if ( *pStatus != RPC_S_OK )
continue;
NoEndpoint = FALSE;
// choose the appropriate authorization settings
if ( Secure )
{
if ( pAuthInfo )
{
// use supplied authorization settings
*pStatus = RpcBindingSetAuthInfoEx(
hRemoteSCM,
pAuthInfo->pwszServerPrincName,
pAuthInfo->dwAuthnLevel,
pAuthInfo->dwAuthnSvc,
pAuthInfo->pAuthIdentityData,
pAuthInfo->dwAuthzSvc,
&Qos );
}
else
{
// use default authorization settings
*pStatus = RpcBindingSetAuthInfoEx(
hRemoteSCM,
NULL,
RPC_C_AUTHN_LEVEL_CONNECT,
RPC_C_AUTHN_WINNT,
NULL,
0,
&Qos );
}
}
else
{
// use unsecure authorization settings
*pStatus = RpcBindingSetAuthInfoEx(
hRemoteSCM,
NULL,
RPC_C_AUTHN_LEVEL_NONE,
RPC_C_AUTHN_NONE,
NULL,
0,
&Qos );
}
if ( *pStatus != RPC_S_OK )
continue;
//
// This loop only executes twice if we need to try the call without
// an endpoint specified.
//
for (;;)
{
// try the call
*pStatus = CallRemoteSCM( hRemoteSCM,
aMyProtseqs[ProtseqIndex],
pActParams,
pwszPathForServer,
&hr );
if ( *pStatus == RPC_S_OK || FNonFatalRpcError(*pStatus) )
{
//
// If the call completed on the remote SCM, or if we got an
// "expected" error code, then we cache the binding handle.
// Note that this does not necessarily mean the activation
// was successful.
//
InsertHandle( pActParams->pToken,
aMyProtseqs[ProtseqIndex],
hRemoteSCM,
pAuthInfo,
Secure );
if ( *pStatus == RPC_S_OK )
{
// log message if hr indicates failure
if ( FAILED(hr) )
LogRemoteSideFailure( pActParams, pwszServerName, pwszPathForServer, hr );
return hr;
}
break;
}
if ( *pStatus == RPC_S_UNKNOWN_IF )
{
if ( ! NoEndpoint )
{
(void) RpcBindingReset( hRemoteSCM );
NoEndpoint = TRUE;
continue;
}
}
// if we got here, we got an unexpected error
RpcBindingFree(&hRemoteSCM);
break;
}
}
// log message indicating failure to communicate.
LogRemoteSideUnavailable( pActParams, pwszServerName );
return HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE);
}
BOOL
CRemoteServer::FNonFatalRpcError( RPC_STATUS Status )
{
switch( Status )
{
case RPC_S_ACCESS_DENIED:
case RPC_S_UNKNOWN_AUTHN_SERVICE:
case RPC_S_UNKNOWN_AUTHZ_SERVICE:
return TRUE;
default:
return FALSE;
}
}
RPC_STATUS CallRemoteSCM(
handle_t hRemoteSCM,
USHORT ProtseqId,
ACTIVATION_PARAMS * pActParams,
WCHAR * pwszPathForServer,
HRESULT * phr )
{
RPC_STATUS Status;
COMVERSION ServerVersion;
pActParams->ORPCthis->flags = ORPCF_NULL;
Status = RemoteActivation(
hRemoteSCM,
pActParams->ORPCthis,
pActParams->ORPCthat,
pActParams->Clsid,
pwszPathForServer,
pActParams->pIFDStorage,
RPC_C_IMP_LEVEL_IDENTIFY,
pActParams->Mode,
pActParams->Interfaces,
pActParams->pIIDs,
1,
&ProtseqId,
pActParams->pOxidServer,
&pActParams->pOxidInfo->psa,
&pActParams->pOxidInfo->ipidRemUnknown,
&pActParams->pOxidInfo->dwAuthnHint,
&ServerVersion,
phr,
pActParams->ppIFD,
pActParams->pResults );
//
// Note that this will only give us a bad status is there is a
// communication failure.
//
if ( Status != RPC_S_OK )
return Status;
//
// If the activation fails we return success for the communication
// status, but the overall operation has failed and the error will
// be propogated back to the client.
//
if ( FAILED(*phr) )
return RPC_S_OK;
pActParams->ProtseqId = ProtseqId;
return RPC_S_OK;
}
CRemoteServer::CRemoteServer(
const WCHAR * pwszServer,
HRESULT &hr
) : CStringID(pwszServer, hr)
{
InitializeCriticalSection( &hLock );
memset( HandleList, 0, sizeof(HandleList) );
}
CRemoteServer::~CRemoteServer()
{
// these objects are never destroyed, this
// should never happen
Win4Assert("Why Am I Here?");
}
handle_t
CRemoteServer::LookupHandle( CToken * pToken, COAUTHINFO* pAuthInfo, BOOL fSecure )
{
handle_t hHandle;
int n;
hHandle = 0;
EnterCriticalSection( &hLock );
for ( n = 0; n < MAX_REMOTE_HANDLES; n++ )
{
if ( (HandleList[n].pToken == pToken) && HandleList[n].Valid)
{
// if we're looking for a secure handle, check the auth info
if ( fSecure && pAuthInfo && !(FEquivalentAuthInfo(HandleList[n].pAuthInfo,pAuthInfo)) )
{
continue;
}
if ( HandleList[n].fSecure == fSecure )
{
HandleList[n].Refs++;
hHandle = HandleList[n].hRemoteSCM;
break;
}
}
}
LeaveCriticalSection( &hLock );
return hHandle;
}
void
CRemoteServer::ReleaseHandle( handle_t hHandle )
{
int n;
EnterCriticalSection( &hLock );
for ( n = 0; n < MAX_REMOTE_HANDLES; n++ )
{
if ( HandleList[n].hRemoteSCM == hHandle )
{
HandleList[n].Refs--;
if ( (HandleList[n].Refs == 0) && ! HandleList[n].Valid )
{
RpcBindingFree( &HandleList[n].hRemoteSCM );
HandleList[n].hRemoteSCM = 0;
HandleList[n].pToken = 0;
}
}
}
LeaveCriticalSection( &hLock );
}
void
CRemoteServer::InsertHandle(
CToken * pToken,
USHORT ProtseqId,
handle_t hHandle,
COAUTHINFO* pAuthInfo,
BOOL fSecure )
{
int n;
int FreeSlot;
HRESULT hr;
FreeSlot = -1;
EnterCriticalSection( &hLock );
//
// First we'll search for a free slot.
//
for ( n = 0; n < MAX_REMOTE_HANDLES; n++ )
{
if ( (HandleList[n].Refs == 0) && ! HandleList[n].Valid )
{
FreeSlot = n;
break;
}
}
//
// OK if there are no free slots. We simply don't have room to cache
// the handle in this case.
//
if ( FreeSlot == -1 )
{
RpcBindingFree(&hHandle);
goto EXIT_INSERT_HANDLE;
}
//
// See if we already have another handle cached for this client.
//
for ( n = 0; n < MAX_REMOTE_HANDLES; n++ )
{
if ( (HandleList[n].pToken == pToken) && HandleList[n].Valid &&
(HandleList[n].fSecure == fSecure) && (FEquivalentAuthInfo(
HandleList[n].pAuthInfo,pAuthInfo)))
{
//
// Hmm, what to do. We've found another binding handle for use
// by the same client. We'll invalidate this one since it's probably
// older.
//
if ( HandleList[n].Refs == 0 )
{
RpcBindingFree( &HandleList[n].hRemoteSCM );
HandleList[n].hRemoteSCM = 0;
HandleList[n].pToken = 0;
}
HandleList[n].Valid = FALSE;
}
}
if( pAuthInfo )
{
hr = CopyAuthInfo(&(HandleList[FreeSlot].pAuthInfo),pAuthInfo);
if ( FAILED(hr) )
{
RpcBindingFree(&hHandle);
goto EXIT_INSERT_HANDLE;
}
}
else
{
HandleList[FreeSlot].pAuthInfo = NULL;
}
HandleList[FreeSlot].hRemoteSCM = hHandle;
HandleList[FreeSlot].ProtseqId = ProtseqId;
HandleList[FreeSlot].pToken = pToken;
HandleList[FreeSlot].Refs = 0;
HandleList[FreeSlot].fSecure = fSecure;
HandleList[FreeSlot].Valid = TRUE;
EXIT_INSERT_HANDLE:
LeaveCriticalSection( &hLock );
}
void
CRemoteServer::InvalidateHandle( handle_t hHandle )
{
int n;
EnterCriticalSection( &hLock );
for ( n = 0; n < MAX_REMOTE_HANDLES; n++ )
{
if ( HandleList[n].hRemoteSCM == hHandle )
{
if ( HandleList[n].Refs == 0 )
{
RpcBindingFree( &HandleList[n].hRemoteSCM );
HandleList[n].hRemoteSCM = 0;
HandleList[n].pToken = 0;
}
HandleList[n].Valid = FALSE;
break;
}
}
LeaveCriticalSection( &hLock );
}
USHORT
CRemoteServer::GetProtseqId( handle_t hHandle )
{
int n;
USHORT id;
id = (USHORT) 0xffff;
EnterCriticalSection( &hLock );
for ( n = 0; n < MAX_REMOTE_HANDLES; n++ )
{
if ( HandleList[n].hRemoteSCM == hHandle )
{
id = HandleList[n].ProtseqId;
break;
}
}
LeaveCriticalSection( &hLock );
return id;
}
CRemoteServer *
CRemSrvList::Add(const WCHAR *pwszPath, HRESULT &hr)
{
CStringID csid(pwszPath, hr);
if ( FAILED(hr) )
return NULL;
CRemoteServer *pRemoteServer = (CRemoteServer *) Search(&csid);
if ( pRemoteServer == NULL )
{
pRemoteServer = new CRemoteServer(pwszPath, hr);
if ( pRemoteServer == NULL )
{
hr = E_OUTOFMEMORY;
}
else if ( FAILED(hr) )
{
delete pRemoteServer;
}
else if ( Insert(pRemoteServer) == NULL )
{
hr = E_OUTOFMEMORY;
}
if ( FAILED(hr) )
return NULL;
}
return pRemoteServer;
}
HRESULT
CRemoteServer::CopyAuthIdentity(
COAUTHIDENTITY** ppAuthIdentDest,
COAUTHIDENTITY* pAuthIdentSrc)
{
HRESULT hr = E_OUTOFMEMORY;
*ppAuthIdentDest = NULL;
if ( !(*ppAuthIdentDest = (COAUTHIDENTITY*)PrivMemAlloc(sizeof(COAUTHIDENTITY))) )
{
goto COPY_AUTHIDENTITY_EXIT;
}
(*ppAuthIdentDest)->User = NULL;
(*ppAuthIdentDest)->Domain = NULL;
(*ppAuthIdentDest)->Password = NULL;
if ( pAuthIdentSrc->User )
{
if(!((*ppAuthIdentDest)->User = (USHORT *)
PrivMemAlloc((pAuthIdentSrc->UserLength+1) * sizeof(USHORT))))
{
goto COPY_AUTHIDENTITY_EXIT;
}
memcpy( (*ppAuthIdentDest)->User,
pAuthIdentSrc->User,
(pAuthIdentSrc->UserLength + 1) * sizeof(WCHAR));
}
if ( pAuthIdentSrc->Domain )
{
if(!((*ppAuthIdentDest)->Domain = (USHORT *)
PrivMemAlloc((pAuthIdentSrc->DomainLength+1) * sizeof(USHORT))))
{
goto COPY_AUTHIDENTITY_EXIT;
}
memcpy( (*ppAuthIdentDest)->Domain,
pAuthIdentSrc->Domain,
(pAuthIdentSrc->DomainLength + 1) * sizeof(WCHAR));
}
if ( pAuthIdentSrc->Password )
{
if(!((*ppAuthIdentDest)->Password = (USHORT *)
PrivMemAlloc((pAuthIdentSrc->PasswordLength+1) * sizeof(USHORT))))
{
goto COPY_AUTHIDENTITY_EXIT;
}
memcpy( (*ppAuthIdentDest)->Password,
pAuthIdentSrc->Domain,
(pAuthIdentSrc->PasswordLength + 1) * sizeof(WCHAR));
}
(*ppAuthIdentDest)->UserLength = pAuthIdentSrc->UserLength;
(*ppAuthIdentDest)->DomainLength = pAuthIdentSrc->DomainLength;
(*ppAuthIdentDest)->PasswordLength = pAuthIdentSrc->PasswordLength;
(*ppAuthIdentDest)->Flags = pAuthIdentSrc->Flags;
return S_OK;
COPY_AUTHIDENTITY_EXIT:
if(*ppAuthIdentDest)
{
if((*ppAuthIdentDest)->User)
{
PrivMemFree((*ppAuthIdentDest)->User);
}
if((*ppAuthIdentDest)->Domain)
{
PrivMemFree((*ppAuthIdentDest)->Domain);
}
if((*ppAuthIdentDest)->Password)
{
PrivMemFree((*ppAuthIdentDest)->Password);
}
PrivMemFree(*ppAuthIdentDest);
}
return hr;
}
HRESULT
CRemoteServer::CopyAuthInfo(
COAUTHINFO** ppAuthInfoDest,
COAUTHINFO* pAuthInfoSrc)
{
HRESULT hr = E_OUTOFMEMORY;
*ppAuthInfoDest = NULL;
if ( !(*ppAuthInfoDest = (COAUTHINFO*)PrivMemAlloc(sizeof(COAUTHINFO))) )
{
goto COPY_AUTHINFO_EXIT;
}
// only alloc space for pwszServerPrincName if its non-null
if(pAuthInfoSrc->pwszServerPrincName)
{
if ( !((*ppAuthInfoDest)->pwszServerPrincName =
(LPWSTR)PrivMemAlloc((lstrlenW(pAuthInfoSrc->pwszServerPrincName) + 1) *
sizeof(WCHAR))) )
{
goto COPY_AUTHINFO_EXIT;
}
}
else
{
(*ppAuthInfoDest)->pwszServerPrincName = NULL;
}
// copy the AuthIdentity if its non-null
if(pAuthInfoSrc->pAuthIdentityData)
{
if ( FAILED(CopyAuthIdentity(&((*ppAuthInfoDest)->pAuthIdentityData),
pAuthInfoSrc->pAuthIdentityData)) )
{
goto COPY_AUTHINFO_EXIT;
}
}
else
{
(*ppAuthInfoDest)->pAuthIdentityData = NULL;
}
(*ppAuthInfoDest)->dwAuthnSvc = pAuthInfoSrc->dwAuthnSvc;
(*ppAuthInfoDest)->dwAuthzSvc = pAuthInfoSrc->dwAuthzSvc;
(*ppAuthInfoDest)->dwAuthnLevel = pAuthInfoSrc->dwAuthnLevel;
(*ppAuthInfoDest)->dwImpersonationLevel = pAuthInfoSrc->dwImpersonationLevel;
(*ppAuthInfoDest)->dwCapabilities = pAuthInfoSrc->dwCapabilities;
if(pAuthInfoSrc->pwszServerPrincName)
{
lstrcpyW((*ppAuthInfoDest)->pwszServerPrincName,pAuthInfoSrc->pwszServerPrincName);
}
return S_OK;
COPY_AUTHINFO_EXIT:
if ( *ppAuthInfoDest )
{
if ( (*ppAuthInfoDest)->pwszServerPrincName )
{
PrivMemFree( (*ppAuthInfoDest)->pwszServerPrincName );
}
PrivMemFree( *ppAuthInfoDest );
}
return hr;
}
BOOL
CRemoteServer::FEquivalentAuthIdent(
COAUTHIDENTITY* pAuthIdent,
COAUTHIDENTITY* pAuthIdentOther )
{
if ( pAuthIdent->Flags != pAuthIdentOther->Flags )
{
return FALSE;
}
ULONG cch;
if ( pAuthIdent->User && pAuthIdentOther->User )
{
if ( (cch = pAuthIdent->UserLength) != pAuthIdentOther->UserLength )
{
return FALSE;
}
if ( memcmp(pAuthIdent->User,pAuthIdentOther->User,(cch+1) * sizeof(WCHAR)) != 0 )
{
return FALSE;
}
}
else if ( pAuthIdent->User || pAuthIdentOther->User )
return FALSE;
if ( pAuthIdent->Domain && pAuthIdentOther->Domain )
{
if ( (cch = pAuthIdent->DomainLength) != pAuthIdentOther->DomainLength )
{
return FALSE;
}
if ( memcmp(pAuthIdent->Domain,pAuthIdentOther->Domain,(cch+1) * sizeof(WCHAR)) != 0 )
{
return FALSE;
}
}
else if ( pAuthIdent->Domain || pAuthIdentOther->Domain )
return FALSE;
if ( pAuthIdent->Password && pAuthIdentOther->Password )
{
if ( (cch = pAuthIdent->PasswordLength) != pAuthIdentOther->PasswordLength )
{
return FALSE;
}
if ( memcmp(pAuthIdent->Password,pAuthIdentOther->Password,(cch+1) * sizeof(WCHAR)) != 0 )
{
return FALSE;
}
}
else if ( pAuthIdent->Password || pAuthIdentOther->Password )
return FALSE;
return TRUE;
}
BOOL
CRemoteServer::FEquivalentAuthInfo(
COAUTHINFO* pAuthInfo,
COAUTHINFO* pAuthInfoOther)
{
if ( pAuthInfo && pAuthInfoOther )
{
if ( (pAuthInfo->dwAuthnSvc != pAuthInfoOther->dwAuthnSvc) ||
(pAuthInfo->dwAuthzSvc != pAuthInfoOther->dwAuthzSvc) ||
(pAuthInfo->dwAuthnLevel != pAuthInfoOther->dwAuthnLevel) ||
(pAuthInfo->dwImpersonationLevel != pAuthInfoOther->dwImpersonationLevel) ||
(pAuthInfo->dwCapabilities != pAuthInfoOther->dwCapabilities) )
{
return FALSE;
}
// only compare pwszServerPrincName's if they're both specified
if(pAuthInfo->pwszServerPrincName && pAuthInfoOther->pwszServerPrincName)
{
if ( lstrcmpW(pAuthInfo->pwszServerPrincName,
pAuthInfoOther->pwszServerPrincName) != 0 )
{
return FALSE;
}
}
else
{
// if one was NULL, both should be NULL for equality
if(pAuthInfo->pwszServerPrincName != pAuthInfoOther->pwszServerPrincName)
{
return FALSE;
}
}
if(pAuthInfo->pAuthIdentityData && pAuthInfoOther->pAuthIdentityData)
{
if (!(FEquivalentAuthIdent(pAuthInfo->pAuthIdentityData,
pAuthInfoOther->pAuthIdentityData)) )
{
return FALSE;
}
}
else
{
// if either authident was NULL, they should both be NULL for equality
if(pAuthInfo->pAuthIdentityData != pAuthInfoOther->pAuthIdentityData)
{
return FALSE;
}
}
}
else
{
if ( pAuthInfo != pAuthInfoOther )
{
return FALSE;
}
}
return TRUE;
}
void SkipListDeleteRemoteServer(void *pvRemoteServer)
{
CRemoteServer *p = (CRemoteServer*)pvRemoteServer;
// p->CheckSig();
delete p;
}