lib/win32/security.rb in win32-security-0.1.4 vs lib/win32/security.rb in win32-security-0.2.0
- old
+ new
@@ -1,67 +1,110 @@
# This file allows users to require all security related classes from
# a single file, instead of having to require individual files.
-require 'windows/process'
-require 'windows/security'
-require 'windows/handle'
-require 'windows/error'
+require File.join(File.dirname(__FILE__), 'security', 'windows', 'constants')
+require File.join(File.dirname(__FILE__), 'security', 'windows', 'structs')
+require File.join(File.dirname(__FILE__), 'security', 'windows', 'functions')
# The Win32 module serves as a namespace only.
module Win32
# The Security class encapsulates security aspects of MS Windows.
class Security
# Base error class for all Win32::Security errors.
class Error < StandardError; end
- include Windows::Security
+ include Windows::Security::Functions
+ include Windows::Security::Constants
+ include Windows::Security::Structs
+ extend Windows::Security::Functions
- extend Windows::Process
- extend Windows::Security
- extend Windows::Handle
- extend Windows::Error
-
# The version of the win32-security library
- VERSION = '0.1.4'
+ VERSION = '0.2.0'
+ # Used by OpenProcessToken
+ TOKEN_QUERY = 8
+
# Returns whether or not the owner of the current process is running
# with elevated security privileges.
#
- # Only supported on Windows Vista or later.
+ # On Windows XP an earlier this method is actually just checking to
+ # see if the caller's process is a member of the local Administrator's
+ # group.
#
def self.elevated_security?
- token = 0.chr * 4
+ if windows_version < 6
+ sid_ptr = FFI::MemoryPointer.new(:pointer)
+ nt_auth_ptr = FFI::MemoryPointer.new(SID_IDENTIFIER_AUTHORITY,1)
- unless OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, token)
- raise Error, get_last_error
- end
+ nt_auth = SID_IDENTIFIER_AUTHORITY.new(nt_auth_ptr)
+ nt_auth[:Value].to_ptr.put_bytes(0, 0.chr*5 + 5.chr)
- begin
- token = token.unpack('V')[0]
+ bool = AllocateAndInitializeSid(
+ nt_auth_ptr,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ sid_ptr
+ )
+ unless bool
+ raise SystemCallError.new("AllocateAndInitializeSid", FFI.errno)
+ end
- te = 0.chr * 4 # TOKEN_ELEVATION
- rl = 0.chr * 4 # Return length
+ pbool = FFI::MemoryPointer.new(:long)
- bool = GetTokenInformation(
- token,
- TokenElevation,
- te,
- te.size,
- rl
- )
+ unless CheckTokenMembership(0, sid_ptr.read_pointer, pbool)
+ raise SystemCallError.new("CheckTokenMembership", FFI.errno)
+ end
- raise Error, get_last_error unless bool
- ensure
- CloseHandle(token)
+ pbool.read_long != 0
+ else
+ token = FFI::MemoryPointer.new(:ulong)
+
+ unless OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, token)
+ raise SystemCallError.new("OpenProcessToken", FFI.errno)
+ end
+
+ begin
+ token = token.read_ulong
+
+ # Since the TokenElevation struct only has 1 member, we use a pointer.
+ te = FFI::MemoryPointer.new(:ulong)
+ rl = FFI::MemoryPointer.new(:ulong)
+
+ bool = GetTokenInformation(
+ token,
+ :TokenElevation,
+ te,
+ te.size,
+ rl
+ )
+
+ raise SystemCallError.new("GetTokenInformation", FFI.errno) unless bool
+ ensure
+ CloseHandle(token)
+ end
+
+ te.read_ulong != 0
end
+ end
- # TokenIsElevated member of the TOKEN_ELEVATION struct
- te.unpack('L')[0] != 0
+ private
+
+ def self.windows_version
+ ver = OSVERSIONINFO.new
+ ver[:dwOSVersionInfoSize] = ver.size
+
+ unless GetVersionExA(ver)
+ raise SystemCallError.new("GetVersionEx", FFI.errno)
+ end
+
+ ver[:dwMajorVersion]
end
end
end
require 'win32/security/sid'
-#require 'win32/security/acl'
+require 'win32/security/acl'
#require 'win32/security/ace'