[Win32utils-devel] Help needed for get_permissions

Daniel Berger djberg96 at gmail.com
Fri Nov 30 20:10:03 UTC 2012


On Thu, Nov 29, 2012 at 8:23 PM, Heesob Park <phasis at gmail.com> wrote:
> Hi,
>
> 2012/11/30 Daniel Berger <djberg96 at gmail.com>:
>> I'm working on the win32-file-security lib (the security functions
>> split out from win32-file), but I'm stuck on the get_permissions
>> method conversion to FFI. Specifically, the ACL struct doesn't seem to
>> get filled with correct values on the call to
>> GetSecurityDescriptorDacl. They're junk.
>>
>> I've tried creating a new ACL from the pointer, but that didn't seem
>> to work. Any ideas?
>>
> I guess you have some trouble for the pointer of pointer.
>
> Here is a working code:
>
> require 'ffi'
>
> class String
>   # Convenience method for converting strings to UTF-16LE for wide character
>   # functions that require it.
>   def wincode
>     (self.tr(File::SEPARATOR, File::ALT_SEPARATOR) + 0.chr).encode('UTF-16LE')
>   end
> end
>
> class File
>   extend FFI::Library
>   ffi_lib 'advapi32'
>
>   SE_DACL_PRESENT           = 4
>   DACL_SECURITY_INFORMATION = 4
>   ACCESS_ALLOWED_ACE_TYPE   = 0
>   ERROR_INSUFFICIENT_BUFFER = 122
>
>   class ACL < FFI::Struct
>     layout(
>       :AclRevision, :uchar,
>       :Sbz1, :uchar,
>       :AclSize, :ushort,
>       :AceCount, :ushort,
>       :Sbz2, :ushort
>     )
>   end
>
>   attach_function :GetFileSecurityW, [:buffer_in, :ulong, :pointer,
> :ulong, :pointer], :bool
>   attach_function :GetSecurityDescriptorControl, [:pointer, :pointer,
> :pointer], :bool
>   attach_function :GetSecurityDescriptorDacl, [:pointer, :pointer,
> ACL, :pointer], :ulong
>
>   def self.get_permissions(file, host=nil)
>     size_needed_ptr = FFI::MemoryPointer.new(:ulong)
>     security_ptr    = FFI::MemoryPointer.new(:ulong)
>
>     wide_file = file.wincode
>
>     # First pass, get the size needed
>     bool = GetFileSecurityW(
>       wide_file,
>       DACL_SECURITY_INFORMATION,
>       security_ptr,
>       security_ptr.size,
>       size_needed_ptr
>     )
>
>     errno = FFI.errno
>
>     if !bool && errno != ERROR_INSUFFICIENT_BUFFER
>       raise SystemCallError.new("GetFileSecurity", errno)
>     end
>
>     size_needed = size_needed_ptr.read_ulong
>
>     security_ptr = FFI::MemoryPointer.new(size_needed)
>
>     # Second pass, this time with the appropriately sized security pointer
>     bool = GetFileSecurityW(
>       wide_file,
>       DACL_SECURITY_INFORMATION,
>       security_ptr,
>       security_ptr.size,
>       size_needed_ptr
>     )
>
>     unless bool
>       raise SystemCallError.new("GetFileSecurity", FFI.errno)
>     end
>
>     control_ptr  = FFI::MemoryPointer.new(:ulong)
>     revision_ptr = FFI::MemoryPointer.new(:ulong)
>
>     unless GetSecurityDescriptorControl(security_ptr, control_ptr, revision_ptr)
>       raise SystemCallError.new("GetSecurityDescriptorControl", FFI.errno)
>     end
>
>     control = control_ptr.read_ulong
>
>     if control & SE_DACL_PRESENT == 0
>       raise ArgumentError, "No DACL present: explicit deny all"
>     end
>
>     acl_pptr = FFI::MemoryPointer.new(:pointer)
>     dacl_present_ptr   = FFI::MemoryPointer.new(:bool)
>     dacl_defaulted_ptr = FFI::MemoryPointer.new(:ulong)
>
>     val = GetSecurityDescriptorDacl(
>       security_ptr,
>       dacl_present_ptr,
>       acl_pptr,
>       dacl_defaulted_ptr
>     )
>     if val == 0
>       raise SystemCallError.new("GetSecurityDescriptorDacl", FFI.errno)
>     end
>     acl = ACL.new(acl_pptr.read_pointer)
>     if acl[:AclRevision] == 0
>       raise ArgumentError, "DACL is NULL: implicit access grant"
>     end
>
>     p acl[:AclRevision]
>     p acl[:AclSize]
>     p acl[:AceCount]
>   end
> end
>
> File.get_permissions('test.txt')

Thanks!

I think I'm stuck again, this time the SidStart member of the
ACCESS_ALLOWED_ACE struct isn't valid. Can you please take a look?

git clone https://github.com/djberg96/win32-file-security.git

Thanks,

Dan


More information about the win32utils-devel mailing list