📄 pc_net_prog.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 <bldver.h>
#include <creg.hxx>
#include <winsock.h>
#include "SMB_Globals.h"
#include "PC_NET_PROG.h"
#include "SMBCommands.h"
#include "SMBErrors.h"
#include "ShareInfo.h"
#include "PrintQueue.h"
#include "utils.h"
#include "rapi.h"
#include "security.h"
#include "FileServer.h"
#include "SMBPackets.h"
#include "ConnectionManager.h"
#include "Cracker.h"
#ifdef SMB_NMPIPE
#include "ipcstream.h"
#endif
//
// Forward declarations
DWORD SMB_ReadX_Helper(SMB_PACKET *pSMB,
SMB_PROCESS_CMD *_pRawRequest,
SMB_PROCESS_CMD *_pRawResponse,
UINT *puiUsed,
USHORT MaxCount,
USHORT FID,
ULONG FileOffset);
DWORD SMB_WriteX_Helper(SMB_PACKET *pSMB,
SMB_PROCESS_CMD *_pRawRequest,
SMB_PROCESS_CMD *_pRawResponse,
UINT *puiUsed,
USHORT FID,
ULONG Offset,
ULONG Requested,
BYTE *pData);
HRESULT TCP_TerminateSession(ULONG ulConnectionID);
HRESULT NB_TerminateSession(ULONG ulConnectionID);
BYTE *memmem(const BYTE *src, UINT uiSrcSize, const BYTE *search, UINT uiSearchSize)
{
BYTE *pRet = NULL;
//
// While we have memory keep looking
while(uiSrcSize && NULL != src) {
//
// Find the first character, if it exists see if the
// search is there
BYTE *pTemp = (BYTE *)memchr(src, *search, uiSrcSize);
if(NULL == pTemp) {
goto Done;
}
uiSrcSize -= (pTemp - src);
src = pTemp;
//
// If the buffers are the same for the next uiSearchSize return the ptr
if(0 == memcmp(src, search, uiSearchSize)) {
pRet = (BYTE *)src;
goto Done;
} else {
//
// Advance beyond this character
src ++;
uiSrcSize --;
}
}
Done:
return pRet;
}
LONG
GetTimeZoneBias()
{
TIME_ZONE_INFORMATION TzInfo;
if (GetTimeZoneInformation(&TzInfo) == 0xffffffff) {
TRACEMSG(ZONE_ERROR,(L"SMBSRV: Error in GetTimeZoneInfo: %d",GetLastError()));
return 0;
}
else
return TzInfo.Bias;
}
HRESULT RebasePointer(CHAR **pOldPtr, RAPIBuilder *pBuilder, UINT uiIdx, CHAR *pBasePtr)
{
if(NULL == pOldPtr || NULL == pBuilder || NULL == pBasePtr || 0xFFFFFFFF == uiIdx)
return E_INVALIDARG;
if(NULL == *pOldPtr)
*pOldPtr = NULL;
CHAR *pNewPtr;
HRESULT hr = pBuilder->MapFloatToFixed(uiIdx, (BYTE **)&pNewPtr);
if(FAILED(hr))
goto Done;
*pOldPtr = (CHAR *)(pNewPtr - pBasePtr);
Done:
return hr;
}
//BUGBUG: because the next bug is so important
//BUGBUG: until pTotalUsed isnt defaulting to NULL we prob have mistakes when
// buffer sizes are too small!! must fix this
HRESULT AddStringToFloat(const CHAR *pString, CHAR **pDest, CHAR *pBasePtr, RAPIBuilder *pBuilder, UINT *pTotalUsed = NULL)
{
if(NULL == pDest || NULL == pBuilder)
return E_INVALIDARG;
HRESULT hr;
//do strings first
if(NULL == pString) {
*pDest = NULL;
}
else {
UINT uiSize = strlen(pString)+1;
if(pTotalUsed) {
*pTotalUsed += uiSize;
}
if(FAILED(hr = pBuilder->ReserveFloatBlock(uiSize, pDest, pBasePtr)))
return hr;
memmove(*pDest, pString, uiSize);
}
return S_OK;
}
HRESULT AddStringToFloat(const CHAR *pString, CHAR **pDest, RAPIBuilder *pBuilder, UINT *uiIdx)
{
if(NULL == pDest || NULL == pBuilder || NULL == uiIdx)
return E_INVALIDARG;
HRESULT hr;
//do strings first
if(NULL == pString) {
*pDest = NULL;
*uiIdx = 0xFFFFFFFF;
}
else {
UINT uiSize = strlen(pString)+1;
CHAR *pFloat;
if(FAILED(hr = pBuilder->ReserveFloatBlock(uiSize, uiIdx)))
return hr;
if(FAILED(hr = pBuilder->MapFloatToFixed(*uiIdx, (BYTE **)&pFloat)))
return hr;
memmove(pFloat, pString, uiSize);
*pDest = pFloat;
}
return S_OK;
}
UINT FindLength(BYTE **ppString, UINT *pLenRemaining) {
UINT uiStringLen = 0;
UINT uiRemaining = *pLenRemaining;
BYTE *pString = *ppString;
while(uiStringLen <= uiRemaining && 0!=pString[uiStringLen])
uiStringLen ++;
if(uiStringLen > uiRemaining)
return 0xFFFFFFFF;
else {
*ppString = pString;
*pLenRemaining -= uiStringLen;
ASSERT(*pLenRemaining >= 0);
return uiStringLen;
}
}
DWORD SMB_Com_Session_Setup_ANDX_LM(SMB_PACKET *pSMB,
SMB_PROCESS_CMD *pRequest,
SMB_PROCESS_CMD *pResponse,
UINT *puiUsed)
{
DWORD dwRet = 0;
SMB_COM_SESSION_SETUP_REQUEST_NTLM *pSessionRequest =
(SMB_COM_SESSION_SETUP_REQUEST_NTLM *)pRequest->pDataPortion;
SMB_COM_SESSION_SETUP_RESPONSE_NTLM *pSessionResponse =
(SMB_COM_SESSION_SETUP_RESPONSE_NTLM *)pResponse->pDataPortion;
UINT uiLeftInRequest = 0;
BYTE *pEndOfRequest = NULL;
BOOL fIsGuest = TRUE;
BYTE *pNativeOS = NULL;
BYTE *pNativeLanman = NULL;
ce::smart_ptr<ActiveConnection> pMyConnection = NULL;
StringTokenizer SecurityTokens;
//
// Verify that we have enough data to satisfy requests
if(pRequest->uiDataSize <= sizeof(SMB_COM_SESSION_SETUP_REQUEST_NTLM)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-COM_SESSION_SETUP_ANDX -- requst too large!!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
if(pResponse->uiDataSize <= sizeof(SMB_COM_SESSION_SETUP_RESPONSE_NTLM)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-COM_SESSION_SETUP_ANDX -- response too large!!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
uiLeftInRequest = pRequest->uiDataSize - sizeof(SMB_COM_SESSION_SETUP_REQUEST_NTLM);
pEndOfRequest = (BYTE *)(pSessionRequest+1);
//
// Find our connection state
pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB);
if(!pMyConnection) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: COM_SESSION_SETUP_ANDX: -- cant find connection 0x%x!", pSMB->ulConnectionID));
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Put in any capabilities they support/want
if(0 != (pSMB->pInSMB->Flags2 & SMB_FLAGS2_UNICODE)) {
pMyConnection->SetUnicode(TRUE);
}
//
// Clean up the response
memset(pSessionResponse, 0, sizeof(SMB_COM_SESSION_SETUP_RESPONSE_NTLM));
if(13 == pSessionRequest->ANDX.WordCount) {
BYTE *pInsensitivePass = NULL;
BYTE *pSensitivePass = NULL;
// At the end we will find the security information
SecurityTokens.Reset(pEndOfRequest, pRequest->uiDataSize-sizeof(SMB_COM_SESSION_SETUP_REQUEST_NTLM));
if(FAILED(SecurityTokens.GetByteArray(&pInsensitivePass,
pSessionRequest->CaseInsensitivePasswordLength))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: COM_SESSION_SETUP_ANDX: -- error getting insensitive password!"));
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
if(FAILED(SecurityTokens.GetByteArray(&pSensitivePass,
pSessionRequest->CaseSensitivePasswordLength))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: COM_SESSION_SETUP_ANDX: -- error getting sensitive password!"));
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Handle user name
if(TRUE == pMyConnection->SupportsUnicode(pSMB->pInSMB)) {
WCHAR *pUserName = NULL;
UINT uiNameLen;
if(FAILED(SecurityTokens.GetUnicodeString(&pUserName, &uiNameLen))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: COM_SESSION_SETUP_ANDX: -- error getting username!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
if(FAILED(pMyConnection->SetUserName(pUserName))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: COM_SESSION_SETUP_ANDX: -- error setting username!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
} else {
CHAR *pUserName = NULL;
UINT uiNameLen;
if(FAILED(SecurityTokens.GetString(&pUserName, &uiNameLen))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: COM_SESSION_SETUP_ANDX: -- error getting username!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
if(uiNameLen >1 && FAILED(pMyConnection->SetUserName(StringConverter(pUserName).GetString()))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: COM_SESSION_SETUP_ANDX: -- error setting username!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
}
//
// See if they put in a password here
if(0 != pSessionRequest->CaseInsensitivePasswordLength) {
BYTE *pPassword = (BYTE *)(pSessionRequest + 1);
if(pResponse->uiDataSize <= sizeof(SMB_COM_SESSION_SETUP_RESPONSE_NTLM)+pSessionRequest->CaseInsensitivePasswordLength) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-COM_SESSION_SETUP_ANDX -- response too large!!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
if(TRUE == VerifyPassword(pMyConnection, pPassword, pSessionRequest->CaseInsensitivePasswordLength)) {
TRACEMSG(ZONE_SECURITY, (L"SMBSRV COM_SESSION_SETUP_ANDX: access granted"));
pMyConnection->SetGuest(FALSE);
} else {
CReg RegAllowAll;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -