2.1.5.1.2.1 Algorithm to Check Access to an Existing File

The inputs to the algorithm are:

  • Open: The Open for an in-progress Open operation to an existing file.

On completion, the algorithm returns:

  • Status: An NTSTATUS code that specifies the result of the access check.

This object store MUST perform access checks when opening an existing file, making use of the file's security descriptor and possibly the parent file's security descriptor.

Pseudocode for these checks is as follows:

  • If Open.File.FileType is DataFile and (File.FileAttributes.FILE_ATTRIBUTE_READONLY && (DesiredAccess.FILE_WRITE_DATA || DesiredAccess.FILE_APPEND_DATA)), then return STATUS_ACCESS_DENIED.

  • If ((File.FileAttributes.FILE_ATTRIBUTE_READONLY || File.Volume.IsReadOnly) && CreateOptions.FILE_DELETE_ON_CLOSE), then return STATUS_CANNOT_DELETE.

  • If Open.RemainingDesiredAccess is nonzero:

    • If Open.RemainingDesiredAccess.MAXIMUM_ALLOWED is TRUE:

      • For each Access Flag in FILE_ALL_ACCESS, the object store MUST set Open.GrantedAccess.Access if AccessCheck(SecurityContext, File.SecurityDescriptor, Access) returns TRUE.

      • If File.FileAttributes.FILE_ATTRIBUTE_READONLY or File.Volume.IsReadOnly, then the object store MUST clear (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD) from Open.GrantedAccess.

    • Else:

      • For each Access Flag in Open.RemainingDesired.Access, the object store MUST set Open.GrantedAccess.Access if AccessCheck(SecurityContext, File.SecurityDescriptor, Access) returns TRUE.

    • EndIf

    • If (Open.RemainingDesiredAccess.MAXIMUM_ALLOWED || Open.RemainingDesiredAccess.DELETE), the object store MUST set Open.GrantedAccess.DELETE if AccessCheck(SecurityContext, Open.Link.ParentFile.SecurityDescriptor, FILE_DELETE_CHILD) returns TRUE.

    • If (Open.RemainingDesiredAccess.MAXIMUM_ALLOWED || Open.RemainingDesiredAccess.FILE_READ_ATTRIBUTES), the object store MUST set Open.GrantedAccess.FILE_READ_ATTRIBUTES if AccessCheck(SecurityContext, Open.Link.ParentFile.SecurityDescriptor, FILE_LIST_DIRECTORY) returns TRUE.

    • Open.RemainingDesiredAccess &= ~(Open.GrantedAccess | MAXIMUM_ALLOWED)

    • If Open.RemainingDesiredAccess is nonzero, then return STATUS_ACCESS_DENIED.

  • EndIf

Since deletion of a file's primary stream implies deletion of the entire file, including any alternate data streams, the object store MUST check for sharing conflicts involving deletion of the primary stream and the sharing modes of all opens to the file.

Pseudocode for these checks is as follows:

  • If Open.SharingMode.FILE_SHARE_DELETE is FALSE and Open.GrantedAccess contains any one or more of (FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE):

    • For each ExistingOpen in Open.File.OpenList:

      • If ExistingOpen.GrantedAccess.DELETE is TRUE and (ExistingOpen.Stream.StreamType is DirectoryStream or ExistingOpen.Stream.Name is empty), then return STATUS_SHARING_VIOLATION.

    • EndFor

  • EndIf

  • If Open.GrantedAccess.DELETE is TRUE and (Open.Stream.StreamType is DirectoryStream or Open.Stream.Name is empty):

    • For each ExistingOpen in Open.File.OpenList:

      • If ExistingOpen.SharingMode.FILE_SHARE_DELETE is FALSE and ExistingOpen.GrantedAccess contains one or more of (FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE), then return STATUS_SHARING_VIOLATION.

    • EndFor

  • EndIf

  • Return STATUS_SUCCESS.