facter 2.4.6-universal-darwin → 2.5.0-universal-darwin
Sign up to get free protection for your applications and to get access to all the features.
- 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
|