예제 #1
0
NTSTATUS
SrvSessionCreateTree(
    PLWIO_SRV_SESSION pSession,
    PSRV_SHARE_INFO   pShareInfo,
    PLWIO_SRV_TREE*   ppTree
    )
{
    NTSTATUS ntStatus = 0;
    PLWIO_SRV_TREE pTree = NULL;
    BOOLEAN bInLock = FALSE;
    USHORT  tid = 0;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pSession->mutex);

    ntStatus = SrvSessionUpdateLastActivityTime_inlock(pSession);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvSessionAcquireTreeId_inlock(
                    pSession,
                    &tid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvTreeCreate(
                    tid,
                    pShareInfo,
                    &pTree);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = LwRtlRBTreeAdd(
                    pSession->pTreeCollection,
                    &pTree->tid,
                    pTree);
    BAIL_ON_NT_STATUS(ntStatus);

    pTree->uid                    = pSession->uid;
    pTree->ulConnectionResourceId = pSession->ulConnectionResourceId;

    *ppTree = SrvTreeAcquire(pTree);

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pSession->mutex);

    return ntStatus;

error:

    *ppTree = NULL;

    if (pTree)
    {
        SrvTreeRelease(pTree);
    }

    goto cleanup;
}
예제 #2
0
static
NTSTATUS
SrvBuildOpenState(
    PSRV_EXEC_CONTEXT       pExecContext,
    POPEN_REQUEST_HEADER    pRequestHeader,
    PWSTR                   pwszFilename,
    PSRV_OPEN_STATE_SMB_V1* ppOpenState
    )
{
    NTSTATUS                   ntStatus       = STATUS_SUCCESS;
    PLWIO_SRV_CONNECTION       pConnection    = pExecContext->pConnection;
    PSRV_PROTOCOL_EXEC_CONTEXT pCtxProtocol   = pExecContext->pProtocolContext;
    PSRV_EXEC_CONTEXT_SMB_V1   pCtxSmb1       = pCtxProtocol->pSmb1Context;
    PSRV_OPEN_STATE_SMB_V1     pOpenState   = NULL;

    ntStatus = SrvAllocateMemory(
                    sizeof(SRV_OPEN_STATE_SMB_V1),
                    (PVOID*)&pOpenState);
    BAIL_ON_NT_STATUS(ntStatus);

    pOpenState->refCount = 1;

    pthread_mutex_init(&pOpenState->mutex, NULL);
    pOpenState->pMutex = &pOpenState->mutex;

    pOpenState->stage = SRV_OPEN_STAGE_SMB_V1_INITIAL;

    // TODO: Handle root fids
    ntStatus = SrvAllocateMemory(
                    sizeof(IO_FILE_NAME),
                    (PVOID*)&pOpenState->pFilename);
    BAIL_ON_NT_STATUS(ntStatus);

    pOpenState->pTree = SrvTreeAcquire(pCtxSmb1->pTree);

    ntStatus = SrvBuildTreeRelativePath(
                    pCtxSmb1->pTree,
                    pwszFilename,
                    pOpenState->pFilename);
    BAIL_ON_NT_STATUS(ntStatus);

    pOpenState->pwszFilename = pwszFilename;

    ntStatus = IoRtlEcpListAllocate(&pOpenState->pEcpList);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = IoRtlEcpListInsert(pOpenState->pEcpList,
                                  SRV_ECP_TYPE_NET_OPEN_INFO,
                                  &pOpenState->networkOpenInfo,
                                  sizeof(pOpenState->networkOpenInfo),
                                  NULL);
    BAIL_ON_NT_STATUS(ntStatus);

    /* For named pipes, we need to pipe some extra data into the npfs driver:
     *  - Session key
     *  - Client principal name
     *  - Client address
     */
    if (SrvTreeIsNamedPipe(pCtxSmb1->pTree))
    {
        ntStatus = SrvConnectionGetNamedPipeSessionKey(
                       pConnection,
                       pOpenState->pEcpList);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = SrvConnectionGetNamedPipeClientAddress(
                       pConnection,
                       pOpenState->pEcpList);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = IoRtlEcpListInsert(pOpenState->pEcpList,
                                      SRV_ECP_TYPE_PIPE_INFO,
                                      &pOpenState->filePipeInfo,
                                      sizeof(pOpenState->filePipeInfo),
                                      NULL);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = IoRtlEcpListInsert(pOpenState->pEcpList,
                                      SRV_ECP_TYPE_PIPE_LOCAL_INFO,
                                      &pOpenState->filePipeLocalInfo,
                                      sizeof(pOpenState->filePipeLocalInfo),
                                      NULL);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    pOpenState->usCreateOptions = FILE_NON_DIRECTORY_FILE;

    pOpenState->usShareAccess = (FILE_SHARE_READ  |
                                 FILE_SHARE_WRITE |
                                 FILE_SHARE_DELETE);

    switch (pRequestHeader->usDesiredAccess & 0x70)
    {
        case 0x00: /* compatibility mode */

            ntStatus = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntStatus);

            break;

        case 0x10: /* deny read/write/execute (exclusive) */

            pOpenState->usShareAccess &= (USHORT)~FILE_SHARE_READ;
            pOpenState->usShareAccess &= (USHORT)~FILE_SHARE_WRITE;

            break;

        case 0x20: /* deny write */

            pOpenState->usShareAccess &= (USHORT)~FILE_SHARE_WRITE;

            break;

        case 0x30: /* deny read/execute */

            pOpenState->usShareAccess &= (USHORT)~FILE_SHARE_READ;

            break;

        case 0x40: /* deny none */

            break;
    }

    /* desired access mask */
    switch (pRequestHeader->usDesiredAccess & 0x7)
    {
        case 0x00:

            pOpenState->ulDesiredAccessMask = GENERIC_READ;

            break;

        case 0x01:

            pOpenState->ulDesiredAccessMask = GENERIC_WRITE;

            break;

        case 0x02:

            pOpenState->ulDesiredAccessMask = GENERIC_READ | GENERIC_WRITE;

            break;

        case 0x03:

            pOpenState->ulDesiredAccessMask = (GENERIC_READ  |
                                               GENERIC_EXECUTE);

            break;

        default:

            ntStatus = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntStatus);

            break;
    }

    /* action to take if the file exists */
    switch (pRequestHeader->usOpenFunction)
    {
        case 0x0000: /* Weird EXECUTE -> OPEN_IF semantics */

            if ((pOpenState->ulDesiredAccessMask & GENERIC_EXECUTE) == 0) {
                ntStatus = STATUS_INVALID_DISPOSITION;
                BAIL_ON_NT_STATUS(ntStatus);
            }

            pOpenState->ulCreateDisposition = FILE_OPEN_IF;

            break;

        case 0x0001: /* Open file */

            pOpenState->ulCreateDisposition = FILE_OPEN;

            break;

        case 0x0002: /* truncate file */

            pOpenState->ulCreateDisposition = FILE_OVERWRITE;

            break;

        case 0x0010: /* create new file */

            pOpenState->ulCreateDisposition = FILE_CREATE;

            break;

        case 0x0011: /* open or create file */

            pOpenState->ulCreateDisposition = FILE_OPEN_IF;

            break;

        case 0x0012: /* create or truncate */

            pOpenState->ulCreateDisposition = FILE_OVERWRITE_IF;

            break;

        default:

            ntStatus = STATUS_INVALID_DISPOSITION;
            BAIL_ON_NT_STATUS(ntStatus);

            break;
    }

    pOpenState->pRequestHeader = pRequestHeader;

    *ppOpenState = pOpenState;

cleanup:

    return ntStatus;

error:

    *ppOpenState = NULL;

    if (pOpenState)
    {
        SrvFreeOpenState(pOpenState);
    }

    goto cleanup;
}