cygwin: try unprivileged symlink creation on W10 1703 and later

Add new SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE flag to
CreateSymbolicLinkW call when running on W10 1703 or later.
Don't do that on older versions to avoid ERROR_INVALID_PARAMETER.

Preliminary, needs testing.  There's an off-chance that the
flag results in the same ERROR_INVALID_PARAMETER on 1703 if the
developer settings are not enabled.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2017-04-24 17:17:29 +02:00
parent e7bcf4633e
commit ffcfbf4b66
1 changed files with 9 additions and 2 deletions

View File

@ -1621,6 +1621,10 @@ cnt_bs (PWCHAR s, PWCHAR e)
return num; return num;
} }
#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 2
#endif
static int static int
symlink_native (const char *oldpath, path_conv &win32_newpath) symlink_native (const char *oldpath, path_conv &win32_newpath)
{ {
@ -1628,6 +1632,7 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
path_conv win32_oldpath; path_conv win32_oldpath;
PUNICODE_STRING final_oldpath, final_newpath; PUNICODE_STRING final_oldpath, final_newpath;
UNICODE_STRING final_oldpath_buf; UNICODE_STRING final_oldpath_buf;
DWORD flags;
if (isabspath (oldpath)) if (isabspath (oldpath))
{ {
@ -1724,9 +1729,11 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
final_oldpath->Buffer[1] = L'\\'; final_oldpath->Buffer[1] = L'\\';
} }
/* Try to create native symlink. */ /* Try to create native symlink. */
flags = win32_oldpath.isdir () ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
if (wincap.has_unprivileged_createsymlink ())
flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
if (!CreateSymbolicLinkW (final_newpath->Buffer, final_oldpath->Buffer, if (!CreateSymbolicLinkW (final_newpath->Buffer, final_oldpath->Buffer,
win32_oldpath.isdir () flags))
? SYMBOLIC_LINK_FLAG_DIRECTORY : 0))
{ {
/* Repair native newpath, we still need it. */ /* Repair native newpath, we still need it. */
final_newpath->Buffer[1] = L'?'; final_newpath->Buffer[1] = L'?';