Determine si el proceso de Windows tiene privilegios para crear un enlace simbólico

Quiero determinar mediante programación si el usuario actual (o el proceso) tiene acceso para crear enlaces simbólicos. En Windows (Vista y superior), uno no puede crear un enlace simbólico sin el SeCreateSymbolicLinkPrivilege y, de forma predeterminada, esto solo se asigna a los administradores. Si se intenta crear un enlace simbólico sin este privilegio, se produce un error de Windows 1314 (el cliente no tiene un privilegio requerido).

Para demostrar esta restricción, creé una instalación limpia de Windows, inicié sesión como la cuenta de administrador inicial (restringida a través de UAC) y no pude crear un enlace simbólico en el directorio de inicio.

Después de ejecutar el símbolo del sistema como administrador o deshabilitar UAC, ese comando se ejecuta sin error.

De acuerdo aEste artículo, "todo proceso ejecutado en nombre del usuario tiene una copia del token [de acceso]".

Asi que he creadoun script en Python para consultar los permisos. Para mayor comodidad y posteridad, incluyo un extracto a continuación.

La idea detrás del script es enumerar todos los privilegios y determinar si el proceso tiene el privilegio requerido. Desafortunadamente, encuentro que el proceso actual no tiene el privilegio deseado, incluso cuando puede crear enlaces simbólicos.

Sospecho que el problema es que a pesar de que los privilegios del usuario actual no incluyen explícitamente el privilegio, la membresía de su grupo permite ese privilegio.

En resumen, ¿cómo puedo determinar si un proceso dado tendrá privilegios para crear enlaces simbólicos (sin intentar crear uno)? Se prefiere un ejemplo en C o C ++ o Python, aunque cualquier cosa que utilice la API de Windows será adecuado.

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)

Respuestas a la pregunta(1)

Su respuesta a la pregunta