Exemplo n.º 1
0
NTSTATUS
PvfsCanonicalPathName(
    PSTR *ppszPath,
    IO_FILE_NAME IoPath
    )
{
    PPVFS_CCB pRootCcb = NULL;
    NTSTATUS ntError = STATUS_SUCCESS;
    PSTR pszFilename = NULL;
    PSTR pszCompletePath = NULL;

    if (IoPath.FileName)
    {
        ntError = PvfsWC16CanonicalPathName(&pszFilename, IoPath.FileName);
        BAIL_ON_NT_STATUS(ntError);
    }

    if (IoPath.RootFileHandle)
    {
        ntError = PvfsAcquireCCB(IoPath.RootFileHandle, &pRootCcb);
        BAIL_ON_NT_STATUS(ntError);

        ntError = LwRtlCStringAllocatePrintf(
            &pszCompletePath,
            "%s%s%s",
            pRootCcb->pszFilename,
            (pszFilename ? (*pszFilename == '/' ? "" : "/") : ""),
            (pszFilename ? pszFilename : ""));
        BAIL_ON_NT_STATUS(ntError);
    }
    else
    {
        pszCompletePath = pszFilename;
        pszFilename = NULL;
    }

    if (!pszCompletePath)
    {
        ntError = STATUS_OBJECT_NAME_INVALID;
        BAIL_ON_NT_STATUS(ntError);
    }


    *ppszPath = pszCompletePath;

cleanup:
    LwRtlCStringFree(&pszFilename);

    if (pRootCcb)
    {
        PvfsReleaseCCB(pRootCcb);
    }

    return ntError;

error:
    LwRtlCStringFree(&pszCompletePath);

    goto cleanup;
}
Exemplo n.º 2
0
VOID
NtRegCloseConfig(
    PLWREG_CONFIG_REG pReg
    )
{
    if (pReg)
    {
        LwRtlCStringFree(&pReg->pszConfigKey);

        LwRtlCStringFree(&pReg->pszPolicyKey);

        if (pReg->hConnection)
        {
            if ( pReg->hKey )
            {
                NtRegCloseKey(pReg->hConnection, pReg->hKey);
                pReg->hKey = NULL;
            }
            NtRegCloseServer(pReg->hConnection);
            pReg->hConnection = NULL;
        }

        RTL_FREE(&pReg);
    }
}
Exemplo n.º 3
0
NTSTATUS
PvfsSysStatByFileName(
    IN PPVFS_FILE_NAME FileName,
    IN OUT PPVFS_STAT Stat
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PSTR fileName = NULL;

    ntError = PvfsLookupStreamDiskFileName(&fileName, FileName);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSysStat(fileName, Stat);
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    if (fileName)
    {
        LwRtlCStringFree(&fileName);
    }

    return ntError;

error:
    goto cleanup;
}
Exemplo n.º 4
0
NTSTATUS
PvfsSysMkDirByFileName(
    IN PPVFS_FILE_NAME DirectoryName,
    mode_t mode
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PSTR directoryName = NULL;

    PVFS_BAIL_ON_INVALID_FILENAME(DirectoryName, ntError);

    // Data stream is not directory
    if (!PvfsIsDefaultStreamName(DirectoryName))
    {
        ntError = STATUS_NOT_A_DIRECTORY;
        BAIL_ON_NT_STATUS(ntError);
    }

    ntError = PvfsLookupStreamDiskFileName(&directoryName, DirectoryName);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSysMkDir(directoryName, mode);
    BAIL_ON_NT_STATUS(ntError);

error:
    if (directoryName)
    {
        LwRtlCStringFree(&directoryName);
    }

    return ntError;
}
Exemplo n.º 5
0
NTSTATUS
PvfsSysChownByFileName(
    IN PPVFS_FILE_NAME pFileName,
    uid_t uid,
    gid_t gid
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    int unixerr = 0;
    PSTR pszFilename = NULL;

    ntError = PvfsLookupStreamDiskFileName(&pszFilename, pFileName);
    BAIL_ON_NT_STATUS(ntError);

    if (chown(pszFilename, uid, gid) == -1)
    {
        PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError);
    }

error:
    if (pszFilename)
    {
        LwRtlCStringFree(&pszFilename);
    }

    return ntError;
}
Exemplo n.º 6
0
static
NTSTATUS
PvfsFindParentFCB(
    PPVFS_FCB *ppParentFcb,
    PCSTR pszFilename
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_FCB pFcb = NULL;
    PSTR pszDirname = NULL;
    PPVFS_CB_TABLE_ENTRY pBucket = NULL;

    if (LwRtlCStringIsEqual(pszFilename, "/", TRUE))
    {
        ntError = STATUS_SUCCESS;
        *ppParentFcb = NULL;

        goto cleanup;
    }

    ntError = PvfsFileDirname(&pszDirname, pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsCbTableGetBucket(&pBucket, &gPvfsDriverState.FcbTable, pszDirname);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsCbTableLookup((PPVFS_CONTROL_BLOCK*)OUT_PPVOID(&pFcb), pBucket, pszDirname);
    if (ntError == STATUS_OBJECT_NAME_NOT_FOUND)
    {
        ntError = PvfsCreateFCB(
                      &pFcb,
                      pszDirname,
                      FALSE,
                      0,
                      0);
    }
    BAIL_ON_NT_STATUS(ntError);

    *ppParentFcb = PvfsReferenceFCB(pFcb);

cleanup:
    if (pFcb)
    {
        PvfsReleaseFCB(&pFcb);
    }

    if (pszDirname)
    {
        LwRtlCStringFree(&pszDirname);
    }

    return ntError;

error:

    goto cleanup;
}
Exemplo n.º 7
0
VOID
SrvStatsConfigFreeContents(
    PSRV_STATISTICS_CONFIG pConfig
    )
{
    LwRtlCStringFree(&pConfig->pszProviderPath);

    memset(pConfig, 0, sizeof(*pConfig));
}
Exemplo n.º 8
0
NTSTATUS
NtRegReadConfigEnum(
    PLWREG_CONFIG_REG pReg,
    PCSTR   pszName,
    BOOLEAN bUsePolicy,
    DWORD   dwMin,
    DWORD   dwMax,
    const PCSTR   *ppszEnumNames,
    PDWORD  pdwValue
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PSTR pszValue = NULL;
    DWORD dwEnumIndex = 0;

    ntStatus = NtRegReadConfigString(
                pReg,
                pszName,
                bUsePolicy,
                &pszValue,
                NULL);
    BAIL_ON_NT_STATUS(ntStatus);

    if (pszValue != NULL )
    {
        for (dwEnumIndex = 0;
             dwEnumIndex <= dwMax - dwMin;
             dwEnumIndex++)
        {
            if(LwRtlCStringCompare(
                   pszValue,
                   ppszEnumNames[dwEnumIndex], FALSE) == 0)
            {
                *pdwValue = dwEnumIndex + dwMin;
                break;
            }
        }
    }

cleanup:
    LwRtlCStringFree(&pszValue);

    return ntStatus;

error:
    goto cleanup;
}
Exemplo n.º 9
0
DWORD
DNSGetPtrNameForAddr(
    PSTR* ppszRecordName,
    PSOCKADDR_IN pAddr
    )
{
    DWORD dwError = 0;
    PSTR pszRecordName = NULL;
    DWORD dwIPV4Addr = ntohl(pAddr->sin_addr.s_addr);

    if (pAddr->sin_family != AF_INET)
    {
        dwError = LWDNS_ERROR_INVALID_IP_ADDRESS;
        BAIL_ON_LWDNS_ERROR(dwError);
    }

    dwError = LwRtlCStringAllocatePrintf(
                    &pszRecordName,
                    "%d.%d.%d.%d.in-addr.arpa",
                    (dwIPV4Addr >>  0) & 255,
                    (dwIPV4Addr >>  8) & 255,
                    (dwIPV4Addr >> 16) & 255,
                    (dwIPV4Addr >> 24) & 255
                );
    if (dwError)
    {
        dwError = ENOMEM;
        BAIL_ON_LWDNS_ERROR(dwError);
    }

    *ppszRecordName = pszRecordName;

cleanup:
    return dwError;

error:
    *ppszRecordName = NULL;
    LwRtlCStringFree(&pszRecordName);

    goto cleanup;
}
Exemplo n.º 10
0
static
VOID
PvfsNotifyFullReportCtxFree(
    PPVFS_NOTIFY_REPORT_RECORD *ppReport
    )
{
    PPVFS_NOTIFY_REPORT_RECORD pReport = NULL;

    if (ppReport && *ppReport)
    {
        pReport = (PPVFS_NOTIFY_REPORT_RECORD)*ppReport;

        if (pReport->pFcb)
        {
            PvfsReleaseFCB(&pReport->pFcb);
        }

        LwRtlCStringFree(&pReport->pszFilename);

        PVFS_FREE(ppReport);
    }

    return;
}
Exemplo n.º 11
0
NTSTATUS
PvfsAccessCheckFileEnumerate(
    PPVFS_CCB pCcb,
    PCSTR pszRelativeFilename
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PACCESS_TOKEN pToken = pCcb->pUserToken;
    PSTR pszFilename = NULL;
    ACCESS_MASK AccessMask = 0;
    ACCESS_MASK GrantedAccess = 0;
    PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
    BYTE pRelativeSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE];
    ULONG ulRelativeSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;
    BOOLEAN bGranted = FALSE;
    SECURITY_INFORMATION SecInfo = (OWNER_SECURITY_INFORMATION |
                                    GROUP_SECURITY_INFORMATION |
                                    DACL_SECURITY_INFORMATION  |
                                    SACL_SECURITY_INFORMATION);
    ACCESS_MASK Desired = (FILE_READ_ATTRIBUTES|
                           FILE_READ_EA|
                           FILE_READ_DATA|
                           READ_CONTROL);
    PSID pOwner = NULL;
    BOOLEAN bOwnerDefaulted = FALSE;

    /* Create the absolute path */

    ntError = LwRtlCStringAllocatePrintf(
                  &pszFilename,
                  "%s/%s",
                  pCcb->pScb->pOwnerFcb->pszFilename,
                  pszRelativeFilename);
    BAIL_ON_NT_STATUS(ntError);

    /* Check the file object itself */

    ntError = PvfsGetSecurityDescriptorFilename(
                  pszFilename,
                  SecInfo,
                  (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pRelativeSecDescBuffer),
                  &ulRelativeSecDescLength);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSecurityAclSelfRelativeToAbsoluteSD(
                  &pSecDesc,
                  (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pRelativeSecDescBuffer));
    BAIL_ON_NT_STATUS(ntError);

    // Tests against NTFS/Win2003R2 show that the file/directory object
    // owner is always granted FILE_READ_ATTRIBUTE

    ntError = RtlGetOwnerSecurityDescriptor(
                  pSecDesc,
                  &pOwner,
                  &bOwnerDefaulted);
    BAIL_ON_NT_STATUS(ntError);

    if (RtlIsSidMemberOfToken(pToken, pOwner))
    {
        ClearFlag(Desired, FILE_READ_ATTRIBUTES);
        SetFlag(GrantedAccess, FILE_READ_ATTRIBUTES);
    }

    /* Now check access */

    bGranted = RtlAccessCheck(
                   pSecDesc,
                   pToken,
                   Desired,
                   GrantedAccess,
                   &gPvfsDriverState.GenericSecurityMap,
                   &AccessMask,
                   &ntError);
    if (!bGranted)
    {
        ntError = STATUS_ACCESS_DENIED;
    }
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    if (pszFilename)
    {
        LwRtlCStringFree(&pszFilename);
    }

    if (pSecDesc)
    {
        PvfsFreeAbsoluteSecurityDescriptor(&pSecDesc);
    }

    return ntError;

error:
    goto cleanup;
}
Exemplo n.º 12
0
NTSTATUS
PvfsSysRemoveByFileName(
    IN PPVFS_FILE_NAME FileName
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PSTR fileName = NULL;
    PSTR streamDir = NULL;
    PVFS_STAT streamDirStat = { 0 };
    PVFS_STAT fileStat = { 0 };
    PSTR pszMetaDataPath = NULL;

    ntError = PvfsLookupStreamDiskFileName(&fileName, FileName);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSysStat(fileName, &fileStat);
    if (ntError == STATUS_SUCCESS)
    {
        if(S_ISDIR(fileStat.s_mode))
        {
            ntError = LwRtlCStringAllocatePrintf(
                          &pszMetaDataPath,
                          "%s/%s",
                          fileName,
                          PVFS_STREAM_METADATA_DIR_NAME);
            BAIL_ON_NT_STATUS(ntError);

            if (PvfsSysIsEmptyDir(pszMetaDataPath))
            {
                ntError = PvfsSysRemove(pszMetaDataPath);
                BAIL_ON_NT_STATUS(ntError);
            }
        }
    }
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSysRemove(fileName);
    BAIL_ON_NT_STATUS(ntError);

    if (PvfsIsDefaultStreamName(FileName))
    {
        // Have to remove the stream directory as well

        ntError = PvfsLookupStreamDirectoryPath(&streamDir, FileName);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysStat(streamDir, &streamDirStat);
        if (ntError == STATUS_SUCCESS)
        {
            ntError = PvfsSysRemoveDir(streamDir) ;
            BAIL_ON_NT_STATUS(ntError);
        }
        else
        {
            // Squash the error is the stream directory did not exist
            ntError = STATUS_SUCCESS;
        }
        BAIL_ON_NT_STATUS(ntError);
    }

error:
    if (fileName)
    {
        LwRtlCStringFree(&fileName);
    }
    if (streamDir)
    {
        LwRtlCStringFree(&streamDir);
    }
    if (pszMetaDataPath)
    {
        LwRtlCStringFree(&pszMetaDataPath);
    }

    return ntError;
}
Exemplo n.º 13
0
NTSTATUS
PvfsLookupPath(
    PSTR *ppszDiskPath,
    PCSTR pszPath,
    BOOLEAN bCaseSensitive
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PVFS_STAT Stat = {0};
    PSTR pszDiskPath = NULL;

    /* Check the cache */

    ntError = PvfsPathCacheLookup(&pszDiskPath, pszPath);
    if (ntError == STATUS_SUCCESS)
    {
        /* Check that the path is still good.  If not fallback
           to manual checks */

        ntError = PvfsSysStat(pszDiskPath, &Stat);
        if (ntError == STATUS_SUCCESS) {
            *ppszDiskPath = pszDiskPath;
            pszDiskPath = NULL;
            goto cleanup;
        }

        LwRtlCStringFree(&pszDiskPath);
        pszDiskPath = NULL;
    }

    /* See if we are lucky */

    ntError = PvfsSysStat(pszPath, &Stat);
    if (ntError == STATUS_SUCCESS)
    {
        ntError = RtlCStringDuplicate(ppszDiskPath, pszPath);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsPathCacheAdd(*ppszDiskPath);
        BAIL_ON_NT_STATUS(ntError);

        goto cleanup;
    }

    /* Done if use case sensitive matches */

    if (bCaseSensitive) {
        ntError = STATUS_OBJECT_NAME_NOT_FOUND;
        BAIL_ON_NT_STATUS(ntError);
    }

    /* Resolve the path */

    ntError = PvfsResolvePath(ppszDiskPath, pszPath);
    BAIL_ON_NT_STATUS(ntError);

    /* This should succeed now */
    ntError = PvfsSysStat(*ppszDiskPath, &Stat);
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    LwRtlCStringFree(&pszDiskPath);

    return ntError;

error:
    LwRtlCStringFree(ppszDiskPath);

    goto cleanup;
}
Exemplo n.º 14
0
static
NTSTATUS
PvfsSysRemoveDir(
    PSTR pszDirname
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    DIR *pDir = NULL;
    struct dirent *pDirEntry = NULL;
    struct dirent dirEntry = { 0 };
    PSTR pszPath = NULL;
    PVFS_STAT streamDirStat = { 0 };

    ntError = PvfsSysOpenDir(pszDirname, &pDir);
    BAIL_ON_NT_STATUS(ntError);

    for (ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry);
            pDirEntry;
            ntError = PvfsSysReadDir(pDir, &dirEntry, &pDirEntry))
    {
        /* First check the error return */
        BAIL_ON_NT_STATUS(ntError);

        memset(&streamDirStat, 0, sizeof(PVFS_STAT));
        if (pszPath)
        {
            LwRtlCStringFree(&pszPath);
        }

        ntError = LwRtlCStringAllocatePrintf(
                      &pszPath,
                      "%s/%s",
                      pszDirname,
                      pDirEntry->d_name);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysStat(pszPath, &streamDirStat);
        if (ntError == STATUS_SUCCESS)
        {
            if(S_ISDIR(streamDirStat.s_mode))
            {
                if (!LwRtlCStringIsEqual(pDirEntry->d_name, ".", FALSE) &&
                        !LwRtlCStringIsEqual(pDirEntry->d_name, "..", FALSE))
                {
                    ntError = PvfsSysRemoveDir(pszPath);
                    BAIL_ON_NT_STATUS(ntError);
                }
            }
            else
            {
                ntError = PvfsSysRemove(pszPath);
                BAIL_ON_NT_STATUS(ntError);
            }
        }
        else
        {
            // Squash the error is the stream directory did not exist
            ntError = STATUS_SUCCESS;
        }
    }

    ntError = PvfsSysCloseDir(pDir);
    BAIL_ON_NT_STATUS(ntError);
    pDir = NULL;

    ntError = PvfsSysRemove(pszDirname);
    BAIL_ON_NT_STATUS(ntError);

error:
    if (pszPath)
    {
        LwRtlCStringFree(&pszPath);
    }

    if (pDir)
    {
        PvfsSysCloseDir(pDir);
    }

    return ntError;
}
Exemplo n.º 15
0
static
NTSTATUS
PvfsRenameFile(
    PPVFS_CCB pCcb,
    PPVFS_FILE_NAME pNewFileName
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PPVFS_CB_TABLE scbTable = &gPvfsDriverState.ScbTable;
    PPVFS_CB_TABLE_ENTRY pTargetBucket = NULL;
    PPVFS_CB_TABLE_ENTRY pCurrentBucket = NULL;
    BOOLEAN renameLock = FALSE;
    BOOLEAN targetBucketLock = FALSE;
    BOOLEAN currentBucketLock = FALSE;
    PPVFS_FCB pFcb = NULL;
    PLW_LIST_LINKS scbCursorLink = NULL;
    PPVFS_SCB scbCursor = NULL;
    BOOLEAN scbMutexLock = FALSE;
    BOOLEAN fcbListLocked = FALSE;
    PPVFS_FILE_NAME origTargetFileName = NULL;
    PPVFS_FILE_NAME scbCursorFileName = NULL;
    PSTR origFullStreamName = NULL;
    PSTR newFullStreamName = NULL;

    // The CCB holds out reference down the chain so no need to take a new one
    pFcb = pCcb->pScb->pOwnerFcb;

    ntError = PvfsAllocateFileNameFromScb(&origTargetFileName, pCcb->pScb);
    BAIL_ON_NT_STATUS(ntError);

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(renameLock, &scbTable->rwLock);
    LWIO_LOCK_RWMUTEX_SHARED(fcbListLocked, &pFcb->rwScbLock);

    ntError = PvfsRenameFCB(pFcb, pCcb, pNewFileName);
    BAIL_ON_NT_STATUS(ntError);

    for (scbCursorLink = PvfsListTraverse(pFcb->pScbList, NULL);
         scbCursorLink;
         scbCursorLink = PvfsListTraverse(pFcb->pScbList, scbCursorLink))
    {
        scbCursor = LW_STRUCT_FROM_FIELD(
                          scbCursorLink,
                          PVFS_SCB,
                          FcbList);

        ntError = PvfsAllocateFileNameFromScb(&scbCursorFileName, scbCursor);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsAllocateCStringFromFileName(
                      &newFullStreamName,
                      scbCursorFileName);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsRenameBaseFileName(
                      scbCursorFileName,
                      PvfsGetCStringBaseFileName(origTargetFileName));
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsAllocateCStringFromFileName(
                      &origFullStreamName,
                      scbCursorFileName);
        BAIL_ON_NT_STATUS(ntError);

        pCurrentBucket = scbCursor->BaseControlBlock.pBucket;

        ntError = PvfsCbTableGetBucket(&pTargetBucket, scbTable, newFullStreamName);
        BAIL_ON_NT_STATUS(ntError);

        LWIO_LOCK_MUTEX(scbMutexLock, &scbCursor->BaseControlBlock.Mutex);
        LWIO_LOCK_RWMUTEX_EXCLUSIVE(currentBucketLock, &pCurrentBucket->rwLock);
        if (pCurrentBucket != pTargetBucket)
        {
            // Will be moved to a new bucket in the table
            LWIO_LOCK_RWMUTEX_EXCLUSIVE(targetBucketLock, &pTargetBucket->rwLock);
        }

        ntError = PvfsCbTableRemove_inlock(
                      (PPVFS_CONTROL_BLOCK)scbCursor,
                      origFullStreamName);
        LWIO_ASSERT(STATUS_SUCCESS == ntError);

        ntError = PvfsCbTableAdd_inlock(
                      pTargetBucket,
                      newFullStreamName,
                     (PPVFS_CONTROL_BLOCK)scbCursor);
        if (STATUS_SUCCESS != ntError)
        {
            LWIO_LOG_ERROR(
                "Failed to rename stream \"%s\" (%s)\n",
                newFullStreamName,
                LwNtStatusToName(ntError));
        }

        LWIO_UNLOCK_RWMUTEX(targetBucketLock, &pTargetBucket->rwLock);
        LWIO_UNLOCK_RWMUTEX(currentBucketLock, &pCurrentBucket->rwLock);
        LWIO_UNLOCK_MUTEX(scbMutexLock, &scbCursor->BaseControlBlock.Mutex);

        if (origFullStreamName)
        {
            LwRtlCStringFree(&origFullStreamName);
        }
        if (newFullStreamName)
        {
            LwRtlCStringFree(&newFullStreamName);
        }
    }

error:
    LWIO_UNLOCK_MUTEX(scbMutexLock, &scbCursor->BaseControlBlock.Mutex);
    LWIO_UNLOCK_RWMUTEX(targetBucketLock, &pTargetBucket->rwLock);
    LWIO_UNLOCK_RWMUTEX(currentBucketLock, &pCurrentBucket->rwLock);

    LWIO_UNLOCK_RWMUTEX(fcbListLocked, &pFcb->rwScbLock);
    LWIO_UNLOCK_RWMUTEX(renameLock, &scbTable->rwLock);

    if (origTargetFileName)
    {
        PvfsFreeFileName(origTargetFileName);
    }
    if (origFullStreamName)
    {
        LwRtlCStringFree(&origFullStreamName);
    }
    if (newFullStreamName)
    {
        LwRtlCStringFree(&newFullStreamName);
    }

    return ntError;
}
Exemplo n.º 16
0
NTSTATUS
PvfsSysOpenByFileName(
    OUT int *pFd,
    OUT PBOOLEAN pbCreateOwnerFile,
    IN PPVFS_FILE_NAME pFileName,
    IN int iFlags,
    IN mode_t Mode
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    int fd = -1;
    int unixerr = 0;
    PSTR pszFilename = NULL;
    PVFS_STAT Stat = {0};
    int Ownerfd = -1;
    PSTR pszStreamDirectoryName = NULL;
    PSTR pszMetadataPath = NULL;
    BOOLEAN bCreateOwnerFile = FALSE;

    // Need make sure the object (file/directory) exists
    // Before non-default stream objects can be created
    if (!PvfsIsDefaultStreamName(pFileName))
    {
        ntError = PvfsSysStat(pFileName->FileName, &Stat);
        if (LW_STATUS_OBJECT_NAME_NOT_FOUND == ntError)
        {
            ntError = PvfsSysOpen(
                          &Ownerfd,
                          pFileName->FileName,
                          iFlags,
                          Mode);
            if (STATUS_SUCCESS == ntError)
            {
                bCreateOwnerFile = TRUE;
            }
        }
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsLookupStreamDirectoryPath(&pszStreamDirectoryName,
                                                pFileName);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsFileDirname(&pszMetadataPath,
                                  pszStreamDirectoryName);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysOpenDir(pszMetadataPath, NULL);
        if (LW_STATUS_OBJECT_NAME_NOT_FOUND == ntError)
        {
            // create meta data directory
            ntError = PvfsSysMkDir(
                          pszMetadataPath,
                          (mode_t)gPvfsDriverConfig.CreateDirectoryMode);
            BAIL_ON_NT_STATUS(ntError);
        }
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysOpenDir(pszStreamDirectoryName, NULL);
        if (LW_STATUS_OBJECT_NAME_NOT_FOUND == ntError)
        {
            // create stream directory for an object
            ntError = PvfsSysMkDir(
                          pszStreamDirectoryName,
                          (mode_t)gPvfsDriverConfig.CreateDirectoryMode);
            BAIL_ON_NT_STATUS(ntError);
        }
        BAIL_ON_NT_STATUS(ntError);

        ntError = LwRtlCStringAllocatePrintf(
                      &pszFilename,
                      "%s/%s",
                      pszStreamDirectoryName,
                      PvfsGetCStringBaseStreamName(pFileName));
        BAIL_ON_NT_STATUS(ntError);
    }
    else
    {
        ntError = LwRtlCStringDuplicate(&pszFilename,
                                        PvfsGetCStringBaseFileName(pFileName));
        BAIL_ON_NT_STATUS(ntError);
    }

    if ((fd = open(pszFilename, iFlags, Mode)) == -1) {
        PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError);
    }

    *pFd = fd;
    *pbCreateOwnerFile = bCreateOwnerFile;

cleanup:

    if (pszFilename)
    {
        LwRtlCStringFree(&pszFilename);
    }
    if (pszStreamDirectoryName)
    {
        LwRtlCStringFree(&pszStreamDirectoryName);
    }
    if (pszMetadataPath)
    {
        LwRtlCStringFree(&pszMetadataPath);
    }

    if (Ownerfd != -1)
    {
        PvfsSysClose(Ownerfd);
    }

    return ntError;

error:
    if (fd != -1)
    {
        PvfsSysClose(fd);
    }

    goto cleanup;
}
Exemplo n.º 17
0
NTSTATUS
PvfsRenameFCB(
    PPVFS_FCB pFcb,
    PPVFS_CCB pCcb,
    PPVFS_FILE_NAME pNewFilename
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PPVFS_CB_TABLE fcbTable = &gPvfsDriverState.FcbTable;
    PPVFS_FCB pNewParentFcb = NULL;
    PPVFS_FCB pOldParentFcb = NULL;
    PPVFS_FCB pTargetFcb = NULL;
    PPVFS_CB_TABLE_ENTRY pTargetBucket = NULL;
    PPVFS_CB_TABLE_ENTRY pCurrentBucket = NULL;
    BOOLEAN currentFcbControl = FALSE;
    BOOLEAN targetFcbListLocked = FALSE;
    BOOLEAN targetBucketLocked = FALSE;
    BOOLEAN currentBucketLocked = FALSE;
    BOOLEAN fcbRwLocked = FALSE;
    BOOLEAN renameLock = FALSE;
    PPVFS_FILE_NAME currentFileName = NULL;

    /* If the target has an existing SCB, remove it from the Table and let
       the existing ref counters play out (e.g. pending change notifies. */

    BAIL_ON_INVALID_PTR(pNewFilename, ntError);

    ntError = PvfsFindParentFCB(&pNewParentFcb, pNewFilename->FileName);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsAllocateFileNameFromScb(&currentFileName, pCcb->pScb);
    BAIL_ON_NT_STATUS(ntError);

    // Obtain all locks for the rename
    LWIO_LOCK_RWMUTEX_EXCLUSIVE(renameLock, &fcbTable->rwLock);
    LWIO_LOCK_MUTEX(currentFcbControl, &pFcb->BaseControlBlock.Mutex);

    pCurrentBucket = pFcb->BaseControlBlock.pBucket;

    ntError = PvfsCbTableGetBucket(
                  &pTargetBucket,
                  fcbTable,
                  pNewFilename->FileName);
    BAIL_ON_NT_STATUS(ntError);

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(currentBucketLocked, &pCurrentBucket->rwLock);
    if (pCurrentBucket != pTargetBucket)
    {
        LWIO_LOCK_RWMUTEX_EXCLUSIVE(targetBucketLocked, &pTargetBucket->rwLock);
    }

    // Do the rename work now
    ntError = PvfsCbTableLookup_inlock(
                  (PPVFS_CONTROL_BLOCK*)OUT_PPVOID(&pTargetFcb),
                  pTargetBucket,
                  pNewFilename->FileName);
    if (ntError == STATUS_SUCCESS)
    {
        if (pTargetFcb != pFcb)
        {
            // Remove an existing FCB for the target file/stream (if one exists)
            // But make sure it is a different FCB

            LWIO_LOCK_RWMUTEX_SHARED(targetFcbListLocked, &pTargetFcb->rwScbLock);

            if (pTargetFcb->OpenHandleCount > 0 )
            {
                // if TargetScb has open handles cannot rename
                // This except in the batch-oplock case
                ntError = STATUS_INVALID_PARAMETER;
                BAIL_ON_NT_STATUS(ntError);
            }

            LWIO_UNLOCK_RWMUTEX(targetFcbListLocked, &pTargetFcb->rwScbLock);

            // TODO - How to get the Control Mutex without violating the
            // lock heirarchy?  Does it matter at all ?

            ntError = PvfsRemoveStreamObjects(pTargetFcb);
            LWIO_ASSERT(STATUS_SUCCESS == ntError);

            ntError = PvfsCbTableRemove_inlock(
                          (PPVFS_CONTROL_BLOCK)pTargetFcb,
                          pTargetFcb->pszFilename);
            LWIO_ASSERT(STATUS_SUCCESS == ntError);
        }
    }

    ntError = PvfsSysRenameByFileName(currentFileName, pNewFilename);
    // Ignore the error here and continue

    ntError = PvfsPathCacheRemove(currentFileName);
    // Ignore the error here and continue

    /* Remove the SCB from the table, update the lookup key, and then re-add.
       Otherwise you will get memory corruption as a freed pointer gets left
       in the Table because if cannot be located using the current (updated)
       filename. Another reason to use the dev/inode pair instead if we could
       solve the "Create New File" issue. */

    // Remove FCB
    ntError = PvfsCbTableRemove_inlock(
                  (PPVFS_CONTROL_BLOCK)pFcb,
                  pFcb->pszFilename);
    LWIO_ASSERT(STATUS_SUCCESS == ntError);

    // Rename FCB & Update parent links
    LWIO_LOCK_RWMUTEX_EXCLUSIVE(fcbRwLocked, &pFcb->BaseControlBlock.RwLock);
    LwRtlCStringFree(&pFcb->pszFilename);

    ntError = LwRtlCStringDuplicate(&pFcb->pszFilename, pNewFilename->FileName);
    BAIL_ON_NT_STATUS(ntError);

    if (pNewParentFcb != pFcb->pParentFcb)
    {
        pOldParentFcb = pFcb->pParentFcb;
        pFcb->pParentFcb = pNewParentFcb;
        pNewParentFcb = NULL;
    }
    LWIO_UNLOCK_RWMUTEX(fcbRwLocked, &pFcb->BaseControlBlock.RwLock);

    // Re-Add SCB
    ntError = PvfsCbTableAdd_inlock(
                  pTargetBucket,
                  pFcb->pszFilename,
                  (PPVFS_CONTROL_BLOCK)pFcb);
    BAIL_ON_NT_STATUS(ntError);

error:

    // Release all locks .. Whew!
    LWIO_UNLOCK_RWMUTEX(targetFcbListLocked, &pTargetFcb->rwScbLock);
    LWIO_UNLOCK_RWMUTEX(targetBucketLocked, &pTargetBucket->rwLock);
    LWIO_UNLOCK_RWMUTEX(currentBucketLocked, &pCurrentBucket->rwLock);
    LWIO_UNLOCK_RWMUTEX(fcbRwLocked, &pFcb->BaseControlBlock.RwLock);
    LWIO_UNLOCK_MUTEX(currentFcbControl, &pFcb->BaseControlBlock.Mutex);
    LWIO_UNLOCK_RWMUTEX(renameLock, &fcbTable->rwLock);

    if (pNewParentFcb)
    {
        PvfsReleaseFCB(&pNewParentFcb);
    }
    if (pOldParentFcb)
    {
        PvfsReleaseFCB(&pOldParentFcb);
    }
    if (pTargetFcb)
    {
        PvfsReleaseFCB(&pTargetFcb);
    }
    if (currentFileName)
    {
        PvfsFreeFileName(currentFileName);
    }

    return ntError;
}
Exemplo n.º 18
0
NTSTATUS
PvfsRemoveStreamObjects(
    IN PPVFS_FCB pFcb
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    BOOLEAN scbBucketLocked = FALSE;
    BOOLEAN scbLocked = FALSE;
    PLW_LIST_LINKS scbCursorLink = NULL;
    PPVFS_SCB scbCursor = NULL;
    PPVFS_FILE_NAME streamName = NULL;
    PSTR fullStreamName = NULL;
    PPVFS_CB_TABLE_ENTRY scbCursorBucket = NULL;

    for (scbCursorLink = PvfsListTraverse(pFcb->pScbList, NULL);
         scbCursorLink;
         scbCursorLink = PvfsListTraverse(pFcb->pScbList, scbCursorLink))
    {
        scbCursor = LW_STRUCT_FROM_FIELD(
                          scbCursorLink,
                          PVFS_SCB,
                          FcbList);

        LWIO_ASSERT(scbCursor->OpenHandleCount == 0);

        status = PvfsAllocateFileNameFromScb(&streamName, scbCursor);
        BAIL_ON_NT_STATUS(status);

        status = PvfsAllocateCStringFromFileName(&fullStreamName, streamName);
        BAIL_ON_NT_STATUS(status);

        LWIO_LOCK_MUTEX(scbLocked, &scbCursor->BaseControlBlock.Mutex);

        scbCursorBucket = scbCursor->BaseControlBlock.pBucket;
        LWIO_LOCK_RWMUTEX_EXCLUSIVE(scbBucketLocked, &scbCursorBucket->rwLock);

        status = PvfsCbTableRemove_inlock(
                      (PPVFS_CONTROL_BLOCK)scbCursor,
                      fullStreamName);
        LWIO_ASSERT(STATUS_SUCCESS == status);

        LWIO_UNLOCK_RWMUTEX(scbBucketLocked, &scbCursorBucket->rwLock);
        LWIO_UNLOCK_MUTEX(scbLocked, &scbCursor->BaseControlBlock.Mutex);

        if (streamName)
        {
            PvfsFreeFileName(streamName);
            streamName = NULL;
        }
        if (fullStreamName)
        {
            LwRtlCStringFree(&fullStreamName);
        }
    }

error:

    LWIO_UNLOCK_RWMUTEX(scbBucketLocked, &scbCursorBucket->rwLock);
    LWIO_UNLOCK_MUTEX(scbLocked, &scbCursor->BaseControlBlock.Mutex);

    if (streamName)
    {
        PvfsFreeFileName(streamName);
    }
    if (fullStreamName)
    {
        LwRtlCStringFree(&fullStreamName);
    }

    return status;
}
Exemplo n.º 19
0
NTSTATUS
PvfsSysRenameByFileName(
    IN PPVFS_FILE_NAME OriginalFileName,
    IN PPVFS_FILE_NAME NewFileName
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    int unixerr = 0;
    PSTR oldFilename = NULL;
    PSTR newFilename = NULL;
    PSTR oldStreamDir = NULL;
    PSTR newStreamDir = NULL;
    PSTR newStreamDirParent = NULL;
    PVFS_STAT streamDirStat = { 0 };

    ntError = PvfsLookupStreamDiskFileName(&oldFilename, OriginalFileName);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsLookupStreamDiskFileName(&newFilename, NewFileName);
    BAIL_ON_NT_STATUS(ntError);

    if (rename(oldFilename, newFilename) == -1 )
    {
        PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError);
    }

    if (PvfsIsDefaultStreamName(OriginalFileName))
    {
        // Have to rename the stream directory as well

        ntError = PvfsLookupStreamDirectoryPath(&oldStreamDir, OriginalFileName);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsLookupStreamDirectoryPath(&newStreamDir, NewFileName);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysStat(oldStreamDir, &streamDirStat);
        if (ntError == STATUS_SUCCESS)
        {
            ntError = PvfsFileDirname(&newStreamDirParent, newStreamDir);
            BAIL_ON_NT_STATUS(ntError);

            LwRtlZeroMemory(&streamDirStat, sizeof(streamDirStat));

            ntError = PvfsSysStat(newStreamDirParent, &streamDirStat);
            switch (ntError)
            {
            case STATUS_SUCCESS:
                if (!S_ISDIR(streamDirStat.s_mode))
                {
                    ntError = STATUS_NOT_A_DIRECTORY;
                }
                break;

            case STATUS_OBJECT_NAME_NOT_FOUND:
                ntError = PvfsSysMkDir(
                              newStreamDirParent,
                              (mode_t)gPvfsDriverConfig.CreateDirectoryMode);
                break;

            default:
                break;
            }
            BAIL_ON_NT_STATUS(ntError);

            if (rename(oldStreamDir, newStreamDir) == -1)
            {
                // We are now in an inconstsent state -- What should we do?
                // We cannot safely roll back to the original name
                // as someone else may have it.  Let's BAIL for now although
                // in the future we may decide that this should just log an error
                // but not fail
                PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError);
            }
        }

        // Squash the error is the stream directory did not exist
        ntError = STATUS_SUCCESS;
    }

error:
    if (oldFilename)
    {
        LwRtlCStringFree(&oldFilename);
    }
    if (newFilename)
    {
        LwRtlCStringFree(&newFilename);
    }
    if (oldStreamDir)
    {
        LwRtlCStringFree(&oldStreamDir);
    }
    if (newStreamDir)
    {
        LwRtlCStringFree(&newStreamDir);
    }
    if (newStreamDirParent)
    {
        LwRtlCStringFree(&newStreamDirParent);
    }


    return ntError;
}
Exemplo n.º 20
0
NTSTATUS
NtRegReadConfigMultiString(
    PLWREG_CONFIG_REG pReg,
    PCSTR   pszName,
    BOOLEAN bUsePolicy,
    PSTR    *ppszValue,
    PDWORD  pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    BOOLEAN bGotValue = FALSE;
    PSTR pszValue = NULL;
    char szValue[MAX_VALUE_LENGTH];
    DWORD dwType = 0;
    DWORD dwSize = 0;

    if (bUsePolicy)
    {
        if (!pReg->pszPolicyKey)
        {
            ntStatus = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        dwSize = sizeof(szValue);
        memset(szValue, 0, dwSize);
        ntStatus = NtRegGetValueA(
                    pReg->hConnection,
                    pReg->hKey,
                    pReg->pszPolicyKey,
                    pszName,
                    RRF_RT_REG_MULTI_SZ,
                    &dwType,
                    szValue,
                    &dwSize);
        if (!ntStatus)
        {
            bGotValue = TRUE;
        }
    }

    if (!bGotValue )
    {
        dwSize = sizeof(szValue);
        memset(szValue, 0, dwSize);
        ntStatus = NtRegGetValueA(
                    pReg->hConnection,
                    pReg->hKey,
                    pReg->pszConfigKey,
                    pszName,
                    RRF_RT_REG_MULTI_SZ,
                    &dwType,
                    szValue,
                    &dwSize);
        if (!ntStatus)
        {
            bGotValue = TRUE;
        }
    }

    if (bGotValue)
    {
        ntStatus = LW_RTL_ALLOCATE(&pszValue, char,
                                        dwSize);
        BAIL_ON_NT_STATUS(ntStatus);

        memcpy(pszValue, szValue, dwSize);

        LwRtlCStringFree(ppszValue);
        *ppszValue = pszValue;
        pszValue = NULL;

        if (pdwSize)
        {
            *pdwSize = dwSize;
        }
    }

    ntStatus = 0;

cleanup:

    LwRtlCStringFree(&pszValue);

    return ntStatus;

error:
    goto cleanup;
}