Определите, имеет ли процесс Windows право на создание символической ссылки
Я хочу программно определить, есть ли у текущего пользователя (или процесса) доступ к созданию символических ссылок. В Windows (Vista и выше) невозможно создать символическую ссылку без SeCreateSymbolicLinkPrivilege, и по умолчанию она назначается только администраторам. Если попытаться создать символическую ссылку без этой привилегии, возникает ошибка Windows 1314 (требуемая привилегия не поддерживается клиентом).
Чтобы продемонстрировать это ограничение, я создал чистую установку Windows, вошел в систему как начальная учетная запись администратора (ограниченная через UAC) и не смог создать символическую ссылку в домашнем каталоге.
После запуска командной строки от имени администратора или отключения UAC эта команда выполняется без ошибок.
Согласно сэта статья, «каждый процесс, выполняемый от имени пользователя, имеет копию токена [access]».
Итак, я создалскрипт Python для запроса разрешений, Для удобства и потомства я привожу отрывок ниже.
Идея сценария состоит в том, чтобы перечислить все привилегии и определить, есть ли у процесса требуемая привилегия, ge. К сожалению, я считаю, что текущий процесс на самом деле не имеет желаемой привилегии, даже если он может создавать символические ссылки.
Я подозреваю, что проблема в том, что, хотя привилегии текущего пользователя явно не включают привилегию, членство в его группе действительно предоставляет эту привилегию.
Короче говоря, как я могу определить, будет ли данный процесс иметь привилегию для создания символических ссылок (не пытаясь создать одну)? Пример на C или C ++ или Python предпочтителен, хотя все, что использует Windows API, подойдет.
def get_process_token():
token = wintypes.HANDLE()
TOKEN_ALL_ACCESS = 0xf01ff
res = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token)
if not res > 0: raise RuntimeError("Couldn't get process token")
return token
def get_privilege_information():
# first call with zero length to determine what size buffer we need
return_length = wintypes.DWORD()
params = [
get_process_token(),
TOKEN_INFORMATION_CLASS.TokenPrivileges,
None,
0,
return_length,
]
res = GetTokenInformation(*params)
# assume we now have the necessary length in return_length
buffer = ctypes.create_string_buffer(return_length.value)
params[2] = buffer
params[3] = return_length.value
res = GetTokenInformation(*params)
assert res > 0, "Error in second GetTokenInformation (%d)" % res
privileges = ctypes.cast(buffer, ctypes.POINTER(TOKEN_PRIVILEGES)).contents
return privileges
privileges = get_privilege_information()
print("found {0} privileges".format(privileges.count))
map(print, privileges)