コード例 #1
0
ファイル: sharedb.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
SrvShareDbBeginEnum(
    HANDLE  hRepository,
    ULONG   ulLimit,
    PHANDLE phResume
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSRV_SHARE_DB_ENUM_CONTEXT pEnumContext = NULL;

    ntStatus = SrvAllocateMemory(
                    sizeof(SRV_SHARE_DB_ENUM_CONTEXT),
                    (PVOID*)&pEnumContext);
    BAIL_ON_NT_STATUS(ntStatus);

    pEnumContext->ulOffset = 0;
    pEnumContext->ulLimit = ulLimit;

    *phResume = (HANDLE)pEnumContext;

cleanup:

    return ntStatus;

error:

    *phResume = NULL;

    SRV_SAFE_FREE_MEMORY(pEnumContext);

    goto cleanup;
}
コード例 #2
0
ファイル: path.c プロジェクト: bhanug/likewise-open
NTSTATUS
SrvMatchPathPrefix(
    PWSTR pwszPath,
    ULONG ulPathLength,
    PWSTR pwszPrefix
    )
{
    NTSTATUS ntStatus = STATUS_NO_MATCH;
    ULONG   ulPrefixLength = wc16slen(pwszPrefix);
    PWSTR   pwszTmp = NULL;

    if (ulPathLength >= ulPrefixLength)
    {
        ntStatus = SrvAllocateMemory(
                        (ulPrefixLength + 1) * sizeof(wchar16_t),
                        (PVOID*)&pwszTmp);
        BAIL_ON_NT_STATUS(ntStatus);

        memcpy( (PBYTE)pwszTmp,
                (PBYTE)pwszPath,
                ulPrefixLength * sizeof(wchar16_t));

        if (!SMBWc16sCaseCmp(pwszTmp, pwszPrefix))
        {
            ntStatus = STATUS_SUCCESS;
        }
    }

error:

    SRV_SAFE_FREE_MEMORY(pwszTmp);

    return ntStatus;
}
コード例 #3
0
ファイル: srvsession.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
SrvSessionCreate(
    USHORT            uid,
    PLWIO_SRV_SESSION* ppSession
    )
{
    NTSTATUS ntStatus = 0;
    PLWIO_SRV_SESSION pSession = NULL;

    LWIO_LOG_DEBUG("Creating session [uid:%u]", uid);

    ntStatus = SrvAllocateMemory(
                    sizeof(LWIO_SRV_SESSION),
                    (PVOID*)&pSession);
    BAIL_ON_NT_STATUS(ntStatus);

    pSession->refcount = 1;

    pthread_rwlock_init(&pSession->mutex, NULL);
    pSession->pMutex = &pSession->mutex;

    pSession->uid = uid;

    ntStatus = WireGetCurrentNTTime(&pSession->llBirthTime);
    BAIL_ON_NT_STATUS(ntStatus);

    pSession->llLastActivityTime = pSession->llBirthTime;

    LWIO_LOG_DEBUG("Associating session [object:0x%x][uid:%u]", pSession, uid);

    ntStatus = LwRtlRBTreeCreate(
                    &SrvSessionTreeCompare,
                    NULL,
                    &SrvSessionTreeRelease,
                    &pSession->pTreeCollection);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvFinderCreateRepository(
                    &pSession->hFinderRepository);
    BAIL_ON_NT_STATUS(ntStatus);

    SRV_ELEMENTS_INCREMENT_SESSIONS;

    *ppSession = pSession;

cleanup:

    return ntStatus;

error:

    *ppSession = NULL;

    if (pSession)
    {
        SrvSessionRelease(pSession);
    }

    goto cleanup;
}
コード例 #4
0
ファイル: rename.c プロジェクト: FarazShaikh/LikewiseSMB2
static
NTSTATUS
SrvBuildRenameState(
    PSMB_RENAME_REQUEST_HEADER pRequestHeader,
    PWSTR                      pwszOldName,
    PWSTR                      pwszNewName,
    PSRV_RENAME_STATE_SMB_V1*  ppRenameState
    )
{
    NTSTATUS                 ntStatus     = STATUS_SUCCESS;
    PSRV_RENAME_STATE_SMB_V1 pRenameState = NULL;

    if (!pwszOldName || !*pwszOldName || !pwszNewName || !*pwszNewName)
    {
        ntStatus = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = SrvAllocateMemory(
                    sizeof(SRV_RENAME_STATE_SMB_V1),
                    (PVOID*)&pRenameState);
    BAIL_ON_NT_STATUS(ntStatus);

    pRenameState->refCount = 1;

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

    pRenameState->stage = SRV_RENAME_STAGE_SMB_V1_INITIAL;

    pRenameState->pRequestHeader = pRequestHeader;
    pRenameState->pwszOldName    = pwszOldName;
    pRenameState->pwszNewName    = pwszNewName;

    *ppRenameState = pRenameState;

cleanup:

    return ntStatus;

error:

    *ppRenameState = NULL;

    if (pRenameState)
    {
        SrvFreeRenameState(pRenameState);
    }

    goto cleanup;
}
コード例 #5
0
ファイル: getinfo.c プロジェクト: numberer6/likewise-open-1
static
NTSTATUS
SrvBuildGetInfoState_SMB_V2(
    PSMB2_GET_INFO_REQUEST_HEADER pRequestHeader,
    PLWIO_SRV_FILE_2              pFile,
    PBYTE                         pInputBuffer,
    ULONG                         ulInputBufferLength,
    PSRV_GET_INFO_STATE_SMB_V2*   ppGetInfoState
)
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSRV_GET_INFO_STATE_SMB_V2 pGetInfoState = NULL;

    ntStatus = SrvAllocateMemory(
                   sizeof(SRV_GET_INFO_STATE_SMB_V2),
                   (PVOID*)&pGetInfoState);
    BAIL_ON_NT_STATUS(ntStatus);

    pGetInfoState->refCount = 1;

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

    pGetInfoState->stage = SRV_GET_INFO_STAGE_SMB_V2_INITIAL;

    pGetInfoState->pRequestHeader = pRequestHeader;

    pGetInfoState->pFile = SrvFile2Acquire(pFile);

    pGetInfoState->pInputBuffer = pInputBuffer;

    pGetInfoState->ulInputBufferLength = ulInputBufferLength;

    *ppGetInfoState = pGetInfoState;

cleanup:

    return ntStatus;

error:

    *ppGetInfoState = NULL;

    if (pGetInfoState)
    {
        SrvFreeGetInfoState_SMB_V2(pGetInfoState);
    }

    goto cleanup;
}
コード例 #6
0
ファイル: delete.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
SrvBuildDeleteState(
    PSMB_DELETE_REQUEST_HEADER  pRequestHeader,
    PWSTR                       pwszSearchPattern,
    BOOLEAN                     bUseLongFilenames,
    PSRV_DELETE_STATE_SMB_V1*   ppDeleteState
    )
{
    NTSTATUS                 ntStatus    = STATUS_SUCCESS;
    PSRV_DELETE_STATE_SMB_V1 pDeleteState = NULL;

    ntStatus = SrvAllocateMemory(
                    sizeof(SRV_DELETE_STATE_SMB_V1),
                    (PVOID*)&pDeleteState);
    BAIL_ON_NT_STATUS(ntStatus);

    pDeleteState->refCount = 1;

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

    pDeleteState->stage = SRV_DELETE_STAGE_SMB_V1_INITIAL;

    pDeleteState->pRequestHeader    = pRequestHeader;
    pDeleteState->pwszSearchPattern = pwszSearchPattern;
    pDeleteState->bUseLongFilenames = bUseLongFilenames;
    pDeleteState->usSearchAttributes = pRequestHeader->usSearchAttributes;

    *ppDeleteState = pDeleteState;

cleanup:

    return ntStatus;

error:

    *ppDeleteState = NULL;

    if (pDeleteState)
    {
        SrvFreeDeleteState(pDeleteState);
    }

    goto cleanup;
}
コード例 #7
0
ファイル: socket.c プロジェクト: bhanug/likewise-open
NTSTATUS
SrvSocketStringToAddressA(
    PCSTR            pszAddress,
    struct sockaddr** ppSocketAddress,
    SOCKLEN_TYPE*       pAddressLength
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    struct addrinfo* pAddrInfo = NULL;
    struct sockaddr* pSocketAddress = NULL;

    ntStatus = SrvSocketGetAddrInfoA(pszAddress, &pAddrInfo);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvAllocateMemory(
                    pAddrInfo->ai_addrlen,
                    OUT_PPVOID(&pSocketAddress));
    BAIL_ON_NT_STATUS(ntStatus);

    memcpy(pSocketAddress, pAddrInfo->ai_addr, pAddrInfo->ai_addrlen);

    *ppSocketAddress = pSocketAddress;
    *pAddressLength = pAddrInfo->ai_addrlen;

cleanup:

    if (pAddrInfo)
    {
        freeaddrinfo(pAddrInfo);
    }

    return ntStatus;

error:

    if (pSocketAddress)
    {
        SrvFreeMemory(pSocketAddress);
    }

    *ppSocketAddress = NULL;
    *pAddressLength = 0;

    goto cleanup;
}
コード例 #8
0
ファイル: flush.c プロジェクト: FarazShaikh/LikewiseSMB2
static
NTSTATUS
SrvBuildFlushState_SMB_V2(
    PSMB2_FID                pFid,
    PLWIO_SRV_FILE_2         pFile,
    PSRV_FLUSH_STATE_SMB_V2* ppFlushState
    )
{
    NTSTATUS                ntStatus    = STATUS_SUCCESS;
    PSRV_FLUSH_STATE_SMB_V2 pFlushState = NULL;

    ntStatus = SrvAllocateMemory(
                    sizeof(SRV_FLUSH_STATE_SMB_V2),
                    (PVOID*)&pFlushState);
    BAIL_ON_NT_STATUS(ntStatus);

    pFlushState->refCount = 1;

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

    pFlushState->stage = SRV_FLUSH_STAGE_SMB_V2_INITIAL;

    pFlushState->pFid  = pFid;
    pFlushState->pFile = SrvFile2Acquire(pFile);

    *ppFlushState = pFlushState;

cleanup:

    return ntStatus;

error:

    *ppFlushState = NULL;

    if (pFlushState)
    {
        SrvFreeFlushState_SMB_V2(pFlushState);
    }

    goto cleanup;
}
コード例 #9
0
ファイル: checkdir.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
SrvBuildCheckdirState(
    PSMB_CHECK_DIRECTORY_REQUEST_HEADER pRequestHeader,
    PWSTR                               pwszPathFragment,
    PSRV_CHECKDIR_STATE_SMB_V1*         ppCheckdirState
    )
{
    NTSTATUS                   ntStatus       = STATUS_SUCCESS;
    PSRV_CHECKDIR_STATE_SMB_V1 pCheckdirState = NULL;

    ntStatus = SrvAllocateMemory(
                    sizeof(SRV_CHECKDIR_STATE_SMB_V1),
                    (PVOID*)&pCheckdirState);
    BAIL_ON_NT_STATUS(ntStatus);

    pCheckdirState->refCount = 1;

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

    pCheckdirState->stage = SRV_CHECKDIR_STAGE_SMB_V1_INITIAL;

    pCheckdirState->pwszPathFragment = pwszPathFragment;
    pCheckdirState->pRequestHeader   = pRequestHeader;

    *ppCheckdirState = pCheckdirState;

cleanup:

    return ntStatus;

error:

    *ppCheckdirState = NULL;

    if (pCheckdirState)
    {
        SrvFreeCheckdirState(pCheckdirState);
    }

    goto cleanup;
}
コード例 #10
0
ファイル: srvfinder.c プロジェクト: bhanug/likewise-open
NTSTATUS
SrvFinderCreateRepository(
    OUT PHANDLE phFinderRepository
    )
{
    NTSTATUS ntStatus = 0;
    PSRV_FINDER_REPOSITORY pFinderRepository = NULL;

    ntStatus = SrvAllocateMemory(
                    sizeof(SRV_FINDER_REPOSITORY),
                    (PVOID*)&pFinderRepository);
    BAIL_ON_NT_STATUS(ntStatus);

    pFinderRepository->refCount = 1;

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

    ntStatus = LwRtlRBTreeCreate(
                    &SrvFinderCompareSearchSpaces,
                    NULL,
                    &SrvFinderFreeData,
                    &pFinderRepository->pSearchSpaceCollection);
    BAIL_ON_NT_STATUS(ntStatus);

    *phFinderRepository = pFinderRepository;

cleanup:

    return ntStatus;

error:

    *phFinderRepository = NULL;

    if (pFinderRepository)
    {
        SrvFinderFreeRepository(pFinderRepository);
    }

    goto cleanup;
}
コード例 #11
0
ファイル: srvasyncstate.c プロジェクト: bhanug/likewise-open
NTSTATUS
SrvAsyncStateCreate(
    ULONG64                         ullAsyncId,
    USHORT                          usCommand,
    HANDLE                          hAsyncState,
    PFN_LWIO_SRV_CANCEL_ASYNC_STATE pfnCancelAsyncState,
    PFN_LWIO_SRV_FREE_ASYNC_STATE   pfnFreeAsyncState,
    PLWIO_ASYNC_STATE*              ppAsyncState
    )
{
    NTSTATUS          ntStatus    = STATUS_SUCCESS;
    PLWIO_ASYNC_STATE pAsyncState = NULL;

    ntStatus = SrvAllocateMemory(
                    sizeof(LWIO_ASYNC_STATE),
                    (PVOID*)&pAsyncState);
    BAIL_ON_NT_STATUS(ntStatus);

    pAsyncState->refcount = 1;

    pthread_rwlock_init(&pAsyncState->mutex, NULL);
    pAsyncState->pMutex = &pAsyncState->mutex;

    pAsyncState->ullAsyncId        = ullAsyncId;
    pAsyncState->usCommand         = usCommand;
    pAsyncState->hAsyncState       = hAsyncState;
    pAsyncState->pfnFreeAsyncState = pfnFreeAsyncState;
    pAsyncState->pfnCancelAsyncState = pfnCancelAsyncState;

    *ppAsyncState = pAsyncState;

cleanup:

    return ntStatus;

error:

    *ppAsyncState = NULL;

    goto cleanup;
}
コード例 #12
0
ファイル: notify_request.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
SrvBuildNotifyRequestState_SMB_V2(
    PSMB2_NOTIFY_CHANGE_HEADER         pRequestHeader,
    PSRV_NOTIFY_REQUEST_STATE_SMB_V2*  ppNotifyRequestState
    )
{
    NTSTATUS ntStatus     = STATUS_SUCCESS;
    PSRV_NOTIFY_REQUEST_STATE_SMB_V2 pNotifyRequestState = NULL;

    ntStatus = SrvAllocateMemory(
                    sizeof(SRV_NOTIFY_REQUEST_STATE_SMB_V2),
                    (PVOID*)&pNotifyRequestState);
    BAIL_ON_NT_STATUS(ntStatus);

    pNotifyRequestState->refCount = 1;

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

    pNotifyRequestState->stage = SRV_NOTIFY_STAGE_SMB_V2_INITIAL;

    pNotifyRequestState->pRequestHeader = pRequestHeader;

    *ppNotifyRequestState = pNotifyRequestState;

cleanup:

    return ntStatus;

error:

    *ppNotifyRequestState = NULL;

    if (pNotifyRequestState)
    {
        SrvFreeNotifyRequestState_SMB_V2(pNotifyRequestState);
    }

    goto cleanup;
}
コード例 #13
0
ファイル: context.c プロジェクト: bhanug/likewise-open
NTSTATUS
SrvBuildEmptyExecContext(
   OUT PSRV_EXEC_CONTEXT* ppContext
   )
{
    NTSTATUS          ntStatus = STATUS_SUCCESS;
    PSRV_EXEC_CONTEXT pContext = NULL;

    ntStatus = SrvAllocateMemory(sizeof(SRV_EXEC_CONTEXT), (PVOID*)&pContext);
    BAIL_ON_NT_STATUS(ntStatus);

    pthread_mutex_init(&pContext->execMutex, NULL);
    pContext->pExecMutex = &pContext->execMutex;

    ntStatus = SrvLogContextCreate(&pContext->pLogContext);
    BAIL_ON_NT_STATUS(ntStatus);

    pContext->refCount = 1;

    pContext->bInternal = TRUE;

    *ppContext = pContext;

cleanup:

    return ntStatus;

error:

    *ppContext = NULL;

    if (pContext)
    {
        SrvReleaseExecContext(pContext);
    }

    goto cleanup;
}
コード例 #14
0
ファイル: regshare.c プロジェクト: FarazShaikh/LikewiseSMB2
static
NTSTATUS
SrvShareRegWriteToShareInfo(
    IN  REG_DATA_TYPE    regDataType,
    IN  PWSTR            pwszShareName,
    IN  PBYTE            pData,
    IN  ULONG            ulDataLen,
    IN  REG_DATA_TYPE    regSecDataType,
    IN  PBYTE            pSecData,
    IN  ULONG            ulSecDataLen,
    OUT PSRV_SHARE_INFO* ppShareInfo
    )
{
    NTSTATUS        ntStatus     = STATUS_SUCCESS;
    PSRV_SHARE_INFO pShareInfo   = NULL;
    PWSTR*          ppwszValues  = NULL;
    PSTR            pszFlags     = NULL;

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

    pShareInfo->refcount = 1;

    pthread_rwlock_init(&pShareInfo->mutex, NULL);
    pShareInfo->pMutex = &pShareInfo->mutex;

    ntStatus = SrvAllocateStringW(pwszShareName, &pShareInfo->pwszName);
    BAIL_ON_NT_STATUS(ntStatus);

    if (pData)
    {
        ULONG iValue = 0;
        wchar16_t wszCommentPrefix[] = REG_KEY_COMMENT_PREFIX_W;
        ULONG     ulCommentPrefixLen =
                            (sizeof(wszCommentPrefix)/sizeof(wchar16_t)) - 1;
        wchar16_t wszPathPrefix[]    = REG_KEY_PATH_PREFIX_W;
        ULONG     ulPathPrefixLen =
                            (sizeof(wszPathPrefix)/sizeof(wchar16_t)) - 1;
        wchar16_t wszServicePrefix[] = REG_KEY_SERVICE_PREFIX_W;
        ULONG     ulServicePrefixLen =
                            (sizeof(wszServicePrefix)/sizeof(wchar16_t)) - 1;

        wchar16_t wszFlagsPrefix[]   = REG_KEY_FLAGS_PREFIX_W;
        ULONG     ulFlagsPrefixLen =
                            (sizeof(wszFlagsPrefix)/sizeof(wchar16_t)) - 1;

        ntStatus = NtRegByteArrayToMultiStrs(pData, ulDataLen, &ppwszValues);
        BAIL_ON_NT_STATUS(ntStatus);

        for (; ppwszValues[iValue]; iValue++)
        {
            PWSTR pwszValue = &ppwszValues[iValue][0];

            if (!wc16sncmp(&wszPathPrefix[0], pwszValue, ulPathPrefixLen))
            {
                SRV_SAFE_FREE_MEMORY(pShareInfo->pwszPath);

                ntStatus = SrvAllocateStringW(
                                &pwszValue[ulPathPrefixLen],
                                &pShareInfo->pwszPath);
                BAIL_ON_NT_STATUS(ntStatus);
            }
            else if (!wc16sncmp(&wszCommentPrefix[0], pwszValue, ulCommentPrefixLen))
            {
                SRV_SAFE_FREE_MEMORY(pShareInfo->pwszComment);

                ntStatus = SrvAllocateStringW(
                                &pwszValue[ulCommentPrefixLen],
                                &pShareInfo->pwszComment);
                BAIL_ON_NT_STATUS(ntStatus);
            }
            else if (!wc16sncmp(&wszServicePrefix[0], pwszValue, ulServicePrefixLen))
            {
                ntStatus = SrvShareMapServiceStringToIdW(
                                &pwszValue[ulServicePrefixLen],
                                &pShareInfo->service);
                BAIL_ON_NT_STATUS(ntStatus);

            }
            else if (!wc16sncmp(&wszFlagsPrefix[0], pwszValue, ulFlagsPrefixLen))
            {
                ntStatus = RtlCStringAllocateFromWC16String(
                                &pszFlags,
                                &pwszValue[ulFlagsPrefixLen]);
                BAIL_ON_NT_STATUS(ntStatus);

                pShareInfo->ulFlags = strtol(pszFlags, NULL, 16);
            }
            else
            {
                ntStatus = STATUS_INVALID_PARAMETER_3;
                BAIL_ON_NT_STATUS(ntStatus);
            }
        }
    }

    if (!pShareInfo->pwszComment)
    {
        wchar16_t wszComment[] = {0};

        ntStatus = SrvAllocateStringW(
                        &wszComment[0],
                        &pShareInfo->pwszComment);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (ulSecDataLen)
    {
        ntStatus = SrvShareSetSecurity(
                       pShareInfo,
                       (PSECURITY_DESCRIPTOR_RELATIVE)pSecData,
                       ulSecDataLen);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    else
    {
        ntStatus = SrvShareSetDefaultSecurity(pShareInfo);
        BAIL_ON_NT_STATUS(ntStatus);
    }



    *ppShareInfo = pShareInfo;

cleanup:

    if (ppwszValues)
    {
        RegFreeMultiStrsW(ppwszValues);
    }

    RTL_FREE(&pszFlags);

    return ntStatus;

error:

    if (pShareInfo)
    {
        SrvShareReleaseInfo(pShareInfo);
    }

    goto cleanup;
}
コード例 #15
0
ファイル: regshare.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
SrvShareRegEnum(
    HANDLE            hRepository,
    HANDLE            hResume,
    PSRV_SHARE_INFO** pppShareInfoList,
    PULONG            pulNumSharesFound
    )
{
    NTSTATUS ntStatus          = 0;
    ULONG    ulIndex           = 0;
    ULONG    ulBatchIndex      = 0;
    HKEY     hRootKey          = NULL;
    HKEY     hKey              = NULL;
    HKEY     hSecKey           = NULL;
    PWSTR    pwszValueName     = NULL;
    PBYTE    pData             = NULL;
    REG_DATA_TYPE    dataType  = REG_UNKNOWN;
    wchar16_t wszHKTM[]        = HKEY_THIS_MACHINE_W;
    wchar16_t wszSharesKey[]   = REG_KEY_PATH_SRV_SHARES_W;
    wchar16_t wszShareSecKey[] = REG_KEY_PATH_SRV_SHARES_SECURITY_W;
    PSRV_SHARE_INFO* ppShareInfoList  = NULL;
    REG_DATA_TYPE    dataSecType      = REG_UNKNOWN;
    ULONG            ulNumSharesFound = 0;
    BYTE             pSecData[MAX_VALUE_LENGTH] = {0};
    PSRV_SHARE_REG_ENUM_CONTEXT pResume = (PSRV_SHARE_REG_ENUM_CONTEXT)hResume;

    if (!pResume)
    {
        ntStatus = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = NtRegOpenKeyExW(
                    hRepository,
                    NULL,
                    &wszHKTM[0],
                    0,
                    KEY_READ,
                    &hRootKey);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = NtRegOpenKeyExW(
                    hRepository,
                    hRootKey,
                    &wszSharesKey[0],
                    0,
                    KEY_READ,
                    &hKey);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = NtRegOpenKeyExW(
                    hRepository,
                    hRootKey,
                    &wszShareSecKey[0],
                    0,
                    KEY_READ,
                    &hSecKey);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvAllocateMemory(
                    pResume->ulBatchLimit * sizeof(*ppShareInfoList),
                    (PVOID) &ppShareInfoList);
    BAIL_ON_NT_STATUS(ntStatus);

    ulBatchIndex = pResume->ulBatchIndex;

    for (ulIndex = 0; ulIndex < pResume->ulBatchLimit; ulIndex++)
    {
        ULONG ulMaxValueNameLen = 0;
        ULONG ulMaxValueLen     = 0;
        ULONG ulMaxSecValueLen  = 0;

        ulMaxValueNameLen =
                    (pResume->ulMaxValueNameLen + 1) * sizeof(*pwszValueName);
        ulMaxValueLen    = pResume->ulMaxValueLen;
        ulMaxSecValueLen = MAX_VALUE_LENGTH;

        if (ulMaxValueNameLen)
        {
            SRV_SAFE_FREE_MEMORY_AND_RESET(pwszValueName);

            ntStatus = SrvAllocateMemory(
                            ulMaxValueNameLen,
                            (PVOID*) &pwszValueName);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        if (ulMaxValueLen)
        {
            SRV_SAFE_FREE_MEMORY_AND_RESET(pData);

            ntStatus = SrvAllocateMemory(ulMaxValueLen, (PVOID*) &pData);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        ntStatus = NtRegEnumValueW(
                      hRepository,
                      hKey,
                      ulBatchIndex++,
                      pwszValueName,
                      &ulMaxValueNameLen,
                      NULL,
                      &dataType,
                      pData,
                      &ulMaxValueLen);
        if (ntStatus == STATUS_NO_MORE_MATCHES || ntStatus == STATUS_NO_MORE_ENTRIES)
        {
            ntStatus = STATUS_SUCCESS;
            break;
        }
        BAIL_ON_NT_STATUS(ntStatus);

        if (REG_MULTI_SZ != dataType)
        {
            continue;
        }

        ntStatus = NtRegGetValueW(
                        hRepository,
                        hSecKey,
                        NULL,
                        pwszValueName,
                        RRF_RT_REG_BINARY,
                        &dataSecType,
                        pSecData,
                        &ulMaxSecValueLen);
        if (STATUS_OBJECT_NAME_NOT_FOUND == ntStatus)
        {
            ntStatus = 0;
            ulMaxSecValueLen = 0;
        }
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = SrvShareRegWriteToShareInfo(
                      dataType,
                      pwszValueName,
                      pData,
                      ulMaxValueLen,
                      dataSecType,
                      pSecData,
                      ulMaxSecValueLen,
                      &ppShareInfoList[ulNumSharesFound++]);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    pResume->ulBatchIndex = ulBatchIndex;

    *pppShareInfoList = ppShareInfoList;
    *pulNumSharesFound = ulNumSharesFound;

cleanup:

    if (hRootKey)
    {
	NtRegCloseKey(hRepository, hRootKey);
    }
    if (hKey)
    {
	NtRegCloseKey(hRepository, hKey);
    }
    if (hSecKey)
    {
	NtRegCloseKey(hRepository, hSecKey);
    }

    SRV_SAFE_FREE_MEMORY(pwszValueName);
    SRV_SAFE_FREE_MEMORY(pData);

    return ntStatus;

error:

    *pppShareInfoList = NULL;
    *pulNumSharesFound = 0;

    if (ppShareInfoList)
    {
        SrvShareFreeInfoList(ppShareInfoList, ulNumSharesFound);
    }

    goto cleanup;
}
コード例 #16
0
ファイル: regshare.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
SrvShareRegBeginEnum(
    HANDLE  hRepository,
    ULONG   ulBatchLimit,
    PHANDLE phResume
    )
{
    NTSTATUS  ntStatus       = 0;
    HKEY      hRootKey       = NULL;
    HKEY      hKey           = NULL;
    wchar16_t wszHKTM[]      = HKEY_THIS_MACHINE_W;
    wchar16_t wszSharesKey[] = REG_KEY_PATH_SRV_SHARES_W;
    PSRV_SHARE_REG_ENUM_CONTEXT pEnumContext = NULL;

    if (!ulBatchLimit || (ulBatchLimit == UINT32_MAX))
    {
        ntStatus = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = SrvAllocateMemory(
                    sizeof(SRV_SHARE_REG_ENUM_CONTEXT),
                    (PVOID*)&pEnumContext);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = NtRegOpenKeyExW(
                    hRepository,
                    NULL,
                    &wszHKTM[0],
                    0,
                    KEY_READ,
                    &hRootKey);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = NtRegOpenKeyExW(
                    hRepository,
                    hRootKey,
                    &wszSharesKey[0],
                    0,
                    KEY_READ,
                    &hKey);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = NtRegQueryInfoKeyW(
                    hRepository,
                    hKey,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    &pEnumContext->ulValuesAvailable,
                    &pEnumContext->ulMaxValueNameLen,
                    &pEnumContext->ulMaxValueLen,
                    NULL,
                    NULL);
    BAIL_ON_NT_STATUS(ntStatus);

    pEnumContext->ulBatchLimit = ulBatchLimit;

    *phResume = (HANDLE)pEnumContext;

cleanup:

    if (hRootKey)
    {
	NtRegCloseKey(hRepository, hRootKey);
    }
    if (hKey)
    {
	NtRegCloseKey(hRepository, hKey);
    }

    return ntStatus;

error:

    *phResume = NULL;

    SRV_SAFE_FREE_MEMORY(pEnumContext);

    goto cleanup;
}
コード例 #17
0
ファイル: regshare.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
SrvShareRegAdd(
    IN HANDLE hRepository,
    IN PWSTR  pwszShareName,
    IN PWSTR  pwszPath,
    IN PWSTR  pwszComment,
    IN PBYTE  pSecDesc,
    IN ULONG  ulSecDescLen,
    IN PWSTR  pwszService,
    IN ULONG  ulFlags
    )
{
    NTSTATUS ntStatus    = 0;
    HKEY     hRootKey    = NULL;
    HKEY     hKey        = NULL;
    HKEY     hSecKey     = NULL;
    PWSTR*   ppwszValues = NULL;
    PBYTE    pOutData    = NULL;
    SSIZE_T  cOutDataLen = 0;
    PWSTR    pwszFlags   = NULL;
    ULONG    ulCount     = 0;
    wchar16_t wszHKTM[]          = HKEY_THIS_MACHINE_W;
    wchar16_t wszSharesKey[]     = REG_KEY_PATH_SRV_SHARES_W;
    wchar16_t wszShareSecKey[]   = REG_KEY_PATH_SRV_SHARES_SECURITY_W;
    wchar16_t wszPathPrefix[]    = REG_KEY_PATH_PREFIX_W;
    wchar16_t wszFlagsPrefix[]   = REG_KEY_FLAGS_PREFIX_W;
    ULONG     ulPathPrefixLen =
                        (sizeof(wszPathPrefix)/sizeof(wchar16_t)) - 1;
    ULONG     ulFlagsPrefixLen =
                        (sizeof(wszFlagsPrefix)/sizeof(wchar16_t)) - 1;

    if (IsNullOrEmptyString(pwszShareName))
    {
        ntStatus = STATUS_INVALID_PARAMETER_2;
        BAIL_ON_NT_STATUS(ntStatus);
    }
    if (IsNullOrEmptyString(pwszPath))
    {
        ntStatus = STATUS_INVALID_PARAMETER_3;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = NtRegOpenKeyExW(
                    hRepository,
                    NULL,
                    &wszHKTM[0],
                    0,
                    KEY_ALL_ACCESS,
                    &hRootKey);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = NtRegOpenKeyExW(
                    hRepository,
                    hRootKey,
                    &wszSharesKey[0],
                    0,
                    KEY_ALL_ACCESS,
                    &hKey);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvAllocateMemory(sizeof(PWSTR) * 5, (PVOID*)&ppwszValues);
    BAIL_ON_NT_STATUS(ntStatus);

    // Path
    ntStatus = SrvAllocateMemory(
                    sizeof(wszPathPrefix) + wc16slen(pwszPath) * sizeof(wchar16_t),
                    (PVOID*)&ppwszValues[ulCount]);
    BAIL_ON_NT_STATUS(ntStatus);

    memcpy( (PBYTE)&ppwszValues[ulCount][0],
            (PBYTE)&wszPathPrefix[0],
            sizeof(wszPathPrefix) - sizeof(wchar16_t));
    memcpy( (PBYTE)&ppwszValues[ulCount][ulPathPrefixLen],
            (PBYTE)pwszPath,
            wc16slen(pwszPath) * sizeof(wchar16_t));

    if (!IsNullOrEmptyString(pwszComment))
    {
        wchar16_t wszCommentPrefix[] = REG_KEY_COMMENT_PREFIX_W;
        ULONG     ulCommentPrefixLen =
                            (sizeof(wszCommentPrefix)/sizeof(wchar16_t)) - 1;

        ntStatus = SrvAllocateMemory(
                            sizeof(wszCommentPrefix) + wc16slen(pwszComment) * sizeof(wchar16_t),
                            (PVOID*)&ppwszValues[++ulCount]);
        BAIL_ON_NT_STATUS(ntStatus);

        memcpy( (PBYTE)&ppwszValues[ulCount][0],
                (PBYTE)&wszCommentPrefix[0],
                sizeof(wszCommentPrefix) - sizeof(wchar16_t));
        memcpy( (PBYTE)&ppwszValues[ulCount][ulCommentPrefixLen],
                (PBYTE)pwszComment,
                wc16slen(pwszComment) * sizeof(wchar16_t));
    }

    if (!IsNullOrEmptyString(pwszService))
    {
        wchar16_t wszServicePrefix[] = REG_KEY_SERVICE_PREFIX_W;
        ULONG     ulServicePrefixLen =
                            (sizeof(wszServicePrefix)/sizeof(wchar16_t)) - 1;

        ntStatus = SrvAllocateMemory(
                            sizeof(wszServicePrefix) + wc16slen(pwszService) * sizeof(wchar16_t),
                            (PVOID*)&ppwszValues[++ulCount]);
        BAIL_ON_NT_STATUS(ntStatus);

        memcpy( (PBYTE)&ppwszValues[ulCount][0],
                (PBYTE)&wszServicePrefix[0],
                sizeof(wszServicePrefix) - sizeof(wchar16_t));
        memcpy( (PBYTE)&ppwszValues[ulCount][ulServicePrefixLen],
                (PBYTE)pwszService,
                wc16slen(pwszService) * sizeof(wchar16_t));
    }

    // Flags
    ntStatus = LwRtlWC16StringAllocatePrintfW(&pwszFlags, L"0x%08x", ulFlags);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvAllocateMemory(
                            sizeof(wszFlagsPrefix) + wc16slen(pwszFlags) * sizeof(wchar16_t),
                            OUT_PPVOID(&ppwszValues[++ulCount]));
    BAIL_ON_NT_STATUS(ntStatus);

    memcpy((PBYTE)&ppwszValues[ulCount][0],
           (PBYTE)&wszFlagsPrefix[0],
           sizeof(wszFlagsPrefix) - sizeof(wchar16_t));
    memcpy((PBYTE)&ppwszValues[ulCount][ulFlagsPrefixLen],
           (PBYTE)pwszFlags,
           wc16slen(pwszFlags) * sizeof(wchar16_t));

    ntStatus = NtRegMultiStrsToByteArrayW(ppwszValues, &pOutData, &cOutDataLen);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = NtRegSetValueExW(
                    hRepository,
                    hKey,
                    pwszShareName,
                    0,
                    REG_MULTI_SZ,
                    pOutData,
                    cOutDataLen);
    BAIL_ON_NT_STATUS(ntStatus);

    if ((pSecDesc && !ulSecDescLen) || (!pSecDesc && ulSecDescLen))
    {
        ntStatus = STATUS_INVALID_PARAMETER_5;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = NtRegOpenKeyExW(
                    hRepository,
                    hRootKey,
                    &wszShareSecKey[0],
                    0,
                    KEY_ALL_ACCESS,
                    &hSecKey);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = NtRegSetValueExW(
                    hRepository,
                    hSecKey,
                    pwszShareName,
                    0,
                    REG_BINARY,
                    pSecDesc,
                    ulSecDescLen);
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    if (hRootKey)
    {
	NtRegCloseKey(hRepository, hRootKey);
    }
    if (hKey)
    {
	NtRegCloseKey(hRepository, hKey);
    }
    if (hSecKey)
    {
	NtRegCloseKey(hRepository, hSecKey);
    }
    if (ppwszValues)
    {
        SrvShareFreeStringArray(ppwszValues, 4);
    }
    if (pOutData)
    {
        RegFreeMemory(pOutData);
    }

    RTL_FREE(&pwszFlags);

    return ntStatus;

error:

    goto cleanup;
}
コード例 #18
0
ファイル: openx.c プロジェクト: bhanug/likewise-open
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;
}
コード例 #19
0
ファイル: srvtree2.c プロジェクト: bhanug/likewise-open
NTSTATUS
SrvTree2Create(
    PLWIO_SRV_SESSION_2 pSession,
    ULONG             ulTid,
    PSRV_SHARE_INFO   pShareInfo,
    PLWIO_SRV_TREE_2* ppTree
    )
{
    NTSTATUS ntStatus = 0;
    PLWIO_SRV_TREE_2 pTree = NULL;

    LWIO_LOG_DEBUG("Creating Tree [tid: %u]", ulTid);

    ntStatus = SrvAllocateMemory(sizeof(LWIO_SRV_TREE_2), (PVOID*)&pTree);
    BAIL_ON_NT_STATUS(ntStatus);

    pTree->refcount = 1;

    pthread_rwlock_init(&pTree->mutex, NULL);
    pTree->pMutex = &pTree->mutex;

    pTree->pSession = pSession;;
    SrvSession2Acquire(pSession);

    pTree->ulTid = ulTid;
    pTree->ullUid = pSession->ullUid;

    pTree->resource.resourceType                  = SRV_RESOURCE_TYPE_TREE;
    pTree->resource.pAttributes                   = &pTree->resourceAttrs;
    pTree->resource.pAttributes->protocolVersion  = SMB_PROTOCOL_VERSION_2;
    pTree->resource.pAttributes->treeId.ulTid     = pTree->ulTid;
    pTree->resource.pAttributes->sessionId.ullUid = pTree->ullUid;
    pTree->resource.pAttributes->ulConnectionResourceId =
                                             pSession->ulConnectionResourceId;

    LWIO_LOG_DEBUG("Associating Tree [object:0x%x][tid:%u]",
                    pTree,
                    ulTid);

    pTree->pShareInfo = pShareInfo;
    SrvShareAcquireInfo(pShareInfo);

    pTree->ullNextAvailableFid = 0xFFFFFFFF00000001LL;

    ntStatus = LwRtlRBTreeCreate(
                    &SrvTree2FileCompare,
                    NULL,
                    &SrvTree2FileRelease,
                    &pTree->pFileCollection);
    BAIL_ON_NT_STATUS(ntStatus);

    SRV_ELEMENTS_INCREMENT_TREE_CONNECTS;

    *ppTree = pTree;

cleanup:

    return ntStatus;

error:

    *ppTree = NULL;

    if (pTree)
    {
        SrvTree2Release(pTree);
    }

    goto cleanup;
}
コード例 #20
0
ファイル: sharedb.c プロジェクト: FarazShaikh/LikewiseSMB2
static
NTSTATUS
SrvShareDbWriteToShareInfo(
    IN     sqlite3_stmt*     pSqlStatement,
    OUT    PSRV_SHARE_INFO** pppShareInfoList,
    IN OUT PULONG            pulNumSharesFound
    )
{
    NTSTATUS ntStatus = 0;
    PSRV_SHARE_INFO* ppShareInfoList = NULL;
    PSRV_SHARE_INFO pShareInfo = NULL;
    PWSTR pwszStringVal = NULL;
    ULONG ulIntVal = 0;
    ULONG ulNumSharesAllocated = 0;
    ULONG ulNumSharesAvailable = 0;
    ULONG iShare = 0;

    while ((ntStatus = sqlite3_step(pSqlStatement)) == SQLITE_ROW)
    {
        ULONG iCol = 0;

        if (!ulNumSharesAvailable)
        {
            PSRV_SHARE_INFO* ppShareInfoListNew = NULL;
            ULONG ulNumSharesNew = 5;
            ULONG ulNumSharesAllocatedNew = ulNumSharesAllocated + ulNumSharesNew;

            ntStatus = SrvAllocateMemory(
                            sizeof(PSRV_SHARE_INFO) * ulNumSharesAllocatedNew,
                            (PVOID*)&ppShareInfoListNew);
            BAIL_ON_NT_STATUS(ntStatus);

            if (ppShareInfoList)
            {
                memcpy((PBYTE)ppShareInfoListNew,
                       (PBYTE)ppShareInfoList,
                       sizeof(PSRV_SHARE_INFO) * ulNumSharesAllocated);

                SrvFreeMemory(ppShareInfoList);
            }

            ppShareInfoList = ppShareInfoListNew;
            ulNumSharesAllocated = ulNumSharesAllocatedNew;
            ulNumSharesAvailable = ulNumSharesNew;
        }

        ntStatus = SrvAllocateMemory(
                        sizeof(SRV_SHARE_INFO),
                        (PVOID*)&pShareInfo);
        BAIL_ON_NT_STATUS(ntStatus);

        pShareInfo->refcount = 1;

        pthread_rwlock_init(&pShareInfo->mutex, NULL);
        pShareInfo->pMutex = &pShareInfo->mutex;

        for (; iCol < 5; iCol++)
        {
            const unsigned char* pszStringVal = NULL;
            ULONG ulNumBytes = sqlite3_column_bytes(pSqlStatement, iCol);

            switch(iCol)
            {
                case 0: /* ShareName */

                    if (ulNumBytes)
                    {
                        pszStringVal = sqlite3_column_text(pSqlStatement, iCol);

                        ntStatus = SrvMbsToWc16s(
                                           (PCSTR)pszStringVal,
                                           &pShareInfo->pwszName);
                        BAIL_ON_NT_STATUS(ntStatus);
                    }

                    break;

                case 1: /* PathName */

                    if (ulNumBytes)
                    {
                        pszStringVal = sqlite3_column_text(pSqlStatement, iCol);

                        ntStatus = SrvMbsToWc16s(
                                           (PCSTR)pszStringVal,
                                           &pShareInfo->pwszPath);
                        BAIL_ON_NT_STATUS(ntStatus);
                    }

                    break;

                case 2: /* Comment */

                    if (ulNumBytes)
                    {
                        pszStringVal = sqlite3_column_text(pSqlStatement, iCol);

                        ntStatus = SrvMbsToWc16s(
                                           (PCSTR)pszStringVal,
                                           &pShareInfo->pwszComment);
                    }
                    else
                    {
                       /* Deal with empty comments */
                       ntStatus = SrvMbsToWc16s(
                                       "",
                                       &pShareInfo->pwszComment);
                    }
                    BAIL_ON_NT_STATUS(ntStatus);

                    break;

                case 3: /* Security Descriptor */

                    if (ulNumBytes)
                    {
                        PCVOID pBlob = sqlite3_column_blob(pSqlStatement, iCol);

                        ntStatus = SrvAllocateMemory(
                                       ulNumBytes,
                                       (PVOID*)&pShareInfo->pSecDesc);
                        BAIL_ON_NT_STATUS(ntStatus);

                        memcpy(pShareInfo->pSecDesc, pBlob, ulNumBytes);
                        pShareInfo->ulSecDescLen = ulNumBytes;
                    }

                    break;

                case 4: /* service */

                    if (ulNumBytes)
                    {
                        pszStringVal = sqlite3_column_text(pSqlStatement, iCol);
                    }

		    ntStatus = SrvMbsToWc16s(
                                    (PCSTR)pszStringVal,
				    &pwszStringVal);
		    BAIL_ON_NT_STATUS(ntStatus);

                    ntStatus = SrvShareMapServiceStringToId(
                                    pwszStringVal,
                                    &pShareInfo->service);
                    BAIL_ON_NT_STATUS(ntStatus);

                    break;

                case 5: /* flags */

                    if (ulNumBytes)
                    {
                        ulIntVal = sqlite3_column_int(pSqlStatement, iCol);
		    }

                    pShareInfo->ulFlags = ulIntVal;

                    break;
            }
        }

        *(ppShareInfoList + iShare++) = pShareInfo;
        pShareInfo = NULL;

        ulNumSharesAvailable--;
    }
    if (ntStatus == SQLITE_DONE)
    {
        ntStatus = STATUS_SUCCESS;
    }
    BAIL_ON_LWIO_SRV_SQLITE_ERROR_STMT(ntStatus, pSqlStatement);

    *pppShareInfoList = ppShareInfoList;
    *pulNumSharesFound = iShare;

cleanup:
    SRV_SAFE_FREE_MEMORY(pwszStringVal);

    if (pShareInfo)
    {
        SrvShareReleaseInfo(pShareInfo);
    }

    return ntStatus;

error:

    *pppShareInfoList = NULL;
    *pulNumSharesFound = 0;

    if (ppShareInfoList)
    {
        SrvShareFreeInfoList(ppShareInfoList, iShare);
    }

    goto cleanup;
}
コード例 #21
0
ファイル: trans2si.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
SrvUnmarshalSetEaListInformation(
    PSRV_EXEC_CONTEXT pExecContext
    )
{
    NTSTATUS                   ntStatus     = 0;
    PSRV_PROTOCOL_EXEC_CONTEXT pCtxProtocol = pExecContext->pProtocolContext;
    PSRV_EXEC_CONTEXT_SMB_V1   pCtxSmb1     = pCtxProtocol->pSmb1Context;
    PSRV_TRANS2_STATE_SMB_V1   pTrans2State = NULL;
    ULONG                      ulBytesAvailable  = 0;
    ULONG                      ulOffset          = 0;
    PBYTE                      pDataCursor       = NULL;
    PTRANS2_FILE_EA_LIST_INFORMATION pFileEaListInfo = NULL;
    PFILE_FULL_EA_INFORMATION  pFileFullEaInformation = NULL;

    pTrans2State = (PSRV_TRANS2_STATE_SMB_V1)pCtxSmb1->hState;

    pDataCursor = pTrans2State->pData;
    ulOffset    = pTrans2State->pRequestHeader->dataOffset;
    ulBytesAvailable = pTrans2State->pRequestHeader->dataCount;

    if (ulBytesAvailable < sizeof(TRANS2_FILE_EA_LIST_INFORMATION))
    {
        ntStatus = STATUS_INVALID_NETWORK_RESPONSE;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    pFileEaListInfo   = (PTRANS2_FILE_EA_LIST_INFORMATION)pDataCursor;
    pDataCursor      += sizeof(TRANS2_FILE_EA_LIST_INFORMATION);
    ulBytesAvailable -= sizeof(TRANS2_FILE_EA_LIST_INFORMATION);
    ulOffset         += sizeof(TRANS2_FILE_EA_LIST_INFORMATION);

    if (pFileEaListInfo->ulEaListSize <= 0)
    {
        ntStatus = STATUS_INVALID_NETWORK_RESPONSE;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    /* Assume for now that we are only allocating one
       FILE_FULL_EA_INFORMATION record which is all that has
       been observed from WinXP --jerry */

    pTrans2State->usBytesAllocated = pFileEaListInfo->ulEaListSize + sizeof(ULONG);

    ntStatus = SrvAllocateMemory(
                    pTrans2State->usBytesAllocated,
                    (PVOID*)&pTrans2State->pData2);
    BAIL_ON_NT_STATUS(ntStatus);

    pFileFullEaInformation = (PFILE_FULL_EA_INFORMATION)pTrans2State->pData2;

    pFileFullEaInformation->NextEntryOffset = 0;
    memcpy((PBYTE)&pFileFullEaInformation->Flags,
           (PBYTE)&pFileEaListInfo->pEaList[0],
           pFileEaListInfo->ulEaListSize);

cleanup:

    return ntStatus;

error:

    goto cleanup;
}
コード例 #22
0
ファイル: trans2si.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
SrvUnmarshalRenameInformation(
    PSRV_EXEC_CONTEXT pExecContext
    )
{
    NTSTATUS                   ntStatus     = 0;
    PSRV_PROTOCOL_EXEC_CONTEXT pCtxProtocol = pExecContext->pProtocolContext;
    PSRV_EXEC_CONTEXT_SMB_V1   pCtxSmb1     = pCtxProtocol->pSmb1Context;
    PSRV_TRANS2_STATE_SMB_V1   pTrans2State = NULL;
    ULONG                      ulBytesAvailable  = 0;
    ULONG                      ulOffset          = 0;
    PWSTR                      pwszFilename      = NULL;
    PBYTE                      pDataCursor       = NULL;
    BOOLEAN                    bTreeInLock       = FALSE;
    PSMB_FILE_RENAME_INFO_HEADER pFileRenameInfo = NULL;

    pTrans2State = (PSRV_TRANS2_STATE_SMB_V1)pCtxSmb1->hState;

    pDataCursor = pTrans2State->pData;
    ulOffset    = pTrans2State->pRequestHeader->dataOffset;
    ulBytesAvailable = pTrans2State->pRequestHeader->dataCount;

    if (ulBytesAvailable < sizeof(SMB_FILE_RENAME_INFO_HEADER))
    {
        ntStatus = STATUS_INVALID_NETWORK_RESPONSE;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    pFileRenameInfo   = (PSMB_FILE_RENAME_INFO_HEADER)pDataCursor;
    pDataCursor      += sizeof(SMB_FILE_RENAME_INFO_HEADER);
    ulBytesAvailable -= sizeof(SMB_FILE_RENAME_INFO_HEADER);
    ulOffset         += sizeof(SMB_FILE_RENAME_INFO_HEADER);

    if (ulOffset % 2)
    {
        if (ulBytesAvailable < 1)
        {
            ntStatus = STATUS_INVALID_NETWORK_RESPONSE;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        pDataCursor++;
        ulOffset++;
        ulBytesAvailable--;
    }

    if (!pFileRenameInfo->ulFileNameLength ||
        (ulBytesAvailable < pFileRenameInfo->ulFileNameLength))
    {
        ntStatus = STATUS_INVALID_NETWORK_RESPONSE;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (pFileRenameInfo->ulRootDir)
    {
        ntStatus = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    pwszFilename = (PWSTR)pDataCursor;

    pTrans2State->usBytesAllocated =
            sizeof(FILE_RENAME_INFORMATION) + pFileRenameInfo->ulFileNameLength;

    ntStatus = SrvAllocateMemory(
                    pTrans2State->usBytesAllocated,
                    (PVOID*)&pTrans2State->pData2);
    BAIL_ON_NT_STATUS(ntStatus);

    ((PFILE_RENAME_INFORMATION)pTrans2State->pData2)->ReplaceIfExists =
                            pFileRenameInfo->ucReplaceIfExists ? TRUE : FALSE;

    ((PFILE_RENAME_INFORMATION)pTrans2State->pData2)->FileNameLength =
                            pFileRenameInfo->ulFileNameLength;

    memcpy((PBYTE)((PFILE_RENAME_INFORMATION)pTrans2State->pData2)->FileName,
           (PBYTE)pwszFilename,
           pFileRenameInfo->ulFileNameLength);

cleanup:

    LWIO_UNLOCK_RWMUTEX(bTreeInLock, &pCtxSmb1->pTree->mutex);

    return ntStatus;

error:

    goto cleanup;
}
コード例 #23
0
ファイル: srvtimer.c プロジェクト: bhanug/likewise-open
static
PVOID
SrvTimerMain(
    IN  PVOID pData
    )
{
    NTSTATUS status = 0;
    PSRV_TIMER_CONTEXT pContext = (PSRV_TIMER_CONTEXT)pData;
    PSRV_TIMER_REQUEST pTimerRequest = NULL;
    LONG64 llCurTime = 0LL;
    BOOLEAN bInLock = FALSE;

    LWIO_LOG_DEBUG("Srv timer starting");

    LWIO_LOCK_MUTEX(bInLock, &pContext->mutex);

    while (!SrvTimerMustStop_inlock(pContext))
    {
        int errCode = 0;
        BOOLEAN bRetryWait = FALSE;

        // If we have a current timer request, check if it is time to service it
        if (pTimerRequest)
        {
            status = WireGetCurrentNTTime(&llCurTime);
            BAIL_ON_NT_STATUS(status);

            if (llCurTime >= pTimerRequest->llExpiry &&
                !pTimerRequest->bCanceled)
            {
                SrvTimerDetachRequest_inlock(pContext, pTimerRequest);

                LWIO_UNLOCK_MUTEX(bInLock, &pContext->mutex);

                if (pTimerRequest->pfnTimerExpiredCB)
                {
                    // Timer has not been canceled
                    pTimerRequest->pfnTimerExpiredCB(
                                        pTimerRequest,
                                        pTimerRequest->pUserData);
                }

                LWIO_LOCK_MUTEX(bInLock, &pContext->mutex);
            }

            SrvTimerRelease(pTimerRequest);
            pTimerRequest = NULL;
        }

        // Get the next timer request in queue
        status = SrvTimerGetNextRequest_inlock(pContext, &pTimerRequest);
        if (status == STATUS_NOT_FOUND)
        {
            // If the queue is empty wait for a day or until a request arrives
            struct timespec tsLong = { .tv_sec = time(NULL) + 86400,
                                       .tv_nsec = 0 };

            status = STATUS_SUCCESS;

            do
            {
                bRetryWait = FALSE;

                errCode = pthread_cond_timedwait(
                                &pContext->event,
                                &pContext->mutex,
                                &tsLong);

                if (errCode == ETIMEDOUT)
                {
                    if (time(NULL) < tsLong.tv_sec)
                    {
                        bRetryWait = TRUE;
                        continue;
                    }

                    break;
                }

                status = LwErrnoToNtStatus(errCode);
                BAIL_ON_NT_STATUS(status);

            } while (bRetryWait && !SrvTimerMustStop_inlock(pContext));

            continue;
        }
        BAIL_ON_NT_STATUS(status);

        // At this point, we have a timer request - wait for its specified time
        do
        {
            struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
            bRetryWait = FALSE;

            status = WireNTTimeToTimeSpec(pTimerRequest->llExpiry, &ts);
            BAIL_ON_NT_STATUS(status);

            errCode = pthread_cond_timedwait(
                            &pContext->event,
                            &pContext->mutex,
                            &ts);
            if (errCode == ETIMEDOUT)
            {
                status = WireGetCurrentNTTime(&llCurTime);
                BAIL_ON_NT_STATUS(status);

                if (llCurTime < pTimerRequest->llExpiry)
                {
                    bRetryWait = TRUE;
                    continue;
                }

                break;
            }

            status = LwErrnoToNtStatus(errCode);
            BAIL_ON_NT_STATUS(status);

        } while (bRetryWait && !SrvTimerMustStop_inlock(pContext));
    }

cleanup:

    LWIO_UNLOCK_MUTEX(bInLock, &pContext->mutex);

    if (pTimerRequest)
    {
        SrvTimerRelease(pTimerRequest);
    }

    LWIO_LOG_DEBUG("Srv timer stopping");

    return NULL;

error:

    LWIO_LOG_ERROR("Srv timer stopping due to error [%d]", status);

    goto cleanup;
}

static
NTSTATUS
SrvTimerGetNextRequest_inlock(
    IN  PSRV_TIMER_CONTEXT  pContext,
    OUT PSRV_TIMER_REQUEST* ppTimerRequest
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSRV_TIMER_REQUEST pTimerRequest = NULL;

    if (!pContext->pRequests)
    {
        status = STATUS_NOT_FOUND;
        BAIL_ON_NT_STATUS(status);
    }

    pTimerRequest = pContext->pRequests;

    InterlockedIncrement(&pTimerRequest->refCount);

    *ppTimerRequest = pTimerRequest;

cleanup:

    return status;

error:

    *ppTimerRequest = NULL;

    goto cleanup;
}

static
NTSTATUS
SrvTimerDetachRequest_inlock(
    IN OUT PSRV_TIMER_CONTEXT pContext,
    IN OUT PSRV_TIMER_REQUEST pTimerRequest
    )
{
    if (pTimerRequest->pPrev)
    {
        pTimerRequest->pPrev->pNext = pTimerRequest->pNext;

        if (pTimerRequest->pNext)
        {
            pTimerRequest->pNext->pPrev = pTimerRequest->pPrev;
        }
    }
    else
    {
        pContext->pRequests = pTimerRequest->pNext;

        if (pTimerRequest->pNext)
        {
            pTimerRequest->pNext->pPrev = NULL;
        }
    }

    pTimerRequest->pPrev = NULL;
    pTimerRequest->pNext = NULL;

    // Removed from timer queue
    InterlockedDecrement(&pTimerRequest->refCount);

    return STATUS_SUCCESS;
}

NTSTATUS
SrvTimerPostRequestSpecific(
    IN  PSRV_TIMER             pTimer,
    IN  LONG64                 llExpiry,
    IN  PVOID                  pUserData,
    IN  PFN_SRV_TIMER_CALLBACK pfnTimerExpiredCB,
    OUT PSRV_TIMER_REQUEST*    ppTimerRequest
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSRV_TIMER_REQUEST pTimerRequest = NULL;
    PSRV_TIMER_REQUEST pTimerIter = NULL;
    PSRV_TIMER_REQUEST pPrev = NULL;
    BOOLEAN bInLock = FALSE;

    if (!llExpiry)
    {
        status = STATUS_INVALID_PARAMETER_1;
        BAIL_ON_NT_STATUS(status);
    }
    if (!pfnTimerExpiredCB)
    {
        status = STATUS_INVALID_PARAMETER_3;
        BAIL_ON_NT_STATUS(status);
    }

    status = SrvAllocateMemory(
                    sizeof(SRV_TIMER_REQUEST),
                    (PVOID*)&pTimerRequest);
    BAIL_ON_NT_STATUS(status);

    pTimerRequest->refCount = 1;

    pTimerRequest->llExpiry = llExpiry;
    pTimerRequest->pUserData = pUserData;
    pTimerRequest->pfnTimerExpiredCB = pfnTimerExpiredCB;
    pTimerRequest->bCanceled = FALSE;

    LWIO_LOCK_MUTEX(bInLock, &pTimer->context.mutex);

    for (pTimerIter = pTimer->context.pRequests;
         pTimerIter && (pTimerIter->llExpiry <= llExpiry);
         pPrev = pTimerIter, pTimerIter = pTimerIter->pNext);

    if (!pPrev)
    {
        pTimerRequest->pNext = pTimer->context.pRequests;
        if (pTimer->context.pRequests)
        {
            pTimer->context.pRequests->pPrev = pTimerRequest;
        }
        pTimer->context.pRequests = pTimerRequest;
    }
    else
    {
        pTimerRequest->pNext = pPrev->pNext;
        pTimerRequest->pPrev = pPrev;
        pPrev->pNext = pTimerRequest;
        if (pTimerRequest->pNext)
        {
            pTimerRequest->pNext->pPrev = pTimerRequest;
        }
    }

    // +1 for timer queue
    InterlockedIncrement(&pTimerRequest->refCount);

    LWIO_UNLOCK_MUTEX(bInLock, &pTimer->context.mutex);

    pthread_cond_signal(&pTimer->context.event);

    // +1 for caller
    InterlockedIncrement(&pTimerRequest->refCount);

    *ppTimerRequest = pTimerRequest;

cleanup:

    LWIO_UNLOCK_MUTEX(bInLock, &pTimer->context.mutex);

    if (pTimerRequest)
    {
        SrvTimerRelease(pTimerRequest);
    }

    return status;

error:

    *ppTimerRequest = NULL;

    goto cleanup;
}
コード例 #24
0
ファイル: dbcontext.c プロジェクト: bhanug/likewise-open
NTSTATUS
SrvShareDbAcquireContext(
    PSRV_SHARE_DB_CONTEXT* ppDbContext
    )
{
    NTSTATUS ntStatus = 0;
    BOOLEAN bInLock = FALSE;
    PSRV_SHARE_DB_GLOBALS pGlobals = &gShareRepository_lwshare;
    PSRV_SHARE_DB_CONTEXT pDbContext = NULL;

    LWIO_LOCK_MUTEX(bInLock, &pGlobals->mutex);

    if (pGlobals->ulNumDbContexts)
    {
        pDbContext = pGlobals->pDbContextList;
        pGlobals->pDbContextList = pGlobals->pDbContextList->pNext;
        pDbContext->pNext = NULL;

        pGlobals->ulNumDbContexts--;

        LWIO_UNLOCK_MUTEX(bInLock, &pGlobals->mutex);
    }
    else
    {
        PCSTR pszShareDbPath = LWIO_SRV_SHARE_DB;

        ntStatus = SrvAllocateMemory(
                        sizeof(SRV_SHARE_DB_CONTEXT),
                        (PVOID*)&pDbContext);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = sqlite3_open(
                        pszShareDbPath,
                        &pDbContext->pDbHandle);
        if (ntStatus)
        {
            LWIO_LOG_ERROR("Sqlite3 Error (code: %d): %s",
                                    ntStatus,
                                    "Failed to open database handle""");
            ntStatus = STATUS_INTERNAL_DB_ERROR;
        }
        BAIL_ON_NT_STATUS(ntStatus);
    }

    *ppDbContext = pDbContext;

cleanup:

    LWIO_UNLOCK_MUTEX(bInLock, &pGlobals->mutex);

    return ntStatus;

error:

    *ppDbContext = NULL;

    if (pDbContext)
    {
        SrvShareDbFreeContext(pDbContext);
    }

    goto cleanup;
}
コード例 #25
0
ファイル: notify_request.c プロジェクト: bhanug/likewise-open
static
NTSTATUS
SrvMarshalNotifyResponse_SMB_V2(
    PBYTE  pNotifyResponse,
    ULONG  ulNotifyResponseLength,
    PBYTE* ppBuffer,
    PULONG pulBufferLength
    )
{
    NTSTATUS ntStatus         = STATUS_SUCCESS;
    PBYTE    pBuffer          = NULL;
    ULONG    ulBufferLength   = 0;
    ULONG    ulOffset         = 0;
    ULONG    ulNumRecords     = 0;
    ULONG    iRecord          = 0;
    ULONG    ulBytesAvailable = ulNotifyResponseLength;
    PBYTE    pDataCursor      = NULL;
    PFILE_NOTIFY_INFORMATION pNotifyCursor = NULL;
    PFILE_NOTIFY_INFORMATION pPrevHeader   = NULL;
    PFILE_NOTIFY_INFORMATION pCurHeader    = NULL;

    pNotifyCursor = (PFILE_NOTIFY_INFORMATION)pNotifyResponse;

    while (pNotifyCursor && (ulBufferLength < ulBytesAvailable))
    {
        ulBufferLength += offsetof(FILE_NOTIFY_INFORMATION, FileName);

        if (!pNotifyCursor->FileNameLength)
        {
            ulBufferLength += sizeof(wchar16_t);
        }
        else
        {
            ulBufferLength += pNotifyCursor->FileNameLength;
        }

        ulNumRecords++;

        if (pNotifyCursor->NextEntryOffset)
        {
            if (ulBufferLength % 4)
            {
                USHORT usAlignment = (4 - (ulBufferLength % 4));

                ulBufferLength += usAlignment;
            }

            pNotifyCursor =
                (PFILE_NOTIFY_INFORMATION)(((PBYTE)pNotifyCursor) +
                                            pNotifyCursor->NextEntryOffset);
        }
        else
        {
            pNotifyCursor = NULL;
        }
    }

    if (ulBufferLength)
    {
        ntStatus = SrvAllocateMemory(ulBufferLength, (PVOID*)&pBuffer);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    pNotifyCursor = (PFILE_NOTIFY_INFORMATION)pNotifyResponse;
    pDataCursor   = pBuffer;

    for (; iRecord < ulNumRecords; iRecord++)
    {
        pPrevHeader = pCurHeader;
        pCurHeader = (PFILE_NOTIFY_INFORMATION)pDataCursor;

        /* Update next entry offset for previous entry. */
        if (pPrevHeader != NULL)
        {
            pPrevHeader->NextEntryOffset = ulOffset;
        }

        ulOffset = 0;

        pCurHeader->NextEntryOffset = 0;
        pCurHeader->Action = pNotifyCursor->Action;
        pCurHeader->FileNameLength = pNotifyCursor->FileNameLength;

        pDataCursor += offsetof(FILE_NOTIFY_INFORMATION, FileName);
        ulOffset    += offsetof(FILE_NOTIFY_INFORMATION, FileName);

        if (pNotifyCursor->FileNameLength)
        {
            memcpy( pDataCursor,
                    (PBYTE)pNotifyCursor->FileName,
                    pNotifyCursor->FileNameLength);

            pDataCursor += pNotifyCursor->FileNameLength;
            ulOffset    += pNotifyCursor->FileNameLength;
        }
        else
        {
            pDataCursor += sizeof(wchar16_t);
            ulOffset    += sizeof(wchar16_t);
        }

        if (pNotifyCursor->NextEntryOffset != 0)
        {
            if (ulOffset % 4)
            {
                USHORT usAlign = 4 - (ulOffset % 4);

                pDataCursor += usAlign;
                ulOffset    += usAlign;
            }
        }

        pNotifyCursor =
                    (PFILE_NOTIFY_INFORMATION)(((PBYTE)pNotifyCursor) +
                                    pNotifyCursor->NextEntryOffset);
    }

    *ppBuffer        = pBuffer;
    *pulBufferLength = ulBufferLength;

cleanup:

    return ntStatus;

error:

    *ppBuffer        = NULL;
    *pulBufferLength = 0;

    if (pBuffer)
    {
        SrvFreeMemory(pBuffer);
    }

    goto cleanup;
}
コード例 #26
0
ファイル: driver.c プロジェクト: FarazShaikh/LikewiseSMB2
static
NTSTATUS
SrvBuildDefaultShareSID(
    PSECURITY_DESCRIPTOR_RELATIVE* ppSecDesc
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc = NULL;
    ULONG ulRelSecDescLen = 0;
    PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL;
    DWORD dwAceCount = 0;
    PSID pOwnerSid = NULL;
    PSID pGroupSid = NULL;
    PACL pDacl = NULL;
    DWORD dwSizeDacl = 0;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } localSystemSid;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } administratorsSid;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } builtinUsersSid;
    ULONG ulLocalSystemSidSize = sizeof(localSystemSid.buffer);
    ULONG ulAdministratorsSidSize = sizeof(administratorsSid.buffer);
    ULONG ulBuiltinUsersSidSize = sizeof(builtinUsersSid.buffer);
    ACCESS_MASK builtinUsersAccessMask = 0;
    ULONG ulAceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;

    /* Build the new Absolute Security Descriptor */

    ntStatus = RTL_ALLOCATE(
                   &pAbsSecDesc,
                   VOID,
                   SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateSecurityDescriptorAbsolute(
                  pAbsSecDesc,
                  SECURITY_DESCRIPTOR_REVISION);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Create some SIDs */

    ntStatus = RtlCreateWellKnownSid(
                   WinLocalSystemSid,
                   NULL,
                   (PSID)localSystemSid.buffer,
                   &ulLocalSystemSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateWellKnownSid(
                   WinBuiltinAdministratorsSid,
                   NULL,
                   (PSID)administratorsSid.buffer,
                   &ulAdministratorsSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateWellKnownSid(
                    WinBuiltinUsersSid,
                    NULL,
                    (PSID)builtinUsersSid.buffer,
                    &ulBuiltinUsersSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Owner: Local System */

    ntStatus = RtlDuplicateSid(&pOwnerSid, &localSystemSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetOwnerSecurityDescriptor(
                   pAbsSecDesc,
                   pOwnerSid,
                   FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Group: Administrators */

    ntStatus = RtlDuplicateSid(&pGroupSid, &administratorsSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetGroupSecurityDescriptor(
                   pAbsSecDesc,
                   pGroupSid,
                   FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* DACL:
       Administrators - (Full Control)
       LocalSystem    - (Full Control)
       Builtin Users  - (Read && Execute && List Directory Contents)
     */

    dwAceCount = 3;

    dwSizeDacl = ACL_HEADER_SIZE +
        dwAceCount * sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(&localSystemSid.sid) +
        RtlLengthSid(&administratorsSid.sid) +
        RtlLengthSid(&builtinUsersSid.sid) -
        dwAceCount * sizeof(ULONG);

    ntStatus= RTL_ALLOCATE(&pDacl, VOID, dwSizeDacl);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateAcl(pDacl, dwSizeDacl, ACL_REVISION);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  ulAceFlags,
                  FILE_ALL_ACCESS,
                  &localSystemSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  ulAceFlags,
                  FILE_ALL_ACCESS,
                  &administratorsSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    builtinUsersAccessMask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  ulAceFlags,
                  builtinUsersAccessMask,
                  &builtinUsersSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetDaclSecurityDescriptor(
                  pAbsSecDesc,
                  TRUE,
                  pDacl,
                  FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Create the SelfRelative SD */

    ntStatus = RtlAbsoluteToSelfRelativeSD(
                   pAbsSecDesc,
                   NULL,
                   &ulRelSecDescLen);
    if (ntStatus == STATUS_BUFFER_TOO_SMALL)
    {
        ntStatus = SrvAllocateMemory(ulRelSecDescLen, (PVOID*)&pRelSecDesc);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = RtlAbsoluteToSelfRelativeSD(
                       pAbsSecDesc,
                       pRelSecDesc,
                       &ulRelSecDescLen);
    }
    BAIL_ON_NT_STATUS(ntStatus);

    *ppSecDesc = pRelSecDesc;

cleanup:

    RTL_FREE(&pAbsSecDesc);
    RTL_FREE(&pOwnerSid);
    RTL_FREE(&pGroupSid);
    RTL_FREE(&pDacl);

    return ntStatus;

error:

    *ppSecDesc = NULL;

    if (pRelSecDesc)
    {
        SrvFreeMemory(pRelSecDesc);
    }

    goto cleanup;
}
コード例 #27
0
ファイル: driver.c プロジェクト: FarazShaikh/LikewiseSMB2
static
NTSTATUS
SrvInitialize(
    IO_DEVICE_HANDLE hDevice
    )
{
    NTSTATUS ntStatus = 0;
    INT      iWorker = 0;

    memset(&gSMBSrvGlobals, 0, sizeof(gSMBSrvGlobals));

    pthread_mutex_init(&gSMBSrvGlobals.mutex, NULL);
    gSMBSrvGlobals.pMutex = &gSMBSrvGlobals.mutex;

    ntStatus = SrvInitConfig(&gSMBSrvGlobals.config);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvReadConfig(&gSMBSrvGlobals.config);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SMBPacketCreateAllocator(
                    gSMBSrvGlobals.config.ulMaxNumPackets,
                    &gSMBSrvGlobals.hPacketAllocator);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvProdConsInitContents(
                    &gSMBSrvGlobals.workQueue,
                    gSMBSrvGlobals.config.ulMaxNumWorkItemsInQueue,
                    &SrvReleaseExecContextHandle);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvShareInit();
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvShareInitList(&gSMBSrvGlobals.shareList);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvShareBootstrapNamedPipeRoot(&gSMBSrvGlobals.shareList);
    BAIL_ON_NT_STATUS(ntStatus);

    if (gSMBSrvGlobals.config.bBootstrapDefaultSharePath)
    {
        ntStatus = SrvShareBootstrapDiskRoot(&gSMBSrvGlobals.shareList);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = SrvElementsInit();
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvStatisticsInitialize();
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvProtocolInit(
                    &gSMBSrvGlobals.workQueue,
                    gSMBSrvGlobals.hPacketAllocator,
                    &gSMBSrvGlobals.shareList);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvAllocateMemory(
                    gSMBSrvGlobals.config.ulNumWorkers * sizeof(LWIO_SRV_WORKER),
                    (PVOID*)&gSMBSrvGlobals.pWorkerArray);
    BAIL_ON_NT_STATUS(ntStatus);

    gSMBSrvGlobals.ulNumWorkers = gSMBSrvGlobals.config.ulNumWorkers;

    for (; iWorker < gSMBSrvGlobals.config.ulNumWorkers; iWorker++)
    {
        PLWIO_SRV_WORKER pWorker = &gSMBSrvGlobals.pWorkerArray[iWorker];

        pWorker->workerId = iWorker + 1;

        ntStatus = SrvWorkerInit(pWorker);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    gSMBSrvGlobals.hDevice = hDevice;

error:

    return ntStatus;
}
コード例 #28
0
ファイル: utils.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
SrvShareSetSecurity(
    IN  PSRV_SHARE_INFO pShareInfo,
    IN  PSECURITY_DESCRIPTOR_RELATIVE pIncRelSecDesc,
    IN  ULONG ulIncRelSecDescLen
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSECURITY_DESCRIPTOR_ABSOLUTE pIncAbsSecDesc = NULL;
    PSECURITY_DESCRIPTOR_ABSOLUTE pFinalAbsSecDesc = NULL;
    PSECURITY_DESCRIPTOR_RELATIVE pFinalRelSecDesc = NULL;
    ULONG ulFinalRelSecDescLen = 0;
    SECURITY_INFORMATION secInfo = 0;
    PSID pOwner = NULL;
    PSID pGroup = NULL;
    PACL pDacl = NULL;
    PACL pSacl = NULL;
    BOOLEAN bDefaulted = FALSE;
    BOOLEAN bPresent = FALSE;
    GENERIC_MAPPING GenericMap = {
        .GenericRead    = FILE_GENERIC_READ,
        .GenericWrite   = FILE_GENERIC_WRITE,
        .GenericExecute = FILE_GENERIC_EXECUTE,
        .GenericAll     = FILE_ALL_ACCESS };

    /* Sanity checks */

    if ((pIncRelSecDesc == NULL) || (ulIncRelSecDescLen == 0))
    {
        ntStatus = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (pShareInfo->ulSecDescLen == 0)
    {
        ntStatus = SrvShareSetDefaultSecurity(pShareInfo);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    /* Make the Absolute version of thr incoming SD and
       get the SecurityInformation */

    ntStatus = SrvShareCreateAbsoluteSecDescFromRel(
                    &pIncAbsSecDesc,
                    pIncRelSecDesc) ;
    BAIL_ON_NT_STATUS(ntStatus);

    /* Don't bail on these.  We'll be checking the pointer */

    ntStatus = RtlGetOwnerSecurityDescriptor(
                   pIncAbsSecDesc,
                   &pOwner,
                   &bDefaulted);
    secInfo |= pOwner ? OWNER_SECURITY_INFORMATION : 0;

    ntStatus = RtlGetGroupSecurityDescriptor(
                   pIncAbsSecDesc,
                   &pGroup,
                   &bDefaulted);
    secInfo |= pGroup ? GROUP_SECURITY_INFORMATION : 0;

    ntStatus = RtlGetDaclSecurityDescriptor(
                   pIncAbsSecDesc,
                   &bPresent,
                   &pDacl,
                   &bDefaulted);
    secInfo |= pDacl ? DACL_SECURITY_INFORMATION : 0;

    ntStatus = RtlGetSaclSecurityDescriptor(
                   pIncAbsSecDesc,
                   &bPresent,
                   &pSacl,
                   &bDefaulted);
    secInfo |= pSacl ? SACL_SECURITY_INFORMATION  : 0;

    /* Assume the new length is not longer than the combined length
       of both the current and incoming relative SecDesc buffers */

    ulFinalRelSecDescLen = ulIncRelSecDescLen + pShareInfo->ulSecDescLen;

    ntStatus = SrvAllocateMemory(
                   ulFinalRelSecDescLen,
                   (PVOID*)&pFinalRelSecDesc);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetSecurityDescriptorInfo(
                   secInfo,
                   pIncRelSecDesc,
                   pShareInfo->pSecDesc,
                   pFinalRelSecDesc,
                   &ulFinalRelSecDescLen,
                   &GenericMap);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SrvShareCreateAbsoluteSecDescFromRel(
                    &pFinalAbsSecDesc,
                    pFinalRelSecDesc) ;
    BAIL_ON_NT_STATUS(ntStatus);

    /* Free the old SecDesc and save the new one */

    SrvShareFreeSecurity(pShareInfo);

    pShareInfo->pSecDesc = pFinalRelSecDesc;
    pShareInfo->ulSecDescLen = ulFinalRelSecDescLen;
    pShareInfo->pAbsSecDesc = pFinalAbsSecDesc;

    ntStatus = STATUS_SUCCESS;

cleanup:
    if (pIncAbsSecDesc)
    {
        SrvShareFreeAbsoluteSecurityDescriptor(&pIncAbsSecDesc);
    }

    return ntStatus;

error:
    if (pFinalRelSecDesc)
    {
        SrvFreeMemory(pFinalRelSecDesc);
    }

    if (pFinalAbsSecDesc)
    {
        SrvShareFreeAbsoluteSecurityDescriptor(&pFinalAbsSecDesc);
    }

    goto cleanup;
}
コード例 #29
0
ファイル: utils.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
SrvShareSetDefaultSecurity(
    PSRV_SHARE_INFO pShareInfo
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSECURITY_DESCRIPTOR_RELATIVE pRelSecDesc = NULL;
    ULONG ulRelSecDescLen = 0;
    PSECURITY_DESCRIPTOR_ABSOLUTE pAbsSecDesc = NULL;
    DWORD dwAceCount = 0;
    PSID pOwnerSid = NULL;
    PSID pGroupSid = NULL;
    PACL pDacl = NULL;
    DWORD dwSizeDacl = 0;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } administratorsSid;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } powerUsersSid;
    union
    {
        SID sid;
        BYTE buffer[SID_MAX_SIZE];
    } everyoneSid;
    ULONG ulAdministratorsSidSize = sizeof(administratorsSid.buffer);
    ULONG ulPowerUsersSidSize = sizeof(powerUsersSid.buffer);
    ULONG ulEveryoneSidSize = sizeof(everyoneSid.buffer);
    ACCESS_MASK worldAccessMask = 0;

    /* Clear out any existing SecDesc's.  This is not a normal
       use case, but be paranoid */

    if (pShareInfo->ulSecDescLen)
    {
        SrvShareFreeSecurity(pShareInfo);
    }

    /* Build the new Absolute Security Descriptor */

    ntStatus = RTL_ALLOCATE(
                   &pAbsSecDesc,
                   VOID,
                   SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateSecurityDescriptorAbsolute(
                  pAbsSecDesc,
                  SECURITY_DESCRIPTOR_REVISION);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Create some SIDs */

    ntStatus = RtlCreateWellKnownSid(
                   WinBuiltinAdministratorsSid,
                   NULL,
                   (PSID)administratorsSid.buffer,
                   &ulAdministratorsSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateWellKnownSid(
                   WinBuiltinPowerUsersSid,
                   NULL,
                   (PSID)powerUsersSid.buffer,
                   &ulPowerUsersSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateWellKnownSid(
                   WinWorldSid,
                   NULL,
                   (PSID)everyoneSid.buffer,
                   &ulEveryoneSidSize);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Owner: Administrators */

    ntStatus = RtlDuplicateSid(&pOwnerSid, &administratorsSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetOwnerSecurityDescriptor(
                   pAbsSecDesc,
                   pOwnerSid,
                   FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Group: Power Users */

    ntStatus = RtlDuplicateSid(&pGroupSid, &powerUsersSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetGroupSecurityDescriptor(
                   pAbsSecDesc,
                   pGroupSid,
                   FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* DACL:
       Administrators - (Full Control)
       Everyone - (Read) for disk shares, (Read/Write) to IPC shares */

    dwAceCount = 2;

    dwSizeDacl = ACL_HEADER_SIZE +
        dwAceCount * sizeof(ACCESS_ALLOWED_ACE) +
        RtlLengthSid(&administratorsSid.sid) +
        RtlLengthSid(&everyoneSid.sid) -
        dwAceCount * sizeof(ULONG);

    ntStatus= RTL_ALLOCATE(&pDacl, VOID, dwSizeDacl);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlCreateAcl(pDacl, dwSizeDacl, ACL_REVISION);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  0,
                  FILE_ALL_ACCESS,
                  &administratorsSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    worldAccessMask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
    if (pShareInfo->service == SHARE_SERVICE_NAMED_PIPE)
    {
        worldAccessMask |= FILE_GENERIC_WRITE;
    }

    ntStatus = RtlAddAccessAllowedAceEx(
                  pDacl,
                  ACL_REVISION,
                  0,
                  worldAccessMask,
                  &everyoneSid.sid);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = RtlSetDaclSecurityDescriptor(
                  pAbsSecDesc,
                  TRUE,
                  pDacl,
                  FALSE);
    BAIL_ON_NT_STATUS(ntStatus);

    /* Create the SelfRelative SD and assign them to the Share */

    ntStatus = RtlAbsoluteToSelfRelativeSD(
                   pAbsSecDesc,
                   NULL,
                   &ulRelSecDescLen);
    if (ntStatus == STATUS_BUFFER_TOO_SMALL)
    {
        ntStatus = SrvAllocateMemory(ulRelSecDescLen, (PVOID*)&pRelSecDesc);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = RtlAbsoluteToSelfRelativeSD(
                       pAbsSecDesc,
                       pRelSecDesc,
                       &ulRelSecDescLen);
    }
    BAIL_ON_NT_STATUS(ntStatus);

    pShareInfo->pSecDesc = pRelSecDesc;
    pShareInfo->ulSecDescLen = ulRelSecDescLen;
    pShareInfo->pAbsSecDesc = pAbsSecDesc;

    ntStatus = STATUS_SUCCESS;


cleanup:

    return ntStatus;

error:
    RTL_FREE(&pAbsSecDesc);
    RTL_FREE(&pOwnerSid);
    RTL_FREE(&pGroupSid);
    RTL_FREE(&pDacl);

    if (pRelSecDesc)
    {
        SrvFreeMemory(pRelSecDesc);
    }

    goto cleanup;
}
コード例 #30
0
ファイル: srvtree.c プロジェクト: FarazShaikh/LikewiseSMB2
NTSTATUS
SrvTreeCreate(
    USHORT          tid,
    PSRV_SHARE_INFO pShareInfo,
    PLWIO_SRV_TREE* ppTree
    )
{
    NTSTATUS ntStatus = 0;
    PLWIO_SRV_TREE pTree = NULL;

    LWIO_LOG_DEBUG("Creating Tree [tid: %u]", tid);

    ntStatus = SrvAllocateMemory(sizeof(LWIO_SRV_TREE), (PVOID*)&pTree);
    BAIL_ON_NT_STATUS(ntStatus);

    pTree->refcount = 1;

    pthread_rwlock_init(&pTree->mutex, NULL);
    pTree->pMutex = &pTree->mutex;

    pTree->tid = tid;

    LWIO_LOG_DEBUG("Associating Tree [object:0x%x][tid:%u]",
                    pTree,
                    tid);

    pTree->pShareInfo = SrvShareAcquireInfo(pShareInfo);

    ntStatus = LwRtlRBTreeCreate(
                    &SrvTreeFileCompare,
                    NULL,
                    &SrvTreeFileRelease,
                    &pTree->pFileCollection);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = LwRtlRBTreeCreate(
                    &SrvTreeAsyncStateCompare,
                    NULL,
                    &SrvTreeAsyncStateRelease,
                    &pTree->pAsyncStateCollection);
    BAIL_ON_NT_STATUS(ntStatus);

    SRV_ELEMENTS_INCREMENT_TREE_CONNECTS;

    *ppTree = pTree;

cleanup:

    return ntStatus;

error:

    *ppTree = NULL;

    if (pTree)
    {
        SrvTreeRelease(pTree);
    }

    goto cleanup;
}