Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1593 lines
35 KiB

/*++
(c) 1998 Seagate Software, Inc. All rights reserved.
Module Name:
fsaftclt.cpp
Abstract:
This class represents a user who the filter has detected accessing a file with placeholder information.
Author:
Chuck Bardeen [cbardeen] 12-Feb-1997
Revision History:
--*/
#include "stdafx.h"
extern "C" {
#include <ntseapi.h>
#include <wchar.h>
#include <lmaccess.h>
#include <lmserver.h>
#include <lmshare.h>
#include <lmapibuf.h>
#include <lmerr.h>
// #define MAC_SUPPORT // NOTE: You must define MAC_SUPPORT in fsafltr.cpp to enable all the code
#ifdef MAC_SUPPORT
#include <macfile.h>
#endif
}
#define WSB_TRACE_IS WSB_TRACE_BIT_FSA
#include "wsb.h"
#include "fsa.h"
#include "fsaftclt.h"
static USHORT iCountFtclt = 0; // Count of existing objects
//
// We need to dynamically load the DLL for MAC support because it is not there if
// the MAC service is not installed.
//
#ifdef MAC_SUPPORT
HANDLE FsaDllSfm = 0;
BOOL FsaMacSupportInstalled = FALSE;
extern "C" {
DWORD (*pAfpAdminConnect) (LPWSTR lpwsServerName, PAFP_SERVER_HANDLE phAfpServer);
VOID (*pAfpAdminDisconnect) (AFP_SERVER_HANDLE hAfpServer);
VOID (*pAfpAdminBufferFree) (PVOID pBuffer);
DWORD (*pAfpAdminSessionEnum) (AFP_SERVER_HANDLE hAfpServer, LPBYTE *lpbBuffer,
DWORD dwPrefMaxLen, LPDWORD lpdwEntriesRead, LPDWORD lpdwTotalEntries,
LPDWORD lpdwResumeHandle);
}
#endif
DWORD FsaIdentifyThread(void *pNotifyInterface);
DWORD FsaIdentifyThread(
void* pVoid
)
/*++
Entry point of the thread that performs identify operation with remote clients.
--*/
{
HRESULT hr;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = ((CFsaFilterClient*) pVoid)->IdentifyThread();
CoUninitialize();
return(hr);
}
static
HRESULT
GetNotifyClientInterface(
IN OLECHAR * machineName,
OUT IFsaRecallNotifyClient ** ppClient
)
{
HRESULT hr = S_OK;
try {
//
// Make sure parameters OK and OUTs initially cleared
//
WsbAffirmPointer ( ppClient );
*ppClient = 0;
//
// If connecting local, things work better to use NULL
// for the computer name
//
if ( machineName ) {
CWsbStringPtr localMachine;
WsbAffirmHr( WsbGetComputerName( localMachine ) );
if( _wcsicmp( localMachine, machineName ) == 0 ) {
machineName = 0;
}
}
//
// Set server info
//
COSERVERINFO csi;
COAUTHINFO cai;
memset ( &csi, 0, sizeof ( csi ) );
memset ( &cai, 0, sizeof ( cai ) );
// Set machine name
csi.pwszName = machineName;
// Create a proxy with security settings of no authentication (note that RsNotify is running with this security)
cai.dwAuthnSvc = RPC_C_AUTHN_WINNT;
cai.dwAuthzSvc = RPC_C_AUTHZ_DEFAULT;
cai.pwszServerPrincName = NULL;
cai.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
cai.pAuthIdentityData = NULL;
cai.dwCapabilities = EOAC_NONE;
cai.dwAuthnLevel = RPC_C_AUTHN_LEVEL_NONE;
csi.pAuthInfo = &cai;
//
// We want IFsaRecallNotifyClient back
//
MULTI_QI mqi;
memset ( &mqi, 0, sizeof ( mqi ) );
mqi.pIID = &IID_IFsaRecallNotifyClient;
//
// Make the connection...
//
WsbAffirmHr ( CoCreateInstanceEx (
CLSID_CFsaRecallNotifyClient, 0,
CLSCTX_NO_FAILURE_LOG | ( machineName ? CLSCTX_REMOTE_SERVER : CLSCTX_LOCAL_SERVER ),
&csi, 1, &mqi ) );
WsbAffirmHr ( mqi.hr );
//
// We need to make sure we clean up correctly if any interface
// post-processing fails, so assign over to a smart pointer for
// the time being
//
CComPtr<IFsaRecallNotifyClient> pClientTemp = (IFsaRecallNotifyClient*)mqi.pItf;
mqi.pItf->Release ( );
//
// Finally, we need to set the security on the procy to allow the
// anonymous connection. Values should be the same as above (COAUTHINFO)
// We need to make sure this is a remote machine first. Otherwise, we
// get an error of E_INVALIDARG.
//
if( machineName ) {
CComPtr<IClientSecurity> pSecurity;
WsbAffirmHr( pClientTemp->QueryInterface( IID_IClientSecurity, (void**)&pSecurity ) );
WsbAffirmHr( pSecurity->SetBlanket ( pClientTemp, RPC_C_AUTHN_NONE, RPC_C_AUTHZ_NONE, 0, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, 0, 0 ) );
}
//
// Finally, assign over and AddRef the return.
//
*ppClient = pClientTemp;
(*ppClient)->AddRef ( );
} WsbCatch ( hr );
return ( hr );
}
HRESULT
CFsaFilterClient::CheckRecallLimit(
IN DWORD minRecallInterval,
IN DWORD maxRecalls,
IN BOOLEAN exemptAdmin
)
/*++
Implements:
IWsbCollectable::CheckRecallLimit().
--*/
{
HRESULT hr = S_OK;
FILETIME now, last;
LARGE_INTEGER tNow, tLast;
ULONG rCount;
WsbTraceIn(OLESTR("CFsaFilterClient::CheckRecallLimit"), OLESTR(""));
try {
//
// Now check for runaway recall limits if the user is not
// an administrator
//
if ((!m_isAdmin) || (!exemptAdmin)) {
//
// See if the time since the end of the last recall is
// less than m_minRecallInterval (in seconds) and if so,
// increment the count.
// If not, then reset the count (if we were not
// already triggered).
// If the count is equal to the max then set the trigger.
//
WsbTrace(OLESTR("CHsmFilter::IoctlThread: Not an administrator or admin is not exempt.\n"));
GetSystemTimeAsFileTime(&now);
tNow.LowPart = now.dwLowDateTime;
tNow.HighPart = now.dwHighDateTime;
GetLastRecallTime(&last);
tLast.LowPart = last.dwLowDateTime;
tLast.HighPart = last.dwHighDateTime;
//
// Get the time (in 100 nano-second units)
// from the end of the last recall until now.
//
tNow.QuadPart -= tLast.QuadPart;
//
// Convert to seconds and check against the interval time
//
tNow.QuadPart /= (LONGLONG) 10000000;
if (tNow.QuadPart < (LONGLONG) minRecallInterval) {
//
// This one counts - increment the count
// and check for a trigger.
//
GetRecallCount(&rCount);
rCount++;
SetRecallCount(rCount);
WsbTrace(OLESTR("CHsmFilterClient::CheckRecallLimit: Recall count bumped to %ls.\n"),
WsbLongAsString(rCount));
if (rCount >= maxRecalls) {
//
// Hit the runaway recall limit. Set the
// limit flag.
//
WsbTrace(OLESTR("CHsmFilter::IoctlThread: Hit the runaway recall limit!!!.\n"));
SetHitRecallLimit(TRUE);
}
} else {
//
// Reset the count if they are not already triggered.
// If they are triggered then reset the trigger and
// limit if it has been a respectable time.
// TBD - What is a respectable time??
//
if (HitRecallLimit() != S_FALSE) {
if (tNow.QuadPart > (LONGLONG) minRecallInterval * 100) {
//
// A respectable time has passed - reset the trigger and count.
//
WsbTrace(OLESTR("CHsmFilterClient::CheckRecallLimit: Resetting recall limit trigger and count.\n"));
SetHitRecallLimit(FALSE);
SetRecallCount(0);
m_loggedLimitError = FALSE;
}
} else {
//
// This one did not count and they were not already triggered.
// Reset the count to zero.
//
WsbTrace(OLESTR("CHsmFilterClient::CheckRecallLimit: Resetting recall count.\n"));
SetRecallCount(0);
}
}
//
// Fail if the limit is hit.
//
WsbAffirm(HitRecallLimit() == S_FALSE, FSA_E_HIT_RECALL_LIMIT);
}
} WsbCatch(hr);
// NOTE - IF RUNAWAY RECALL BEHAVIOR CHANGES TO TRUNCATE ON CLOSE, CHANGE
// FSA_MESSAGE_HIT_RECALL_LIMIT_ACCESSDENIED TO FSA_MESSAGE_HIT_RECALL_LIMIT_TRUNCATEONCLOSE.
if ( (hr == FSA_E_HIT_RECALL_LIMIT) && (!m_loggedLimitError)) {
WsbLogEvent(FSA_MESSAGE_HIT_RECALL_LIMIT_ACCESSDENIED, 0, NULL, (WCHAR *) m_userName, NULL);
m_loggedLimitError = TRUE;
}
WsbTraceOut(OLESTR("CHsmFilterClient::CheckRecallLimit"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CFsaFilterClient::CompareBy(
FSA_FILTERCLIENT_COMPARE by
)
/*++
Implements:
IFsaFilterClient::CompareBy().
--*/
{
HRESULT hr = S_OK;
m_compareBy = by;
m_isDirty = TRUE;
return(hr);
}
HRESULT
CFsaFilterClient::CompareTo(
IN IUnknown* pUnknown,
OUT SHORT* pResult
)
/*++
Implements:
IWsbCollectable::CompareTo().
--*/
{
HRESULT hr = S_OK;
CComPtr<IFsaFilterClient> pClient;
WsbTraceIn(OLESTR("CFsaFilterClient::CompareTo"), OLESTR(""));
try {
// Did they give us a valid item to compare to?
WsbAssert(0 != pUnknown, E_POINTER);
// We need the IWsbBool interface to get the value of the object.
WsbAffirmHr(pUnknown->QueryInterface(IID_IFsaFilterClient, (void**) &pClient));
// Compare the rules.
hr = CompareToIClient(pClient, pResult);
} WsbCatch(hr);
WsbTraceOut(OLESTR("CHsmFilterClient::CompareTo"), OLESTR("hr = <%ls>, result = <%ls>"), WsbHrAsString(hr), WsbPtrToShortAsString(pResult));
return(hr);
}
HRESULT
CFsaFilterClient::CompareToAuthenticationId(
IN LONG luidHigh,
IN ULONG luidLow,
OUT SHORT* pResult
)
/*++
Implements:
IFsaFilterClient::CompareToAuthenticationId().
--*/
{
HRESULT hr = S_OK;
SHORT aResult;
WsbTraceIn(OLESTR("CFsaFilterClient::CompareToAuthenticationId"), OLESTR(""));
try {
if (m_luidHigh > luidHigh) {
aResult = 1;
} else if (m_luidHigh < luidHigh) {
aResult = -1;
} else if (m_luidLow > luidLow) {
aResult = 1;
} else if (m_luidLow < luidLow) {
aResult = -1;
} else {
aResult = 0;
}
if (0 != aResult) {
hr = S_FALSE;
}
if (0 != pResult) {
*pResult = aResult;
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaFilterClient::CompareToAuthenticationId"), OLESTR("hr = <%ls>, result = <%d>"), WsbHrAsString(hr), aResult);
return(hr);
}
HRESULT
CFsaFilterClient::CompareToIClient(
IN IFsaFilterClient* pClient,
OUT SHORT* pResult
)
/*++
Implements:
IFsaFilterClient::CompareToIClient().
--*/
{
HRESULT hr = S_OK;
CWsbStringPtr name;
LONG luidHigh;
ULONG luidLow;
WsbTraceIn(OLESTR("CFsaFilterClient::CompareToIClient"), OLESTR(""));
try {
// Did they give us a valid item to compare to?
WsbAssert(0 != pClient, E_POINTER);
switch (m_compareBy) {
case FSA_FILTERCLIENT_COMPARE_ID:
WsbAffirmHr(pClient->GetAuthenticationId(&luidHigh, &luidLow));
hr = CompareToAuthenticationId(luidHigh, luidLow, pResult);
break;
case FSA_FILTERCLIENT_COMPARE_MACHINE:
WsbAffirmHr(pClient->GetMachineName(&name, 0));
hr = CompareToMachineName(name, pResult);
break;
default:
WsbAssert(FALSE, E_UNEXPECTED);
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaFilterClient::CompareToIClient"), OLESTR("hr = <%ls>, result = <%ls>"), WsbHrAsString(hr), WsbPtrToShortAsString(pResult));
return(hr);
}
HRESULT
CFsaFilterClient::CompareToMachineName(
IN OLECHAR* name,
OUT SHORT* pResult
)
/*++
Implements:
IFsaFilterClient::CompareToMachineName().
--*/
{
HRESULT hr = S_OK;
SHORT aResult;
WsbTraceIn(OLESTR("CFsaFilterClient::CompareToMachineName"), OLESTR(""));
try {
aResult = (SHORT)wcscmp(name, m_machineName); // TBD - Case sensitive or not?
if (0 != aResult) {
hr = S_FALSE;
}
if (0 != pResult) {
*pResult = aResult;
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaFilterClient::CompareToMachineName"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CFsaFilterClient::FinalConstruct(
void
)
/*++
Implements:
CComObjectRoot::FinalConstruct().
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaFilterClient::FinalConstruct"),OLESTR(""));
try {
WsbAffirmHr(CWsbCollectable::FinalConstruct());
m_compareBy = FSA_FILTERCLIENT_COMPARE_ID;
m_luidHigh = 0;
m_luidLow = 0;
m_hasRecallDisabled = FALSE;
m_hitRecallLimit = FALSE;
m_lastRecallTime.dwLowDateTime = 0;
m_lastRecallTime.dwHighDateTime = 0;
m_identified = FALSE;
m_tokenSource = L"";
m_msgCounter = 1;
m_identifyThread = NULL;
m_isAdmin = FALSE;
m_loggedLimitError = FALSE;
} WsbCatch(hr);
iCountFtclt++;
WsbTraceOut(OLESTR("CFsaFilterClient::FinalConstruct"),OLESTR("Count is <%d>"), iCountFtclt);
return(hr);
}
void
CFsaFilterClient::FinalRelease(
void
)
/*++
Implements:
CComObjectRoot::FinalRelease().
--*/
{
WsbTraceIn(OLESTR("CFsaFilterClient::FinalRelease"),OLESTR(""));
CWsbCollectable::FinalRelease();
iCountFtclt--;
WsbTraceOut(OLESTR("CFsaFilterClient::FinalRelease"),OLESTR("Count is <%d>"), iCountFtclt);
}
HRESULT
CFsaFilterClient::GetClassID(
OUT CLSID* pClsid
)
/*++
Implements:
IPersist::GetClassID().
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaFilterClient::GetClassID"), OLESTR(""));
try {
WsbAssert(0 != pClsid, E_POINTER);
*pClsid = CLSID_CFsaFilterClientNTFS;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaFilterClient::GetClassID"), OLESTR("hr = <%ls>, CLSID = <%ls>"), WsbHrAsString(hr), WsbGuidAsString(*pClsid));
return(hr);
}
HRESULT
CFsaFilterClient::GetAuthenticationId(
OUT LONG* pLuidHigh,
OUT ULONG* pLuidLow
)
/*++
Implements:
IFsaFilterClient::GetAuthenticationId().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(0 != pLuidHigh, E_POINTER);
WsbAssert(0 != pLuidLow, E_POINTER);
*pLuidHigh = m_luidHigh;
*pLuidLow = m_luidLow;
} WsbCatch(hr);
return(hr);
}
HRESULT
CFsaFilterClient::GetDomainName(
OUT OLECHAR** pName,
IN ULONG bufferSize
)
/*++
Implements:
IFsaFilterClient::GetDomainName().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(0 != pName, E_POINTER);
WsbAffirmHr(m_domainName.CopyTo(pName, bufferSize));
} WsbCatch(hr);
return(hr);
}
HRESULT
CFsaFilterClient::GetIsAdmin(
OUT BOOLEAN *pIsAdmin
)
/*++
Implements:
IPersist::GetIsAdmin().
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaFilterClient::GetIsAdmin"), OLESTR(""));
try {
WsbAssert(0 != pIsAdmin, E_POINTER);
*pIsAdmin = m_isAdmin;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaFilterClient::GetIsAdmin"), OLESTR("hr = <%ls>, isAdmin = <%u>"), WsbHrAsString(hr), *pIsAdmin);
return(hr);
}
HRESULT
CFsaFilterClient::GetLastRecallTime(
OUT FILETIME* pTime
)
/*++
Implements:
IFsaFilterClient::GetLastRecallTime().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(0 != pTime, E_POINTER);
*pTime = m_lastRecallTime;
} WsbCatch(hr);
return(hr);
}
HRESULT
CFsaFilterClient::GetMachineName(
OUT OLECHAR** pName,
IN ULONG bufferSize
)
/*++
Implements:
IFsaFilterClient::GetMachineName().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(0 != pName, E_POINTER);
WsbAffirmHr(m_machineName.CopyTo(pName, bufferSize));
} WsbCatch(hr);
return(hr);
}
HRESULT
CFsaFilterClient::GetRecallCount(
OUT ULONG* pCount
)
/*++
Implements:
IFsaFilterClient::GetRecallCount().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(0 != pCount, E_POINTER);
*pCount = m_recallCount;
} WsbCatch(hr);
return(hr);
}
HRESULT
CFsaFilterClient::GetUserName(
OUT OLECHAR** pName,
IN ULONG bufferSize
)
/*++
Implements:
IFsaFilterClient::GetUserName().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(0 != pName, E_POINTER);
WsbAffirmHr(m_userName.CopyTo(pName, bufferSize));
} WsbCatch(hr);
return(hr);
}
HRESULT
CFsaFilterClient::GetSizeMax(
OUT ULARGE_INTEGER* pSize
)
/*++
Implements:
IPersistStream::GetSizeMax().
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaFilterClient::GetSizeMax"), OLESTR(""));
try {
WsbAssert(0 != pSize, E_POINTER);
pSize->QuadPart = 0;
// WE don't need to persist these.
hr = E_NOTIMPL;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaFilterClient::GetSizeMax"), OLESTR("hr = <%ls>, Size = <%ls>"), WsbHrAsString(hr), WsbPtrToUliAsString(pSize));
return(hr);
}
HRESULT
CFsaFilterClient::HasRecallDisabled(
void
)
/*++
Implements:
IFsaFilterClient::HasRecallDisabled().
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaFilterClient::HasRecallDisabled"), OLESTR(""));
if (!m_hasRecallDisabled) {
hr = S_FALSE;
}
WsbTraceOut(OLESTR("CHsmFilterClient::HasRecallDisabled"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CFsaFilterClient::HitRecallLimit(
void
)
/*++
Implements:
IFsaFilterClient::HitRecallLimit().
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaFilterClient::HitRecallLimit"), OLESTR(""));
if (!m_hitRecallLimit) {
hr = S_FALSE;
}
WsbTraceOut(OLESTR("CHsmFilterClient::HitRecallLimit"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CFsaFilterClient::IdentifyThread(
void
)
/*++
Implements:
CFsaFilterClient::IdentifyThread().
--*/
{
#define WSB_BUFF_SIZE 1024
HRESULT hr = S_OK;
BOOL done, guestUser, noUser;
DWORD res, totalEnt, numEnt;
UCHAR *buff = NULL;
NET_API_STATUS status;
SESSION_INFO_1 *sess;
CWsbStringPtr pipePath;
ULONG holdOff = 0;
#ifdef MAC_SUPPORT
LPBYTE macBuff = NULL;
PAFP_SESSION_INFO macInfo;
AFP_SERVER_HANDLE macHandle = 0;
DWORD macResume = 0;
DWORD macTotalEntries, macTotalRead;
DWORD result;
#endif
WsbTraceIn(OLESTR("CFsaFilterClient::IdentifyThread"), OLESTR(""));
try {
WsbTrace(OLESTR("CFsaFilterClient::IdentifyThread Flag: %x Client ID: %x:%x Source: %ls\n"),
m_identified, m_luidHigh, m_luidLow, (WCHAR *) m_tokenSource);
//
// If already identified then we bail out here.
//
WsbAffirm(m_identified == FALSE, S_OK);
done = FALSE;
res = 0;
noUser = FALSE;
if (_wcsicmp(m_userName, L"GUEST") == 0) {
/* It is the guest user - find all sessions and
send to ones marked guest */
guestUser = TRUE;
} else {
guestUser = FALSE;
if (wcslen(m_userName) == 0) {
noUser = TRUE;
}
}
CComPtr<IFsaRecallNotifyClient> pRecallClient;
WsbGetComputerName( pipePath );
WsbAffirmHr(pipePath.Prepend("\\\\"));
WsbAffirmHr(pipePath.Append("\\pipe\\"));
WsbAffirmHr(pipePath.Append(WSB_PIPE_NAME));
while ( done == FALSE ) {
if ( (guestUser == FALSE) && (noUser == FALSE) ) {
// If NetSessionEnum fails, try calling again for all users
status = NetSessionEnum(NULL, NULL, m_userName, 1, &buff,
WSB_BUFF_SIZE, &numEnt, &totalEnt, &res);
if (status != 0) {
status = NetSessionEnum(NULL, NULL, NULL, 1, &buff,
WSB_BUFF_SIZE, &numEnt, &totalEnt, &res);
}
} else {
status = NetSessionEnum( NULL, NULL, NULL, 1, &buff,
WSB_BUFF_SIZE, &numEnt, &totalEnt, &res );
}
if ((status == NERR_Success) || (status == ERROR_MORE_DATA)) {
WsbTrace(OLESTR("CHsmFilterClient::IdentifyThread: NetSessionEnum output: Total entries=%ls , Read entries=%ls \n"),
WsbLongAsString(totalEnt), WsbLongAsString(numEnt));
if (status != ERROR_MORE_DATA) {
done = TRUE;
}
sess = (SESSION_INFO_1 *) buff;
while ( numEnt != 0 ) {
//
// If the request was made from the user GUEST then
// we enumerate all sessions and send the
// identification request to all the machines with
// sessions marked as GUEST. This is because the
// session may have some other user name but the
// request could still have GUEST access.
//
if (((guestUser) && (sess->sesi1_user_flags & SESS_GUEST)) ||
(!guestUser)) {
//
// Send the identify request message
//
WsbTrace(OLESTR("CFsaFilterClient::IdentifyThread - Sending identify request to %ls (local machine = %ls)\n"),
sess->sesi1_cname, (WCHAR *) pipePath);
hr = GetNotifyClientInterface ( sess->sesi1_cname, &pRecallClient );
if ( SUCCEEDED ( hr ) ) {
hr = pRecallClient->IdentifyWithServer( pipePath );
if (hr != S_OK) {
WsbTrace(OLESTR("CFsaFilterClient::IdentifyThread - error Identifing (%ls)\n"),
WsbHrAsString(hr));
}
} else {
WsbTrace(OLESTR("CFsaFilterClient::IdentifyThread - error getting notify client interface hr = %ls (%x)\n"),
WsbHrAsString( hr ), hr);
}
hr = S_OK;
pRecallClient.Release ( );
}
sess++;
numEnt--;
}
NetApiBufferFree(buff);
buff = NULL;
} else {
done = TRUE;
}
}
#ifdef MAC_SUPPORT
//
// Done with LAN manager scan, now do a MAC scan.
//
if ( (FsaMacSupportInstalled) && ((pAfpAdminConnect)(NULL, &macHandle) == NO_ERROR) ) {
//
// We have connected to the MAC service - do a session enumeration
//
macResume = 0;
done = FALSE;
while (done == FALSE) {
result = (pAfpAdminSessionEnum)(macHandle, &macBuff, -1,
&macTotalRead, &macTotalEntries, &macResume);
if ((result == NO_ERROR) || (result == ERROR_MORE_DATA)) {
//
// Read some entries - send the message to each one
//
if (macTotalRead == macTotalEntries) {
done = TRUE;
}
macInfo = (PAFP_SESSION_INFO) macBuff;
while ( macTotalRead != 0 ) {
//
// Send to each matching user
//
if ( ( NULL != macInfo->afpsess_ws_name ) &&
( _wcsicmp(m_userName, macInfo->afpsess_username ) == 0 ) ) {
WsbTrace(OLESTR("CHsmFilterClient::IdentifyThread: Send Identify to MAC %ls.\n"),
macInfo->afpsess_ws_name);
//
// Send the identify request message
//
hr = GetNotifyClientInterface ( sess->sesi1_cname, &pRecallClient );
if ( SUCCEEDED ( hr ) ) {
pRecallClient->IdentifyWithServer ( pipePath );
}
hr = S_OK;
pRecallClient.Release ( );
}
macInfo++;
macTotalRead--;
}
(pAfpAdminBufferFree)(macBuff);
macBuff = NULL;
} else {
done = TRUE;
}
(pAfpAdminDisconnect)(macHandle);
macHandle = 0;
}
}
#endif
} WsbCatch(hr);
if (buff != NULL) {
NetApiBufferFree(buff);
}
#ifdef MAC_SUPPORT
if (FsaMacSupportInstalled) {
if (macBuff != NULL) {
(pAfpAdminBufferFree)(macBuff);
}
if (macHandle != 0) {
(pAfpAdminDisconnect)(macHandle);
}
}
#endif
CloseHandle(m_identifyThread);
m_identifyThread = NULL;
WsbTraceOut(OLESTR("CFsaFilterClient::IdentifyThread"), OLESTR("hr = %ls"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CFsaFilterClient::Load(
IN IStream* pStream
)
/*++
Implements:
IPersistStream::Load().
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaFilterClient::Load"), OLESTR(""));
try {
WsbAssert(0 != pStream, E_POINTER);
// No persistence.
hr = E_NOTIMPL;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaFilterClient::Load"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CFsaFilterClient::Save(
IN IStream* pStream,
IN BOOL clearDirty
)
/*++
Implements:
IPersistStream::Save().
--*/
{
HRESULT hr = S_OK;
CComPtr<IPersistStream> pPersistStream;
WsbTraceIn(OLESTR("CFsaFilterClient::Save"), OLESTR("clearDirty = <%ls>"), WsbBoolAsString(clearDirty));
try {
WsbAssert(0 != pStream, E_POINTER);
// No persistence.
hr = E_NOTIMPL;
// If we got it saved and we were asked to clear the dirty bit, then
// do so now.
if (clearDirty) {
m_isDirty = FALSE;
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaFilterClient::Save"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CFsaFilterClient::SendRecallInfo(
IFsaFilterRecall *pRecall,
BOOL starting,
HRESULT rHr
)
/*++
Implements:
CFsaFilterClient::SendRecallInfo
--*/
{
HRESULT hr = E_FAIL;
if( ! m_identified && ( m_identifyThread != NULL ) ) {
//
// Wait for up to 10 seconds for identify thread to complete if
// Client not yet identified
//
WaitForMultipleObjects( 1, &m_identifyThread, FALSE, 10000 );
}
//
// Let the client know that the recall is starting or is finished
//
if ( m_identified ) {
try {
WsbTrace(OLESTR("CFsaFilterClient::SendRecallInfo - Client (%ls) is being notified of recall status (starting = %u hr = %x).\n"),
(WCHAR *) m_machineName, starting, rHr);
//
// Create intermediate server object which will be the client's
// connection back to the service. This object acts as a middle
// man to overcome the admin-only access into the FSA service.
//
CComPtr<IFsaRecallNotifyServer> pRecallServer;
WsbAffirmHr(CoCreateInstance(CLSID_CFsaRecallNotifyServer, 0, CLSCTX_NO_FAILURE_LOG | CLSCTX_ALL, IID_IFsaRecallNotifyServer, (void**)&pRecallServer));
WsbAffirmHr(pRecallServer->Init(pRecall));
CComPtr<IFsaRecallNotifyClient> pRecallClient;
hr = GetNotifyClientInterface ( m_machineName, &pRecallClient );
if ( SUCCEEDED( hr ) ) {
if (starting) {
hr = pRecallClient->OnRecallStarted ( pRecallServer );
} else {
hr = pRecallClient->OnRecallFinished ( pRecallServer, rHr );
}
if (hr != S_OK) {
WsbTrace(OLESTR("CFsaFilterClient::SendRecallInfo - Got the interface but failed in OnRecall... (%ls)\n"),
WsbHrAsString(hr));
}
} else {
WsbTrace(OLESTR("CFsaFilterClient::SendRecallInfo - error getting notify client interface hr = %ls (%x)\n"),
WsbHrAsString( hr ), hr);
}
} WsbCatchAndDo(hr,
WsbTrace(OLESTR("CFsaFilterClient::SendRecallInfo - hr = %ls\n"),
WsbHrAsString(hr));
);
}
return(hr);
}
HRESULT
CFsaFilterClient::SetAuthenticationId(
IN LONG luidHigh,
IN ULONG luidLow
)
/*++
Implements:
IFsaFilterClient::SetAuthenticationId().
--*/
{
m_luidHigh = luidHigh;
m_luidLow = luidLow;
return(S_OK);
}
HRESULT
CFsaFilterClient::SetDomainName(
IN OLECHAR* name
)
/*++
Implements:
IFsaFilterClient::SetDomainName().
--*/
{
HRESULT hr = S_OK;
try {
m_domainName = name;
WsbAssert(m_domainName != 0, E_UNEXPECTED);
} WsbCatch(hr);
return(hr);
}
HRESULT
CFsaFilterClient::SetIsAdmin(
IN BOOLEAN isAdmin
)
/*++
Implements:
IFsaFilterClient::SetIsAdmin().
--*/
{
m_isAdmin = isAdmin;
return(S_OK);
}
HRESULT
CFsaFilterClient::SetLastRecallTime(
IN FILETIME time
)
/*++
Implements:
IFsaFilterClient::SetLastRecallTime().
--*/
{
m_lastRecallTime = time;
return(S_OK);
}
HRESULT
CFsaFilterClient::SetMachineName(
IN OLECHAR* name
)
/*++
Implements:
IFsaFilterClient::SetMachineName().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(name != 0, E_UNEXPECTED);
m_machineName = name;
m_identified = TRUE;
WsbTrace(OLESTR("CFsaFilterClient::SetMachineName Flag: %x Client ID: %x:%x Source: %ls == %ls\n"),
m_identified, m_luidLow, m_luidHigh, (WCHAR *) m_tokenSource, (WCHAR *) m_machineName);
} WsbCatch(hr);
return(hr);
}
HRESULT
CFsaFilterClient::SetRecallCount(
IN ULONG count
)
/*++
Implements:
IFsaFilterClient::SetRecallCount().
--*/
{
m_recallCount = count;
return(S_OK);
}
HRESULT
CFsaFilterClient::SetUserName(
IN OLECHAR* name
)
/*++
Implements:
IFsaFilterClient::SetUserName().
--*/
{
HRESULT hr = S_OK;
try {
m_userName = _wcsupr(name);
WsbAssert(m_userName != 0, E_UNEXPECTED);
} WsbCatch(hr);
return(hr);
}
HRESULT
CFsaFilterClient::SetHasRecallDisabled(
IN BOOL hasBeen
)
/*++
Implements:
IFsaFilterClient::SetHasRecallDisabled().
--*/
{
m_hasRecallDisabled = hasBeen;
return(S_OK);
}
HRESULT
CFsaFilterClient::SetHitRecallLimit(
IN BOOL hasBeen
)
/*++
Implements:
IFsaFilterClient::SetHitRecallLimit().
--*/
{
m_hitRecallLimit = hasBeen;
return(S_OK);
}
HRESULT
CFsaFilterClient::SetTokenSource(
IN CHAR *source
)
/*++
Implements:
IFsaFilterClient::SetTokenSource()
--*/
{
OLECHAR tSource[TOKEN_SOURCE_LENGTH + 1];
mbstowcs((WCHAR *) tSource, source, TOKEN_SOURCE_LENGTH);
m_tokenSource = tSource;
return(S_OK);
}
HRESULT
CFsaFilterClient::StartIdentify(
void
)
/*++
Implements:
CFsaFilterClient::StartIdentify().
--*/
{
#define WSB_BUFF_SIZE 1024
HRESULT hr = S_OK;
DWORD tid;
WsbTraceIn(OLESTR("CFsaFilterClient::StartIdentify"), OLESTR(""));
try {
WsbTrace(OLESTR("CFsaFilterClient::StartIdentify Flag: %x Client ID: %x:%x Source: %ls\n"),
m_identified, m_luidHigh, m_luidLow, (WCHAR *) m_tokenSource);
//
// If already identified then we bail out here.
//
WsbAffirm(m_identified == FALSE, S_OK);
//
// If the request is from User32 then it is local
//
if (_wcsicmp(m_tokenSource, L"User32") == 0) {
//
// Identified as the local machine.
// Set the name and bail out with S_OK
//
WsbGetComputerName( m_machineName );
m_identified = TRUE;
WsbTrace(OLESTR("CHsmFilterClient::StartIdentify: Identified as %ls.\n"),
(WCHAR *) m_machineName);
WsbThrow( S_OK );
} else {
//
// Start the identification thread
//
if (NULL == m_identifyThread) {
WsbTrace(OLESTR("CHsmFilterClient::StartIdentify: Starting ID thread.\n"));
WsbAffirm((m_identifyThread = CreateThread(0, 0, FsaIdentifyThread, (void*) this, 0, &tid)) != 0, HRESULT_FROM_WIN32(GetLastError()));
if (m_identifyThread == NULL) {
WsbAssertHr(E_FAIL); // TBD What error to return here??
}
}
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaFilterClient::StartIdentify"), OLESTR("hr = %ls"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CFsaFilterClient::Test(
USHORT* passed,
USHORT* failed
)
/*++
Implements:
IWsbTestable::Test().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(0 != passed, E_POINTER);
WsbAssert(0 != failed, E_POINTER);
*passed = 0;
*failed = 0;
} WsbCatch(hr);
return(hr);
}