예제 #1
0
static
NTSTATUS
SrvShareBootstrapDiskRoot(
    IN OUT PLWIO_SRV_SHARE_ENTRY_LIST pShareList
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    wchar16_t wszFileRootName[] = {'C','$',0};
    PSTR  pszDefaultSharePath = NULL;
    PWSTR pwszFileSystemRoot = NULL;
    PSRV_SHARE_INFO pShareInfo = NULL;

    ntStatus = SrvShareFindByName(
                        pShareList,
                        &wszFileRootName[0],
                        &pShareInfo);
    if (ntStatus == STATUS_NOT_FOUND)
    {
        wchar16_t wszDesc[] =
                        {'D','e','f','a','u','l','t',' ','S','h','a','r','e',0};
        wchar16_t wszServiceType[] = LWIO_SRV_SHARE_STRING_ID_DISK_W;

        ntStatus = SrvGetDefaultSharePath(&pszDefaultSharePath);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = SrvMbsToWc16s(pszDefaultSharePath, &pwszFileSystemRoot);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = SrvCreateDefaultSharePath(pwszFileSystemRoot);
        BAIL_ON_NT_STATUS(ntStatus);

        ntStatus = SrvShareAdd(
                        pShareList,
                        &wszFileRootName[0],
                        pwszFileSystemRoot,
                        &wszDesc[0],
                        NULL,
                        0,
                        &wszServiceType[0],
                        0);
    }
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    SRV_SAFE_FREE_MEMORY(pszDefaultSharePath);
    SRV_SAFE_FREE_MEMORY(pwszFileSystemRoot);

    return ntStatus;

error:

    LWIO_LOG_ERROR("Failed to bootstrap default shares. [error code: %d]",
                   ntStatus);

    goto cleanup;
}
예제 #2
0
static
VOID
SrvSession2Free(
    PLWIO_SRV_SESSION_2 pSession
    )
{
    LWIO_LOG_DEBUG("Freeing session [object:0x%x][uid:%u]",
                    pSession,
                    pSession->ullUid);

    if (pSession->pMutex)
    {
        pthread_rwlock_destroy(&pSession->mutex);
        pSession->pMutex = NULL;
    }

    if (pSession->pTreeCollection)
    {
        LwRtlRBTreeFree(pSession->pTreeCollection);
    }

    if (pSession->hFinderRepository)
    {
        SrvFinderCloseRepository(pSession->hFinderRepository);
    }

    SRV_SAFE_FREE_MEMORY(pSession->pwszClientPrincipalName);

    if (pSession->pIoSecurityContext) {
        IoSecurityDereferenceSecurityContext(&pSession->pIoSecurityContext);
    }

    SrvFreeMemory(pSession);
}
예제 #3
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;
}
예제 #4
0
NTSTATUS
SrvSession2SetPrincipalName(
    PLWIO_SRV_SESSION_2 pSession,
    PCSTR               pszClientPrincipal
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    BOOLEAN  bInLock  = FALSE;

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pSession->mutex);

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

    SRV_SAFE_FREE_MEMORY(pSession->pwszClientPrincipalName);

    ntStatus = SMBMbsToWc16s(
                    pszClientPrincipal,
                    &pSession->pwszClientPrincipalName);
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &pSession->mutex);

    return ntStatus;

