NtCreateFile: Does a RootDirectory handle granted only FILE_READ_ATTRIBUTES need additional rights?

Chris Terrell 20 Reputation points
2026-09-14T20:59:26.9933333+00:00

@Taki Ly (WICLOUD CORPORATION) , this question follows your request for a separate thread addressing the RootDirectory granted-mask issue.

Question

For user-mode NtCreateFile, does an existing filesystem-directory handle used as RootDirectory require any additional right in its actual granted-access mask beyond FILE_READ_ATTRIBUTES for the child request below?

The purpose is to clarify the supported parent-handle access requirement for a proposed directory-relative metadata acquisition.

Hypothetical scenario

Assume a valid, still-held filesystem-directory handle whose actual granted-access mask is independently established as FILE_READ_ATTRIBUTES alone.

This is a hypothetical premise, not a claim about a local handle or the handle used in the earlier reported tests. I am not reporting a locally observed success or failure.

Parameter Proposed value
RootDirectory The existing filesystem-directory handle described above
ObjectName One literal child component
ObjectAttributes.Attributes 0
DesiredAccess FILE_READ_ATTRIBUTES
ShareAccess FILE_SHARE_READ
CreateDisposition FILE_OPEN
CreateOptions FILE_OPEN_REPARSE_POINT

Neither type-selection flag nor a synchronous, backup-intent, or delete-on-close option is selected. Other valid-call requirements remain separate; this question does not presume overall success.

Requested clarification

Please distinguish the requirement, if any, on the parent handle’s existing granted-access mask from:

  • Traversal checks involving the caller’s security context.
  • Access checks for the child being opened.

A published provision or an attributable, scope-qualified clarification would help. If the published contract does not specify the parent-mask requirement, please distinguish that documentary limitation from a conclusion that an additional right either is or is not required.

Please identify any Windows-version, filesystem, or other conditions that limit the answer.

Existing supporting results

Taki, you mentioned having measured results ready to share. For any existing results relevant to this request, please identify:

  • The tested request shape and environment.
  • The access requested when opening the parent directory.
  • Whether and how the resulting handle’s actual granted-access mask was independently established.

If only requested access is known, please identify that limitation. I am not requesting additional tests.

Scope

This request uses FILE_OPEN_REPARSE_POINT with ObjectAttributes.Attributes = 0; it is separate from the earlier OBJ_DONT_REPARSE tests and does not treat the flags as interchangeable.

Independent authorization of the parent or child, replacement prevention, ReOpenFile compatibility, and completion of a reader method remain outside this question.

Windows development | Windows API - Win32

2 answers

Sort by: Newest
  1. Taki Ly (WICLOUD CORPORATION) 4,450 Reputation points Microsoft External Staff Moderator
    2026-09-15T03:27:27.7166667+00:00

    Hello @Chris Terrell ,

    Thanks for splitting this out. On the setup I tested, a RootDirectory handle whose granted mask is FILE_READ_ATTRIBUTES alone needs no extra right for that child request. Two of your three items are documented; the third is only empirical.

    Child access check: documented, and it runs against the child's own security descriptor, not the parent's. File Security and Access Rights: "the security descriptor of a parent directory is not used to control access to any child file or directory." So your child DesiredAccess (FILE_READ_ATTRIBUTES) is checked against the child, independent of the parent handle.

    Traversal check: documented, and it runs against the caller's token and privileges, not the parent handle's mask. FILE_TRAVERSE is only enforced "by removing the BYPASS_TRAVERSE_CHECKING privilege from users" (same page, and File Access Rights Constants says it is "ignored" by default). That privilege is SeChangeNotifyPrivilege, granted to Everyone by default, so the traverse check is normally skipped.

    Parent handle granted mask: this is the part the contract does not specify. Neither ntifs NtCreateFile, NtOpenFile, nor OBJECT_ATTRIBUTES ties any bit to the RootDirectory handle's granted mask for a relative open. So the docs are silent, and I would not read that silence as either "a bit is required" or "no bit is required." The mechanism is ObReferenceObjectByHandle: the requested access is compared against the handle's granted access. What the docs leave open is which access, if any, the I/O manager requests for that reference.

    That gap is what I measured:

    • Environment: Windows 11 build 26200, local NTFS, caller is the owner, default privileges.
    • Child shape: exactly yours (one component, Attributes = 0, DesiredAccess = FILE_READ_ATTRIBUTES, ShareAccess = FILE_SHARE_READ, CreateDisposition = FILE_OPEN, CreateOptions = FILE_OPEN_REPARSE_POINT).
    • Parent open and granted mask: opened with NtOpenFile (not Win32 CreateFile, which silently adds SYNCHRONIZE and FILE_READ_ATTRIBUTES), requesting one access value at a time and no SYNCHRONIZE, then read the granted mask back independently with NtQueryObject(ObjectBasicInformation).GrantedAccess and confirmed it equaled what I requested.
    • Results: with the parent granted mask measured as FILE_READ_ATTRIBUTES (0x80) alone, the child open returned STATUS_SUCCESS. Same result with FILE_TRAVERSE (0x20) alone, FILE_LIST_DIRECTORY (0x01) alone, and even READ_CONTROL (0x20000) alone with no file-specific bit.

    The READ_CONTROL-only case is the telling one: a parent handle with no directory-specific bit still worked, so the reference did not demand FILE_TRAVERSE or FILE_LIST_DIRECTORY on this build. For your exact question, FILE_READ_ATTRIBUTES alone was enough; the handle only had to be valid and still open.

    One note on the earlier OBJ_DONT_REPARSE thread: there I opened the parent with Win32 CreateFile requesting FILE_LIST_DIRECTORY | SYNCHRONIZE and did not read back its granted mask, so only the requested access is known for that test. The independent measurement above was done specifically for this question.

    I hope this clarifies the parent-handle requirement for your scenario. If anything needs more detail, feel free to follow up and I'll be glad to help. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guide for your confirmation

    Thank you.

    Was this answer helpful?


  2. Chris Terrell 20 Reputation points
    2026-09-14T23:09:42.9766667+00:00

    The AI answer limits its conclusion to the two cited references. The remaining question is whether another documented, supported integration or composition on the existing SCM creation path addresses the stated service-account-substitution scenario.

    Could a human reviewer identify such a contract, or a documented limitation, with the Windows versions/configurations it covers? Ordinary SCM access prerequisites are assumed satisfied in the scenario; the unresolved requirement is independent rejection of the policy-prohibited request before its prohibited creation effects.

    For precision, the cited documentation describes initial service-object security-descriptor creation at installation. I am not asserting an unprotected interval before later security configuration.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.