Określ, czy proces systemu Windows ma uprawnienia do tworzenia dowiązania symbolicznego

Chcę programowo określić, czy bieżący użytkownik (lub proces) ma dostęp do tworzenia dowiązań symbolicznych. W systemie Windows (Vista i nowszym) nie można utworzyć dowiązania symbolicznego bez SeCreateSymbolicLinkPrivilege i domyślnie jest ono przypisywane tylko administratorom. Jeśli ktoś próbuje utworzyć dowiązanie symboliczne bez tego przywileju, pojawia się błąd systemu Windows 1314 (klient nie ma wymaganego przywileju).

Aby zademonstrować to ograniczenie, stworzyłem czystą instalację systemu Windows, zalogowanego jako początkowe konto administratora (ograniczone przez UAC) i nie mogłem utworzyć dowiązania symbolicznego w katalogu domowym.

Po uruchomieniu wiersza polecenia jako administrator lub wyłączeniu kontroli konta użytkownika polecenie to jest wykonywane bez błędu.

WedługTen artykuł, „każdy proces wykonywany w imieniu użytkownika ma kopię tokena [dostęp]”.

Więc stworzyłemskrypt Pythona do wyszukiwania uprawnień. Dla wygody i potomności zamieszczam poniżej fragment.

Ideą skryptu jest wyliczenie wszystkich uprawnień i określenie, czy proces ma wymagane uprawnienia. Niestety, uważam, że obecny proces w rzeczywistości nie ma pożądanego przywileju, nawet jeśli może tworzyć dowiązania symboliczne.

Podejrzewam, że problem polega na tym, że nawet jeśli obecne uprawnienia użytkownika nie obejmują wyraźnie tego przywileju, jego członkostwo w grupie pozwala na ten przywilej.

W skrócie, jak mogę określić, czy dany proces będzie miał przywilej tworzenia dowiązań symbolicznych (bez próby jego utworzenia)? Preferowany jest przykład w C lub C ++ lub Pythonie, choć odpowiednie będzie wszystko, co wykorzystuje API Windows.

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)

questionAnswers(1)

yourAnswerToTheQuestion