error:

    goto cleanup;
}
예제 #5
0
NTSTATUS
SrvSocketGetAddrInfoW(
    PCWSTR            pwszClientname,
    struct addrinfo** ppAddrInfo
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    struct addrinfo* pAddrInfo = NULL;
    PSTR   pszClientname = NULL;

    ntStatus = SrvWc16sToMbs(pwszClientname, &pszClientname);
    BAIL_ON_NT_STATUS(ntStatus);

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

    *ppAddrInfo = pAddrInfo;

cleanup:

    SRV_SAFE_FREE_MEMORY(pszClientname);

    return ntStatus;

error:

    *ppAddrInfo = NULL;

    if (pAddrInfo)
    {
        freeaddrinfo(pAddrInfo);
    }

    goto cleanup;
}
예제 #6
0
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;
}
예제 #7
0
파일: echo.c 프로젝트: bhanug/likewise-open
static
VOID
SrvLogEchoState_SMB_V1(
    PSRV_LOG_CONTEXT pLogContext,
    LWIO_LOG_LEVEL   logLevel,
    PCSTR            pszFunction,
    PCSTR            pszFile,
    ULONG            ulLine,
    ...
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PECHO_REQUEST_HEADER pEchoHeader = NULL; // Do not Free
    PBYTE                pEchoBlob   = NULL; // Do Not Free
    PSTR  pszHexString = NULL;
    ULONG ulLen = 0;
    va_list msgList;

    va_start(msgList, ulLine);

    pEchoHeader = va_arg(msgList, PECHO_REQUEST_HEADER);
    pEchoBlob   = va_arg(msgList, PBYTE);

    if (pEchoHeader)
    {
        if (pEchoHeader->byteCount)
        {
            ntStatus = SrvGetHexDump(
                            pEchoBlob,
                            pEchoHeader->byteCount,
                            SrvLogContextGetMaxLogLength(pLogContext),
                            &pszHexString,
                            &ulLen);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        LW_RTL_LOG_RAW(
            logLevel,
            "srv",
            pszFunction,
            pszFile,
            ulLine,
            "Delete directory state: EchoCount(%u),EchoBlob[%u/%u bytes](%s)",
            pEchoHeader->echoCount,
            ulLen,
            pEchoHeader->byteCount,
            LWIO_SAFE_LOG_STRING(pszHexString));
    }

error:

    va_end(msgList);

    SRV_SAFE_FREE_MEMORY(pszHexString);

    return;
}
예제 #8
0
static
VOID
SrvLogOpenState_SMB_V1(
    PSRV_LOG_CONTEXT pLogContext,
    LWIO_LOG_LEVEL   logLevel,
    PCSTR            pszFunction,
    PCSTR            pszFile,
    ULONG            ulLine,
    ...
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSRV_OPEN_STATE_SMB_V1 pOpenState = NULL;
    PSTR pszPath = NULL;
    va_list msgList;

    va_start(msgList, ulLine);

    pOpenState = va_arg(msgList, PSRV_OPEN_STATE_SMB_V1);

    if (pOpenState)
    {
        ntStatus = SrvUnicodeStringToMbs(
                        &pOpenState->pFilename->Name,
                        &pszPath);
        BAIL_ON_NT_STATUS(ntStatus);

        LW_RTL_LOG_RAW(
            logLevel,
            "srv",
            pszFunction,
            pszFile,
            ulLine,
            "Open state: "
            "alloc-size(%u),creation-time(0x%x),desired-access(0x%x),"
            "file-attrs(0x%x),flags(0x%x),open-function(%u),"
            "search-attrs(0x%x),path(%s)",
            pOpenState->pRequestHeader->ulAllocationSize,
            pOpenState->pRequestHeader->ulCreationTime,
            pOpenState->pRequestHeader->usDesiredAccess,
            pOpenState->pRequestHeader->usFileAttributes,
            pOpenState->pRequestHeader->usFlags,
            pOpenState->pRequestHeader->usOpenFunction,
            pOpenState->pRequestHeader->usSearchAttributes,
            LWIO_SAFE_LOG_STRING(pszPath));
    }

error:

    va_end(msgList);

    SRV_SAFE_FREE_MEMORY(pszPath);

    return;
}
예제 #9
0
NTSTATUS
SrvShareRegEndEnum(
    IN HANDLE hRepository,
    IN HANDLE hResume
    )
{
    PSRV_SHARE_REG_ENUM_CONTEXT pEnumContext =
                                    (PSRV_SHARE_REG_ENUM_CONTEXT)hResume;

    SRV_SAFE_FREE_MEMORY(pEnumContext);

    return STATUS_SUCCESS;
}
예제 #10
0
VOID
SrvLogRequest_SMB_V1(
    PSRV_LOG_CONTEXT pLogContext,
    LWIO_LOG_LEVEL   logLevel,
    PCSTR            pszFunction,
    PCSTR            pszFile,
    ULONG            ulLine,
    ...
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSRV_EXEC_CONTEXT pExecContext = NULL;
    PSTR  pszBuffer = NULL;
    ULONG ulLen     = 0;
    va_list msgList;

    va_start(msgList, ulLine);

    pExecContext = va_arg(msgList, PSRV_EXEC_CONTEXT);

    if (pExecContext)
    {
        ntStatus = SrvGetHexDump(
                        (PBYTE)pExecContext->pSmbRequest->pSMBHeader,
                        pExecContext->pSmbRequest->bufferUsed - sizeof(NETBIOS_HEADER),
                        SrvLogContextGetMaxLogLength(pLogContext),
                        &pszBuffer,
                        &ulLen);
        BAIL_ON_NT_STATUS(ntStatus);

        LW_RTL_LOG_RAW(
            logLevel,
            "srv",
            pszFunction,
            pszFile,
            ulLine,
            "SMB Request:[%u/%u bytes][%s]",
            ulLen,
            pExecContext->pSmbRequest->bufferUsed - sizeof(NETBIOS_HEADER),
            LWIO_SAFE_LOG_STRING(pszBuffer));
    }

error:

    va_end(msgList);

    SRV_SAFE_FREE_MEMORY(pszBuffer);
}
예제 #11
0
static
VOID
SrvLogDeleteState_SMB_V1(
    PSRV_LOG_CONTEXT pLogContext,
    LWIO_LOG_LEVEL   logLevel,
    PCSTR            pszFunction,
    PCSTR            pszFile,
    ULONG            ulLine,
    ...
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSRV_DELETE_STATE_SMB_V1 pDeleteState = NULL;
    PSTR pszSearchPattern = NULL;
    va_list msgList;

    va_start(msgList, ulLine);

    pDeleteState = va_arg(msgList, PSRV_DELETE_STATE_SMB_V1);

    if (pDeleteState)
    {
        if (pDeleteState->pwszSearchPattern)
        {
            ntStatus = SrvWc16sToMbs(pDeleteState->pwszSearchPattern, &pszSearchPattern);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        LW_RTL_LOG_RAW(
            logLevel,
            "srv",
            pszFunction,
            pszFile,
            ulLine,
            "Delete directory state: SearchAttrs(0x%x),UseLongFilenames(%s),SearchPattern(%s)",
            pDeleteState->pRequestHeader->usSearchAttributes,
            pDeleteState->bUseLongFilenames ? "TRUE" : "FALSE",
            LWIO_SAFE_LOG_STRING(pszSearchPattern));
    }

error:

    va_end(msgList);

    SRV_SAFE_FREE_MEMORY(pszSearchPattern);

    return;
}
예제 #12
0
static
VOID
SrvLogCheckDirState_SMB_V1(
    PSRV_LOG_CONTEXT pLogContext,
    LWIO_LOG_LEVEL   logLevel,
    PCSTR            pszFunction,
    PCSTR            pszFile,
    ULONG            ulLine,
    ...
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSRV_CHECKDIR_STATE_SMB_V1 pCheckdirState = NULL;
    PSTR pszPath = NULL;
    va_list msgList;

    va_start(msgList, ulLine);

    pCheckdirState = va_arg(msgList, PSRV_CHECKDIR_STATE_SMB_V1);

    if (pCheckdirState)
    {
        if (pCheckdirState->pwszPathFragment)
        {
            ntStatus = SrvWc16sToMbs(pCheckdirState->pwszPathFragment, &pszPath);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        LW_RTL_LOG_RAW(
            logLevel,
            "lwio",
            pszFunction,
            pszFile,
            ulLine,
            "Check directory state: Path(%s)",
            LWIO_SAFE_LOG_STRING(pszPath));
    }

error:

    va_end(msgList);

    SRV_SAFE_FREE_MEMORY(pszPath);

    return;
}
예제 #13
0
NTSTATUS
SrvShareDbDelete(
    IN HANDLE hRepository,
    IN PWSTR  pwszShareName
    )
{
    NTSTATUS ntStatus = 0;
    PSRV_SHARE_DB_CONTEXT pDbContext = (PSRV_SHARE_DB_CONTEXT)hRepository;
    PSTR pszShareName = NULL;
    BOOLEAN bInLock = FALSE;

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

    ntStatus = SrvWc16sToMbs(pwszShareName, &pszShareName);
    BAIL_ON_NT_STATUS(ntStatus);

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gShareRepository_lwshare.dbMutex);

    if (!pDbContext->pDeleteStmt)
    {
        PCSTR pszQueryTemplate = "DELETE FROM " LWIO_SRV_SHARES_DB_TABLE_NAME \
                   " WHERE UPPER(" LWIO_SRV_SHARES_DB_COL_NAME ") = UPPER(?1)";

        ntStatus = sqlite3_prepare_v2(
                        pDbContext->pDbHandle,
                        pszQueryTemplate,
                        -1,
                        &pDbContext->pDeleteStmt,
                        NULL);
        BAIL_ON_LWIO_SRV_SQLITE_ERROR_DB(ntStatus, pDbContext->pDbHandle);
    }

    ntStatus = sqlite3_bind_text(
                    pDbContext->pDeleteStmt,
                    1,
                    pszShareName,
                    -1,
                    SQLITE_TRANSIENT);
    BAIL_ON_LWIO_SRV_SQLITE_ERROR_STMT(ntStatus, pDbContext->pDeleteStmt);

    if ((ntStatus = sqlite3_step(pDbContext->pDeleteStmt)) == SQLITE_DONE)
    {
        ntStatus = STATUS_SUCCESS;
    }
    BAIL_ON_LWIO_SRV_SQLITE_ERROR_STMT(ntStatus, pDbContext->pDeleteStmt);

cleanup:

    if (pDbContext)
    {
        if (pDbContext->pDeleteStmt)
        {
           sqlite3_reset(pDbContext->pDeleteStmt);
        }
    }

    LWIO_UNLOCK_RWMUTEX(bInLock, &gShareRepository_lwshare.dbMutex);

    SRV_SAFE_FREE_MEMORY(pszShareName);

    return ntStatus;

error:

    goto cleanup;
}
예제 #14
0
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;
}
예제 #15
0
NTSTATUS
SrvShareDbAdd(
    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;
    PSRV_SHARE_DB_CONTEXT pDbContext = NULL;
    PSTR pszShareName = NULL;
    PSTR pszPath = NULL;
    PSTR pszComment = NULL;
    PSTR pszService = NULL;
    BOOLEAN bInLock = FALSE;

    if (pwszShareName)
    {
        ntStatus = SrvWc16sToMbs(pwszShareName, &pszShareName);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    if (pwszPath)
    {
        ntStatus = SrvWc16sToMbs(pwszPath, &pszPath);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    if (pwszComment)
    {
        ntStatus = SrvWc16sToMbs(pwszComment, &pszComment);
        BAIL_ON_NT_STATUS(ntStatus);
    }
    if (pwszService)
    {
        ntStatus = SrvWc16sToMbs(pwszService, &pszService);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &gShareRepository_lwshare.dbMutex);

    pDbContext = (PSRV_SHARE_DB_CONTEXT)hRepository;

    ntStatus = SrvShareDbAdd_inlock(
                    pDbContext,
                    pszShareName,
                    pszPath,
                    pszComment,
                    pSecDesc,
                    ulSecDescLen,
                    pszService,
		    ulFlags);
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    LWIO_UNLOCK_RWMUTEX(bInLock, &gShareRepository_lwshare.dbMutex);

    SRV_SAFE_FREE_MEMORY(pszShareName);
    SRV_SAFE_FREE_MEMORY(pszPath);
    SRV_SAFE_FREE_MEMORY(pszComment);
    SRV_SAFE_FREE_MEMORY(pszService);

    return ntStatus;

error:

    goto cleanup;
}
예제 #16
0
NTSTATUS
SrvShareDbFindByName(
    HANDLE           hRepository,
    PWSTR            pwszShareName,
    PSRV_SHARE_INFO* ppShareInfo
    )
{
    NTSTATUS ntStatus = 0;
    PSRV_SHARE_INFO* ppShareInfoList = NULL;
    PSTR     pszShareName = NULL;
    BOOLEAN  bInLock = FALSE;
    ULONG    ulNumSharesFound = 0;
    PSRV_SHARE_DB_CONTEXT pDbContext = NULL;

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

    pDbContext = (PSRV_SHARE_DB_CONTEXT)hRepository;

    ntStatus = SrvWc16sToMbs(pwszShareName, &pszShareName);
    BAIL_ON_NT_STATUS(ntStatus);

    if (!pDbContext->pFindStmt)
    {
        PCSTR pszQueryTemplate = "SELECT " LWIO_SRV_SHARES_DB_COL_NAME    ","  \
                                           LWIO_SRV_SHARES_DB_COL_PATH    ","  \
                                           LWIO_SRV_SHARES_DB_COL_COMMENT ","  \
                                           LWIO_SRV_SHARES_DB_COL_SECDESC ","  \
                                           LWIO_SRV_SHARES_DB_COL_SERVICE      \
                                 " FROM "  LWIO_SRV_SHARES_DB_TABLE_NAME       \
                    " WHERE UPPER(" LWIO_SRV_SHARES_DB_COL_NAME ") = UPPER(?1)";

        ntStatus = sqlite3_prepare_v2(
                        pDbContext->pDbHandle,
                        pszQueryTemplate,
                        -1,
                        &pDbContext->pFindStmt,
                        NULL);
        BAIL_ON_LWIO_SRV_SQLITE_ERROR_DB(ntStatus, pDbContext->pDbHandle);
    }

    ntStatus = sqlite3_bind_text(
                    pDbContext->pFindStmt,
                    1,
                    pszShareName,
                    -1,
                    SQLITE_TRANSIENT);
    BAIL_ON_LWIO_SRV_SQLITE_ERROR_STMT(ntStatus, pDbContext->pFindStmt);

    LWIO_LOCK_RWMUTEX_SHARED(bInLock, &gShareRepository_lwshare.dbMutex);

    ntStatus = SrvShareDbWriteToShareInfo(
                    pDbContext->pFindStmt,
                    &ppShareInfoList,
                    &ulNumSharesFound);
    BAIL_ON_NT_STATUS(ntStatus);

    *ppShareInfo = *ppShareInfoList;

cleanup:

    if (pDbContext)
    {
        if (pDbContext->pFindStmt)
        {
            sqlite3_reset(pDbContext->pFindStmt);
        }
    }

    LWIO_UNLOCK_RWMUTEX(bInLock, &gShareRepository_lwshare.dbMutex);

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

    SRV_SAFE_FREE_MEMORY(pszShareName);

    return ntStatus;

error:

    *ppShareInfo = NULL;

    goto cleanup;
}
예제 #17
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;
}
예제 #18
0
NTSTATUS
SrvBuildNegotiateResponse_SMB_V1_NTLM_0_12(
    IN PLWIO_SRV_CONNECTION pConnection,
    IN PSMB_PACKET pSmbRequest,
    IN SMB_PROTOCOL_DIALECT Dialect,
    IN USHORT idxDialect,
    OUT PSMB_PACKET* ppSmbResponse
    )
{
    NTSTATUS ntStatus = 0;
    NEGOTIATE_RESPONSE_HEADER* pResponseHeader = NULL;
    time_t    curTime   = 0L;
    LONG64    llUTCTime = 0LL;
    uint16_t  byteCount = 0;
    uint8_t*  pDataCursor = NULL;
    PSRV_PROPERTIES pServerProperties = &pConnection->serverProperties;
    PSMB_PACKET pSmbResponse = NULL;
    PWSTR     pwszHostname = NULL;

    ntStatus = SMBPacketAllocate(
                    pConnection->hPacketAllocator,
                    &pSmbResponse);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = SMBPacketBufferAllocate(
                    pConnection->hPacketAllocator,
                    (64 * 1024) + 4096,
                    &pSmbResponse->pRawBuffer,
                    &pSmbResponse->bufferLen);
    BAIL_ON_NT_STATUS(ntStatus);

    if ((pSmbRequest->pSMBHeader->flags2 & FLAG2_EXT_SEC) == 0)
    {
        pServerProperties->Capabilities &= ~CAP_EXTENDED_SECURITY;
    }

    ntStatus = SMBPacketMarshallHeader(
                pSmbResponse->pRawBuffer,
                pSmbResponse->bufferLen,
                COM_NEGOTIATE,
                0,
                TRUE,
                pSmbRequest->pSMBHeader->tid,
                SMB_V1_GET_PROCESS_ID(pSmbRequest->pSMBHeader),
                0,
                pSmbRequest->pSMBHeader->mid,
                FALSE,
                pSmbResponse);
    BAIL_ON_NT_STATUS(ntStatus);
    if ((pServerProperties->Capabilities & CAP_EXTENDED_SECURITY) == 0)
    {
        pSmbResponse->pSMBHeader->flags2 &= ~FLAG2_EXT_SEC;
    }

    pSmbResponse->pSMBHeader->wordCount = 17;

    pResponseHeader = (NEGOTIATE_RESPONSE_HEADER*)pSmbResponse->pParams;
    pSmbResponse->pData = pSmbResponse->pParams + sizeof(NEGOTIATE_RESPONSE_HEADER);
    pSmbResponse->bufferUsed += sizeof(NEGOTIATE_RESPONSE_HEADER);

    pResponseHeader->dialectIndex = idxDialect;

    pResponseHeader->securityMode = 0;
    if (pServerProperties->preferredSecurityMode == SMB_SECURITY_MODE_USER)
    {
        pResponseHeader->securityMode |= 0x1; // User level security
    }
    if (pServerProperties->bEncryptPasswords)
    {
        pResponseHeader->securityMode |= 0x2;
    }
    if (pServerProperties->bEnableSecuritySignatures)
    {
        pResponseHeader->securityMode |= 0x4;
    }
    if (pServerProperties->bRequireSecuritySignatures)
    {
        pResponseHeader->securityMode |= 0x8;
    }

    pResponseHeader->maxMpxCount = pServerProperties->MaxMpxCount;
    pResponseHeader->maxNumberVcs = pServerProperties->MaxNumberVCs;
    pResponseHeader->maxBufferSize = pServerProperties->MaxBufferSize;
    pResponseHeader->maxRawSize = pServerProperties->MaxRawSize;
    pResponseHeader->sessionKey = 0;
    pResponseHeader->capabilities = pServerProperties->Capabilities;

    curTime = time(NULL);

    ntStatus = WireSMBUTimeToTimeZone(curTime, &pResponseHeader->serverTimeZone);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = WireSMBUTimetoNTTime(curTime, FALSE, &llUTCTime);
    BAIL_ON_NT_STATUS(ntStatus);

    pResponseHeader->systemTimeLow = llUTCTime & 0xFFFFFFFFLL;
    pResponseHeader->systemTimeHigh = (llUTCTime & 0xFFFFFFFF00000000LL) >> 32;

    pDataCursor = pSmbResponse->pData;
    if (pResponseHeader->capabilities & CAP_EXTENDED_SECURITY)
    {
        PBYTE pNegHintsBlob = NULL; /* Do not free */
        ULONG ulNegHintsLength = 0;

        pResponseHeader->encryptionKeyLength = 0;

        memcpy(pDataCursor, pServerProperties->GUID, sizeof(pServerProperties->GUID));
        pDataCursor += sizeof(pServerProperties->GUID);

        byteCount += sizeof(pServerProperties->GUID);

        ntStatus = SrvGssNegHints(&pNegHintsBlob, &ulNegHintsLength);

        /* Microsoft clients ignore the security blob on the neg prot response
           so don't fail here if we can't get a negHintsBlob */

        if (ntStatus == STATUS_SUCCESS)
        {
            memcpy(pDataCursor, pNegHintsBlob, ulNegHintsLength);
            pDataCursor += ulNegHintsLength;
            byteCount += ulNegHintsLength;
        }
    }
    else
    {
        WCHAR wszWorkgroup[] = SRV_NATIVE_DOMAIN_W;
        CHAR  szHostname[HOST_NAME_MAX];
        PWSTR pwszDomain = pConnection->clientProperties.pwszNativeDomain;

        if (!pwszDomain)
        {
            pwszDomain = &wszWorkgroup[0];
        }

        if (gethostname(szHostname, HOST_NAME_MAX) == -1)
        {
            ntStatus = LwErrnoToNtStatus(errno);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        pResponseHeader->encryptionKeyLength =
            sizeof(pConnection->ServerChallenge);

        // Generate challenge and remember it in connection
        if (!RAND_bytes( pConnection->ServerChallenge,
                         sizeof(pConnection->ServerChallenge)))
        {
            ntStatus = STATUS_INTERNAL_ERROR;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        RtlCopyMemory(pDataCursor, &pConnection->ServerChallenge,
                      sizeof(pConnection->ServerChallenge));
        pDataCursor += sizeof(pConnection->ServerChallenge);
        byteCount += sizeof(pConnection->ServerChallenge);

        // Add domain name
        {
            size_t sDomainLen = (wc16slen(pwszDomain)+1) * sizeof(wchar16_t);

            RtlCopyMemory(pDataCursor, pwszDomain, sDomainLen);
            pDataCursor += sDomainLen;
            byteCount += sDomainLen;
        }

        // Add hostname
        {
            size_t sHostnameLen = 0;

            ntStatus = SrvMbsToWc16s(szHostname, &pwszHostname);
            BAIL_ON_NT_STATUS(ntStatus);

            sHostnameLen = (wc16slen(pwszHostname)+1) * sizeof(wchar16_t);
            RtlCopyMemory(pDataCursor, pwszHostname, sHostnameLen);
            pDataCursor += sHostnameLen;
            byteCount += sHostnameLen;
        }
    }

    pResponseHeader->byteCount = byteCount;
    pSmbResponse->bufferUsed += byteCount;

    ntStatus = SMBPacketMarshallFooter(pSmbResponse);
    BAIL_ON_NT_STATUS(ntStatus);

    *ppSmbResponse = pSmbResponse;

cleanup:

    SRV_SAFE_FREE_MEMORY(pwszHostname);

    return ntStatus;

error:

    *ppSmbResponse = NULL;

    if (pSmbResponse)
    {
        SMBPacketRelease(pConnection->hPacketAllocator, pSmbResponse);
    }

    goto cleanup;
}
예제 #19
0
static
NTSTATUS
SrvProtocolEnumCandidateConnections(
    PVOID    pKey,
    PVOID    pData,
    PVOID    pUserData,
    PBOOLEAN pbContinue
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PLWIO_SRV_CONNECTION pConnection = (PLWIO_SRV_CONNECTION)pData;
    PSRV_PROTOCOL_CONNECTION_ENUM_QUERY pConnectionEnumQuery =
                                    (PSRV_PROTOCOL_CONNECTION_ENUM_QUERY)pUserData;
    BOOLEAN bInLock = FALSE;
    PWSTR pwszClientHost = NULL;

    if (pConnectionEnumQuery->pQueryAddress)
    {
        /*
         * Look for connections by computer address first in case
         * that was the qualifier string
         */
        struct addrinfo* pCursor = pConnectionEnumQuery->pQueryAddress;
        BOOLEAN bMatch = FALSE;

        for (; !bMatch && (pCursor != NULL); pCursor = pCursor->ai_next)
        {
            ntStatus = SrvSocketCompareAddress(
                            pConnection->pClientAddress,
                            pConnection->clientAddrLen,
                            pCursor->ai_addr,
                            pCursor->ai_addrlen,
                            &bMatch);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        if (!bMatch)
        {
            pConnection = NULL;
        }
    }

    if (pConnection)
    {
        LWIO_LOCK_RWMUTEX_SHARED(bInLock, &pConnection->mutex);

        ntStatus = SrvSocketAddressToStringW(pConnection->pClientAddress,
                                             &pwszClientHost);
        BAIL_ON_NT_STATUS(ntStatus);

        pConnectionEnumQuery->pwszClientHost    = pwszClientHost;
        pConnectionEnumQuery->pClientAddress    = pConnection->pClientAddress;
        pConnectionEnumQuery->clientAddrLen     = pConnection->clientAddrLen;
        pConnectionEnumQuery->ulConnectionResId
            = pConnection->resource.ulResourceId;

        ntStatus = WireGetCurrentNTTime(&pConnectionEnumQuery->llCurTime);
        BAIL_ON_NT_STATUS(ntStatus);

        switch (SrvConnectionGetProtocolVersion(pConnection))
        {
            case SMB_PROTOCOL_VERSION_1:
                ntStatus = LwRtlRBTreeTraverse(
                                pConnection->pSessionCollection,
                                LWRTL_TREE_TRAVERSAL_TYPE_IN_ORDER,
                                &SrvProtocolProcessCandidateConnection,
                                pConnectionEnumQuery);
                break;

            case SMB_PROTOCOL_VERSION_2:
                ntStatus = LwRtlRBTreeTraverse(
                                pConnection->pSessionCollection,
                                LWRTL_TREE_TRAVERSAL_TYPE_IN_ORDER,
                                &SrvProtocolProcessCandidateConnection2,
                                pConnectionEnumQuery);
                break;

            case SMB_PROTOCOL_VERSION_UNKNOWN:
                /* Ignore connections that are still being established */
                break;

            default:
                ntStatus = STATUS_INTERNAL_ERROR;
                break;
        }
        BAIL_ON_NT_STATUS(ntStatus);
    }

    *pbContinue = TRUE;

cleanup:
    pConnectionEnumQuery->pClientAddress  = NULL;
    pConnectionEnumQuery->clientAddrLen   = 0;
    pConnectionEnumQuery->pwszClientHost  = NULL;

    SRV_SAFE_FREE_MEMORY(pwszClientHost);

    LWIO_UNLOCK_RWMUTEX(bInLock, &pConnection->mutex);

    return ntStatus;

error:
    *pbContinue = FALSE;

    goto cleanup;
}
예제 #20
0
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;
}
예제 #21
0
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;
}
예제 #22
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;
}