Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's making this security descriptor go bad?

I'm trying to read the access for files and directories in Windows using this code (patterned after Tim Golden's proposed patch to os.access to make it read from ACLs on Windows):

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"))

However, every time I run this, I get this:

WindowsError: [Error 1338] The security descriptor structure is invalid.

How am I supposed to pass the SecurityDescriptor to AccessCheck?

EDIT: Changing the DACL_SECURITY_INFORMATION to DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION gives me this:

WindowsError: [Error 122] The data area passed to a system call is too small.
like image 962
Stuart P. Bentley Avatar asked May 12 '11 21:05

Stuart P. Bentley


1 Answers

Apparently by "optional" Windows means "required". I fixed it by allocating a buffer and passing the size of PRIVILEGE_SET (20).

like image 185
Stuart P. Bentley Avatar answered Sep 21 '22 11:09

Stuart P. Bentley