Win32API struct member help


#1

Hi all,

I’m trying to figure out how to get the acl attributes of a simple text
file, and I need a little help getting data out of a struct.
Specifically, I need to get the AceCount from an access control list
(ACL struct) after a call to GetSecurityDescriptorDacl(). Here’s what
I’ve got so far:

require ‘Win32API’

GetFileSecurity =
Win32API.new(‘advapi32’, ‘GetFileSecurity’, ‘PLPLP’, ‘I’)

GetSecurityDescriptorControl =
Win32API.new(‘advapi32’, ‘GetSecurityDescriptorControl’, ‘PPP’, ‘I’)

GetSecurityDescriptorDacl =
Win32API.new(‘advapi32’, ‘GetSecurityDescriptorDacl’, ‘PPPP’, ‘I’)

file = ‘test.txt’ # nothing special about this file

current_length = 0
length_needed = [1].pack(‘L’)
sec_buf = ‘’ # 0 length string

loop do
bool = GetFileSecurity.call(
file,
DACL_SECURITY_INFORMATION,
sec_buf,
sec_buf.length,
length_needed
)

if bool == 0 && GetLastError.call != 122
raise ArgumentError, ‘GetFileSecurity failed’
end

break if sec_buf.length >= length_needed.unpack(‘L’).first
sec_buf += ’ ’ * length_needed.unpack(“L”).first
end

control = [0].pack(‘L’)
revision = [0].pack(‘L’)

if GetSecurityDescriptorControl.call(sec_buf, control, revision) == 0
raise ArgumentError, ‘GetSecurityDescriptorControl failed’
end

No DACL exists

if (control.unpack(‘L’).first & 4) == 0
raise ArgumentError, ‘No DACL present: explicit deny all’
end

dacl_present = [0].pack(‘L’)
dacl_defaulted = [0].pack(‘L’)

acl_ptr = [0].pack(‘L’) # what should this be?

val = GetSecurityDescriptorDacl.call(
sec_buf,
dacl_present,
acl_ptr,
dacl_defaulted
)

if val == 0
raise ArgumentError, ‘GetSecurityDescriptorDacl failed’
end

p acl_ptr.unpack(‘CCSSS’) # [228, 50, 632, nil, nil]

I was expecting 4 for the 4th attribute (AceCount). I tried changing
the initial value of acl_ptr to [0,0,0,0,0].pack(‘CCSSS’) but that
didn’t help. What did I do wrong?

For more on ACL structures:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/acl.asp

Thanks,

Dan