facter 2.4.6-universal-darwin → 2.5.0-universal-darwin
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 +671 -665
@@ -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
|