Skip to content

Commit

Permalink
Merge pull request #1188 from dscho/unprivileged-symlinks
Browse files Browse the repository at this point in the history
Support creating symlinks outside elevated sessions
  • Loading branch information
dscho committed May 24, 2018
2 parents 456f46c + 89ae9e9 commit 97c2c93
Showing 1 changed file with 24 additions and 2 deletions.
26 changes: 24 additions & 2 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ int mingw_core_config(const char *var, const char *value, void *cb)
return 0;
}

static DWORD symlink_file_flags = 0, symlink_directory_flags = 1;
DECLARE_PROC_ADDR(kernel32.dll, BOOLEAN, CreateSymbolicLinkW, LPCWSTR, LPCWSTR, DWORD);

enum phantom_symlink_result {
Expand Down Expand Up @@ -358,7 +359,8 @@ process_phantom_symlink(const wchar_t *wtarget, const wchar_t *wlink)
return PHANTOM_SYMLINK_DONE;

/* otherwise recreate the symlink with directory flag */
if (DeleteFileW(wlink) && CreateSymbolicLinkW(wlink, wtarget, 1))
if (DeleteFileW(wlink) &&
CreateSymbolicLinkW(wlink, wtarget, symlink_directory_flags))
return PHANTOM_SYMLINK_DIRECTORY;

errno = err_win_to_posix(GetLastError());
Expand Down Expand Up @@ -2576,7 +2578,7 @@ int symlink(const char *target, const char *link)
wtarget[len] = '\\';

/* create file symlink */
if (!CreateSymbolicLinkW(wlink, wtarget, 0)) {
if (!CreateSymbolicLinkW(wlink, wtarget, symlink_file_flags)) {
errno = err_win_to_posix(GetLastError());
return -1;
}
Expand Down Expand Up @@ -3098,6 +3100,24 @@ static void maybe_redirect_std_handles(void)
GENERIC_WRITE, FILE_FLAG_NO_BUFFERING);
}

static void adjust_symlink_flags(void)
{
/*
* Starting with Windows 10 Build 14972, symbolic links can be created
* using CreateSymbolicLink() without elevation by passing the flag
* SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x02) as last
* parameter, provided the Developer Mode has been enabled. Some
* earlier Windows versions complain about this flag with an
* ERROR_INVALID_PARAMETER, hence we have to test the build number
* specifically.
*/
if (GetVersion() >= 14972 << 16) {
symlink_file_flags |= 2;
symlink_directory_flags |= 2;
}

}

#if defined(_MSC_VER)

#ifdef _DEBUG
Expand Down Expand Up @@ -3137,6 +3157,7 @@ int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
#endif

maybe_redirect_std_handles();
adjust_symlink_flags();

/* determine size of argv conversion buffer */
maxlen = wcslen(_wpgmptr);
Expand Down Expand Up @@ -3203,6 +3224,7 @@ void mingw_startup(void)
_startupinfo si;

maybe_redirect_std_handles();
adjust_symlink_flags();

/* get wide char arguments and environment */
si.newmode = 0;
Expand Down

0 comments on commit 97c2c93

Please sign in to comment.