Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linklocal requires Administrator permissions when run under Windows default security settings #22

Closed
theoy opened this issue Jan 5, 2016 · 5 comments

Comments

@theoy
Copy link

theoy commented Jan 5, 2016

I love linklocal 😄. I'd like to use it as part of our toolset in splitting up my team's large JS codebase into smaller packages. I'm a big fan of using local links and avoiding global version clobbering/hell.

However, a lot of my team members run Windows for their dev environments, and in Windows there are multiple link-like file system entities (hard links, symbolic links and junctions). They're also a less commonly used feature in Windows (e.g. Explorer creates 'shortcuts', not symlinks, hard links or junctions). I'm not an expert on Windows filesystem security settings, but it appears that the following bad experience happens in Windows.

  • If your account is marked as a member of the Administrators group
  • and User Account Control is enabled (the security system that prompts you for admin actions)
  • then you cannot create symbolic link entities in Windows.

Non-admin users also cannot create "symbolic links" by default, but they can be granted the permission.

References:

I believe this is the default state for the first user account on Windows, and a likely configuration for developers. While there are workarounds (disable UAC, add link privilege for non-admin accounts), I believe it's in the spirit of linklocal to support isolated execution (e.g. running as non-admin so that machine globals cannot be touched).

Investigation

I did some preliminary investigation, and the use of junctions on Windows seems to work in this scenario and not require elevation. Switching to "all junctions all the time" on Windows is easy by removing the OS version check from this line:

  if (os.platform()=='win32' && parseInt(os.release())<6) {

So that the if-block is the same for all versions of Windows.

Verification
  • Configuration
    • Windows 10 64-bit OS, NTFS file system
    • 64-bit NodeJS v0.12.9
    • NPM v3.5.2 (I saw that the travis.yml bootstraps latest NPM)
    • User in administrator group, but command line is unelevated
  • Verified that existing linklocal tests fail npm test
  • Verified that switching to junctions allows for tests to pass in the non-elevated config
  • Verified that node module loader identity resolution succeeds for link type = junction. Specifically... given:
    • pkgA/node_modules/pkgB/node_modules/pkgD/
    • pkgA/node_modules/pkgC/node_modules/pkgD/
    • where both paths are actually junctions of some other path ([root]/pkgD)
    • then Node runtime unifies and recognises that all paths are actually the same module. Any variables and side effects are shared and acted upon the same pkgD, instead of separate copies. In otherwards, the linked paths act as if NPM had dedupe'd them, without having to move the paths.
Open Questions:
  • Do you consider the use of junctions all the time in Windows a small change or a breaking change?Since junctions are interpreted as symbolic links in the Node runtime, it does not seem to be a significant break. Of course, native node modules can call Windows APIs and observe the difference.

I'm happy to chip in, but I think it'd be great to hear what kind of fix would be desired for this (e.g. just changing to junctions, or maybe adding a switch to explicitly specify the link type for Windows)

theoy added a commit to theoy/linklocal that referenced this issue Jan 6, 2016
Windows supports two different types of "soft links", whereas in most MacOS/Linux-based operating systems, the common practice is to use symbolic links. LinkLocal was already using 'junction' links on Windows for versions older than Vista (e.g. XP). However, using a link type of 'symbolic link' on Windows for higher versions throws an error if you are using default Windows settings and are running as a normal user or an administrator that has not elevated into admin mode (e.g. UAC). So this change is of the flavour to just switch to using 'junction' links all the time on Windows, since unelevated/non-admin users are allowed to manage those under default Windows security settings.

Prior to this change, existing LinkLocal tests while on unelevated/non-admin would fail if using default Windows security settings. I verified this change makes it pass for non-admin/unelevated users in the default Windows security config at least on Windows 10 64-bit OS, NTFS file system (default FS type), 64-bit Node v0.12.9, NPM 3.5.2.
theoy added a commit to theoy/linklocal that referenced this issue Jan 6, 2016
Windows supports two different types of "soft links", whereas in most MacOS/Linux-based operating systems, the common practice is to use symbolic links. LinkLocal was already using 'junction' links on Windows for versions older than Vista (e.g. XP). However, using a link type of 'symbolic link' on Windows for higher versions throws an error if you are using default Windows settings and are running as a normal user or an administrator that has not elevated into admin mode (e.g. UAC). So this change is of the flavour to just switch to using 'junction' links all the time on Windows, since unelevated/non-admin users are allowed to manage those under default Windows security settings.

Prior to this change, existing LinkLocal tests while on unelevated/non-admin would fail if using default Windows security settings. I verified this change makes it pass for non-admin/unelevated users in the default Windows security config at least on Windows 10 64-bit OS, NTFS file system (default FS type), 64-bit Node v0.12.9, NPM 3.5.2.
@theoy
Copy link
Author

theoy commented Jan 6, 2016

Updated OP with references to documentation on junctions and symbolic links on Windows, and a pull request #23 that does the simple-fix of just always using junctions. :)

Note, both symbolic links and junctions are supported in Microsoft's new ReFS, which may become eventually incorporated to desktop/workstation editions of Windows (brings incremental resiliency checking for large drives and copy-on-write).

@timoxley - let me know if there's anything I can do to help out! :)

@timoxley
Copy link
Owner

I've never used this on windows, do you have any opinions on this @vweevers?

@vweevers
Copy link
Contributor

npm uses junctions too nowadays. It's fine to switch to junctions, but beware that junctions must be absolute in node 0.10. Node's fs.symlink(.., .., "junction") does resolve a relative target, but not relative to the link's parent directory as it should. This was fixed in iojs / node 4, but has not been backported yet. So to be safe, use absolute paths.

@theoy
Copy link
Author

theoy commented Jan 29, 2016

This was fixed in iojs / node 4, but has not been backported yet. So to be safe, use absolute paths.
--@vweevers

IIRC, when linklocal uses junctions for Windows XP, it already has the same workaround implemented (convert the path to absolute).

I did find one other difference between junctions and symbolic links on Windows - in that junctions have to be to resolve to a directory on a local disk, whereas symbolic links allow for targets that are SMB network paths. It seems that would be okay for most linklocal users though? How many users use a file:... path while intending for the destination to be a network location?

@vweevers
Copy link
Contributor

@theoy Ah, you're right. I did that myself some time ago (#11) 😬 Though the warning couldn't hurt.

I also believe the junction and its target need to be on the same disk. But that's not a problem for linklocal either, b/c everything is local (happening in the same working directory).

timoxley added a commit that referenced this issue Dec 9, 2016
Fix #22 - Always use Junctions on Windows
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants