facter 2.4.6-x64-mingw32 → 2.5.0-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +8 -8
- data/ext/build_defaults.yaml +1 -1
- data/ext/project_data.yaml +1 -6
- data/lib/facter/ec2.rb +8 -1
- data/lib/facter/ec2/rest.rb +3 -5
- data/lib/facter/gce/metadata.rb +1 -1
- data/lib/facter/kernelrelease.rb +2 -7
- data/lib/facter/operatingsystem/linux.rb +15 -10
- data/lib/facter/operatingsystem/windows.rb +22 -23
- data/lib/facter/util/config.rb +3 -3
- data/lib/facter/util/ec2.rb +2 -2
- data/lib/facter/util/ip.rb +4 -4
- data/lib/facter/util/memory.rb +1 -1
- data/lib/facter/util/windows.rb +10 -0
- data/lib/facter/util/windows/api_types.rb +143 -0
- data/lib/facter/util/windows/dir.rb +41 -0
- data/lib/facter/util/windows/error.rb +85 -0
- data/lib/facter/util/windows/process.rb +285 -0
- data/lib/facter/util/windows/user.rb +180 -0
- data/lib/facter/util/windows_root.rb +2 -2
- data/lib/facter/util/wmi.rb +35 -2
- data/lib/facter/version.rb +1 -1
- data/lib/facter/virtual.rb +2 -0
- data/spec/fixtures/unit/interfaces/ifconfig_net_tools_1.60_v6.txt +9 -0
- data/spec/integration/util/windows/user_spec.rb +59 -0
- data/spec/spec_helper.rb +0 -7
- data/spec/unit/ec2/rest_spec.rb +14 -8
- data/spec/unit/interfaces_spec.rb +10 -0
- data/spec/unit/ipaddress6_spec.rb +1 -0
- data/spec/unit/kernelrelease_spec.rb +1 -4
- data/spec/unit/memory_spec.rb +1 -1
- data/spec/unit/operatingsystem/windows_spec.rb +47 -40
- data/spec/unit/util/ec2_spec.rb +3 -3
- metadata +670 -696
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            require 'facter/util/windows'
         | 
| 2 | 
            +
            require 'ffi'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Facter::Util::Windows::Dir
         | 
| 5 | 
            +
              extend FFI::Library
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              COMMON_APPDATA = 0x0023
         | 
| 8 | 
            +
              S_OK           = 0x0
         | 
| 9 | 
            +
              MAX_PATH       = 260;
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def get_common_appdata
         | 
| 12 | 
            +
                common_appdata = ''
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                # this pointer actually points to a :lpwstr (pointer) since we're letting Windows allocate for us
         | 
| 15 | 
            +
                FFI::MemoryPointer.new(:pointer, ((MAX_PATH + 1) * 2)) do |buffer_ptr|
         | 
| 16 | 
            +
                  # hwndOwner, nFolder, hToken, dwFlags, pszPath
         | 
| 17 | 
            +
                  if SHGetFolderPathW(0, COMMON_APPDATA, 0, 0, buffer_ptr) != S_OK
         | 
| 18 | 
            +
                    raise Facter::Util::Windows::Error.new("Could not find COMMON_APPDATA path")
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  common_appdata = buffer_ptr.read_arbitrary_wide_string_up_to(MAX_PATH + 1)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                common_appdata
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
              module_function :get_common_appdata
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              ffi_convention :stdcall
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/bb762181(v=vs.85).aspx
         | 
| 31 | 
            +
              # HRESULT SHGetFolderPath(
         | 
| 32 | 
            +
              #   _In_  HWND   hwndOwner,
         | 
| 33 | 
            +
              #   _In_  int    nFolder,
         | 
| 34 | 
            +
              #   _In_  HANDLE hToken,
         | 
| 35 | 
            +
              #   _In_  DWORD  dwFlags,
         | 
| 36 | 
            +
              #   _Out_ LPTSTR pszPath
         | 
| 37 | 
            +
              # );
         | 
| 38 | 
            +
              ffi_lib :shell32
         | 
| 39 | 
            +
              attach_function_private :SHGetFolderPathW,
         | 
| 40 | 
            +
                [:handle, :int32, :handle, :dword, :lpwstr], :hresult
         | 
| 41 | 
            +
            end
         | 
| @@ -0,0 +1,85 @@ | |
| 1 | 
            +
            require 'facter/util/windows'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # represents an error resulting from a Win32 error code
         | 
| 4 | 
            +
            class Facter::Util::Windows::Error < RuntimeError
         | 
| 5 | 
            +
              require 'ffi'
         | 
| 6 | 
            +
              extend FFI::Library
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              attr_reader :code
         | 
| 9 | 
            +
              attr_reader :original
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              # NOTE: FFI.errno only works properly when prior Win32 calls have been made
         | 
| 12 | 
            +
              # through FFI bindings.  Calls made through Win32API do not have their error
         | 
| 13 | 
            +
              # codes captured by FFI.errno
         | 
| 14 | 
            +
              def initialize(message, code = FFI.errno, original = nil)
         | 
| 15 | 
            +
                @original = original
         | 
| 16 | 
            +
                super(message + ":  #{self.class.format_error_code(code)}")
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                @code = code
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              # Helper method that wraps FormatMessage that returns a human readable string.
         | 
| 22 | 
            +
              def self.format_error_code(code)
         | 
| 23 | 
            +
                # specifying 0 will look for LANGID in the following order
         | 
| 24 | 
            +
                # 1.Language neutral
         | 
| 25 | 
            +
                # 2.Thread LANGID, based on the thread's locale value
         | 
| 26 | 
            +
                # 3.User default LANGID, based on the user's default locale value
         | 
| 27 | 
            +
                # 4.System default LANGID, based on the system default locale value
         | 
| 28 | 
            +
                # 5.US English
         | 
| 29 | 
            +
                dwLanguageId = 0
         | 
| 30 | 
            +
                flags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
         | 
| 31 | 
            +
                    FORMAT_MESSAGE_FROM_SYSTEM |
         | 
| 32 | 
            +
                    FORMAT_MESSAGE_ARGUMENT_ARRAY |
         | 
| 33 | 
            +
                    FORMAT_MESSAGE_IGNORE_INSERTS |
         | 
| 34 | 
            +
                    FORMAT_MESSAGE_MAX_WIDTH_MASK
         | 
| 35 | 
            +
                error_string = ''
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                # this pointer actually points to a :lpwstr (pointer) since we're letting Windows allocate for us
         | 
| 38 | 
            +
                FFI::MemoryPointer.new(:pointer, 1) do |buffer_ptr|
         | 
| 39 | 
            +
                  length = FormatMessageW(flags, FFI::Pointer::NULL, code, dwLanguageId,
         | 
| 40 | 
            +
                                          buffer_ptr, 0, FFI::Pointer::NULL)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  if length == FFI::WIN32_FALSE
         | 
| 43 | 
            +
                    # can't raise same error type here or potentially recurse infinitely
         | 
| 44 | 
            +
                    raise Facter::Error.new("FormatMessageW could not format code #{code}")
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  # returns an FFI::Pointer with autorelease set to false, which is what we want
         | 
| 48 | 
            +
                  buffer_ptr.read_win32_local_pointer do |wide_string_ptr|
         | 
| 49 | 
            +
                    if wide_string_ptr.null?
         | 
| 50 | 
            +
                      raise Facter::Error.new("FormatMessageW failed to allocate buffer for code #{code}")
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    error_string = wide_string_ptr.read_wide_string(length)
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                error_string
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              ERROR_FILE_NOT_FOUND      = 2
         | 
| 61 | 
            +
              ERROR_ACCESS_DENIED       = 5
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              FORMAT_MESSAGE_ALLOCATE_BUFFER   = 0x00000100
         | 
| 64 | 
            +
              FORMAT_MESSAGE_IGNORE_INSERTS    = 0x00000200
         | 
| 65 | 
            +
              FORMAT_MESSAGE_FROM_SYSTEM       = 0x00001000
         | 
| 66 | 
            +
              FORMAT_MESSAGE_ARGUMENT_ARRAY    = 0x00002000
         | 
| 67 | 
            +
              FORMAT_MESSAGE_MAX_WIDTH_MASK    = 0x000000FF
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              ffi_convention :stdcall
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx
         | 
| 72 | 
            +
              # DWORD WINAPI FormatMessage(
         | 
| 73 | 
            +
              #   _In_      DWORD dwFlags,
         | 
| 74 | 
            +
              #   _In_opt_  LPCVOID lpSource,
         | 
| 75 | 
            +
              #   _In_      DWORD dwMessageId,
         | 
| 76 | 
            +
              #   _In_      DWORD dwLanguageId,
         | 
| 77 | 
            +
              #   _Out_     LPTSTR lpBuffer,
         | 
| 78 | 
            +
              #   _In_      DWORD nSize,
         | 
| 79 | 
            +
              #   _In_opt_  va_list *Arguments
         | 
| 80 | 
            +
              # );
         | 
| 81 | 
            +
              # NOTE: since we're not preallocating the buffer, use a :pointer for lpBuffer
         | 
| 82 | 
            +
              ffi_lib :kernel32
         | 
| 83 | 
            +
              attach_function_private :FormatMessageW,
         | 
| 84 | 
            +
                                      [:dword, :lpcvoid, :dword, :dword, :pointer, :dword, :pointer], :dword
         | 
| 85 | 
            +
            end
         | 
| @@ -0,0 +1,285 @@ | |
| 1 | 
            +
            require 'facter/util/windows'
         | 
| 2 | 
            +
            require 'ffi'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Facter::Util::Windows::Process
         | 
| 5 | 
            +
              extend FFI::Library
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def get_current_process
         | 
| 8 | 
            +
                # this pseudo-handle does not require closing per MSDN docs
         | 
| 9 | 
            +
                GetCurrentProcess()
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              module_function :get_current_process
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              def open_process_token(handle, desired_access, &block)
         | 
| 14 | 
            +
                token_handle = nil
         | 
| 15 | 
            +
                begin
         | 
| 16 | 
            +
                  FFI::MemoryPointer.new(:handle, 1) do |token_handle_ptr|
         | 
| 17 | 
            +
                    result = OpenProcessToken(handle, desired_access, token_handle_ptr)
         | 
| 18 | 
            +
                    if result == FFI::WIN32_FALSE
         | 
| 19 | 
            +
                      raise Facter::Util::Windows::Error.new(
         | 
| 20 | 
            +
                          "OpenProcessToken(#{handle}, #{desired_access.to_s(8)}, #{token_handle_ptr})")
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    yield token_handle = token_handle_ptr.read_handle
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  token_handle
         | 
| 27 | 
            +
                ensure
         | 
| 28 | 
            +
                  FFI::WIN32.CloseHandle(token_handle) if token_handle
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                # token_handle has had CloseHandle called against it, so nothing to return
         | 
| 32 | 
            +
                nil
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
              module_function :open_process_token
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              def get_token_information(token_handle, token_information, &block)
         | 
| 37 | 
            +
                # to determine buffer size
         | 
| 38 | 
            +
                FFI::MemoryPointer.new(:dword, 1) do |return_length_ptr|
         | 
| 39 | 
            +
                  result = GetTokenInformation(token_handle, token_information, nil, 0, return_length_ptr)
         | 
| 40 | 
            +
                  return_length = return_length_ptr.read_dword
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  if return_length <= 0
         | 
| 43 | 
            +
                    raise Facter::Util::Windows::Error.new(
         | 
| 44 | 
            +
                        "GetTokenInformation(#{token_handle}, #{token_information}, nil, 0, #{return_length_ptr})")
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  # re-call API with properly sized buffer for all results
         | 
| 48 | 
            +
                  FFI::MemoryPointer.new(return_length) do |token_information_buf|
         | 
| 49 | 
            +
                    result = GetTokenInformation(token_handle, token_information,
         | 
| 50 | 
            +
                                                 token_information_buf, return_length, return_length_ptr)
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    if result == FFI::WIN32_FALSE
         | 
| 53 | 
            +
                      raise Facter::Util::Windows::Error.new(
         | 
| 54 | 
            +
                          "GetTokenInformation(#{token_handle}, #{token_information}, #{token_information_buf}, " +
         | 
| 55 | 
            +
                              "#{return_length}, #{return_length_ptr})")
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    yield token_information_buf
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                # GetTokenInformation buffer has been cleaned up by this point, nothing to return
         | 
| 63 | 
            +
                nil
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
              module_function :get_token_information
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              def parse_token_information_as_token_elevation(token_information_buf)
         | 
| 68 | 
            +
                TOKEN_ELEVATION.new(token_information_buf)
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
              module_function :parse_token_information_as_token_elevation
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              TOKEN_QUERY = 0x0008
         | 
| 73 | 
            +
              # Returns whether or not the owner of the current process is running
         | 
| 74 | 
            +
              # with elevated security privileges.
         | 
| 75 | 
            +
              #
         | 
| 76 | 
            +
              # Only supported on Windows Vista or later.
         | 
| 77 | 
            +
              #
         | 
| 78 | 
            +
              def elevated_security?
         | 
| 79 | 
            +
                # default / pre-Vista
         | 
| 80 | 
            +
                elevated = false
         | 
| 81 | 
            +
                handle = nil
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                begin
         | 
| 84 | 
            +
                  handle = get_current_process
         | 
| 85 | 
            +
                  open_process_token(handle, TOKEN_QUERY) do |token_handle|
         | 
| 86 | 
            +
                    get_token_information(token_handle, :TokenElevation) do |token_info|
         | 
| 87 | 
            +
                      token_elevation = parse_token_information_as_token_elevation(token_info)
         | 
| 88 | 
            +
                      # TokenIsElevated member of the TOKEN_ELEVATION struct
         | 
| 89 | 
            +
                      elevated = token_elevation[:TokenIsElevated] != 0
         | 
| 90 | 
            +
                    end
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  elevated
         | 
| 94 | 
            +
                rescue Facter::Util::Windows::Error => e
         | 
| 95 | 
            +
                  raise e if e.code != ERROR_NO_SUCH_PRIVILEGE
         | 
| 96 | 
            +
                ensure
         | 
| 97 | 
            +
                  FFI::WIN32.CloseHandle(handle) if handle
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
              module_function :elevated_security?
         | 
| 101 | 
            +
             | 
| 102 | 
            +
              STATUS_SUCCESS = 0
         | 
| 103 | 
            +
             | 
| 104 | 
            +
              def os_version(&block)
         | 
| 105 | 
            +
                FFI::MemoryPointer.new(OSVERSIONINFOEX.size) do |ver_ptr|
         | 
| 106 | 
            +
                  ver = OSVERSIONINFOEX.new(ver_ptr)
         | 
| 107 | 
            +
                  ver[:dwOSVersionInfoSize] = OSVERSIONINFOEX.size
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  result = RtlGetVersion(ver_ptr)
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  if result != STATUS_SUCCESS
         | 
