lib/win32/security/sid.rb in win32-security-0.2.5 vs lib/win32/security/sid.rb in win32-security-0.3.0

- old
+ new

@@ -1,8 +1,5 @@ -require File.join(File.dirname(__FILE__), 'windows', 'constants') -require File.join(File.dirname(__FILE__), 'windows', 'functions') -require File.join(File.dirname(__FILE__), 'windows', 'structs') require 'socket' # The Win32 module serves as a namespace only. module Win32 @@ -76,31 +73,39 @@ attr_reader :host # Converts a binary SID to a string in S-R-I-S-S... format. # def self.sid_to_string(sid) - string_sid = FFI::MemoryPointer.new(:pointer) + result = nil - unless ConvertSidToStringSid(sid, string_sid) - raise SystemCallError.new("ConvertSidToStringSid", FFI.errno) + FFI::MemoryPointer.new(:pointer) do |string_sid| + unless ConvertSidToStringSid(sid, string_sid) + raise SystemCallError.new("ConvertSidToStringSid", FFI.errno) + end + + result = string_sid.read_pointer.read_string end - string_sid.read_pointer.read_string + result end # Converts a string in S-R-I-S-S... format back to a binary SID. # def self.string_to_sid(string) - sid = FFI::MemoryPointer.new(:pointer) + result = nil - unless ConvertStringSidToSid(string, sid) - raise SystemCallError.new("ConvertStringSidToSid", FFI.errno) - end + FFI::MemoryPointer.new(:pointer) do |sid| + unless ConvertStringSidToSid(string, sid) + raise SystemCallError.new("ConvertStringSidToSid", FFI.errno) + end - ptr = sid.read_pointer + ptr = sid.read_pointer - ptr.read_bytes(GetLengthSid(ptr)) + result = ptr.read_bytes(GetLengthSid(ptr)) + end + + result end # Creates a new SID with +authority+ and up to 8 +subauthorities+, # and returns new Win32::Security::SID object. # @@ -125,25 +130,29 @@ if sub_authorities.length > 8 raise ArgumentError, "maximum of 8 subauthorities allowed" end size = GetSidLengthRequired(sub_authorities.length) - sid = FFI::MemoryPointer.new(:uchar, size) + new_obj = nil - auth = SID_IDENTIFIER_AUTHORITY.new - auth[:Value][5] = authority + FFI::MemoryPointer.new(:uchar, size) do |sid| + auth = SID_IDENTIFIER_AUTHORITY.new + auth[:Value][5] = authority - unless InitializeSid(sid, auth, sub_authorities.length) - raise SystemCallError.new("InitializeSid", FFI.errno) - end + unless InitializeSid(sid, auth, sub_authorities.length) + raise SystemCallError.new("InitializeSid", FFI.errno) + end - sub_authorities.each_index do |i| - ptr = GetSidSubAuthority(sid, i) - ptr.write_ulong(sub_authorities[i]) + sub_authorities.each_index do |i| + ptr = GetSidSubAuthority(sid, i) + ptr.write_ulong(sub_authorities[i]) + end + + new_obj = new(sid.read_string(size)) # Pass a binary string end - new(sid.read_string(size)) # Pass a binary string + new_obj end # Creates and returns a new Win32::Security::SID object, based on # the account name, which may also be a binary SID. If a host is # provided, then the information is retrieved from that host. @@ -180,25 +189,26 @@ bool = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, true, ptoken) if !bool && FFI.errno != ERROR_NO_TOKEN raise SystemCallError.new("OpenThreadToken", FFI.errno) else - ptoken = FFI::MemoryPointer.new(:uintptr_t) + ptoken.clear unless OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, ptoken) raise SystemCallError.new("OpenProcessToken", FFI.errno) end end token = ptoken.read_pointer.to_i + pinfo = FFI::MemoryPointer.new(:pointer) plength = FFI::MemoryPointer.new(:ulong) # First pass, just get the size needed (1 is TokenOwner) GetTokenInformation(token, 1, pinfo, pinfo.size, plength) pinfo = FFI::MemoryPointer.new(plength.read_ulong) - plength = FFI::MemoryPointer.new(:ulong) + plength.clear # Second pass, actual call (1 is TokenOwner) unless GetTokenInformation(token, 1, pinfo, pinfo.size, plength) raise SystemCallError.new("GetTokenInformation", FFI.errno) end @@ -239,22 +249,26 @@ unless bool raise SystemCallError.new("LookupAccountSid", FFI.errno) end elsif ordinal_val < 10 # Assume it's a binary SID. account_ptr = FFI::MemoryPointer.from_string(account) + bool = LookupAccountSid( host, account_ptr, sid, sid_size, domain, domain_size, use_ptr ) + unless bool raise SystemCallError.new("LookupAccountSid", FFI.errno) end + + account_ptr.free else bool = LookupAccountName( host, account, sid, @@ -271,15 +285,15 @@ # The arguments are flipped depending on which path we took if ordinal_val.nil? @sid = token_info.read_string @account = sid.read_string(sid.size).strip elsif ordinal_val < 10 - @sid = account + @sid = account @account = sid.read_string(sid.size).strip else length = GetLengthSid(sid) - @sid = sid.read_string(length) + @sid = sid.read_string(length) @account = account end @host = host @domain = domain.read_string @@ -295,16 +309,20 @@ # Returns the binary SID in string format suitable for display, # storage or transmission. # def to_s - ptr = FFI::MemoryPointer.new(:pointer) + string = nil - unless ConvertSidToStringSid(@sid, ptr) - raise SystemCallError.new("ConvertSidToStringSid", FFI.errno) + FFI::MemoryPointer.new(:pointer) do |ptr| + unless ConvertSidToStringSid(@sid, ptr) + raise SystemCallError.new("ConvertSidToStringSid", FFI.errno) + end + + string = ptr.read_pointer.read_string end - ptr.read_pointer.read_string + string end alias to_str to_s # Returns whether or not the SID object is equal to +other+.