[Win32utils-devel] Need some ACL help for win32-file

Daniel Berger djberg96 at gmail.com
Sun Mar 19 23:45:51 EST 2006


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


More information about the win32utils-devel mailing list