Search code examples
javawindowsniosymlink

How do I create a symlink


On an NTFS volume on Windows 10 Version 1803 build 17134.523 with Developer Mode enabled, I have a file myfile. I can make symbolic links to this file with mklink. However, if I call Files.createSymbolicLink on java jre 1.8.0_201, if throws:

java.nio.file.FileSystemException: linkname: A required privilege is not held by the client.

    at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
    at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
    at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
    at sun.nio.fs.WindowsFileSystemProvider.createSymbolicLink(Unknown Source)
    at java.nio.file.Files.createSymbolicLink(Unknown Source)
    at CreateLinks.main(CreateLinks.java:15)

The same works without problems on the Windows Subsystem for Linux (WSL) with jre 1.8.0_191-8u191-b12-0ubuntu0.18.10.1-b12

How can I make this work on windows without going into WSL? And where is this exception thrown exactly?


Solution

  • Creating symbolic links requires SeCreateSymbolicLinkPrivilege, unless the system is in developer mode and WinAPI CreateSymbolicLink is called with the flag SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (*). CMD's mklink command uses this flag in Windows 10. Apparently Java JRE version 1.8.0_201 does not.

    As to WSL, it inherits the security context from which it is run. If run from a logon that has SeCreateSymbolicLinkPrivilege, recent versions of WSL will create normal Windows symlinks on a drvfs (e.g. NTFS) volume. Otherwise WSL uses a custom symlink type, which is based on an IO_REPARSE_TAG_LX_SYMLINK (0xA000001D) reparse point instead of the normal IO_REPARSE_TAG_SYMLINK (0xA000000C) reparse point. You can query the type of reparse point via the command fsutil reparsepoint query <filename>.


    (*) The docs say "[s]pecify this flag to allow creation of symbolic links when the process is not elevated". More precisely, this flag allows creating symlinks without SeCreateSymbolicLinkPrivilege, which is only related to being "elevated" with the default system settings. Personally, I grant this privilege to the "Authenticated Users" group, in which case creating symlinks doesn't require elevating to full admin access.