Beispiel #1
0
NTSTATUS
PvfsAccessCheckFile(
    PACCESS_TOKEN pToken,
    PPVFS_FILE_NAME FileName,
    ACCESS_MASK Desired,
    ACCESS_MASK *pGranted
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    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;
    PSECURITY_DESCRIPTOR_ABSOLUTE pParentSecDesc = NULL;
    BYTE pParentRelSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE];
    ULONG ulParentRelSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;
    BOOLEAN bGranted = FALSE;
    SECURITY_INFORMATION SecInfo = (OWNER_SECURITY_INFORMATION |
                                    GROUP_SECURITY_INFORMATION |
                                    DACL_SECURITY_INFORMATION  |
                                    SACL_SECURITY_INFORMATION);
    PSID pOwner = NULL;
    BOOLEAN bOwnerDefaulted = FALSE;
    BOOLEAN bWantsDelete = FALSE;
    BOOLEAN bWantsMaximumAccess = FALSE;
    PPVFS_FILE_NAME parentDirectoryName = NULL;
    PPVFS_FILE_NAME relativeFileName = NULL;

    BAIL_ON_INVALID_PTR(pToken, ntError);
    BAIL_ON_INVALID_PTR(pGranted, ntError);

    // Check the file object itself

    ntError = PvfsGetSecurityDescriptorFilename(
                  PvfsGetCStringBaseFileName(FileName),
                  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);
    }

    // Check for access rights.  We'll deal with DELETE separately since that
    // could be granted by the parent directory security descriptor

    if (Desired & DELETE)
    {
        bWantsDelete = TRUE;
        ClearFlag(Desired, DELETE);
    }

    if (Desired & MAXIMUM_ALLOWED)
    {
        bWantsMaximumAccess = TRUE;
    }

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

    GrantedAccess = AccessMask;

    // See if the file object security descriptor grants DELETE
    // Only continue when checking for MAXIMUM_ALLOWED if we haven't been
    // granted DELETE already

    if (bWantsDelete ||
        (bWantsMaximumAccess && !(GrantedAccess & DELETE)))
    {
        AccessMask = 0;

        bGranted = RtlAccessCheck(
                   pSecDesc,
                   pToken,
                   DELETE,
                   GrantedAccess,
                   &gPvfsDriverState.GenericSecurityMap,
                   &AccessMask,
                   &ntError);
        if (!bGranted)
        {
            ntError = PvfsSplitFileNamePath(
                          &parentDirectoryName,
                          &relativeFileName,
                          FileName);
            BAIL_ON_NT_STATUS(ntError);

            ntError = PvfsGetSecurityDescriptorFilename(
                          PvfsGetCStringBaseFileName(parentDirectoryName),
                          SecInfo,
                          (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pParentRelSecDescBuffer),
                          &ulParentRelSecDescLength);
            BAIL_ON_NT_STATUS(ntError);

            ntError = PvfsSecurityAclSelfRelativeToAbsoluteSD(
                          &pParentSecDesc,
                          (PSECURITY_DESCRIPTOR_RELATIVE)((PVOID)pParentRelSecDescBuffer));
            BAIL_ON_NT_STATUS(ntError);

            AccessMask = 0;
            bGranted = RtlAccessCheck(
                           pParentSecDesc,
                           pToken,
                           FILE_DELETE_CHILD,
                           0,
                           &gPvfsDriverState.GenericSecurityMap,
                           &AccessMask,
                           &ntError);

            // This is a hard failure unless we are just trying to determine
            // what the maximum allowed access would be

            if (!bGranted && !bWantsMaximumAccess)
            {
                BAIL_ON_NT_STATUS(ntError);
            }

            AccessMask = DELETE;
        }

        // Combine directory and file object granted permissions

        AccessMask |= GrantedAccess;
    }

    *pGranted = AccessMask;
    ntError = STATUS_SUCCESS;

error:
    if (parentDirectoryName)
    {
        PvfsFreeFileName(relativeFileName);
    }
    if (relativeFileName)
    {
        PvfsFreeFileName(parentDirectoryName);
    }


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

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

    return ntError;
}
Beispiel #2
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;
}
Beispiel #3
0
NTSTATUS
PvfsCreateFileSecurity(
    PACCESS_TOKEN pUserToken,
    PPVFS_CCB pCcb,
    PSECURITY_DESCRIPTOR_RELATIVE pSecurityDescriptor,
    BOOLEAN bIsDirectory
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PSTR pszParentPath = NULL;
    PSTR pszBaseFilename = NULL;
    PSECURITY_DESCRIPTOR_RELATIVE pFinalSecDesc = NULL;
    ULONG FinalSecDescLength = 0;
    BYTE ParentSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE];
    ULONG ParentSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;
    SECURITY_INFORMATION SecInfoAll = (OWNER_SECURITY_INFORMATION |
                                       GROUP_SECURITY_INFORMATION |
                                       DACL_SECURITY_INFORMATION  |
                                       SACL_SECURITY_INFORMATION);
    BYTE DefaultSecDescBuffer[SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE];
    ULONG DefaultSecDescLength = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE;

    LwRtlZeroMemory(ParentSecDescBuffer, ParentSecDescLength);
    LwRtlZeroMemory(DefaultSecDescBuffer, DefaultSecDescLength);

    ntError = PvfsFileSplitPath(
                  &pszParentPath,
                  &pszBaseFilename,
                  pCcb->pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsGetSecurityDescriptorFilename(
                  pszParentPath,
                  SecInfoAll,
                  (PSECURITY_DESCRIPTOR_RELATIVE)ParentSecDescBuffer,
                  &ParentSecDescLength);
    BAIL_ON_NT_STATUS(ntError);

    ntError = RtlCreatePrivateObjectSecurityEx(
                  (PSECURITY_DESCRIPTOR_RELATIVE)ParentSecDescBuffer,
                  pSecurityDescriptor,
                  &pFinalSecDesc,
                  &FinalSecDescLength,
                  NULL,
                  bIsDirectory,
                  SEF_DACL_AUTO_INHERIT|SEF_SACL_AUTO_INHERIT,
                  pUserToken,
                  &gPvfsFileGenericMapping);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsSetSecurityDescriptorFile(
                  pCcb,
                  SecInfoAll,
                  pFinalSecDesc,
                  FinalSecDescLength);
    BAIL_ON_NT_STATUS(ntError);

cleanup:
    LW_RTL_FREE(&pFinalSecDesc);
    RtlCStringFree(&pszParentPath);
    RtlCStringFree(&pszBaseFilename);

    return ntError;

error:
    goto cleanup;
}