📄 connectionmanager.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
#include "SMB_Globals.h"
#include "ConnectionManager.h"
#include "Cracker.h"
#include "SMBCommands.h"
#include "PC_NET_PROG.h"
#include "FileServer.h"
UniqueID ActiveConnection::m_UIDFindFirstHandle;
#ifdef DEBUG
BOOL ConnectionManager::m_fFirstInst = TRUE;
#endif
#define MAX_NUM_GUESTS 20
ActiveConnection::ActiveConnection():m_ulConnectionID(0xFFFFFFFF),
m_fIsUnicode(FALSE), m_fContextSet(FALSE),
m_fIsGuest(TRUE)
{
IFDBG(m_uiAcceptCalled = 0;);
m_dwLastUsed = GetTickCount();
InitializeCriticalSection(&m_csConnectionLock);
}
#ifdef DEBUG
VOID
ActiveConnection::DebugPrint()
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
TRACEMSG(ZONE_ERROR, (L"Connection: "));
TRACEMSG(ZONE_ERROR, (L" USER: %s", m_UserName.GetString()));
// Find First handles
ce::list<FIND_FIRST_NODE, ACTIVE_CONN_FIND_FIRST_ALLOC >::iterator itFF;
ce::list<FIND_FIRST_NODE, ACTIVE_CONN_FIND_FIRST_ALLOC >::iterator itFFEnd = m_FindHandleList.end();
TRACEMSG(ZONE_ERROR, (L" FindFirst Handles:"));
for(itFF = m_FindHandleList.begin(); itFF != itFFEnd; itFF++) {
TRACEMSG(ZONE_ERROR, (L" %d -- %s", (*itFF).SearchString.GetString(), (*itFF).usSID));
}
ce::list<ce::smart_ptr<TIDState>, SHARE_MANANGER_TID_ALLOC >::iterator itSM;
ce::list<ce::smart_ptr<TIDState>, SHARE_MANANGER_TID_ALLOC >::iterator itSMEnd = m_MyTidList.end();
TRACEMSG(ZONE_ERROR, (L" TID Handles:"));
for(itSM = m_MyTidList.begin(); itSM != itSMEnd; itSM++) {
TRACEMSG(ZONE_ERROR, (L" TID: %d", (*itSM)->TID()));
(*itSM)->DebugPrint();
}
ce::list<NotificationNode>::iterator itNN;
ce::list<NotificationNode>::iterator itNNEnd = m_NotificationNodeList.end();
TRACEMSG(ZONE_ERROR, (L" Notification Handles:"));
for(itNN = m_NotificationNodeList.begin(); itNN != itNNEnd; itNN++) {
TRACEMSG(ZONE_ERROR, (L" NID: %d", (*itNN).pMyNode->GetID()));
}
}
#endif
ActiveConnection::~ActiveConnection()
{
//
// Destroy any handles we may have
while(m_FindHandleList.size()) {
ce::list<FIND_FIRST_NODE, ACTIVE_CONN_FIND_FIRST_ALLOC>::iterator it = m_FindHandleList.begin();
ActiveConnection::CloseFindHandle((*it).usSID);
}
//
// Destroy any credentials we may still have
if(TRUE == m_fContextSet) {
FreeCredentialsHandle(&(m_Credentials));
DeleteSecurityContext(&(m_ContextHandle));
}
//
// Purge out any active notifications we may have
SMB_Globals::g_pWakeUpOnEvent->Freeze();
EnterCriticalSection(&m_csConnectionLock);
while(m_NotificationNodeList.size()) {
m_NotificationNodeList.front().pMyNode->Terminate();
m_NotificationNodeList.pop_front();
}
LeaveCriticalSection(&m_csConnectionLock);
SMB_Globals::g_pWakeUpOnEvent->UnFreeze();
DeleteCriticalSection(&m_csConnectionLock);
}
BOOL
ActiveConnection::HasOpenedResources()
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
ce::list<ce::smart_ptr<TIDState>, SHARE_MANANGER_TID_ALLOC>::iterator it;
ce::list<ce::smart_ptr<TIDState>, SHARE_MANANGER_TID_ALLOC>::iterator itEnd = m_MyTidList.end();
//
// Find our node
for(it = m_MyTidList.begin(); it != itEnd; it++) {
if((*it)->HasOpenedResources()) {
return TRUE;
}
}
return FALSE;
}
VOID
ActiveConnection::SetUnicode(BOOL fStatus)
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
m_fIsUnicode = fStatus;
}
BOOL
ActiveConnection::SupportsUnicode(SMB_HEADER *pRequest, BYTE smb, BYTE subCmd)
{
if(!(pRequest->Flags2 & SMB_FLAGS2_UNICODE)) {
return FALSE;
}
else {
return TRUE;
}
}
VOID
ActiveConnection::SetConnectionInfo(ULONG ulConnectionID, USHORT usUid)
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
m_ulConnectionID = ulConnectionID;
m_usUid = usUid;
}
ULONG
ActiveConnection::ConnectionID()
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
return m_ulConnectionID;
}
USHORT
ActiveConnection::Uid()
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
return m_usUid;
}
HRESULT
ActiveConnection::CancelWakeUpEvent(USHORT usUid, USHORT usPid, USHORT usTid, USHORT usMid)
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
HRESULT hr = E_FAIL;
ce::list<NotificationNode>::iterator it, itEnd;
for(it = m_NotificationNodeList.begin(), itEnd = m_NotificationNodeList.end(); it != itEnd; ++it) {
if((*it).usUid == usUid &&
(*it).usPid== usPid &&
(*it).usTid == usTid &&
(*it).usMid == usMid) {
(*it).pMyNode->Terminate();
m_NotificationNodeList.erase(it);
hr = S_OK;
break;
}
}
return hr;
}
HRESULT ActiveConnection::AddWakeUpEvent(WakeUpNode *pNode, USHORT usId, USHORT usUid, USHORT usPid, USHORT usTid, USHORT usMid)
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
m_NotificationNodeList.insert(m_NotificationNodeList.begin());
m_NotificationNodeList.front().pMyNode = pNode;
m_NotificationNodeList.front().usUid = usUid;
m_NotificationNodeList.front().usPid = usPid;
m_NotificationNodeList.front().usTid = usTid;
m_NotificationNodeList.front().usMid = usMid;
return S_OK;
}
HRESULT ActiveConnection::RemoveWakeUpEvent(USHORT usId)
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
HRESULT hr = E_FAIL;
ce::list<NotificationNode>::iterator it, itEnd;
for(it = m_NotificationNodeList.begin(), itEnd = m_NotificationNodeList.end(); it != itEnd; ++it) {
if((*it).pMyNode->GetID() == usId) {
m_NotificationNodeList.erase(it);
hr = S_OK;
break;
}
}
return hr;
}
HRESULT
ActiveConnection::BindToTID(Share *pShare, ce::smart_ptr<TIDState> &pTIDState)
{
TIDState *pNewState;
HRESULT hr;
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
if(NULL == (pNewState = new TIDState())) {
hr = E_OUTOFMEMORY;
goto Done;
}
if(FAILED(pNewState->Init(pShare))) {
delete pNewState;
hr = E_UNEXPECTED;
goto Done;
}
if(!m_MyTidList.push_back(pNewState)) {
return NULL;
}
pTIDState = m_MyTidList.back();
hr = S_OK;
Done:
return hr;
}
HRESULT
ActiveConnection::TerminateConnectionsForShare(Share *pShare)
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
ce::list<ce::smart_ptr<TIDState>, SHARE_MANANGER_TID_ALLOC>::iterator it, itEnd;
BOOL fFound = FALSE;
//
// Find our node
// BUGBUG: when we have NT SMB's we can fix this! (when we delete a share we tell
// the connection
for(it = m_MyTidList.begin(), itEnd = m_MyTidList.end(); it != itEnd; ) {
if((*it)->GetShare() == pShare) {
RETAILMSG(1, (L"SMBSRV: Cant delete share because its in use!"));
fFound = TRUE;
++it;
} else {
++it;
}
}
return (TRUE==fFound)?E_FAIL:S_OK;
}
HRESULT
ActiveConnection::UnBindTID(USHORT usTid)
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
ce::list<ce::smart_ptr<TIDState>, SHARE_MANANGER_TID_ALLOC>::iterator it;
ce::list<ce::smart_ptr<TIDState>, SHARE_MANANGER_TID_ALLOC>::iterator itEnd = m_MyTidList.end();
ASSERT(0xFFFF != usTid );
BOOL fFound = FALSE;
//
// Find our node
for(it = m_MyTidList.begin(); it != itEnd; it++) {
if((*it)->TID() == usTid) {
fFound = TRUE;
m_MyTidList.erase(it);
break;
}
}
return (TRUE==fFound)?S_OK:E_FAIL;
}
HRESULT
ActiveConnection::FindTIDState(USHORT usTid, ce::smart_ptr<TIDState> &pTIDState, DWORD dwAccessPerms)
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
ce::list<ce::smart_ptr<TIDState>, SHARE_MANANGER_TID_ALLOC>::iterator it;
ce::list<ce::smart_ptr<TIDState>, SHARE_MANANGER_TID_ALLOC>::iterator itEnd = m_MyTidList.end();
ASSERT(0xFFFF != usTid );
HRESULT hr = E_FAIL;
pTIDState = NULL;
//
// Find our node
for(it = m_MyTidList.begin(); it != itEnd; it++) {
if((*it)->TID() == usTid) {
pTIDState = *it;
break;
}
}
if(pTIDState) {
if((!pTIDState->GetShare()) || (E_ACCESSDENIED == (hr = (pTIDState->GetShare()->AllowUser(UserName(), dwAccessPerms))))) {
TRACEMSG(ZONE_SECURITY, (L"SMB_SRVR: user denied access to share state!"));
pTIDState = NULL;
hr = E_ACCESSDENIED;
}
} else {
TRACEMSG(ZONE_ERROR, (L"SMB_SRVR: someone is going after a TID they dont own! (being hacked?)"));
}
return hr;
}
HRESULT
ActiveConnection::CreateNewFindHandle(const WCHAR *pSearchString, USHORT *pusHandle, BOOL fUnicodeRules)
{
CCritSection csLock(&m_csConnectionLock);
csLock.Lock();
HANDLE hSearch = INVALID_HANDLE_VALUE;
USHORT usHandle = 0xFFFF;
HRESULT hr;
WIN32_FIND_DATA w32FindData;
PREFAST_ASSERT(NULL != pSearchString && NULL != pusHandle);
StringConverter WildSearch;
BOOL fDotsMatch = FALSE;
WCHAR *pSubSearchString = NULL;
//
// Get a handle
if(FAILED(m_UIDFindFirstHandle.GetID(&usHandle))) {
TRACEMSG(ZONE_ERROR, (L"SMB_SRVR: Error getting FindFirstHandle from unique generator!"));
ASSERT(FALSE);
hr = E_FAIL;
goto Done;
}
//
// Convert the search string to proper wildcard format
if(FAILED(hr = ConvertWildCard(pSearchString, &WildSearch, fUnicodeRules))) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -