Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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)&notifyRequestHeader;
    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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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;
}