static NTSTATUS RdrTransceiveTreeConnect( PRDR_OP_CONTEXT pContext, PRDR_TREE pTree, PCWSTR pwszPath ) { NTSTATUS status = 0; uint32_t packetByteCount = 0; TREE_CONNECT_REQUEST_HEADER *pHeader = NULL; status = RdrAllocateContextPacket( pContext, 1024*64); BAIL_ON_NT_STATUS(status); status = SMBPacketMarshallHeader( pContext->Packet.pRawBuffer, pContext->Packet.bufferLen, COM_TREE_CONNECT_ANDX, 0, 0, 0, gRdrRuntime.SysPid, pTree->pSession->uid, 0, TRUE, &pContext->Packet); BAIL_ON_NT_STATUS(status); pContext->Packet.pData = pContext->Packet.pParams + sizeof(TREE_CONNECT_REQUEST_HEADER); pContext->Packet.bufferUsed += sizeof(TREE_CONNECT_REQUEST_HEADER); /* If most commands have word counts which are easy to compute, this should be folded into a parameter to SMBPacketMarshallHeader() */ pContext->Packet.pSMBHeader->wordCount = 4; pHeader = (TREE_CONNECT_REQUEST_HEADER *) pContext->Packet.pParams; pHeader->flags = SMB_HTOL16(0x8); /* FIXME: magic number */ pHeader->passwordLength = SMB_HTOL16(1); /* strlen("") + terminating NULL */ status = MarshallTreeConnectRequestData( pContext->Packet.pData, pContext->Packet.bufferLen - pContext->Packet.bufferUsed, (pContext->Packet.pData - (uint8_t *) pContext->Packet.pSMBHeader) % 2, &packetByteCount, pwszPath, "?????"); BAIL_ON_NT_STATUS(status); assert(packetByteCount <= UINT16_MAX); pHeader->byteCount = SMB_HTOL16((uint16_t) packetByteCount); pContext->Packet.bufferUsed += packetByteCount; status = SMBPacketMarshallFooter(&pContext->Packet); BAIL_ON_NT_STATUS(status); status = RdrSocketTransceive(pTree->pSession->pSocket, pContext); BAIL_ON_NT_STATUS(status); cleanup: return status; error: goto cleanup; }
static NTSTATUS RdrTransceiveSessionSetup( PRDR_OP_CONTEXT pContext, PRDR_SESSION pSession, PBYTE pBlob, DWORD dwBlobLength ) { NTSTATUS status = 0; uint32_t packetByteCount = 0; WCHAR nativeOS[] = {'U','n','i','x','\0'}; WCHAR nativeLanMan[] = {'L','i','k','e','w','i','s','e',' ','C','I','F','S','\0'}; WCHAR nativeDomain[] = {'W','O','R','K','G','R','O','U','P','\0'}; SESSION_SETUP_REQUEST_HEADER_WC_12 *pHeader = NULL; PRDR_SOCKET pSocket = pSession->pSocket; status = RdrAllocateContextPacket(pContext, 1024*64); BAIL_ON_NT_STATUS(status); status = SMBPacketMarshallHeader( pContext->Packet.pRawBuffer, pContext->Packet.bufferLen, COM_SESSION_SETUP_ANDX, 0, 0, 0xFFFF, gRdrRuntime.SysPid, pSession->uid, 0, TRUE, &pContext->Packet); BAIL_ON_NT_STATUS(status); pContext->Packet.pData = pContext->Packet.pParams + sizeof(SESSION_SETUP_REQUEST_HEADER_WC_12); pContext->Packet.bufferUsed += sizeof(SESSION_SETUP_REQUEST_HEADER_WC_12); pContext->Packet.pSMBHeader->wordCount = 12; pHeader = (SESSION_SETUP_REQUEST_HEADER_WC_12 *) pContext->Packet.pParams; pHeader->maxBufferSize = 12288; pHeader->maxMpxCount = 50; pHeader->vcNumber = 1; pHeader->sessionKey = pSocket->sessionKey; pHeader->securityBlobLength = 0; pHeader->reserved = 0; pHeader->capabilities = CAP_UNICODE | CAP_NT_SMBS | CAP_STATUS32 | CAP_EXTENDED_SECURITY; pHeader->securityBlobLength = dwBlobLength; status = MarshallSessionSetupRequestData( pContext->Packet.pData, pContext->Packet.bufferLen - pContext->Packet.bufferUsed, (pContext->Packet.pData - (uint8_t *) pContext->Packet.pSMBHeader) % 2, &packetByteCount, pBlob, dwBlobLength, nativeOS, nativeLanMan, nativeDomain); BAIL_ON_NT_STATUS(status); assert(packetByteCount <= UINT16_MAX); pHeader->byteCount = (uint16_t) packetByteCount; pContext->Packet.bufferUsed += packetByteCount; // byte order conversions SMB_HTOL16_INPLACE(pHeader->maxBufferSize); SMB_HTOL16_INPLACE(pHeader->maxMpxCount); SMB_HTOL16_INPLACE(pHeader->vcNumber); SMB_HTOL32_INPLACE(pHeader->sessionKey); SMB_HTOL16_INPLACE(pHeader->securityBlobLength); //SMB_HTOL32_INPLACE(pHeader->reserved); SMB_HTOL32_INPLACE(pHeader->capabilities); SMB_HTOL16_INPLACE(pHeader->byteCount); status = SMBPacketMarshallFooter(&pContext->Packet); BAIL_ON_NT_STATUS(status); status = RdrSocketTransceive(pSocket, pContext); BAIL_ON_NT_STATUS(status); cleanup: return status; error: goto cleanup; }
NTSTATUS SrvBuildNegotiateResponse_SMB_V1_NTLM_0_12( IN PLWIO_SRV_CONNECTION pConnection, IN PSMB_PACKET pSmbRequest, IN SMB_PROTOCOL_DIALECT Dialect, IN USHORT idxDialect, OUT PSMB_PACKET* ppSmbResponse ) { NTSTATUS ntStatus = 0; NEGOTIATE_RESPONSE_HEADER* pResponseHeader = NULL; time_t curTime = 0L; LONG64 llUTCTime = 0LL; uint16_t byteCount = 0; uint8_t* pDataCursor = NULL; PSRV_PROPERTIES pServerProperties = &pConnection->serverProperties; PSMB_PACKET pSmbResponse = NULL; PWSTR pwszHostname = NULL; ntStatus = SMBPacketAllocate( pConnection->hPacketAllocator, &pSmbResponse); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SMBPacketBufferAllocate( pConnection->hPacketAllocator, (64 * 1024) + 4096, &pSmbResponse->pRawBuffer, &pSmbResponse->bufferLen); BAIL_ON_NT_STATUS(ntStatus); if ((pSmbRequest->pSMBHeader->flags2 & FLAG2_EXT_SEC) == 0) { pServerProperties->Capabilities &= ~CAP_EXTENDED_SECURITY; } ntStatus = SMBPacketMarshallHeader( pSmbResponse->pRawBuffer, pSmbResponse->bufferLen, COM_NEGOTIATE, 0, TRUE, pSmbRequest->pSMBHeader->tid, SMB_V1_GET_PROCESS_ID(pSmbRequest->pSMBHeader), 0, pSmbRequest->pSMBHeader->mid, FALSE, pSmbResponse); BAIL_ON_NT_STATUS(ntStatus); if ((pServerProperties->Capabilities & CAP_EXTENDED_SECURITY) == 0) { pSmbResponse->pSMBHeader->flags2 &= ~FLAG2_EXT_SEC; } pSmbResponse->pSMBHeader->wordCount = 17; pResponseHeader = (NEGOTIATE_RESPONSE_HEADER*)pSmbResponse->pParams; pSmbResponse->pData = pSmbResponse->pParams + sizeof(NEGOTIATE_RESPONSE_HEADER); pSmbResponse->bufferUsed += sizeof(NEGOTIATE_RESPONSE_HEADER); pResponseHeader->dialectIndex = idxDialect; pResponseHeader->securityMode = 0; if (pServerProperties->preferredSecurityMode == SMB_SECURITY_MODE_USER) { pResponseHeader->securityMode |= 0x1; // User level security } if (pServerProperties->bEncryptPasswords) { pResponseHeader->securityMode |= 0x2; } if (pServerProperties->bEnableSecuritySignatures) { pResponseHeader->securityMode |= 0x4; } if (pServerProperties->bRequireSecuritySignatures) { pResponseHeader->securityMode |= 0x8; } pResponseHeader->maxMpxCount = pServerProperties->MaxMpxCount; pResponseHeader->maxNumberVcs = pServerProperties->MaxNumberVCs; pResponseHeader->maxBufferSize = pServerProperties->MaxBufferSize; pResponseHeader->maxRawSize = pServerProperties->MaxRawSize; pResponseHeader->sessionKey = 0; pResponseHeader->capabilities = pServerProperties->Capabilities; curTime = time(NULL); ntStatus = WireSMBUTimeToTimeZone(curTime, &pResponseHeader->serverTimeZone); BAIL_ON_NT_STATUS(ntStatus); ntStatus = WireSMBUTimetoNTTime(curTime, FALSE, &llUTCTime); BAIL_ON_NT_STATUS(ntStatus); pResponseHeader->systemTimeLow = llUTCTime & 0xFFFFFFFFLL; pResponseHeader->systemTimeHigh = (llUTCTime & 0xFFFFFFFF00000000LL) >> 32; pDataCursor = pSmbResponse->pData; if (pResponseHeader->capabilities & CAP_EXTENDED_SECURITY) { PBYTE pNegHintsBlob = NULL; /* Do not free */ ULONG ulNegHintsLength = 0; pResponseHeader->encryptionKeyLength = 0; memcpy(pDataCursor, pServerProperties->GUID, sizeof(pServerProperties->GUID)); pDataCursor += sizeof(pServerProperties->GUID); byteCount += sizeof(pServerProperties->GUID); ntStatus = SrvGssNegHints(&pNegHintsBlob, &ulNegHintsLength); /* Microsoft clients ignore the security blob on the neg prot response so don't fail here if we can't get a negHintsBlob */ if (ntStatus == STATUS_SUCCESS) { memcpy(pDataCursor, pNegHintsBlob, ulNegHintsLength); pDataCursor += ulNegHintsLength; byteCount += ulNegHintsLength; } } else { WCHAR wszWorkgroup[] = SRV_NATIVE_DOMAIN_W; CHAR szHostname[HOST_NAME_MAX]; PWSTR pwszDomain = pConnection->clientProperties.pwszNativeDomain; if (!pwszDomain) { pwszDomain = &wszWorkgroup[0]; } if (gethostname(szHostname, HOST_NAME_MAX) == -1) { ntStatus = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(ntStatus); } pResponseHeader->encryptionKeyLength = sizeof(pConnection->ServerChallenge); // Generate challenge and remember it in connection if (!RAND_bytes( pConnection->ServerChallenge, sizeof(pConnection->ServerChallenge))) { ntStatus = STATUS_INTERNAL_ERROR; BAIL_ON_NT_STATUS(ntStatus); } RtlCopyMemory(pDataCursor, &pConnection->ServerChallenge, sizeof(pConnection->ServerChallenge)); pDataCursor += sizeof(pConnection->ServerChallenge); byteCount += sizeof(pConnection->ServerChallenge); // Add domain name { size_t sDomainLen = (wc16slen(pwszDomain)+1) * sizeof(wchar16_t); RtlCopyMemory(pDataCursor, pwszDomain, sDomainLen); pDataCursor += sDomainLen; byteCount += sDomainLen; } // Add hostname { size_t sHostnameLen = 0; ntStatus = SrvMbsToWc16s(szHostname, &pwszHostname); BAIL_ON_NT_STATUS(ntStatus); sHostnameLen = (wc16slen(pwszHostname)+1) * sizeof(wchar16_t); RtlCopyMemory(pDataCursor, pwszHostname, sHostnameLen); pDataCursor += sHostnameLen; byteCount += sHostnameLen; } } pResponseHeader->byteCount = byteCount; pSmbResponse->bufferUsed += byteCount; ntStatus = SMBPacketMarshallFooter(pSmbResponse); BAIL_ON_NT_STATUS(ntStatus); *ppSmbResponse = pSmbResponse; cleanup: SRV_SAFE_FREE_MEMORY(pwszHostname); return ntStatus; error: *ppSmbResponse = NULL; if (pSmbResponse) { SMBPacketRelease(pConnection->hPacketAllocator, pSmbResponse); } goto cleanup; }
static NTSTATUS RdrTransceiveNegotiate( PRDR_OP_CONTEXT pContext, PRDR_SOCKET pSocket ) { NTSTATUS status = STATUS_SUCCESS; PNEGOTIATE_REQUEST_HEADER pRequestHeader = NULL; uint32_t packetByteCount = 0; BYTE const* pszDialects[2] = {NULL, NULL}; ULONG ulDialectCount = 0; pszDialects[ulDialectCount++] = (BYTE const*) "NT LM 0.12"; if (gRdrRuntime.config.bSmb2Enabled) { pszDialects[ulDialectCount++] = (BYTE const*) "SMB 2.002"; } status = RdrAllocateContextPacket(pContext, 1024*64); BAIL_ON_NT_STATUS(status); status = SMBPacketMarshallHeader( pContext->Packet.pRawBuffer, pContext->Packet.bufferLen, COM_NEGOTIATE, 0, /* error */ 0, /* is response */ 0xFFFF, /* tid */ gRdrRuntime.SysPid, /* pid */ 0, /* uid */ 0, /* mid */ FALSE, /* sign messages */ &pContext->Packet); BAIL_ON_NT_STATUS(status); pContext->Packet.pData = pContext->Packet.pParams + sizeof(NEGOTIATE_REQUEST_HEADER); pContext->Packet.bufferUsed += sizeof(NEGOTIATE_REQUEST_HEADER); pContext->Packet.pSMBHeader->wordCount = 0; /* No parameter words */ pRequestHeader = (PNEGOTIATE_REQUEST_HEADER)pContext->Packet.pParams; status = MarshallNegotiateRequest( pContext->Packet.pData, pContext->Packet.bufferLen - pContext->Packet.bufferUsed, &packetByteCount, pszDialects, ulDialectCount); BAIL_ON_NT_STATUS(status); assert(packetByteCount <= UINT16_MAX); pRequestHeader->byteCount = (uint16_t) packetByteCount; pContext->Packet.bufferUsed += packetByteCount; // byte order conversions SMB_HTOL16_INPLACE(pRequestHeader->byteCount); status = SMBPacketMarshallFooter(&pContext->Packet); BAIL_ON_NT_STATUS(status); status = RdrSocketTransceive(pSocket, pContext); BAIL_ON_NT_STATUS(status); cleanup: return status; error: goto cleanup; }
NTSTATUS SrvBuildNegotiateResponse_SMB_V1_Invalid( PLWIO_SRV_CONNECTION pConnection, PSMB_PACKET pSmbRequest, PSMB_PACKET* ppSmbResponse ) { NTSTATUS ntStatus = 0; NEGOTIATE_INVALID_RESPONSE_HEADER* pResponseHeader = NULL; PSMB_PACKET pSmbResponse = NULL; ntStatus = SMBPacketAllocate( pConnection->hPacketAllocator, &pSmbResponse); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SMBPacketBufferAllocate( pConnection->hPacketAllocator, (64 * 1024) + 4096, &pSmbResponse->pRawBuffer, &pSmbResponse->bufferLen); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SMBPacketMarshallHeader( pSmbResponse->pRawBuffer, pSmbResponse->bufferLen, COM_NEGOTIATE, 0, TRUE, 0, pSmbRequest->pSMBHeader->tid, 0, 0, FALSE, pSmbResponse); BAIL_ON_NT_STATUS(ntStatus); if ((pConnection->serverProperties.Capabilities & CAP_EXTENDED_SECURITY) == 0) { pSmbResponse->pSMBHeader->flags2 &= ~FLAG2_EXT_SEC; } pSmbResponse->pSMBHeader->wordCount = 1; pResponseHeader = (NEGOTIATE_INVALID_RESPONSE_HEADER*)pSmbResponse->pParams; pSmbResponse->pData = pSmbResponse->pParams + sizeof(NEGOTIATE_INVALID_RESPONSE_HEADER); pSmbResponse->bufferUsed += sizeof(NEGOTIATE_INVALID_RESPONSE_HEADER); pResponseHeader->dialectIndex = 0xFF; pResponseHeader->byteCount = 0; ntStatus = SMBPacketMarshallFooter(pSmbResponse); BAIL_ON_NT_STATUS(ntStatus); *ppSmbResponse = pSmbResponse; cleanup: return ntStatus; error: *ppSmbResponse = NULL; if (pSmbResponse) { SMBPacketRelease(pConnection->hPacketAllocator, pSmbResponse); } goto cleanup; }
static NTSTATUS SrvNotifyBuildExecContext( PSRV_CHANGE_NOTIFY_STATE_SMB_V1 pNotifyState, PSRV_EXEC_CONTEXT* ppExecContext ) { NTSTATUS ntStatus = STATUS_SUCCESS; PSRV_EXEC_CONTEXT pExecContext = NULL; PSMB_PACKET pSmbRequest = NULL; PBYTE pParams = NULL; ULONG ulParamLength = 0; PBYTE pData = NULL; ULONG ulDataLen = 0; ULONG ulDataOffset = 0; PBYTE pBuffer = NULL; ULONG ulBytesAvailable = 0; ULONG ulOffset = 0; USHORT usBytesUsed = 0; USHORT usTotalBytesUsed = 0; PSMB_HEADER pHeader = NULL; // Do not free PBYTE pWordCount = NULL; // Do not free PANDX_HEADER pAndXHeader = NULL; // Do not free PUSHORT pSetup = NULL; UCHAR ucSetupCount = 0; ULONG ulParameterOffset = 0; ULONG ulNumPackageBytesUsed = 0; SMB_NOTIFY_CHANGE_HEADER notifyRequestHeader = {0}; ntStatus = SMBPacketAllocate( pNotifyState->pConnection->hPacketAllocator, &pSmbRequest); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SMBPacketBufferAllocate( pNotifyState->pConnection->hPacketAllocator, (64 * 1024) + 4096, &pSmbRequest->pRawBuffer, &pSmbRequest->bufferLen); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvInitPacket_SMB_V1(pSmbRequest, TRUE); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvBuildExecContext( pNotifyState->pConnection, pSmbRequest, TRUE, &pExecContext); BAIL_ON_NT_STATUS(ntStatus); pSmbRequest->sequence = pNotifyState->ulRequestSequence; pBuffer = pSmbRequest->pRawBuffer; ulBytesAvailable = pSmbRequest->bufferLen; if (ulBytesAvailable < sizeof(NETBIOS_HEADER)) { ntStatus = STATUS_INVALID_NETWORK_RESPONSE; BAIL_ON_NT_STATUS(ntStatus); } pBuffer += sizeof(NETBIOS_HEADER); ulBytesAvailable -= sizeof(NETBIOS_HEADER); ntStatus = SrvMarshalHeader_SMB_V1( pBuffer, ulOffset, ulBytesAvailable, COM_NT_TRANSACT, pNotifyState->ioStatusBlock.Status, FALSE, /* not a response */ pNotifyState->usTid, pNotifyState->ulPid, pNotifyState->usUid, pNotifyState->usMid, pNotifyState->pConnection->serverProperties.bRequireSecuritySignatures, &pHeader, &pWordCount, &pAndXHeader, &usBytesUsed); BAIL_ON_NT_STATUS(ntStatus); pBuffer += usBytesUsed; ulOffset += usBytesUsed; ulBytesAvailable -= usBytesUsed; usTotalBytesUsed += usBytesUsed; notifyRequestHeader.usFid = pNotifyState->usFid; pSetup = (PUSHORT)¬ifyRequestHeader; ucSetupCount = sizeof(notifyRequestHeader)/sizeof(USHORT); *pWordCount = 18 + ucSetupCount; ntStatus = WireMarshallNtTransactionRequest( pBuffer, ulBytesAvailable, ulOffset, SMB_SUB_COMMAND_NT_TRANSACT_NOTIFY_CHANGE, pSetup, ucSetupCount, pParams, ulParamLength, pData, ulDataLen, &ulDataOffset, &ulParameterOffset, &ulNumPackageBytesUsed); BAIL_ON_NT_STATUS(ntStatus); // pBuffer += ulNumPackageBytesUsed; // ulOffset += ulNumPackageBytesUsed; // ulBytesAvailable -= ulNumPackageBytesUsed; usTotalBytesUsed += ulNumPackageBytesUsed; pSmbRequest->bufferUsed += usTotalBytesUsed; ntStatus = SMBPacketMarshallFooter(pSmbRequest); BAIL_ON_NT_STATUS(ntStatus); *ppExecContext = pExecContext; cleanup: if (pSmbRequest) { SMBPacketRelease( pNotifyState->pConnection->hPacketAllocator, pSmbRequest); } return ntStatus; error: *ppExecContext = NULL; if (pExecContext) { SrvReleaseExecContext(pExecContext); } goto cleanup; }
static NTSTATUS RdrTranscieveRenameFile( PRDR_OP_CONTEXT pContext, PRDR_TREE pTree, USHORT usSearchAttributes, PCWSTR pwszSourceFile, PCWSTR pwszDestFile ) { NTSTATUS status = STATUS_SUCCESS; PSMB_RENAME_REQUEST_HEADER pHeader = NULL; PBYTE pCursor = NULL; ULONG ulSourceFileLength = 0; ULONG ulDestFileLength = 0; status = RdrAllocateContextPacket(pContext, 1024*64); BAIL_ON_NT_STATUS(status); status = SMBPacketMarshallHeader( pContext->Packet.pRawBuffer, pContext->Packet.bufferLen, COM_RENAME, 0, 0, pTree->tid, gRdrRuntime.SysPid, pTree->pSession->uid, 0, TRUE, &pContext->Packet); BAIL_ON_NT_STATUS(status); if (pTree->usSupportFlags & SMB_SHARE_IS_IN_DFS) { pContext->Packet.pSMBHeader->flags2 |= FLAG2_DFS; } pContext->Packet.pData = pContext->Packet.pParams + sizeof(SMB_RENAME_REQUEST_HEADER); pContext->Packet.bufferUsed += sizeof(SMB_RENAME_REQUEST_HEADER); pContext->Packet.pSMBHeader->wordCount = 1; pHeader = (PSMB_RENAME_REQUEST_HEADER) pContext->Packet.pParams; pHeader->usSearchAttributes = usSearchAttributes; pCursor = pContext->Packet.pData; ulSourceFileLength = LwRtlWC16StringNumChars(pwszSourceFile); ulDestFileLength = LwRtlWC16StringNumChars(pwszDestFile); /* Old filename format */ *(pCursor++) = 0x04; pContext->Packet.bufferUsed += 1; /* Align old filename */ if ((pCursor - (PBYTE) pContext->Packet.pSMBHeader) % 2) { pCursor++; pContext->Packet.bufferUsed++; } /* Write old filename */ SMB_HTOLWSTR(pCursor, pwszSourceFile, ulSourceFileLength); pCursor += (ulSourceFileLength + 1) * sizeof(WCHAR); pContext->Packet.bufferUsed += (ulSourceFileLength + 1) * sizeof(WCHAR); /* New filename format */ *(pCursor++) = 0x04; pContext->Packet.bufferUsed += 1; /* Align new filename */ if ((pCursor - (PBYTE) pContext->Packet.pSMBHeader) % 2) { pCursor++; pContext->Packet.bufferUsed++; } /* Write new filename */ SMB_HTOLWSTR(pCursor, pwszDestFile, ulDestFileLength); pCursor += (ulDestFileLength + 1) * sizeof(WCHAR); pContext->Packet.bufferUsed += (ulDestFileLength + 1) * sizeof(WCHAR); pHeader->usByteCount = (USHORT) (pCursor - pContext->Packet.pData); status = SMBPacketMarshallFooter(&pContext->Packet); BAIL_ON_NT_STATUS(status); status = RdrSocketTransceive(pTree->pSession->pSocket, pContext); BAIL_ON_NT_STATUS(status); cleanup: return status; error: goto cleanup; }
static NTSTATUS RdrTransceiveSetPathInfo( PRDR_OP_CONTEXT pContext, PRDR_CCB pFile, SMB_INFO_LEVEL infoLevel, PVOID pInfo, ULONG ulInfoLength ) { NTSTATUS status = STATUS_SUCCESS; TRANSACTION_REQUEST_HEADER *pHeader = NULL; USHORT usSetup = SMB_SUB_COMMAND_TRANS2_SET_PATH_INFORMATION; SMB_SET_PATH_INFO_HEADER setHeader = {0}; PBYTE pRequestParameters = NULL; PBYTE pRequestData = NULL; USHORT usRequestDataCount = 0; PBYTE pCursor = NULL; ULONG ulRemainingSpace = 0; PBYTE pByteCount = NULL; PWSTR pwszPath = infoLevel != SMB_SET_FILE_RENAME_INFO ? RDR_CCB_PATH(pFile) : pFile->pwszPath; PBYTE pFileName = NULL; status = RdrAllocateContextPacket(pContext, 1024*64); BAIL_ON_NT_STATUS(status); status = SMBPacketMarshallHeader( pContext->Packet.pRawBuffer, pContext->Packet.bufferLen, COM_TRANSACTION2, 0, 0, pFile->pTree->tid, gRdrRuntime.SysPid, pFile->pTree->pSession->uid, 0, TRUE, &pContext->Packet); BAIL_ON_NT_STATUS(status); /* Don't use DFS paths for FILE_RENAME_INFO -- it doesn't work */ if (RDR_CCB_IS_DFS(pFile) && infoLevel != SMB_SET_FILE_RENAME_INFO) { pContext->Packet.pSMBHeader->flags2 |= FLAG2_DFS; } pContext->Packet.pData = pContext->Packet.pParams + sizeof(TRANSACTION_REQUEST_HEADER); pCursor = pContext->Packet.pParams; ulRemainingSpace = pContext->Packet.bufferLen - (pCursor - pContext->Packet.pRawBuffer); status = WireMarshalTrans2RequestSetup( pContext->Packet.pSMBHeader, &pCursor, &ulRemainingSpace, &usSetup, 1, &pHeader, &pByteCount); BAIL_ON_NT_STATUS(status); pRequestParameters = pCursor; setHeader.infoLevel = SMB_HTOL16(infoLevel); setHeader.reserved = 0; status = MarshalData(&pCursor, &ulRemainingSpace, (PBYTE) &setHeader, sizeof(setHeader)); BAIL_ON_NT_STATUS(status); status = Align((PBYTE) pContext->Packet.pSMBHeader, &pCursor, &ulRemainingSpace, sizeof(WCHAR)); BAIL_ON_NT_STATUS(status); pFileName = pCursor; status = Advance(&pCursor, &ulRemainingSpace, (LwRtlWC16StringNumChars(pwszPath) + 1) * sizeof(WCHAR)); BAIL_ON_NT_STATUS(status); SMB_HTOLWSTR( pFileName, pwszPath, LwRtlWC16StringNumChars(pwszPath) + 1); pRequestData = pCursor; status = RdrMarshalFileInfo( pContext->Packet.pSMBHeader, &pCursor, &ulRemainingSpace, infoLevel, pInfo, ulInfoLength); BAIL_ON_NT_STATUS(status); usRequestDataCount = pCursor - pRequestData; pHeader->totalParameterCount = SMB_HTOL16(pRequestData - pRequestParameters); pHeader->totalDataCount = SMB_HTOL16(usRequestDataCount); pHeader->maxParameterCount = SMB_HTOL16(sizeof(setHeader)); pHeader->maxDataCount = SMB_HTOL16(0); pHeader->maxSetupCount = SMB_HTOL16(0); pHeader->flags = SMB_HTOL16(0); pHeader->timeout = SMB_HTOL16(0); pHeader->parameterCount = SMB_HTOL16(pRequestData - pRequestParameters); pHeader->parameterOffset = SMB_HTOL16(pRequestParameters - (PBYTE) pContext->Packet.pSMBHeader); pHeader->dataCount = SMB_HTOL16(usRequestDataCount); pHeader->dataOffset = SMB_HTOL16(pRequestData - (PBYTE) pContext->Packet.pSMBHeader); pHeader->setupCount = SMB_HTOL8(1); /* Update byte count */ status = MarshalUshort(&pByteCount, NULL, (pCursor - pByteCount) - 2); /* Update used length */ pContext->Packet.bufferUsed += (pCursor - pContext->Packet.pParams); status = SMBPacketMarshallFooter(&pContext->Packet); BAIL_ON_NT_STATUS(status); status = RdrSocketTransceive(pFile->pTree->pSession->pSocket, pContext); BAIL_ON_NT_STATUS(status); cleanup: return status; error: goto cleanup; }
static NTSTATUS RdrTransceiveSetFileInfo( PRDR_OP_CONTEXT pContext, PRDR_CCB pFile, SMB_INFO_LEVEL infoLevel, PVOID pInfo, ULONG ulInfoLength ) { NTSTATUS status = STATUS_SUCCESS; TRANSACTION_REQUEST_HEADER *pHeader = NULL; USHORT usSetup = SMB_SUB_COMMAND_TRANS2_SET_FILE_INFORMATION; SMB_SET_FILE_INFO_HEADER setHeader = {0}; PBYTE pRequestParameters = NULL; PBYTE pRequestData = NULL; USHORT usRequestDataCount = 0; PBYTE pCursor = NULL; ULONG ulRemainingSpace = 0; PBYTE pByteCount = NULL; status = RdrAllocateContextPacket(pContext, 1024*64); BAIL_ON_NT_STATUS(status); status = SMBPacketMarshallHeader( pContext->Packet.pRawBuffer, pContext->Packet.bufferLen, COM_TRANSACTION2, 0, 0, pFile->pTree->tid, gRdrRuntime.SysPid, pFile->pTree->pSession->uid, 0, TRUE, &pContext->Packet); BAIL_ON_NT_STATUS(status); pContext->Packet.pData = pContext->Packet.pParams + sizeof(TRANSACTION_REQUEST_HEADER); pCursor = pContext->Packet.pParams; ulRemainingSpace = pContext->Packet.bufferLen - (pCursor - pContext->Packet.pRawBuffer); status = WireMarshalTrans2RequestSetup( pContext->Packet.pSMBHeader, &pCursor, &ulRemainingSpace, &usSetup, 1, &pHeader, &pByteCount); BAIL_ON_NT_STATUS(status); pRequestParameters = pCursor; setHeader.usFid = pFile->fid; setHeader.infoLevel = infoLevel; status = MarshalData(&pCursor, &ulRemainingSpace, (PBYTE) &setHeader, sizeof(setHeader)); BAIL_ON_NT_STATUS(status); pRequestData = pCursor; status = RdrMarshalFileInfo( pContext->Packet.pSMBHeader, &pCursor, &ulRemainingSpace, infoLevel, pInfo, ulInfoLength); BAIL_ON_NT_STATUS(status); usRequestDataCount = pCursor - pRequestData; pHeader->totalParameterCount = SMB_HTOL16(sizeof(setHeader)); pHeader->totalDataCount = SMB_HTOL16(usRequestDataCount); pHeader->maxParameterCount = SMB_HTOL16(sizeof(setHeader)); pHeader->maxDataCount = SMB_HTOL16(0); pHeader->maxSetupCount = SMB_HTOL16(0); pHeader->flags = SMB_HTOL16(0); pHeader->timeout = SMB_HTOL16(0); pHeader->parameterCount = SMB_HTOL16(sizeof(setHeader)); pHeader->parameterOffset = SMB_HTOL16(pRequestParameters - (PBYTE) pContext->Packet.pSMBHeader); pHeader->dataCount = SMB_HTOL16(usRequestDataCount); pHeader->dataOffset = SMB_HTOL16(pRequestData - (PBYTE) pContext->Packet.pSMBHeader); pHeader->setupCount = SMB_HTOL8(1); /* Update byte count */ status = MarshalUshort(&pByteCount, NULL, (pCursor - pByteCount) - 2); /* Update used length */ pContext->Packet.bufferUsed += (pCursor - pContext->Packet.pParams); status = SMBPacketMarshallFooter(&pContext->Packet); BAIL_ON_NT_STATUS(status); status = RdrSocketTransceive(pFile->pTree->pSession->pSocket, pContext); BAIL_ON_NT_STATUS(status); cleanup: return status; error: goto cleanup; }