NTSTATUS SrvConnectionFindSession_SMB_V1( PSRV_EXEC_CONTEXT_SMB_V1 pSmb1Context, PLWIO_SRV_CONNECTION pConnection, USHORT usUid, PLWIO_SRV_SESSION* ppSession ) { NTSTATUS ntStatus = STATUS_SUCCESS; PLWIO_SRV_SESSION pSession = NULL; if (usUid) { if (pSmb1Context->pSession) { if (pSmb1Context->pSession->uid != usUid) { ntStatus = STATUS_INVALID_NETWORK_RESPONSE; BAIL_ON_NT_STATUS(ntStatus); } else { pSession = SrvSessionAcquire(pSmb1Context->pSession); } } else { ntStatus = SrvConnectionFindSession( pConnection, usUid, &pSession); BAIL_ON_NT_STATUS(ntStatus); pSmb1Context->pSession = SrvSessionAcquire(pSession); } } else if (pSmb1Context->pSession) { pSession = SrvSessionAcquire(pSmb1Context->pSession); } else { ntStatus = STATUS_NO_SUCH_LOGON_SESSION; BAIL_ON_NT_STATUS(ntStatus); } *ppSession = pSession; cleanup: return ntStatus; error: *ppSession = NULL; if (pSession) { SrvSessionRelease(pSession); } goto cleanup; }
NTSTATUS SrvProcessLogoffAndX( PSRV_EXEC_CONTEXT pExecContext ) { NTSTATUS ntStatus = 0; PLWIO_SRV_CONNECTION pConnection = pExecContext->pConnection; PSRV_PROTOCOL_EXEC_CONTEXT pCtxProtocol = pExecContext->pProtocolContext; PSRV_EXEC_CONTEXT_SMB_V1 pCtxSmb1 = pCtxProtocol->pSmb1Context; ULONG iMsg = pCtxSmb1->iMsg; PSRV_MESSAGE_SMB_V1 pSmbRequest = &pCtxSmb1->pRequests[iMsg]; PSRV_MESSAGE_SMB_V1 pSmbResponse = &pCtxSmb1->pResponses[iMsg]; PLOGOFF_RESPONSE_HEADER pResponseHeader = NULL; // Do not free PBYTE pOutBuffer = pSmbResponse->pBuffer; ULONG ulBytesAvailable = pSmbResponse->ulBytesAvailable; ULONG ulOffset = 0; ULONG ulTotalBytesUsed = 0; PLWIO_SRV_SESSION pSession = NULL; ntStatus = SrvConnectionFindSession( pConnection, pSmbRequest->pHeader->uid, &pSession); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SrvSetStatSessionInfo(pExecContext, pSession); BAIL_ON_NT_STATUS(ntStatus); SRV_LOG_DEBUG( pExecContext->pLogContext, SMB_PROTOCOL_VERSION_1, pSmbRequest->pHeader->command, "Logging off session: command(%u),uid(%u),mid(%u),pid(%u),tid(%u)", pSmbRequest->pHeader->command, pSmbRequest->pHeader->uid, pSmbRequest->pHeader->mid, SMB_V1_GET_PROCESS_ID(pSmbRequest->pHeader), pSmbRequest->pHeader->tid); SrvSessionRundown(pSession); if (!pSmbResponse->ulSerialNum) { ntStatus = SrvMarshalHeader_SMB_V1( pOutBuffer, ulOffset, ulBytesAvailable, COM_LOGOFF_ANDX, STATUS_SUCCESS, TRUE, pConnection->serverProperties.Capabilities, pSmbRequest->pHeader->tid, SMB_V1_GET_PROCESS_ID(pSmbRequest->pHeader), pSmbRequest->pHeader->uid, pSmbRequest->pHeader->mid, pConnection->serverProperties.bRequireSecuritySignatures, &pSmbResponse->pHeader, &pSmbResponse->pWordCount, &pSmbResponse->pAndXHeader, &pSmbResponse->usHeaderSize); } else { ntStatus = SrvMarshalHeaderAndX_SMB_V1( pOutBuffer, ulOffset, ulBytesAvailable, COM_LOGOFF_ANDX, &pSmbResponse->pWordCount, &pSmbResponse->pAndXHeader, &pSmbResponse->usHeaderSize); } BAIL_ON_NT_STATUS(ntStatus); pOutBuffer += pSmbResponse->usHeaderSize; ulOffset += pSmbResponse->usHeaderSize; ulBytesAvailable -= pSmbResponse->usHeaderSize; ulTotalBytesUsed += pSmbResponse->usHeaderSize; *pSmbResponse->pWordCount = 2; if (ulBytesAvailable < sizeof(LOGOFF_RESPONSE_HEADER)) { ntStatus = STATUS_INVALID_BUFFER_SIZE; BAIL_ON_NT_STATUS(ntStatus); } pResponseHeader = (PLOGOFF_RESPONSE_HEADER)pOutBuffer; // pOutBuffer += sizeof(LOGOFF_RESPONSE_HEADER); // ulOffset += sizeof(LOGOFF_RESPONSE_HEADER); // ulBytesAvailable -= sizeof(LOGOFF_RESPONSE_HEADER); ulTotalBytesUsed += sizeof(LOGOFF_RESPONSE_HEADER); pResponseHeader->byteCount = 0; pSmbResponse->ulMessageSize = ulTotalBytesUsed; cleanup: if (pSession) { SrvSessionRelease(pSession); } return ntStatus; error: if (ulTotalBytesUsed) { pSmbResponse->pHeader = NULL; pSmbResponse->pAndXHeader = NULL; memset(pSmbResponse->pBuffer, 0, ulTotalBytesUsed); } pSmbResponse->ulMessageSize = 0; goto cleanup; }