Beispiel #1
0
NTSTATUS
SrvFinderCreateSearchSpace(
    IN  IO_FILE_HANDLE  hRootFileHandle,
    IN  PSRV_SHARE_INFO pShareInfo,
    IN  PIO_CREATE_SECURITY_CONTEXT pIoSecurityContext,
    IN  HANDLE         hFinderRepository,
    IN  PWSTR          pwszFilesystemPath,
    IN  PWSTR          pwszSearchPattern,
    IN  SMB_FILE_ATTRIBUTES usSearchAttrs,
    IN  USHORT         usFlags,
    IN  ULONG          ulSearchStorageType,
    IN  SMB_INFO_LEVEL infoLevel,
    IN  BOOLEAN        bUseLongFilenames,
    IN  ACCESS_MASK    accessMask,
    OUT PHANDLE        phFinder,
    OUT PUSHORT        pusSearchId
    )
{
    NTSTATUS ntStatus = 0;
    IO_FILE_HANDLE      hFile = NULL;
    IO_STATUS_BLOCK     ioStatusBlock = {0};
    IO_FILE_NAME        fileName = {0};
    PVOID               pSecurityDescriptor = NULL;
    PVOID               pSecurityQOS = NULL;
    PSRV_FINDER_REPOSITORY pFinderRepository = NULL;
    PSRV_SEARCH_SPACE pSearchSpace = NULL;
    USHORT   usCandidateSearchId = 0;
    BOOLEAN  bFound = FALSE;
    BOOLEAN  bInLock = FALSE;
    PIO_ECP_LIST pEcpList = NULL;
    FILE_CREATE_OPTIONS createOptions = 0;

    pFinderRepository = (PSRV_FINDER_REPOSITORY)hFinderRepository;

    fileName.RootFileHandle = hRootFileHandle;

    ntStatus = LwRtlUnicodeStringInitEx(&fileName.Name, pwszFilesystemPath);
    BAIL_ON_NT_STATUS(ntStatus);

    if (pShareInfo->Flags & SHARE_INFO_FLAG_ABE_ENABLED)
    {
        ntStatus = IoRtlEcpListAllocate(&pEcpList);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = SrvIoPrepareAbeEcpList(pEcpList);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (usFlags & SMB_FIND_WITH_BACKUP_INTENT)
    {
        createOptions |= FILE_OPEN_FOR_BACKUP_INTENT;
    }

    ntStatus = SrvIoCreateFile(
                    pShareInfo,
                    &hFile,
                    NULL,
                    &ioStatusBlock,
                    pIoSecurityContext,
                    &fileName,
                    pSecurityDescriptor,
                    pSecurityQOS,
                    accessMask,
                    0,
                    FILE_ATTRIBUTE_NORMAL,
                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                    FILE_OPEN,
                    createOptions,
                    NULL, /* EA Buffer */
                    0,    /* EA Length */
                    pEcpList);
    BAIL_ON_NT_STATUS(ntStatus);

    LWIO_LOCK_MUTEX(bInLock, &pFinderRepository->mutex);

    usCandidateSearchId = pFinderRepository->usNextSearchId;

    do
    {
        PSRV_SEARCH_SPACE pSearchSpace = NULL;

	// 0 is not a valid search id

        if (!usCandidateSearchId || (usCandidateSearchId == UINT16_MAX))
        {
            usCandidateSearchId = 1;
        }

        ntStatus = LwRtlRBTreeFind(
                        pFinderRepository->pSearchSpaceCollection,
                        &usCandidateSearchId,
                        (PVOID*)&pSearchSpace);
        if (ntStatus == STATUS_NOT_FOUND)
        {
            ntStatus = STATUS_SUCCESS;
            bFound = TRUE;
        }
	else
	{
            usCandidateSearchId++;
	}

        BAIL_ON_NT_STATUS(ntStatus);

    } while ((usCandidateSearchId != pFinderRepository->usNextSearchId) && !bFound);

    if (!bFound)
    {
        ntStatus = STATUS_TOO_MANY_OPENED_FILES;
        BAIL_ON_NT_STATUS(ntStatus);
    }

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

    pSearchSpace->refCount = 1;

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

    pSearchSpace->usSearchId = usCandidateSearchId;

    ntStatus = LwRtlRBTreeAdd(
                    pFinderRepository->pSearchSpaceCollection,
                    &pSearchSpace->usSearchId,
                    pSearchSpace);
    BAIL_ON_NT_STATUS(ntStatus);

    pSearchSpace->hFile = hFile;
    hFile = NULL;
    pSearchSpace->infoLevel = infoLevel;
    pSearchSpace->usSearchAttrs = usSearchAttrs;
    pSearchSpace->ulSearchStorageType = ulSearchStorageType;
    pSearchSpace->bUseLongFilenames = bUseLongFilenames;

    ntStatus = SrvAllocateStringW(
                    pwszSearchPattern,
                    &pSearchSpace->pwszSearchPattern);
    BAIL_ON_NT_STATUS(ntStatus);

    InterlockedIncrement(&pSearchSpace->refCount);

    pFinderRepository->usNextSearchId = usCandidateSearchId + 1;

    *phFinder = pSearchSpace;
    *pusSearchId = usCandidateSearchId;

cleanup:

    LWIO_UNLOCK_MUTEX(bInLock, &pFinderRepository->mutex);

    if (pEcpList)
    {
        IoRtlEcpListFree(&pEcpList);
    }

    return ntStatus;

error:

    *phFinder = NULL;
    *pusSearchId = 0;

    if (pSearchSpace)
    {
        SrvFinderReleaseSearchSpace(pSearchSpace);
    }

    if (hFile)
    {
        IoCloseFile(hFile);
    }

    goto cleanup;
}
Beispiel #2
0
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;
}
Beispiel #3
0
NTSTATUS
SrvFinderBuildSearchPath(
    IN              PWSTR    pwszPath,
    IN              PWSTR    pwszSearchPattern,
       OUT          PWSTR*   ppwszFilesystemPath,
       OUT          PWSTR*   ppwszSearchPattern,
    IN OUT OPTIONAL PBOOLEAN pbPathHasWildCards
    )
{
    NTSTATUS ntStatus = 0;
    wchar16_t wszStar[]         = {'*',  0};
    wchar16_t wszBackslash[]    = {'\\', 0};
    wchar16_t wszQuestionMark[] = {'?',  0};
    wchar16_t wszQuote[]        = {'\"', 0};
    wchar16_t wszGT[]           = {'>',  0};
    wchar16_t wszLT[]           = {'<',  0};
    wchar16_t wszDot[]          = {'.',  0};
    size_t    sLen = 0;
    PWSTR     pwszCursor = NULL;
    PWSTR     pwszLastSlash = NULL;
    PWSTR     pwszFilesystemPath = NULL;
    PWSTR     pwszSearchPattern3 = NULL;
    PWSTR     pwszSearchPattern2 = NULL;
    BOOLEAN   bPathHasWildCards  = FALSE;

    sLen = IsNullOrEmptyString(pwszPath) ? 0 : wc16slen(pwszPath);

    while (pwszSearchPattern && *pwszSearchPattern &&
           (*pwszSearchPattern == wszBackslash[0]))
    {
          pwszSearchPattern++;
    }

    if (pwszSearchPattern && *pwszSearchPattern)
    {
        ntStatus = SrvAllocateStringW(pwszSearchPattern, &pwszSearchPattern3);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    pwszCursor = pwszSearchPattern3;
    while (pwszCursor && *pwszCursor)
    {
        if (*pwszCursor == wszGT[0])
        {
            bPathHasWildCards = TRUE;
            *pwszCursor = wszQuestionMark[0];
        }
        else if (*pwszCursor == wszQuote[0])
        {
            PWSTR pwszNext = pwszCursor;

            pwszNext++;

            if (!pwszNext ||
                ((*pwszNext == wszQuestionMark[0] ||
                  *pwszNext == wszStar[0] ||
                  *pwszNext == wszGT[0] ||
                  *pwszNext == wszLT[0] ||
                  *pwszNext == wszQuote[0])))
            {
                bPathHasWildCards = TRUE;
                *pwszCursor = wszDot[0];
            }
        }
        else if (*pwszCursor == wszLT[0])
        {
            PWSTR pwszNext = pwszCursor;

            bPathHasWildCards = TRUE;

            pwszNext++;

            if (pwszNext ||
                (((*pwszNext == wszDot[0]) ||
                 (*pwszNext == wszQuote[0]) ||
                 (*pwszNext == wszLT[0]))))
            {
                *pwszCursor = wszStar[0];
            }
        }

        pwszCursor++;
    }

    pwszCursor = pwszSearchPattern3;

    while (pwszCursor && *pwszCursor)
    {
        if (*pwszCursor == wszBackslash[0])
        {
            pwszLastSlash = pwszCursor;
        }
        else if ((*pwszCursor == wszStar[0]) ||
                 (*pwszCursor == wszQuestionMark[0]))
        {
            bPathHasWildCards = TRUE;

            break;
        }

        pwszCursor++;
    }

    if (pwszLastSlash)
    {
        PBYTE pDataCursor = NULL;
        size_t sSuffixLen = 0;

        sSuffixLen = ((PBYTE)pwszLastSlash - (PBYTE)pwszSearchPattern3);

        ntStatus = SrvAllocateMemory(
                        sLen * sizeof(wchar16_t) + sizeof(wszBackslash[0]) + sSuffixLen + sizeof(wchar16_t),
                        (PVOID*)&pwszFilesystemPath);
        BAIL_ON_NT_STATUS(ntStatus);

        pDataCursor = (PBYTE)pwszFilesystemPath;
        if (sLen)
        {
            memcpy(pDataCursor, (PBYTE)pwszPath, sLen * sizeof(wchar16_t));
            pDataCursor += sLen * sizeof(wchar16_t);
        }

        *((wchar16_t*)pDataCursor) = wszBackslash[0];
        pDataCursor += sizeof(wszBackslash[0]);

        memcpy(pDataCursor, pwszSearchPattern, sSuffixLen);
    }
    else if (pwszPath)
    {
        ntStatus = SrvAllocateStringW(
                        pwszPath,
                        &pwszFilesystemPath);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    pwszCursor = (pwszLastSlash ? ++pwszLastSlash : pwszSearchPattern3);
    if (pwszCursor && *pwszCursor)
    {
        ntStatus = SrvAllocateStringW(pwszCursor, &pwszSearchPattern2);
    }
    else
    {
        ntStatus = SrvAllocateStringW(wszStar, &pwszSearchPattern2);
    }
    BAIL_ON_NT_STATUS(ntStatus);

    *ppwszFilesystemPath = pwszFilesystemPath;
    *ppwszSearchPattern  = pwszSearchPattern2;

    if (pbPathHasWildCards)
    {
        *pbPathHasWildCards  = bPathHasWildCards;
    }

cleanup:

    SRV_SAFE_FREE_MEMORY(pwszSearchPattern3);

    return ntStatus;

error:

    *ppwszFilesystemPath = NULL;
    *ppwszSearchPattern  = NULL;

    if (pbPathHasWildCards)
    {
        *pbPathHasWildCards  = FALSE;
    }

    SRV_SAFE_FREE_MEMORY(pwszFilesystemPath);
    SRV_SAFE_FREE_MEMORY(pwszSearchPattern2);

    goto cleanup;
}