Daniel Berger
2006-Mar-25 17:13 UTC
[Win32utils-devel] Help with File.set_permissions port
I''ve got a (broken) version of File.set_permissions in CVS, and I need some help finishing it off please. Heesob, can you take a look? Thanks, Dan
Hi,> I''ve got a (broken) version of File.set_permissions in CVS, and I need > some help finishing it off please. > > Heesob, can you take a look? > > Thanks, > > DanHere is set_permissions: def self.set_permissions(file, perms) raise TypeError unless perms.kind_of?(Hash) account_rights = 0 pSD = 0.chr * SECURITY_DESCRIPTOR_MIN_LENGTH if @@InitializeSecurityDescriptor.call(pSD, 1) == 0 raise ArgumentError, get_last_error end cb_acl = 1024 cb_sid = 1024 acl_new = 0.chr * cb_acl if @@InitializeAcl.call(acl_new, cb_acl, ACL_REVISION2) == 0 raise ArgumentError, get_last_error end pSID = 0.chr * cb_sid psnuType = 0.chr * cb_sid allAce = 0.chr * ALLOW_ACE_LENGTH pAllAce = @@memset.call(allAce,0,0) # address of allAce # pAllAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE allAce[0] = 0 perms.each{ |account, mask| next if mask.nil? cchDomain = [80].pack(''L'') cbSID = [1024].pack(''L'') domain_buf = 0.chr * 80 server, account = account.split("\\") if [''BUILTIN'', ''NT AUTHORITY''].include?(server.upcase) server = nil end val = @@LookupAccountName.call( server, account, pSID, cbSID, domain_buf, cchDomain, psnuType ) if val == 0 raise ArgumentError, get_last_error end size = [0,0,0,0,0].pack(''CCSLL'').length # sizeof(ACCESS_ALLOWED_ACE) val = @@CopySid.call( ALLOW_ACE_LENGTH - size, pAllAce + 8, # address of pAllAce->SidStart pSID ) if val == 0 raise ArgumentError, get_last_error end if (GENERIC_ALL & mask).nonzero? account_rights = GENERIC_ALL & mask elsif (GENERIC_RIGHTS_CHK & mask).nonzero? account_rights = GENERIC_RIGHTS_MASK & mask end # pAllAce->Header.AceFlags = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE ; allAce[1] = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE 2.times{ if account_rights != 0 allAce[2,2] = [12 - 4 + @@GetLengthSid.call(pSID)].pack(''S'') allAce[4,4] = [account_rights].pack(''L'') val = @@AddAce.call( acl_new, ACL_REVISION2, MAXDWORD, pAllAce, allAce[2,2].unpack(''S'').first ) if val == 0 raise ArgumentError, get_last_error end # pAllAce->Header.AceFlags = CONTAINER_INHERIT_ACE allAce[1] = CONTAINER_INHERIT_ACE else # pAllAce->Header.AceFlags = 0 allAce[1] = 0 end account_rights = REST_RIGHTS_MASK & mask } } if @@SetSecurityDescriptorDacl.call(pSD, 1, acl_new, 0) == 0 raise ArgumentError, get_last_error end if @@SetFileSecurity.call(file, DACL_SECURITY_INFORMATION, pSD) == 0 raise ArgumentError, get_last_error end self end And update or define functions like this: @@CopySid = Win32API.new(''advapi32'', ''CopySid'', ''LLP'', ''I'') @@AddAce = Win32API.new(''advapi32'', ''AddAce'', ''PLLLL'', ''I'') @@memset = Win32API.new(''msvcrt'', ''memset'', ''PLL'', ''L'') Today''s point: memset is introduced for acquiring address of ruby string. str = "1234" pstr = memset.call(a,0,0) # address of str Regards, Park Heesob