2

我正在尝试使用 CreateSymbolicLinkW() 函数(来自 Kernel32.dll)来创建符号链接。

在各自的机器上(Win7 Pro x64 SP1):

  • UAC 已启用(=具有本地管理员权限的用户进程默认情况下未提升)
  • 我已授予所有经过身份验证的用户“创建符号链接”用户权限分配(通过计算机 -> Windows 设置 -> 安全 -> 本地策略 -> 用户权限分配 -> 创建符号链接 = 已验证用户的组策略)
  • 我已启用所有可能的符号链接评估类型(再次通过组策略设置)。(确认“fsutil 行为查询 SymlinkEvaluation”返回:“本地到本地符号链接已启用。本地到远程符号链接已启用。远程到本地符号链接已启用。远程到远程符号链接已启用。”

现在的情况是:

  • 当我在 UNELEVATED 进程中以非管理员用户身份运行 CreateSymbolicLinkW() 时,它可以工作(创建符号链接)
  • 当我在 ELEVATED 进程中以 ADMIN 用户身份运行 CreateSymbolicLinkW() 时,它可以工作(已创建符号链接)
  • 当我在 UNELEVATED (!) 进程中以 ADMIN (!) 用户身份运行 CreateSymbolicLinkW() 时,它不起作用

最后一种情况是实际问题。GetLastError 返回的错误是:1314 (= "a required privilege is notheld by the client")

为什么管理员用户在未提升的进程中失败,而它对未提升的外壳中的任何非管理员用户都有效?

我的代码旨在由任何类型的用户运行,最好在未提升的过程中运行。在任何情况下,我都希望避免让管理员用户将流程提升为解决方法。

顺便说一句,使用 Windows shell 中的 MKLINK 命令也可以重现相同的行为(对于非提升外壳中的管理员用户失败,而它适用于非提升外壳中的所有非管理员用户)。

Python 2.7 示例代码:

import ctypes
CreateSymbolicLinkW = ctypes.WinDLL("Kernel32").CreateSymbolicLinkW
CreateSymbolicLinkW(u"c:\\linktest\\testlink.txt", u"c:\\linktest\\testtarget.txt",0)
print(ctypes.WinDLL("Kernel32").GetLastError())
4

1 回答 1

6

您观察到的行为是由于 UAC 和默认情况下为管理员用户提供的受限令牌。此令牌是通过获取普通管理员用户的令牌并对其进行过滤以删除各种管理员权限而自动创建的。

whoami /priv您可以通过在 DOS 提示符下运行命令来查看您的令牌具有哪些权限。在提升的提示中,您的令牌将拥有比未提升的提示更大的权限集,包括创建符号链接权限。

不幸的是,我不相信有办法解决这个问题,因为这正是 UAC 的设计方式。我认为没有任何方法可以控制管理令牌的过滤方式,这是关键问题 - 除了完全禁用 UAC。

于 2015-03-15T19:18:21.377 回答