From c34815d88159e446e26421f420ac847f1e6186e6 Mon Sep 17 00:00:00 2001 From: Vidar Tonaas Fauske Date: Tue, 19 Sep 2017 11:22:50 +0200 Subject: [PATCH 1/7] bpo-31512: Remove unneeded windows symlink checks As Windows XP is no longer supported, these symlink checks can be removed. --- Modules/posixmodule.c | 68 ++----------------------------------------- 1 file changed, 2 insertions(+), 66 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index f4c01048cdae3c..2f89c561ce2096 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -320,10 +320,7 @@ extern int lstat(const char *, struct stat *); #include #include /* for ShellExecute() */ #include /* for UNLEN */ -#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */ #define HAVE_SYMLINK -static int win32_can_symlink = 0; -#endif #endif /* _MSC_VER */ #ifndef MAXPATHLEN @@ -7470,22 +7467,6 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) #if defined(MS_WINDOWS) -/* Grab CreateSymbolicLinkW dynamically from kernel32 */ -static BOOLEAN (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL; - -static int -check_CreateSymbolicLink(void) -{ - HINSTANCE hKernel32; - /* only recheck */ - if (Py_CreateSymbolicLinkW) - return 1; - hKernel32 = GetModuleHandleW(L"KERNEL32"); - *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32, - "CreateSymbolicLinkW"); - return Py_CreateSymbolicLinkW != NULL; -} - /* Remove the last portion of the path - return 0 on success */ static int _dirnameW(WCHAR *path) @@ -7593,26 +7574,14 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, int result; #endif -#ifdef MS_WINDOWS - if (!check_CreateSymbolicLink()) { - PyErr_SetString(PyExc_NotImplementedError, - "CreateSymbolicLink functions not found"); - return NULL; - } - if (!win32_can_symlink) { - PyErr_SetString(PyExc_OSError, "symbolic link privilege not held"); - return NULL; - } -#endif - #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH /* if src is a directory, ensure target_is_directory==1 */ target_is_directory |= _check_dirW(src->wide, dst->wide); - result = Py_CreateSymbolicLinkW(dst->wide, src->wide, - target_is_directory); + result = CreateSymbolicLinkW(dst->wide, src->wide, + target_is_directory); _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS @@ -13020,35 +12989,6 @@ static PyMethodDef posix_methods[] = { {NULL, NULL} /* Sentinel */ }; - -#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) -static int -enable_symlink() -{ - HANDLE tok; - TOKEN_PRIVILEGES tok_priv; - LUID luid; - - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok)) - return 0; - - if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid)) - return 0; - - tok_priv.PrivilegeCount = 1; - tok_priv.Privileges[0].Luid = luid; - tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv, - sizeof(TOKEN_PRIVILEGES), - (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) - return 0; - - /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */ - return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1; -} -#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ - static int all_ins(PyObject *m) { @@ -13644,10 +13584,6 @@ INITFUNC(void) PyObject *list; const char * const *trace; -#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) - win32_can_symlink = enable_symlink(); -#endif - m = PyModule_Create(&posixmodule); if (m == NULL) return NULL; From 60dc7058330e855a94808ee808f6031348193656 Mon Sep 17 00:00:00 2001 From: Vidar Tonaas Fauske Date: Mon, 18 Sep 2017 20:48:37 +0200 Subject: [PATCH 2/7] bpo-31512: Enable symlinks for Windows 10 in dev mode On Windows 10 (build > 14972), symlinks are available for unprivileged users when the machine is in developer mode. --- Doc/library/os.rst | 15 +++---- .../2017-10-04-12-40-45.bpo-31512.YQeBt2.rst | 2 + Modules/posixmodule.c | 44 ++++++++++++++++--- Modules/winreparse.h | 5 +++ 4 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2017-10-04-12-40-45.bpo-31512.YQeBt2.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index bae432d33b0bd4..dc9e2f88908226 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2665,19 +2665,15 @@ features: as a directory if *target_is_directory* is ``True`` or a file symlink (the default) otherwise. On non-Window platforms, *target_is_directory* is ignored. - Symbolic link support was introduced in Windows 6.0 (Vista). :func:`symlink` - will raise a :exc:`NotImplementedError` on Windows versions earlier than 6.0. - This function can support :ref:`paths relative to directory descriptors `. .. note:: - On Windows, the *SeCreateSymbolicLinkPrivilege* is required in order to - successfully create symlinks. This privilege is not typically granted to - regular users but is available to accounts which can escalate privileges - to the administrator level. Either obtaining the privilege or running your - application as an administrator are ways to successfully create symlinks. + On newer versions of Windows 10, unprivileged accounts can create symlinks + if Developer Mode is enabled. When Developer Mode is not available/enabled, + the *SeCreateSymbolicLinkPrivilege* privilege is required, or the process + must be run as an administrator. :exc:`OSError` is raised when the function is called by an unprivileged @@ -2695,6 +2691,9 @@ features: .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *src* and *dst*. + .. versionchanged:: 3.7 + Added support for unelevated symlinks on Windows with Developer Mode. + .. function:: sync() diff --git a/Misc/NEWS.d/next/Windows/2017-10-04-12-40-45.bpo-31512.YQeBt2.rst b/Misc/NEWS.d/next/Windows/2017-10-04-12-40-45.bpo-31512.YQeBt2.rst new file mode 100644 index 00000000000000..a6dbb5c0639b61 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2017-10-04-12-40-45.bpo-31512.YQeBt2.rst @@ -0,0 +1,2 @@ +With the Windows 10 Creators Update, non-elevated users can now create +symlinks as long as the computer has Developer Mode enabled. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 2f89c561ce2096..2f8540d91a4302 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7570,21 +7570,55 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, { #ifdef MS_WINDOWS DWORD result; + DWORD flags = 0; + + /* Assumed true, set to false if detected to not be available. */ + static int windows_has_symlink_unprivileged_flag = TRUE; #else int result; #endif #ifdef MS_WINDOWS + if (windows_has_symlink_unprivileged_flag) { + /* Allow non-admin symlinks if system allows it. */ + flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH - /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirW(src->wide, dst->wide); - result = CreateSymbolicLinkW(dst->wide, src->wide, - target_is_directory); - _Py_END_SUPPRESS_IPH + /* if src is a directory, ensure flags==1 (target_is_directory bit) */ + flags |= target_is_directory | _check_dirW(src->wide, dst->wide); + + result = CreateSymbolicLinkW(dst->wide, src->wide, flags); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS + if (windows_has_symlink_unprivileged_flag && !result && + ERROR_INVALID_PARAMETER == GetLastError()) { + + Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + /* This error might be caused by + SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported. + Try again, and update windows_has_symlink_unprivileged_flag if we + are successful this time. + + NOTE: There is a risk of a race condition here if there are other + conditions than the flag causing ERROR_INVALID_PARAMETER, and + another process (or thread) changes that condition in between our + calls to CreateSymbolicLink. + */ + flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); + result = CreateSymbolicLinkW(dst->wide, src->wide, flags); + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + + if (result || ERROR_INVALID_PARAMETER != GetLastError()) { + windows_has_symlink_unprivileged_flag = FALSE; + } + } + if (!result) return path_error2(src, dst); diff --git a/Modules/winreparse.h b/Modules/winreparse.h index 28049c9af90664..f06f701f999ca6 100644 --- a/Modules/winreparse.h +++ b/Modules/winreparse.h @@ -45,6 +45,11 @@ typedef struct { FIELD_OFFSET(_Py_REPARSE_DATA_BUFFER, GenericReparseBuffer) #define _Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) +// Defined in WinBase.h in 'recent' versions of Windows 10 SDK +#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE +#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2 +#endif + #ifdef __cplusplus } #endif From 021aa77415e24fe12bf6d750c6ffec67aa5dc9bb Mon Sep 17 00:00:00 2001 From: Vidar Tonaas Fauske Date: Tue, 6 Mar 2018 00:57:44 +0100 Subject: [PATCH 3/7] fix whitespace --- Modules/posixmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 2f8540d91a4302..23ec680c3aa798 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7591,7 +7591,7 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, flags |= target_is_directory | _check_dirW(src->wide, dst->wide); result = CreateSymbolicLinkW(dst->wide, src->wide, flags); - _Py_END_SUPPRESS_IPH + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (windows_has_symlink_unprivileged_flag && !result && @@ -7611,7 +7611,7 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, */ flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); result = CreateSymbolicLinkW(dst->wide, src->wide, flags); - _Py_END_SUPPRESS_IPH + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (result || ERROR_INVALID_PARAMETER != GetLastError()) { From c9c86672311fa39cf1d2508f425c3dbff23c2113 Mon Sep 17 00:00:00 2001 From: Vidar Tonaas Fauske Date: Wed, 5 Sep 2018 14:14:53 +0200 Subject: [PATCH 4/7] 3.7 -> 3.8 as inclusion point --- Doc/library/os.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index dc9e2f88908226..f79136b46be1a7 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2691,7 +2691,7 @@ features: .. versionchanged:: 3.6 Accepts a :term:`path-like object` for *src* and *dst*. - .. versionchanged:: 3.7 + .. versionchanged:: 3.8 Added support for unelevated symlinks on Windows with Developer Mode. From 19b9a081261e4c52983df4cd629629090bdfe1b1 Mon Sep 17 00:00:00 2001 From: Vidar Tonaas Fauske Date: Tue, 27 Nov 2018 10:30:04 -0600 Subject: [PATCH 5/7] Use constant for win32 symlink dir flag --- Modules/posixmodule.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 23ec680c3aa798..88f163fda09076 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7588,7 +7588,9 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH /* if src is a directory, ensure flags==1 (target_is_directory bit) */ - flags |= target_is_directory | _check_dirW(src->wide, dst->wide); + if (target_is_directory || _check_dirW(src->wide, dst->wide)) { + flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; + } result = CreateSymbolicLinkW(dst->wide, src->wide, flags); _Py_END_SUPPRESS_IPH From bf973bd0c76b41e633ed04428617fb8f151ba5f1 Mon Sep 17 00:00:00 2001 From: Vidar Tonaas Fauske Date: Tue, 9 Apr 2019 11:43:15 +0100 Subject: [PATCH 6/7] Remove unneeded IPH suppress for win symlinks --- Modules/posixmodule.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index e8dbdcc94aa701..c1b99c4da3ec62 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7871,21 +7871,18 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, } Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH /* if src is a directory, ensure flags==1 (target_is_directory bit) */ if (target_is_directory || _check_dirW(src->wide, dst->wide)) { flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; } result = CreateSymbolicLinkW(dst->wide, src->wide, flags); - _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (windows_has_symlink_unprivileged_flag && !result && ERROR_INVALID_PARAMETER == GetLastError()) { Py_BEGIN_ALLOW_THREADS - _Py_BEGIN_SUPPRESS_IPH /* This error might be caused by SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported. Try again, and update windows_has_symlink_unprivileged_flag if we @@ -7898,7 +7895,6 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, */ flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); result = CreateSymbolicLinkW(dst->wide, src->wide, flags); - _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (result || ERROR_INVALID_PARAMETER != GetLastError()) { From 5132324d2ae756d5ceaaf3f8d510b11245894bfc Mon Sep 17 00:00:00 2001 From: Vidar Tonaas Fauske Date: Tue, 9 Apr 2019 12:36:34 +0100 Subject: [PATCH 7/7] Revert "Remove unneeded IPH suppress for win symlinks" This reverts commit bf973bd0c76b41e633ed04428617fb8f151ba5f1. --- Modules/posixmodule.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index c1b99c4da3ec62..e8dbdcc94aa701 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7871,18 +7871,21 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, } Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH /* if src is a directory, ensure flags==1 (target_is_directory bit) */ if (target_is_directory || _check_dirW(src->wide, dst->wide)) { flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; } result = CreateSymbolicLinkW(dst->wide, src->wide, flags); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (windows_has_symlink_unprivileged_flag && !result && ERROR_INVALID_PARAMETER == GetLastError()) { Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH /* This error might be caused by SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE not being supported. Try again, and update windows_has_symlink_unprivileged_flag if we @@ -7895,6 +7898,7 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst, */ flags &= ~(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE); result = CreateSymbolicLinkW(dst->wide, src->wide, flags); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS if (result || ERROR_INVALID_PARAMETER != GetLastError()) { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy