Repository: mesos Updated Branches: refs/heads/master ca6729315 -> 4bf96153a
Windows: Added legacy support for admin-only symlinks. Some users are regrettably stuck on versions of Windows before this feature was added. If the `ALLOW_UNPRIVILEGED` flag is unsupported, the creation of the symlink will fail with `ERROR_INVALID_PARAMETER`. Review: https://reviews.apache.org/r/64461 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4bf96153 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4bf96153 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4bf96153 Branch: refs/heads/master Commit: 4bf96153abfde2c5b18373072a5a85c377293086 Parents: ca67293 Author: Andrew Schwartzmeyer <[email protected]> Authored: Fri Dec 8 13:11:44 2017 -0800 Committer: Andrew Schwartzmeyer <[email protected]> Committed: Thu Dec 14 13:23:02 2017 -0800 ---------------------------------------------------------------------- .../stout/internal/windows/reparsepoint.hpp | 40 ++++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/4bf96153/3rdparty/stout/include/stout/internal/windows/reparsepoint.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/stout/include/stout/internal/windows/reparsepoint.hpp b/3rdparty/stout/include/stout/internal/windows/reparsepoint.hpp index 158f445..858b3c7 100644 --- a/3rdparty/stout/include/stout/internal/windows/reparsepoint.hpp +++ b/3rdparty/stout/include/stout/internal/windows/reparsepoint.hpp @@ -328,29 +328,37 @@ inline Try<Nothing> create_symbolic_link( // Bail out if target is already a reparse point. Try<bool> attribute_set = reparse_point_attribute_set(longpath(target)); if (attribute_set.isSome() && attribute_set.get()) { - return Error( - "Path '" + target + "' is already a reparse point"); + return Error("Path '" + target + "' is already a reparse point"); } - // Avoid requiring administrative privileges to create symbolic links. - DWORD flags = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; - if (target_is_folder) { - flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; - } + DWORD flags = target_is_folder ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; + + // Lambda to create symlink with given flags. + auto link = [&reparse_point, &target](const DWORD flags) { + return ::CreateSymbolicLinkW( + // Path to link. + longpath(reparse_point).data(), + // Path to target. + longpath(target).data(), + flags); + }; // `CreateSymbolicLink` normally adjusts the process token's privileges to // allow for symlink creation; however, we explicitly avoid this with the - // above flag. - if (!::CreateSymbolicLinkW( - // Path to link. - longpath(reparse_point).data(), - // Path to target. - longpath(target).data(), - flags)) { - return WindowsError(); + // following flag to not require administrative privileges. + if (link(flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)) { + return Nothing(); + } + + // If this failed because the non-symbolic link feature was not supported, + // try again without the feature. This is for legacy support. + if (::GetLastError() == ERROR_INVALID_PARAMETER) { + if (link(flags)) { + return Nothing(); + } } - return Nothing(); + return WindowsError(); } } // namespace windows {
