estoy tratando de leer el acceso de los archivos y directorios en Windows utilizando este código (modelado después Tim Golden's proposed patch to os.access to make it read from ACLs on Windows):¿Qué está haciendo que este descriptor de seguridad se estropee?
from ctypes import(
windll,
wintypes,
c_char_p,
c_void_p,
byref
)
from win32api import GetCurrentThread
from win32security import (
GetFileSecurity,
DACL_SECURITY_INFORMATION,
ImpersonateSelf,
SecurityImpersonation,
OpenThreadToken,
TOKEN_ALL_ACCESS,
MapGenericMask
)
from ntsecuritycon import (
FILE_READ_DATA,
FILE_WRITE_DATA,
FILE_EXECUTE,
FILE_ALL_ACCESS
)
import pywintypes
import winnt
TRUE = 1
def CheckAccess(path,AccessDesired):
result = wintypes.BOOL()
granted = wintypes.DWORD(0)
privsetlength = wintypes.DWORD(0)
fileSD = GetFileSecurity(path, DACL_SECURITY_INFORMATION)
if not fileSD.IsValid():
raise Exception("Invalid security descriptor")
ImpersonateSelf(SecurityImpersonation)
token = OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE)
mapping = wintypes.DWORD(MapGenericMask(AccessDesired,
(FILE_READ_DATA, FILE_WRITE_DATA, FILE_EXECUTE, FILE_ALL_ACCESS)))
if not windll.advapi32.AccessCheck(
c_char_p(str(buffer(fileSD))),
wintypes.HANDLE(int(token)),
AccessDesired,
byref(mapping),
c_void_p(0), #privilege set, optional
byref(privsetlength), #size of optional privilege set
byref(granted),
byref(result)
):
code = GetLastError()
raise WindowsError(GetLastError(),FormatMessage(code))
return bool(result)
def HasReadAccess(path):
return CheckAccess(path,FILE_READ_DATA)
def HasWriteAccess(path):
return CheckAccess(path,FILE_WRITE_DATA)
if __name__ == "__main__":
print(HasReadAccess("C:/Python26"))
Sin embargo, cada vez que ejecute esto, me sale esto:
WindowsError: [Error 1338] The security descriptor structure is invalid.
¿Cómo se supone que paso el SecurityDescriptor a AccessCheck?
EDITAR: Cambiar DACL_SECURITY_INFORMATION a DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION me da esto:
WindowsError: [Error 122] The data area passed to a system call is too small.
Hola Stuart, estoy lidiando con el mismo problema en este momento; ¿Podría publicar su código de trabajo final? – Ali
Esto fue de una pasantía que hice hace más de un año, con un código que no llevé conmigo, pero al leer lo que estoy diciendo aquí, creo que el truco es (siguiendo el ejemplo escrito aquí) reemplazar 'privsetlength = wintypes.DWORD (0) 'con' privsetlength = wintypes.DWORD (20) 'y' c_void_p (0) 'con algo así como' create_string_buffer (20) '(He pasado el último año y medio felizmente olvidando todo lo que alguna vez involucró el módulo de Python ctypes). –
Haha :-) ¡bien para ti haber puesto los tipos! Hice que esto funcione. para cualquiera que esté interesado, lo que hice fue llamar primero a AccessCheck con null para obtener el comportamiento predeterminado (privsetlength) y luego recuperarlo con el tamaño correcto (vea los comentarios en msdn de AccessCheck). – Ali