Skip to content

I want to know best practices for checking directory permissions #3871

Closed as not planned

Description

@KazukiSugiyama107

Details

Before creating a directory under a specific directory like mkdir, I would like to check the permissions and see if the directory can be created.
I think the method of receiving an error in the mkdir callback is correct originally, but that method cannot be used because mkdir is executed in the processing of the external library.
After reviewing the documentation, I think the correct way is to use "opendir" to receive the callback.
Is that the right way?

Also, if you use the fs module "opendir", "access" for a directory that you do not have write permission for, the result will be different.
I'd like to know why the results are different, do you understand?

  • access (params : fs.constants.W_OK)
    • No error returned
  • opendir
    • Error callback is returned

OS: Windows 10
Directory: Program Files

Node.js version

14.15.3

Example code

No response

Operating system

Windows 10

Scope

other

Module and version

Not applicable.

Activity

  1. prettydiff commented on May 27, 2022

    @prettydiff

    This is formally answered in the documentation: https://nodejs.org/dist/latest-v18.x/docs/api/fs.html#fsaccesspath-mode-callback

    Notice there is a subsection titled write (NOT RECOMMENDED) that makes use of the access method and a following subsection titled write (RECOMMENDED) that makes use of the open method. These code examples demonstrate how to proceed. The reason for this is stated immediately prior to the code examples:

    Do not use fs.access() to check for the accessibility of a file before calling fs.open(), fs.readFile(), or fs.writeFile(). Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file is not accessible.

  2. KazukiSugiyama107 commented on Jun 3, 2022

    @KazukiSugiyama107
    Author

    Confirmation was delayed. thank you for answering.

    The process I want to implement is to check if the directory has read / execute permissions before using rmdir to delete the directory, and if so, display a dialog without running the delete process. I want to do it.
    Since the deletion process itself depends on the external library, the result of the rmdir callback cannot be received as it is.
    In that case, even if you perform synchronization processing with statSync or accesSync and call the processing with rmdir of the external library, the race condition does not occur.
    Is this idea correct?

    Also, if you call statSync or accesSync synchronously for open and writeFile other than rmdir, wait for the result, and execute it, I think that no conflict will occur. Is that correct?

  3. F3n67u commented on Jun 12, 2022

    @F3n67u

    @KazukiSugiyama107 Thanks for creating this issue. I would suggest using fs.access/fs.accessSync/fsPromises.access to check if you have write permission in your scenario. fs.opendir is not necessary because you don't need to open the dir to check if you have the write permission, fs.opendir will also not readable when its motivation is just checking permission.

    I'd like to know why the results are different, do you understand?

    access (params : fs.constants.W_OK)
        No error returned
    opendir
        Error callback is returned
    

    I made an example code to test fs.access and fs.accessSync, it shows when we access a directory which has no write permission, an error will throw. If I understand your question correctly, then access method will have no problem checking the permission. is anything I missed?

    $ cat test.mjs
    import { accessSync, access, constants } from 'node:fs';
    
    const dir = '/etc';
    
    access(dir, constants.W_OK, (err) => {
      console.log(`check ${dir} permission before rm it via fs.access, result ${err ? 'is not writeable' : 'is writeable'}`);
    });
    
    
    try {
      accessSync(dir, constants.W_OK);
      console.log(`check ${dir} permission before rm it via fs.accessSync, result is writeable`);
    } catch (err) {
      console.log(`check ${dir} permission before rm it via fs.accessSync, result is not writeable`);
    }
    $ node test.mjs  
    check /etc permission before rm it via fs.accessSync, result is not writeable
    check /etc permission before rm it via fs.access, result is not writeable
  4. KazukiSugiyama107 commented on Jun 12, 2022

    @KazukiSugiyama107
    Author

    @F3n67u
    thank you!
    What you answered was what I was looking for.

    However, one question found that the results were different when using fs.accessSync on WinodwsOS and when using it on MacOS.
    I think this is a file system difference, but have you ever seen such a case?

    The confirmation was carried out by changing the authority for the directory.
    The results on Mac OS seem correct, but the results on Windows OS do not seem to be correct.

    Mac OS

    Parameter Permission result
    constants.R_OK Readable Success
    constants.R_OK Writable Failure
    constants.R_OK Executable Failure
    constants.W_OK Readable Failure
    constants.W_OK Writable Success
    constants.W_OK Executable Failure
    constants.X_OK Readable Failure
    constants.X_OK Writable Failure
    constants.X_OK Executable Success

    Windows OS

    Parameter Permission result
    constants.R_OK Read Success
    constants.R_OK Write Success
    constants.R_OK List folder contens Success
    constants.W_OK Read Success
    constants.W_OK Write Success
    constants.W_OK List folder contens Success
    constants.X_OK Read Success
    constants.X_OK Write Success
    constants.X_OK List folder contens Success
  5. F3n67u commented on Jun 12, 2022

    @F3n67u

    On Windows, access-control policies (ACLs) on a directory may limit access to a file or directory. The fs.access() function, however, does not check the ACL and therefore may report that a path is accessible even if the ACL restricts the user from reading or writing to it.

    I don't test it in Windows. Seems related to this problem in Windows.https://nodejs.org/dist/latest-v18.x/docs/api/fs.html#fsaccesspath-mode-callback

  6. KazukiSugiyama107 commented on Jun 13, 2022

    @KazukiSugiyama107
    Author

    I understand.
    As explained below, I have confirmed that it works fine on Windows using fs.openSync.

    Using fs.exists() to check for the existence of a file before calling fs.open(), fs.readFile(), or fs.writeFile() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file does not exist.

    I'm a little skeptical, but is it correct to run fs.openSync in a directory?
    The results I can get are correct, but I'm wondering if there are other ways.

  7. F3n67u commented on Jun 13, 2022

    @F3n67u

    I don't have an answer for you. I don't know the Windows-specific side of the fs module.

    @nodejs/fs Could you folks help with this question?

  8. KazukiSugiyama107 commented on Jul 11, 2022

    @KazukiSugiyama107
    Author

    Can someone please answer how to use fs.openSync?

    #3871 (comment)

  9. KazukiSugiyama107 commented on Oct 2, 2022

    @KazukiSugiyama107
    Author

    I would like to know if anyone has any knowledge of the following comments.

    #3871 (comment)

  10. github-actions commented on Mar 6, 2024

    @github-actions

    There has been no activity on this issue for 11 months. The help repository works best when sustained engagement moves conversation forward. The issue will be closed in 1 month. If you are still experiencing this issue on the latest supported versions of Node.js, please leave a comment.

  11. github-actions commented on Apr 5, 2024

    @github-actions

    Closing after no activity on this issue for 12 months.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions