2011-05-12 16 views
5

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. 

Respuesta

5

parecer por "opcional" de Windows significa "necesaria". Lo arreglé asignando un buffer y pasando el tamaño de PRIVILEGE_SET (20).

+0

Hola Stuart, estoy lidiando con el mismo problema en este momento; ¿Podría publicar su código de trabajo final? – Ali

+2

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). –

+0

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

Cuestiones relacionadas