Hi folks,
I''ve got most everything done for the pure Ruby version of win32-file.
The last thing left (since I''ll be moving the IO methods to a different
package eventually) is the file security stuff. Here''s what
I''ve got so
far for the get_permissions method. However, I''m stuck at GetAce().
If
someone could help me finish up this method, I would be most appreciative.
Also, should we consider dumping this approach in favor of a OLE + WMI
solution, using Win32_LogicalFileSecuritySetting ?
Dan
def self.get_permissions(file)
current_length = 0
length_needed = [1].pack(''L'')
sec_buf = ''''
loop do
bool = @@GetFileSecurity.call(
file,
DACL_SECURITY_INFORMATION,
sec_buf,
sec_buf.length,
length_needed
)
if bool == 0 && @@GetLastError.call !=
ERROR_INSUFFICIENT_BUFFER
raise ArgumentError, get_last_error
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, get_last_error
end
# No DACL exists
if (control.unpack(''L'').first & SE_DACL_PRESENT) ==
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'')
val = @@GetSecurityDescriptorDacl.call(
sec_buf,
dacl_present,
acl_ptr,
dacl_defaulted
)
if val == 0
raise ArgumentError, get_last_error
end
acl_buf = 0.chr * 8
@@memcpy.call(acl_buf, acl_ptr.unpack(''L'').first, 8)
if acl_buf.unpack(''CCSSS'').first == 0
raise ArgumentError, ''DACL is NULL: implicit access
grant''
end
ace_count = acl_buf.unpack(''CCSSS'')[3]
ace_ptr = [0].pack(''L'')
# stuck here
0.upto(ace_count - 1){ |i|
if @@GetAce.call(acl_buf, i, ace_ptr) == 0
next
end
ace_buf = 0.chr * 4
@@memcpy.call(ace_buf, ace_ptr.unpack(''L'').first, 4)
p ace_buf.unpack(''CCS'') # Not what I expect
}
end
Hi,> >Hi folks, > >I''ve got most everything done for the pure Ruby version of >win32-file. >The last thing left (since I''ll be moving the IO methods to a >different >package eventually) is the file security stuff. Here''s what I''ve >got so >far for the get_permissions method. However, I''m stuck at GetAce(). > If >someone could help me finish up this method, I would be most >appreciative. > >Also, should we consider dumping this approach in favor of a OLE + >WMI >solution, using Win32_LogicalFileSecuritySetting ? >Yes. I think we can do more things with this than WMI.>Dan > >def self.get_permissions(file) > current_length = 0 > length_needed = [1].pack(''L'') > sec_buf = '''' > > loop do > bool = @@GetFileSecurity.call( > file, > DACL_SECURITY_INFORMATION, > sec_buf, > sec_buf.length, > length_needed > ) > > if bool == 0 && @@GetLastError.call != >ERROR_INSUFFICIENT_BUFFER > raise ArgumentError, get_last_error > 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, get_last_error > end > > # No DACL exists > if (control.unpack(''L'').first & SE_DACL_PRESENT) == 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'') > > val = @@GetSecurityDescriptorDacl.call( > sec_buf, > dacl_present, > acl_ptr, > dacl_defaulted > ) > > if val == 0 > raise ArgumentError, get_last_error > end > > acl_buf = 0.chr * 8 > @@memcpy.call(acl_buf, acl_ptr.unpack(''L'').first, 8) > > if acl_buf.unpack(''CCSSS'').first == 0 > raise ArgumentError, ''DACL is NULL: implicit access grant'' > end > > ace_count = acl_buf.unpack(''CCSSS'')[3] > ace_ptr = [0].pack(''L'') > > # stuck here > 0.upto(ace_count - 1){ |i| > if @@GetAce.call(acl_buf, i, ace_ptr) == 0 > next > end > > ace_buf = 0.chr * 4 > @@memcpy.call(ace_buf, ace_ptr.unpack(''L'').first, 4) > > p ace_buf.unpack(''CCS'') # Not what I expect > } > > end > >Refer to ruby-talk:184780 define GetAce like this: GetAce = Win32API.new(''advapi32'', ''GetAce'', ''LLP'', ''I'') and call like this: GetAce.call(acl_ptr.unpack(''L'')[0], i, ace_ptr) Regards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Park Heesob > Sent: Monday, March 20, 2006 7:37 PM > To: win32utils-devel at rubyforge.org > Subject: Re: [Win32utils-devel] Need some ACL help for win32-file<snip>> > > >Also, should we consider dumping this approach in favor of a OLE + > >WMI > >solution, using Win32_LogicalFileSecuritySetting ? > > > Yes. I think we can do more things with this than WMI.Wait - you think we should use WMI or we shouldn''t? <snip>> Refer to ruby-talk:184780 > > define GetAce like this: > GetAce = Win32API.new(''advapi32'', ''GetAce'', ''LLP'', ''I'') > > and call like this: > GetAce.call(acl_ptr.unpack(''L'')[0], i, ace_ptr)Ah, thanks. Feel like taking on LookupAccountSid? :) Regards, Dan
Well, I''ve given up trying to figure out the rest of the file permissions stuff (LookupAccountSid, etc). I''m just not getting it. I''ve committed what I''ve done so far (now in the toplevel win32-file project in the CVS repo) in file.rb. Any help appreciated. Regards, Dan
Hi,> Well, I''ve given up trying to figure out the rest of the file > permissions stuff (LookupAccountSid, etc). I''m just not getting it. >Well, Don''t give up :) Here is the LookupAccountSid stuff: 0.upto(ace_count - 1){ |i| if @@GetAce.call(dacl_ptr.unpack(''L'').first, i, ace_ptr) == 0 next end ace_buf = 0.chr * 12 # Header:4,Mask:4,SidStart:4 (struct ACCESS_ALLOWD_ACE) @@memcpy.call(ace_buf, ace_ptr.unpack(''L'').first, ace_buf.size) if ace_buf.unpack(''CCS'').first == ACCESS_ALLOWED_ACE_TYPE name = 0.chr * 256 name_len_ptr = [name.size].pack(''L'') domain = 0.chr * 256 domain_len_ptr = [domain.size].pack(''L'') snu_ptr = 0.chr * 4 val = @@LookupAccountSid.call( nil, # local computer ace_ptr.unpack(''L'').first + 8, # address of ace_ptr->SidStart name, name_len_ptr, domain, domain_len_ptr, snu_ptr ) if val == 0 raise ArgumentError, get_last_error end name = name[0...name_len_ptr.unpack(''L'').first] domain = domain[0...domain_len_ptr.unpack(''L'').first] mask = ace_buf.unpack(''LLL'')[1] puts "\n\nUser:#{name},Domain:#{domain}" puts "FILE_APPEND_DATA" if (mask & FILE_APPEND_DATA).nonzero? puts "FILE_EXECUTE" if (mask & FILE_EXECUTE).nonzero? puts "FILE_READ_ATTRIBUTES" if (mask & FILE_READ_ATTRIBUTES).nonzero? puts "FILE_READ_DATA" if (mask & FILE_READ_DATA).nonzero? puts "FILE_READ_EA" if (mask & FILE_READ_EA).nonzero? puts "FILE_WRITE_ATTRIBUTES" if (mask & FILE_WRITE_ATTRIBUTES).nonzero? puts "FILE_WRITE_DATA" if (mask & FILE_WRITE_DATA).nonzero? puts "FILE_WRITE_EA" if (mask & FILE_WRITE_EA).nonzero? puts "DELETE" if (mask & DELETE).nonzero? puts "READ_CONTROL" if (mask & READ_CONTROL).nonzero? puts "WRITE_DAC" if (mask & WRITE_DAC).nonzero? puts "WRITE_OWNER" if (mask & WRITE_OWNER).nonzero? puts "SYNCHRONIZE" if (mask & SYNCHRONIZE).nonzero? puts "ACCESS_SYSTEM_SECURITY" if (mask & ACCESS_SYSTEM_SECURITY).nonzero? puts "MAXIMUM_ALLOWED" if (mask & MAXIMUM_ALLOWED).nonzero? end And define LookupAccountSid like this: @@LookupAccountSid Win32API.new(''advapi32'', ''LookupAccountSid'', ''PLPPPPP'', ''I'')> I''ve committed what I''ve done so far (now in the toplevel win32-file > project in the CVS repo) in file.rb. Any help appreciated. > > Regards, > > DanRegards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Park Heesob > Sent: Wednesday, March 22, 2006 5:58 AM > To: win32utils-devel at rubyforge.org > Subject: Re: [Win32utils-devel] Need some ACL help for win32-file > > > Hi, > > Well, I''ve given up trying to figure out the rest of the file > > permissions stuff (LookupAccountSid, etc). I''m just not > getting it. > > > Well, Don''t give up :) > > Here is the LookupAccountSid stuff:<snip> Excellent, thanks! I was pretty close. Mainly I was stuck on the second argument (SidStart) and how to handle that. Dan