| 112 | 
            +
                    raise RuntimeError, 'Calling Windows RtlGetVersion failed'
         | 
| 113 | 
            +
                  end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                  yield ver
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                # ver_ptr has already had free called, so nothing to return
         | 
| 119 | 
            +
                nil
         | 
| 120 | 
            +
              end
         | 
| 121 | 
            +
              module_function :os_version
         | 
| 122 | 
            +
             | 
| 123 | 
            +
              def windows_major_version
         | 
| 124 | 
            +
                ver = 0
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                self.os_version do |version|
         | 
| 127 | 
            +
                  ver = version[:dwMajorVersion]
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                ver
         | 
| 131 | 
            +
              end
         | 
| 132 | 
            +
              module_function :windows_major_version
         | 
| 133 | 
            +
             | 
| 134 | 
            +
              def os_version_string
         | 
| 135 | 
            +
                ver = ''
         | 
| 136 | 
            +
                self.os_version do |version|
         | 
| 137 | 
            +
                  ver = "#{version[:dwMajorVersion]}.#{version[:dwMinorVersion]}.#{version[:dwBuildNumber]}"
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                ver
         | 
| 141 | 
            +
              end
         | 
| 142 | 
            +
              module_function :os_version_string
         | 
| 143 | 
            +
             | 
| 144 | 
            +
             | 
| 145 | 
            +
              SM_SERVERR2 = 89
         | 
| 146 | 
            +
             | 
| 147 | 
            +
              def is_2003_r2?
         | 
| 148 | 
            +
                # Peculiar API from user32 - the docs for SM_SERVER2 indicate
         | 
| 149 | 
            +
                # The build number if the system is Windows Server 2003 R2; otherwise, 0.
         | 
| 150 | 
            +
                GetSystemMetrics(SM_SERVERR2) != 0
         | 
| 151 | 
            +
              end
         | 
| 152 | 
            +
              module_function :is_2003_r2?
         | 
| 153 | 
            +
             | 
| 154 | 
            +
              def supports_elevated_security?
         | 
| 155 | 
            +
                windows_major_version >= 6
         | 
| 156 | 
            +
              end
         | 
| 157 | 
            +
              module_function :supports_elevated_security?
         | 
| 158 | 
            +
             | 
| 159 | 
            +
              ffi_convention :stdcall
         | 
| 160 | 
            +
             | 
| 161 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx
         | 
| 162 | 
            +
              # HANDLE WINAPI GetCurrentProcess(void);
         | 
| 163 | 
            +
              ffi_lib :kernel32
         | 
| 164 | 
            +
              attach_function_private :GetCurrentProcess, [], :handle
         | 
| 165 | 
            +
             | 
| 166 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx
         | 
| 167 | 
            +
              # BOOL WINAPI OpenProcessToken(
         | 
| 168 | 
            +
              #   _In_   HANDLE ProcessHandle,
         | 
| 169 | 
            +
              #   _In_   DWORD DesiredAccess,
         | 
| 170 | 
            +
              #   _Out_  PHANDLE TokenHandle
         | 
| 171 | 
            +
              # );
         | 
| 172 | 
            +
              ffi_lib :advapi32
         | 
| 173 | 
            +
              attach_function_private :OpenProcessToken,
         | 
| 174 | 
            +
                                      [:handle, :dword, :phandle], :win32_bool
         | 
| 175 | 
            +
             | 
| 176 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379626(v=vs.85).aspx
         | 
| 177 | 
            +
              TOKEN_INFORMATION_CLASS = enum(
         | 
| 178 | 
            +
                  :TokenUser, 1,
         | 
| 179 | 
            +
                  :TokenGroups,
         | 
| 180 | 
            +
                  :TokenPrivileges,
         | 
| 181 | 
            +
                  :TokenOwner,
         | 
| 182 | 
            +
                  :TokenPrimaryGroup,
         | 
| 183 | 
            +
                  :TokenDefaultDacl,
         | 
| 184 | 
            +
                  :TokenSource,
         | 
| 185 | 
            +
                  :TokenType,
         | 
| 186 | 
            +
                  :TokenImpersonationLevel,
         | 
| 187 | 
            +
                  :TokenStatistics,
         | 
| 188 | 
            +
                  :TokenRestrictedSids,
         | 
| 189 | 
            +
                  :TokenSessionId,
         | 
| 190 | 
            +
                  :TokenGroupsAndPrivileges,
         | 
| 191 | 
            +
                  :TokenSessionReference,
         | 
| 192 | 
            +
                  :TokenSandBoxInert,
         | 
| 193 | 
            +
                  :TokenAuditPolicy,
         | 
| 194 | 
            +
                  :TokenOrigin,
         | 
| 195 | 
            +
                  :TokenElevationType,
         | 
| 196 | 
            +
                  :TokenLinkedToken,
         | 
| 197 | 
            +
                  :TokenElevation,
         | 
| 198 | 
            +
                  :TokenHasRestrictions,
         | 
| 199 | 
            +
                  :TokenAccessInformation,
         | 
| 200 | 
            +
                  :TokenVirtualizationAllowed,
         | 
| 201 | 
            +
                  :TokenVirtualizationEnabled,
         | 
| 202 | 
            +
                  :TokenIntegrityLevel,
         | 
| 203 | 
            +
                  :TokenUIAccess,
         | 
| 204 | 
            +
                  :TokenMandatoryPolicy,
         | 
| 205 | 
            +
                  :TokenLogonSid,
         | 
| 206 | 
            +
                  :TokenIsAppContainer,
         | 
| 207 | 
            +
                  :TokenCapabilities,
         | 
| 208 | 
            +
                  :TokenAppContainerSid,
         | 
| 209 | 
            +
                  :TokenAppContainerNumber,
         | 
| 210 | 
            +
                  :TokenUserClaimAttributes,
         | 
| 211 | 
            +
                  :TokenDeviceClaimAttributes,
         | 
| 212 | 
            +
                  :TokenRestrictedUserClaimAttributes,
         | 
| 213 | 
            +
                  :TokenRestrictedDeviceClaimAttributes,
         | 
| 214 | 
            +
                  :TokenDeviceGroups,
         | 
| 215 | 
            +
                  :TokenRestrictedDeviceGroups,
         | 
| 216 | 
            +
                  :TokenSecurityAttributes,
         | 
| 217 | 
            +
                  :TokenIsRestricted,
         | 
| 218 | 
            +
                  :MaxTokenInfoClass
         | 
| 219 | 
            +
              )
         | 
| 220 | 
            +
             | 
| 221 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/bb530717(v=vs.85).aspx
         | 
| 222 | 
            +
              # typedef struct _TOKEN_ELEVATION {
         | 
| 223 | 
            +
              #   DWORD TokenIsElevated;
         | 
| 224 | 
            +
              # } TOKEN_ELEVATION, *PTOKEN_ELEVATION;
         | 
| 225 | 
            +
              class TOKEN_ELEVATION < FFI::Struct
         | 
| 226 | 
            +
                layout :TokenIsElevated, :dword
         | 
| 227 | 
            +
              end
         | 
| 228 | 
            +
             | 
| 229 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx
         | 
| 230 | 
            +
              # BOOL WINAPI GetTokenInformation(
         | 
| 231 | 
            +
              #   _In_       HANDLE TokenHandle,
         | 
| 232 | 
            +
              #   _In_       TOKEN_INFORMATION_CLASS TokenInformationClass,
         | 
| 233 | 
            +
              #   _Out_opt_  LPVOID TokenInformation,
         | 
| 234 | 
            +
              #   _In_       DWORD TokenInformationLength,
         | 
| 235 | 
            +
              #   _Out_      PDWORD ReturnLength
         | 
| 236 | 
            +
              # );
         | 
| 237 | 
            +
              ffi_lib :advapi32
         | 
| 238 | 
            +
              attach_function_private :GetTokenInformation,
         | 
| 239 | 
            +
                                      [:handle, TOKEN_INFORMATION_CLASS, :lpvoid, :dword, :pdword ], :win32_bool
         | 
| 240 | 
            +
             | 
| 241 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/hardware/ff563620(v=vs.85).aspx
         | 
| 242 | 
            +
              # typedef struct _OSVERSIONINFOEXW {
         | 
| 243 | 
            +
              #   ULONG  dwOSVersionInfoSize;
         | 
| 244 | 
            +
              #   ULONG  dwMajorVersion;
         | 
| 245 | 
            +
              #   ULONG  dwMinorVersion;
         | 
| 246 | 
            +
              #   ULONG  dwBuildNumber;
         | 
| 247 | 
            +
              #   ULONG  dwPlatformId;
         | 
| 248 | 
            +
              #   WCHAR  szCSDVersion[128];
         | 
| 249 | 
            +
              #   USHORT wServicePackMajor;
         | 
| 250 | 
            +
              #   USHORT wServicePackMinor;
         | 
| 251 | 
            +
              #   USHORT wSuiteMask;
         | 
| 252 | 
            +
              #   UCHAR  wProductType;
         | 
| 253 | 
            +
              #   UCHAR  wReserved;
         | 
| 254 | 
            +
              # } RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW;
         | 
| 255 | 
            +
              class OSVERSIONINFOEX < FFI::Struct
         | 
| 256 | 
            +
                layout(
         | 
| 257 | 
            +
                  :dwOSVersionInfoSize, :win32_ulong,
         | 
| 258 | 
            +
                  :dwMajorVersion, :win32_ulong,
         | 
| 259 | 
            +
                  :dwMinorVersion, :win32_ulong,
         | 
| 260 | 
            +
                  :dwBuildNumber, :win32_ulong,
         | 
| 261 | 
            +
                  :dwPlatformId, :win32_ulong,
         | 
| 262 | 
            +
                  :szCSDVersion, [:wchar, 128],
         | 
| 263 | 
            +
                  :wServicePackMajor, :ushort,
         | 
| 264 | 
            +
                  :wServicePackMinor, :ushort,
         | 
| 265 | 
            +
                  :wSuiteMask, :ushort,
         | 
| 266 | 
            +
                  :wProductType, :uchar,
         | 
| 267 | 
            +
                  :wReserved, :uchar,
         | 
| 268 | 
            +
                )
         | 
| 269 | 
            +
              end
         | 
| 270 | 
            +
             | 
| 271 | 
            +
              # NTSTATUS -> :int32 (defined in winerror.h / ntstatus.h)
         | 
| 272 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910(v=vs.85).aspx
         | 
| 273 | 
            +
              # NTSTATUS RtlGetVersion(
         | 
| 274 | 
            +
              #   _Out_ PRTL_OSVERSIONINFOW lpVersionInformation
         | 
| 275 | 
            +
              # );
         | 
| 276 | 
            +
              ffi_lib [FFI::CURRENT_PROCESS, :ntdll]
         | 
| 277 | 
            +
              attach_function :RtlGetVersion, [:pointer], :int32
         | 
| 278 | 
            +
             | 
| 279 | 
            +
              # C++ int is a signed 32-bit integer
         | 
| 280 | 
            +
              # int WINAPI GetSystemMetrics(
         | 
| 281 | 
            +
              #   _In_ int nIndex
         | 
| 282 | 
            +
              # );
         | 
| 283 | 
            +
              ffi_lib :user32
         | 
| 284 | 
            +
              attach_function :GetSystemMetrics, [:int32], :int32
         | 
| 285 | 
            +
            end
         | 
| @@ -0,0 +1,180 @@ | |
| 1 | 
            +
            require 'facter/util/windows'
         | 
| 2 | 
            +
            require 'ffi'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Facter::Util::Windows::User
         | 
| 5 | 
            +
              extend FFI::Library
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def admin?
         | 
| 8 | 
            +
                elevated_supported = Facter::Util::Windows::Process.supports_elevated_security?
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                # if Vista or later, check for unrestricted process token
         | 
| 11 | 
            +
                return Facter::Util::Windows::Process.elevated_security? if elevated_supported
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                # otherwise 2003 or less
         | 
| 14 | 
            +
                check_token_membership
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              module_function :admin?
         | 
| 17 | 
            +
             | 
| 18 | 
            +
             | 
| 19 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/ee207397(v=vs.85).aspx
         | 
| 20 | 
            +
              SECURITY_MAX_SID_SIZE = 68
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def check_token_membership
         | 
| 23 | 
            +
                is_admin = false
         | 
| 24 | 
            +
                FFI::MemoryPointer.new(:byte, SECURITY_MAX_SID_SIZE) do |sid_pointer|
         | 
| 25 | 
            +
                  FFI::MemoryPointer.new(:dword, 1) do |size_pointer|
         | 
| 26 | 
            +
                    size_pointer.write_uint32(SECURITY_MAX_SID_SIZE)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    if CreateWellKnownSid(:WinBuiltinAdministratorsSid, FFI::Pointer::NULL, sid_pointer, size_pointer) == FFI::WIN32_FALSE
         | 
| 29 | 
            +
                      raise Facter::Util::Windows::Error.new("Failed to create administrators SID")
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  if IsValidSid(sid_pointer) == FFI::WIN32_FALSE
         | 
| 34 | 
            +
                    raise RuntimeError,"Invalid SID"
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  FFI::MemoryPointer.new(:win32_bool, 1) do |ismember_pointer|
         | 
| 38 | 
            +
                    if CheckTokenMembership(FFI::Pointer::NULL_HANDLE, sid_pointer, ismember_pointer) == FFI::WIN32_FALSE
         | 
| 39 | 
            +
                      raise Facter::Util::Windows::Error.new("Failed to check membership")
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    # Is administrators SID enabled in calling thread's access token?
         | 
| 43 | 
            +
                    is_admin = ismember_pointer.read_win32_bool
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                is_admin
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
              module_function :check_token_membership
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              ffi_convention :stdcall
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/aa376389(v=vs.85).aspx
         | 
| 54 | 
            +
              # BOOL WINAPI CheckTokenMembership(
         | 
| 55 | 
            +
              #   _In_opt_  HANDLE TokenHandle,
         | 
| 56 | 
            +
              #   _In_      PSID SidToCheck,
         | 
| 57 | 
            +
              #   _Out_     PBOOL IsMember
         | 
| 58 | 
            +
              # );
         | 
| 59 | 
            +
              ffi_lib :advapi32
         | 
| 60 | 
            +
              attach_function_private :CheckTokenMembership,
         | 
| 61 | 
            +
                                      [:handle, :pointer, :pbool], :win32_bool
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379650(v=vs.85).aspx
         | 
| 64 | 
            +
              WELL_KNOWN_SID_TYPE = enum(
         | 
| 65 | 
            +
                  :WinNullSid                                   , 0,
         | 
| 66 | 
            +
                  :WinWorldSid                                  , 1,
         | 
| 67 | 
            +
                  :WinLocalSid                                  , 2,
         | 
| 68 | 
            +
                  :WinCreatorOwnerSid                           , 3,
         | 
| 69 | 
            +
                  :WinCreatorGroupSid                           , 4,
         | 
| 70 | 
            +
                  :WinCreatorOwnerServerSid                     , 5,
         | 
| 71 | 
            +
                  :WinCreatorGroupServerSid                     , 6,
         | 
| 72 | 
            +
                  :WinNtAuthoritySid                            , 7,
         | 
| 73 | 
            +
                  :WinDialupSid                                 , 8,
         | 
| 74 | 
            +
                  :WinNetworkSid                                , 9,
         | 
| 75 | 
            +
                  :WinBatchSid                                  , 10,
         | 
| 76 | 
            +
                  :WinInteractiveSid                            , 11,
         | 
| 77 | 
            +
                  :WinServiceSid                                , 12,
         | 
| 78 | 
            +
                  :WinAnonymousSid                              , 13,
         | 
| 79 | 
            +
                  :WinProxySid                                  , 14,
         | 
| 80 | 
            +
                  :WinEnterpriseControllersSid                  , 15,
         | 
| 81 | 
            +
                  :WinSelfSid                                   , 16,
         | 
| 82 | 
            +
                  :WinAuthenticatedUserSid                      , 17,
         | 
| 83 | 
            +
                  :WinRestrictedCodeSid                         , 18,
         | 
| 84 | 
            +
                  :WinTerminalServerSid                         , 19,
         | 
| 85 | 
            +
                  :WinRemoteLogonIdSid                          , 20,
         | 
| 86 | 
            +
                  :WinLogonIdsSid                               , 21,
         | 
| 87 | 
            +
                  :WinLocalSystemSid                            , 22,
         | 
| 88 | 
            +
                  :WinLocalServiceSid                           , 23,
         | 
| 89 | 
            +
                  :WinNetworkServiceSid                         , 24,
         | 
| 90 | 
            +
                  :WinBuiltinDomainSid                          , 25,
         | 
| 91 | 
            +
                  :WinBuiltinAdministratorsSid                  , 26,
         | 
| 92 | 
            +
                  :WinBuiltinUsersSid                           , 27,
         | 
| 93 | 
            +
                  :WinBuiltinGuestsSid                          , 28,
         | 
| 94 | 
            +
                  :WinBuiltinPowerUsersSid                      , 29,
         | 
| 95 | 
            +
                  :WinBuiltinAccountOperatorsSid                , 30,
         | 
| 96 | 
            +
                  :WinBuiltinSystemOperatorsSid                 , 31,
         | 
| 97 | 
            +
                  :WinBuiltinPrintOperatorsSid                  , 32,
         | 
| 98 | 
            +
                  :WinBuiltinBackupOperatorsSid                 , 33,
         | 
| 99 | 
            +
                  :WinBuiltinReplicatorSid                      , 34,
         | 
| 100 | 
            +
                  :WinBuiltinPreWindows2000CompatibleAccessSid  , 35,
         | 
| 101 | 
            +
                  :WinBuiltinRemoteDesktopUsersSid              , 36,
         | 
| 102 | 
            +
                  :WinBuiltinNetworkConfigurationOperatorsSid   , 37,
         | 
| 103 | 
            +
                  :WinAccountAdministratorSid                   , 38,
         | 
| 104 | 
            +
                  :WinAccountGuestSid                           , 39,
         | 
| 105 | 
            +
                  :WinAccountKrbtgtSid                          , 40,
         | 
| 106 | 
            +
                  :WinAccountDomainAdminsSid                    , 41,
         | 
| 107 | 
            +
                  :WinAccountDomainUsersSid                     , 42,
         | 
| 108 | 
            +
                  :WinAccountDomainGuestsSid                    , 43,
         | 
| 109 | 
            +
                  :WinAccountComputersSid                       , 44,
         | 
| 110 | 
            +
                  :WinAccountControllersSid                     , 45,
         | 
| 111 | 
            +
                  :WinAccountCertAdminsSid                      , 46,
         | 
| 112 | 
            +
                  :WinAccountSchemaAdminsSid                    , 47,
         | 
| 113 | 
            +
                  :WinAccountEnterpriseAdminsSid                , 48,
         | 
| 114 | 
            +
                  :WinAccountPolicyAdminsSid                    , 49,
         | 
| 115 | 
            +
                  :WinAccountRasAndIasServersSid                , 50,
         | 
| 116 | 
            +
                  :WinNTLMAuthenticationSid                     , 51,
         | 
| 117 | 
            +
                  :WinDigestAuthenticationSid                   , 52,
         | 
| 118 | 
            +
                  :WinSChannelAuthenticationSid                 , 53,
         | 
| 119 | 
            +
                  :WinThisOrganizationSid                       , 54,
         | 
| 120 | 
            +
                  :WinOtherOrganizationSid                      , 55,
         | 
| 121 | 
            +
                  :WinBuiltinIncomingForestTrustBuildersSid     , 56,
         | 
| 122 | 
            +
                  :WinBuiltinPerfMonitoringUsersSid             , 57,
         | 
| 123 | 
            +
                  :WinBuiltinPerfLoggingUsersSid                , 58,
         | 
| 124 | 
            +
                  :WinBuiltinAuthorizationAccessSid             , 59,
         | 
| 125 | 
            +
                  :WinBuiltinTerminalServerLicenseServersSid    , 60,
         | 
| 126 | 
            +
                  :WinBuiltinDCOMUsersSid                       , 61,
         | 
| 127 | 
            +
                  :WinBuiltinIUsersSid                          , 62,
         | 
| 128 | 
            +
                  :WinIUserSid                                  , 63,
         | 
| 129 | 
            +
                  :WinBuiltinCryptoOperatorsSid                 , 64,
         | 
| 130 | 
            +
                  :WinUntrustedLabelSid                         , 65,
         | 
| 131 | 
            +
                  :WinLowLabelSid                               , 66,
         | 
| 132 | 
            +
                  :WinMediumLabelSid                            , 67,
         | 
| 133 | 
            +
                  :WinHighLabelSid                              , 68,
         | 
| 134 | 
            +
                  :WinSystemLabelSid                            , 69,
         | 
| 135 | 
            +
                  :WinWriteRestrictedCodeSid                    , 70,
         | 
| 136 | 
            +
                  :WinCreatorOwnerRightsSid                     , 71,
         | 
| 137 | 
            +
                  :WinCacheablePrincipalsGroupSid               , 72,
         | 
| 138 | 
            +
                  :WinNonCacheablePrincipalsGroupSid            , 73,
         | 
| 139 | 
            +
                  :WinEnterpriseReadonlyControllersSid          , 74,
         | 
| 140 | 
            +
                  :WinAccountReadonlyControllersSid             , 75,
         | 
| 141 | 
            +
                  :WinBuiltinEventLogReadersGroup               , 76,
         | 
| 142 | 
            +
                  :WinNewEnterpriseReadonlyControllersSid       , 77,
         | 
| 143 | 
            +
                  :WinBuiltinCertSvcDComAccessGroup             , 78,
         | 
| 144 | 
            +
                  :WinMediumPlusLabelSid                        , 79,
         | 
| 145 | 
            +
                  :WinLocalLogonSid                             , 80,
         | 
| 146 | 
            +
                  :WinConsoleLogonSid                           , 81,
         | 
| 147 | 
            +
                  :WinThisOrganizationCertificateSid            , 82,
         | 
| 148 | 
            +
                  :WinApplicationPackageAuthoritySid            , 83,
         | 
| 149 | 
            +
                  :WinBuiltinAnyPackageSid                      , 84,
         | 
| 150 | 
            +
                  :WinCapabilityInternetClientSid               , 85,
         | 
| 151 | 
            +
                  :WinCapabilityInternetClientServerSid         , 86,
         | 
| 152 | 
            +
                  :WinCapabilityPrivateNetworkClientServerSid   , 87,
         | 
| 153 | 
            +
                  :WinCapabilityPicturesLibrarySid              , 88,
         | 
| 154 | 
            +
                  :WinCapabilityVideosLibrarySid                , 89,
         | 
| 155 | 
            +
                  :WinCapabilityMusicLibrarySid                 , 90,
         | 
| 156 | 
            +
                  :WinCapabilityDocumentsLibrarySid             , 91,
         | 
| 157 | 
            +
                  :WinCapabilitySharedUserCertificatesSid       , 92,
         | 
| 158 | 
            +
                  :WinCapabilityEnterpriseAuthenticationSid     , 93,
         | 
| 159 | 
            +
                  :WinCapabilityRemovableStorageSid             , 94
         | 
| 160 | 
            +
              )
         | 
| 161 | 
            +
             | 
| 162 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/aa446585(v=vs.85).aspx
         | 
| 163 | 
            +
              # BOOL WINAPI CreateWellKnownSid(
         | 
| 164 | 
            +
              #   _In_       WELL_KNOWN_SID_TYPE WellKnownSidType,
         | 
| 165 | 
            +
              #   _In_opt_   PSID DomainSid,
         | 
| 166 | 
            +
              #   _Out_opt_  PSID pSid,
         | 
| 167 | 
            +
              #   _Inout_    DWORD *cbSid
         | 
| 168 | 
            +
              # );
         | 
| 169 | 
            +
              ffi_lib :advapi32
         | 
| 170 | 
            +
              attach_function_private :CreateWellKnownSid,
         | 
| 171 | 
            +
                                      [WELL_KNOWN_SID_TYPE, :pointer, :pointer, :lpdword], :win32_bool
         | 
| 172 | 
            +
             | 
| 173 | 
            +
              # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379151(v=vs.85).aspx
         | 
| 174 | 
            +
              # BOOL WINAPI IsValidSid(
         | 
| 175 | 
            +
              #   _In_  PSID pSid
         | 
| 176 | 
            +
              # );
         | 
| 177 | 
            +
              ffi_lib :advapi32
         | 
| 178 | 
            +
              attach_function_private :IsValidSid,
         | 
| 179 | 
            +
                                      [:pointer], :win32_bool
         | 
| 180 | 
            +
            end
         |