📄 pc_net_prog.cpp
字号:
DWORD dwRet;
UINT uiDialectIdx = 0;
//make sure they (the client) arent trying to blow our buffers
if(usRemaining > (pRequest->uiDataSize - sizeof(SMB_COM_NEGOTIATE_CLIENT_REQUEST))) {
ASSERT(FALSE);
TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: NEGOTIATE -- invalid sizes from client"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//parse out dialects (NOTE: we only support NTLM 0.12)
while(usRemaining) {
UINT uiStringLen=0;
if(0 == usRemaining || 0x02 != *pDialects) {
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
pDialects++; usRemaining--;
while(uiStringLen <= usRemaining && 0!=pDialects[uiStringLen])
uiStringLen ++;
if(0 != pDialects[uiStringLen]) {
TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: NEGOTIATE -- couldnt find Dialect"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
uiStringLen ++; //null
if(0 == strcmp((char *)pDialects, "NT LM 0.12")) {
fHaveNTLM = TRUE;
uiNTLMIdx = uiDialectIdx;
}
usRemaining -= uiStringLen;
pDialects += uiStringLen;
uiDialectIdx ++;
}
// The ordering of which dialect we choose is important -- chose them in order of
// age (if ever there are more dialects -- right now there we only have
// NTLM 0.12
if(fHaveNTLM && -1 != uiDialectIdx) {
SYSTEMTIME SysTime;
FILETIME FileTime;
SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM *pNegPortion =
(SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM *)pResponse->pDataPortion;
if(NULL == pResponse->pDataPortion || pResponse->uiDataSize < sizeof(SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM)) {
TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: NTLM -- not enough data for dialect"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Get the current time, and convert to FILETIME
GetLocalTime(&SysTime);
if(0 == SystemTimeToFileTime(&SysTime, &FileTime)) {
TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: Cant convert SysTime to Filetime"));
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
pNegPortion->inner.WordCount = (sizeof(SMB_COM_NEGOTIATE_SERVER_RESPONSE)-1)/sizeof(WORD);
pNegPortion->inner.DialectIndex = uiNTLMIdx;
pNegPortion->inner.SecurityMode = 3;//bit 0 = share level security, bit 1 = encrypt passwords
// pNegPortion->inner.SecurityMode = 2;//bit 0 = share level security, bit 1 = encrypt passwords
pNegPortion->inner.MaxMpxCount = 50;
pNegPortion->inner.MaxCountVCs = 1;
pNegPortion->inner.MaxTransmitBufferSize = SMB_Globals::MAX_PACKET_SIZE;
pNegPortion->inner.MaxRawSize = SMB_Globals::MAX_PACKET_SIZE;
pNegPortion->inner.SessionKey = 0;
pNegPortion->inner.Capabilities = 0;
// pNegPortion->inner.Capabilities |= CAP_RAW_MODE;
// pNegPortion->inner.Capabilities |= CAP_MPX_MODE;
pNegPortion->inner.Capabilities |= CAP_NT_FIND;
pNegPortion->inner.Capabilities |= CAP_LARGE_FILES;
pNegPortion->inner.Capabilities |= CAP_NT_SMBS;
pNegPortion->inner.Capabilities |= CAP_UNICODE;
pNegPortion->inner.Capabilities |= CAP_LEVEL_II_OPLOCKS;
pNegPortion->inner.Capabilities |= CAP_STATUS32;
//<--CAP_EXTENDED_SECURITY put in only if they put extended security in their flags2 field
TRACEMSG(ZONE_SMB, (L"SMBSRV--NEGOTIATE Caps set to: 0x%x", pNegPortion->inner.Capabilities));
pNegPortion->inner.SystemTimeLow = FileTime.dwLowDateTime;
pNegPortion->inner.SystemTimeHigh = FileTime.dwHighDateTime;
pNegPortion->inner.ServerTimeZone = (USHORT)GetTimeZoneBias();
pNegPortion->inner.EncryptionKeyLength = 0;
pNegPortion->ByteCount = 0;
//
// LM passwords
if(!(SMB_FLAGS2_EXTENDED_SECURITY & pSMB->pInSMB->Flags2)) {
pNegPortion->inner.EncryptionKeyLength = 8;
if(0 == CeGenRandom(8, pNegPortion->Blob)) {
ASSERT(FALSE);
memset(pNegPortion->Blob, 0, 8);
}
if(FAILED(SMB_Globals::g_pConnectionManager->AddChallenge(pSMB->ulConnectionID, pNegPortion->Blob))) {
ASSERT(FALSE);
}
*puiUsed = sizeof(SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM) - 16 + 8; //remove BLOB and add key
pNegPortion->ByteCount += 8;
} else {
BYTE *pBuffer = pNegPortion->Blob;
pNegPortion->inner.Capabilities |= CAP_EXTENDED_SECURITY;
ASSERT(16 == sizeof(SMB_Globals::g_ServerGUID));
memcpy(pBuffer, SMB_Globals::g_ServerGUID, sizeof(SMB_Globals::g_ServerGUID));
pNegPortion->ByteCount += sizeof(SMB_Globals::g_ServerGUID);
pBuffer += sizeof(SMB_Globals::g_ServerGUID);
*puiUsed = sizeof(SMB_COM_NEGOTIATE_SERVER_RESPONSE_DIALECT_LM) - 16 + 16; //remove BLOB and add GUID
//
// Copy in a security blob
CredHandle hNegSecurityHandle;
TimeStamp ts;
if(SEC_E_OK != AcquireCredentialsHandle(NULL, L"Negotiate", SECPKG_CRED_INBOUND,NULL,NULL,NULL,NULL,&hNegSecurityHandle, &ts)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV-NEGOTITAE: couldnt get cred handle"));
ASSERT(FALSE);
}
ULONG Attributes;
SecBufferDesc OutputToken;
TimeStamp Expiry;
SecBuffer OutputBuffer;
CtxtHandle HandleOut;
OutputToken.pBuffers = &OutputBuffer;
OutputToken.cBuffers = 1;
OutputToken.ulVersion = 0;
OutputBuffer.pvBuffer = 0;
OutputBuffer.cbBuffer = 0;
OutputBuffer.BufferType = SECBUFFER_TOKEN;
if(SEC_I_CONTINUE_NEEDED == AcceptSecurityContext(&hNegSecurityHandle,
NULL,NULL,
ISC_REQ_MUTUAL_AUTH | ISC_REQ_FRAGMENT_TO_FIT | ISC_REQ_ALLOCATE_MEMORY | ASC_REQ_ALLOW_NULL_SESSION,
SECURITY_NATIVE_DREP,
&HandleOut, &OutputToken, &Attributes, &Expiry)) {
memcpy(pBuffer, OutputBuffer.pvBuffer, OutputBuffer.cbBuffer);
pNegPortion->ByteCount += (USHORT)OutputBuffer.cbBuffer;
*puiUsed += OutputBuffer.cbBuffer;
FreeContextBuffer(OutputBuffer.pvBuffer);
DeleteSecurityContext(&HandleOut);
}
FreeCredentialsHandle(&hNegSecurityHandle);
}
}
else {
TRACEMSG(ZONE_SMB, (L"SMBSRV-NEGOTIATE: we dont have any dialects in common"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
dwRet = 0;
Done:
return dwRet;
}
DWORD SMB_TRANS_API_ShareEnum(SMB_PACKET *pSMB,
SMB_PROCESS_CMD *_pRawRequest,
SMB_PROCESS_CMD *_pRawResponse,
UINT *puiUsed,
StringTokenizer &RequestTokenizer)
{
DWORD dwRet;
WORD wLevel;
WORD wRecvBufferSize;
UINT uiNumShares = 0;
CHAR *pAPIParam = NULL;
CHAR *pAPIData = NULL;
ce::smart_ptr<ActiveConnection> pMyConnection = NULL;
SMB_COM_TRANSACTION_CLIENT_REQUEST *pRequest = (SMB_COM_TRANSACTION_CLIENT_REQUEST *)_pRawRequest->pDataPortion;
SMB_COM_TRANSACTION_SERVER_RESPONSE *pResponse = (SMB_COM_TRANSACTION_SERVER_RESPONSE *)_pRawResponse->pDataPortion;
if(FAILED(RequestTokenizer.GetString(&pAPIParam))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_TRANS_API_ShareEnum -- Error fetching apiParams! from params!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
if(FAILED(RequestTokenizer.GetString(&pAPIData))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: SMB_TRANS_API_ShareEnum -- Error fetching smpParams! from params!"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
TRACEMSG(ZONE_SMB, (L"...processing SMB_TRANS_API_ShareEnum"));
//
// Special to ShareEnum are two WORD's -- level and recv buffer size
if(FAILED(RequestTokenizer.GetWORD(&wLevel))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- error getting Level from params on API"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
if(FAILED(RequestTokenizer.GetWORD(&wRecvBufferSize))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- error getting Level from params on API"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Find our connection state
if(!(pMyConnection = SMB_Globals::g_pConnectionManager->FindConnection(pSMB))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum: -- cant find connection 0x%x!", pSMB->ulConnectionID));
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Verify the param/data/level to make sure they are what we expected
if((0 != strcmp("WrLeh", (CHAR *)pAPIParam)) ||
(0 != strcmp("B13BWz", (CHAR *)pAPIData)) ||
(1 != wLevel))
{
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- invalid apiparam for api"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
ASSERT(0 == RequestTokenizer.RemainingSize());
//
// Make sure we have more space than they do
if(wRecvBufferSize > _pRawResponse->uiDataSize) {
wRecvBufferSize = _pRawResponse->uiDataSize - sizeof(SMB_COM_TRANSACTION_SERVER_RESPONSE);
}
{
//make 3 pointers... like this (main body plus params)
//[SMB][TRANS_RESPONSE][[TRANS_PARAM_HEADER][SMB_SHARE_INFO * uiNumVisibleShares][sz-strings]]
// the pointers will point to a PARAM header, the array of SMB_SHARE_INFO's,
// and the other to the sz-strings
RAPIBuilder RAPI((BYTE *)(pResponse+1), wRecvBufferSize, pRequest->MaxParameterCount, pRequest->MaxDataCount);
SMB_RAP_RESPONSE_PARAM_HEADER *pParamHeader;
SMB_SHARE_INFO_1 *pFirstShareInfo = NULL;
UINT uiIdx = 0xFFFFFFFF;
//BUGBUG: when we dont have enough memory we need to report back to the client!
if(FAILED(RAPI.ReserveParams(sizeof(SMB_RAP_RESPONSE_PARAM_HEADER), (BYTE**)&pParamHeader))) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- not enough memory in request"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// We wont be alligned if we dont make a gap
while(0 != ((UINT)RAPI.DataPtr() % sizeof(DWORD)))
RAPI.MakeParamByteGap(1);
//
// Build a RAPI response with our share information
for(UINT i=0; i<SMB_Globals::g_pShareManager->NumShares(); i++) {
SMB_SHARE_INFO_1 *pShareInfo;
Share *pShare = SMB_Globals::g_pShareManager->SearchForShare(i);
HRESULT hr;
if(!pShare || pShare->IsHidden() || FAILED(pShare->AllowUser(pMyConnection->UserName(),SEC_READ)))
continue;
if(uiIdx == 0xFFFFFFFF)
uiNumShares = 1;
else
uiNumShares ++;
const CHAR *pRemark = pShare->GetRemark();
UINT uiRemarkLen = (NULL == pRemark)?1:(strlen(pRemark) + 1);
CHAR *pUnbasedRemark;
//
// Reserve enough memory for our share info
//BUGBUG: report back that we dont have enough memory!!
hr = RAPI.ReserveBlock(sizeof(SMB_SHARE_INFO_1), (BYTE**)&pShareInfo);
if(SUCCEEDED(hr))
hr = RAPI.ReserveFloatBlock(uiRemarkLen, &uiIdx);
if(SUCCEEDED(hr))
hr = RAPI.MapFloatToFixed(uiIdx, (BYTE **)&pUnbasedRemark);
if(FAILED(hr)) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- not enough memory in request"));
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Keep track of the first shareInfo structure
if(NULL == pFirstShareInfo)
pFirstShareInfo = pShareInfo;
//
// Write in the remark
if(uiRemarkLen == 1)
*pUnbasedRemark = (CHAR)0x00;
else
memcpy(pUnbasedRemark, pRemark, uiRemarkLen);
//
// Populate the share blob
UINT uiShareNameLen = strlen(pShare->GetShareNameSZ()) + 1;
pShareInfo->Type = pShare->GetShareType();
pShareInfo->Remark = pUnbasedRemark; //note: this is not rebased yet!! we have to do that after coalesce()
pShareInfo->Pad = 0;
memset(pShareInfo->Netname, 0, sizeof(pShareInfo->Netname));
memcpy(pShareInfo->Netname, pShare->GetShareNameSZ(), uiShareNameLen);
ASSERT(pShareInfo->Type <= 3);
}
//
// Coalesce and rebase pointers
if(FAILED(RAPI.Coalesce())) {
TRACEMSG(ZONE_ERROR, (L"SMBSRV: TRANACT -- SMB_TRANS_API_ShareEnum -- internal error with coalesce()!!"));
ASSERT(FALSE);
dwRet = ERROR_CODE(STATUS_INTERNAL_ERROR);
goto Done;
}
//
// Rebase
if(uiIdx != 0xFFFFFFFF) {
SMB_SHARE_INFO_1 *pShareTemp = pFirstShareInfo;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -