summaryrefslogtreecommitdiff
path: root/lib/chef/win32
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2015-02-19 15:17:05 -0800
committerJay Mundrawala <jdmundrawala@gmail.com>2015-02-19 15:17:05 -0800
commit864f9ac95063c7833235c8ed50dcb89653eda03f (patch)
tree93da186fd522bdfc5de6414d011f4c0dd49aeb40 /lib/chef/win32
parent194f49bdb7737e0591271ba95021997e90379c5d (diff)
parenta7f5c92960aedf8d5bfc71abbce430ab075e016a (diff)
downloadchef-jdm/merge-into-12-stable.tar.gz
Merge remote-tracking branch 'origin/master' into HEADjdm/merge-into-12-stable
* origin/master: (642 commits) Remove Chef 12 release notes Update Changelog for Chef 12.1.0 Chef 12.1.0.rc.0 Group spec needs to respond to shell_out fix dpkg regression fix Lint/BlockAlignment whitespaces fixes fix Lint/AmbiguousRegexpLiteral fix Lint/LiteralInCondition fix Lint/Loop style Make tests pass on Windows remove unreachable code Fix unit specs for PR #2934 dont raise exceptions in load_current_resource when checking current status update changelog fix typo in msi provider Added spec for #2914 fix virtual package logic in check_package_state use scalar pkg not array package convert is_virtual_package to hash ... Conflicts: .travis.yml CHANGELOG.md DOC_CHANGES.md RELEASE_NOTES.md appveyor.yml lib/chef/application.rb lib/chef/dsl/recipe.rb lib/chef/knife/bootstrap.rb lib/chef/knife/core/bootstrap_context.rb lib/chef/node/attribute.rb lib/chef/node/attribute_collections.rb lib/chef/node/immutable_collections.rb lib/chef/resource.rb lib/chef/run_context.rb lib/chef/version.rb spec/functional/dsl/reboot_pending_spec.rb spec/functional/event_loggers/windows_eventlog_spec.rb spec/functional/resource/link_spec.rb spec/support/platform_helpers.rb spec/unit/knife_spec.rb spec/unit/mixin/deep_merge_spec.rb spec/unit/mixin/shell_out_spec.rb spec/unit/node/attribute_spec.rb spec/unit/node_spec.rb spec/unit/provider/package/apt_spec.rb spec/unit/provider/service/systemd_service_spec.rb spec/unit/provider_resolver_spec.rb spec/unit/recipe_spec.rb spec/unit/resource/resource_notification_spec.rb spec/unit/run_context_spec.rb
Diffstat (limited to 'lib/chef/win32')
-rw-r--r--lib/chef/win32/api.rb1
-rw-r--r--lib/chef/win32/api/security.rb26
-rw-r--r--lib/chef/win32/file.rb21
-rw-r--r--lib/chef/win32/security.rb46
-rw-r--r--lib/chef/win32/security/token.rb8
-rw-r--r--lib/chef/win32/version.rb4
6 files changed, 102 insertions, 4 deletions
diff --git a/lib/chef/win32/api.rb b/lib/chef/win32/api.rb
index 0330810b3b..8b81947c9b 100644
--- a/lib/chef/win32/api.rb
+++ b/lib/chef/win32/api.rb
@@ -159,6 +159,7 @@ class Chef
host.typedef :pointer, :PDWORD32 # Pointer to a DWORD32.
host.typedef :pointer, :PDWORD64 # Pointer to a DWORD64.
host.typedef :pointer, :PFLOAT # Pointer to a FLOAT.
+ host.typedef :pointer, :PGENERICMAPPING #Pointer to GENERIC_MAPPING
host.typedef :pointer, :PHALF_PTR # Pointer to a HALF_PTR.
host.typedef :pointer, :PHANDLE # Pointer to a HANDLE.
host.typedef :pointer, :PHKEY # Pointer to an HKEY.
diff --git a/lib/chef/win32/api/security.rb b/lib/chef/win32/api/security.rb
index 7ca2d70c8e..229f2ace10 100644
--- a/lib/chef/win32/api/security.rb
+++ b/lib/chef/win32/api/security.rb
@@ -270,6 +270,15 @@ class Chef
:MaxTokenInfoClass
]
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572%28v=vs.85%29.aspx
+ SECURITY_IMPERSONATION_LEVEL = enum :SECURITY_IMPERSONATION_LEVEL, [
+ :SecurityAnonymous,
+ :SecurityIdentification,
+ :SecurityImpersonation,
+ :SecurityDelegation
+ ]
+
+
# SECURITY_DESCRIPTOR is an opaque structure whose contents can vary. Pass the
# pointer around and free it with LocalFree.
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa379561(v=vs.85).aspx
@@ -320,6 +329,19 @@ class Chef
:Attributes, :DWORD
end
+ class GENERIC_MAPPING < FFI::Struct
+ layout :GenericRead, :DWORD,
+ :GenericWrite, :DWORD,
+ :GenericExecute, :DWORD,
+ :GenericAll, :DWORD
+ end
+
+ class PRIVILEGE_SET < FFI::Struct
+ layout :PrivilegeCount, :DWORD,
+ :Control, :DWORD,
+ :Privilege, [LUID_AND_ATTRIBUTES, 1]
+ end
+
class TOKEN_PRIVILEGES < FFI::Struct
layout :PrivilegeCount, :DWORD,
:Privileges, LUID_AND_ATTRIBUTES
@@ -339,6 +361,7 @@ class Chef
ffi_lib "advapi32"
+ safe_attach_function :AccessCheck, [:pointer, :HANDLE, :DWORD, :pointer, :pointer, :pointer, :pointer, :pointer], :BOOL
safe_attach_function :AddAce, [ :pointer, :DWORD, :DWORD, :LPVOID, :DWORD ], :BOOL
safe_attach_function :AddAccessAllowedAce, [ :pointer, :DWORD, :DWORD, :pointer ], :BOOL
safe_attach_function :AddAccessAllowedAceEx, [ :pointer, :DWORD, :DWORD, :DWORD, :pointer ], :BOOL
@@ -348,9 +371,11 @@ class Chef
safe_attach_function :ConvertSidToStringSidA, [ :pointer, :pointer ], :BOOL
safe_attach_function :ConvertStringSidToSidW, [ :pointer, :pointer ], :BOOL
safe_attach_function :DeleteAce, [ :pointer, :DWORD ], :BOOL
+ safe_attach_function :DuplicateToken, [:HANDLE, :SECURITY_IMPERSONATION_LEVEL, :PHANDLE], :BOOL
safe_attach_function :EqualSid, [ :pointer, :pointer ], :BOOL
safe_attach_function :FreeSid, [ :pointer ], :pointer
safe_attach_function :GetAce, [ :pointer, :DWORD, :pointer ], :BOOL
+ safe_attach_function :GetFileSecurityW, [:LPCWSTR, :DWORD, :pointer, :DWORD, :pointer], :BOOL
safe_attach_function :GetLengthSid, [ :pointer ], :DWORD
safe_attach_function :GetNamedSecurityInfoW, [ :LPWSTR, :SE_OBJECT_TYPE, :DWORD, :pointer, :pointer, :pointer, :pointer, :pointer ], :DWORD
safe_attach_function :GetSecurityDescriptorControl, [ :pointer, :PWORD, :LPDWORD], :BOOL
@@ -369,6 +394,7 @@ class Chef
safe_attach_function :LookupPrivilegeDisplayNameW, [ :LPCWSTR, :LPCWSTR, :LPWSTR, :LPDWORD, :LPDWORD ], :BOOL
safe_attach_function :LookupPrivilegeValueW, [ :LPCWSTR, :LPCWSTR, :PLUID ], :BOOL
safe_attach_function :MakeAbsoluteSD, [ :pointer, :pointer, :LPDWORD, :pointer, :LPDWORD, :pointer, :LPDWORD, :pointer, :LPDWORD, :pointer, :LPDWORD], :BOOL
+ safe_attach_function :MapGenericMask, [ :PDWORD, :PGENERICMAPPING ], :void
safe_attach_function :OpenProcessToken, [ :HANDLE, :DWORD, :PHANDLE ], :BOOL
safe_attach_function :QuerySecurityAccessMask, [ :DWORD, :LPDWORD ], :void
safe_attach_function :SetFileSecurityW, [ :LPWSTR, :DWORD, :pointer ], :BOOL
diff --git a/lib/chef/win32/file.rb b/lib/chef/win32/file.rb
index d489c9ce8a..e6640caa3c 100644
--- a/lib/chef/win32/file.rb
+++ b/lib/chef/win32/file.rb
@@ -155,6 +155,27 @@ class Chef
end
end
+ def self.file_access_check(path, desired_access)
+ security_descriptor = Chef::ReservedNames::Win32::Security.get_file_security(path)
+ token_rights = Chef::ReservedNames::Win32::Security::TOKEN_IMPERSONATE |
+ Chef::ReservedNames::Win32::Security::TOKEN_QUERY |
+ Chef::ReservedNames::Win32::Security::TOKEN_DUPLICATE |
+ Chef::ReservedNames::Win32::Security::STANDARD_RIGHTS_READ
+ token = Chef::ReservedNames::Win32::Security.open_process_token(
+ Chef::ReservedNames::Win32::Process.get_current_process,
+ token_rights)
+ duplicate_token = token.duplicate_token(:SecurityImpersonation)
+
+ mapping = Chef::ReservedNames::Win32::Security::GENERIC_MAPPING.new
+ mapping[:GenericRead] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_READ
+ mapping[:GenericWrite] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_WRITE
+ mapping[:GenericExecute] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_EXECUTE
+ mapping[:GenericAll] = Chef::ReservedNames::Win32::Security::FILE_ALL_ACCESS
+
+ Chef::ReservedNames::Win32::Security.access_check(security_descriptor, duplicate_token,
+ desired_access, mapping)
+ end
+
# ::File compat
class << self
alias :stat :info
diff --git a/lib/chef/win32/security.rb b/lib/chef/win32/security.rb
index 48ca78647f..3902d8caaf 100644
--- a/lib/chef/win32/security.rb
+++ b/lib/chef/win32/security.rb
@@ -32,6 +32,34 @@ class Chef
extend Chef::ReservedNames::Win32::API::Security
extend Chef::ReservedNames::Win32::API::Macros
+ def self.access_check(security_descriptor, token, desired_access, generic_mapping)
+ token_handle = token.handle.handle
+ security_descriptor_ptr = security_descriptor.pointer
+
+ rights_ptr = FFI::MemoryPointer.new(:ulong)
+ rights_ptr.write_ulong(desired_access)
+
+ # This function takes care of calling MapGenericMask, so you don't have to
+ MapGenericMask(rights_ptr, generic_mapping)
+
+ result_ptr = FFI::MemoryPointer.new(:ulong)
+
+ # Because optional actually means required
+ privileges = PRIVILEGE_SET.new
+ privileges[:PrivilegeCount] = 0
+ privileges_length_ptr = FFI::MemoryPointer.new(:ulong)
+ privileges_length_ptr.write_ulong(privileges.size)
+
+ granted_access_ptr = FFI::MemoryPointer.new(:ulong)
+
+ unless AccessCheck(security_descriptor_ptr, token_handle, rights_ptr.read_ulong,
+ generic_mapping, privileges, privileges_length_ptr, granted_access_ptr,
+ result_ptr)
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+ result_ptr.read_ulong == 1
+ end
+
def self.add_ace(acl, ace, insert_position = MAXDWORD, revision = ACL_REVISION)
acl = acl.pointer if acl.respond_to?(:pointer)
ace = ace.pointer if ace.respond_to?(:pointer)
@@ -148,6 +176,24 @@ class Chef
GetLengthSid(sid)
end
+ def self.get_file_security(path, info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)
+ size_ptr = FFI::MemoryPointer.new(:ulong)
+
+ success = GetFileSecurityW(path.to_wstring, info, nil, 0, size_ptr)
+
+ if !success && FFI::LastError.error != ERROR_INSUFFICIENT_BUFFER
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+
+ security_descriptor_ptr = FFI::MemoryPointer.new(size_ptr.read_ulong)
+ unless GetFileSecurityW(path.to_wstring, info, security_descriptor_ptr, size_ptr.read_ulong, size_ptr)
+ Chef::ReservedNames::Win32::Error.raise!
+ end
+
+ SecurityDescriptor.new(security_descriptor_ptr)
+ end
+
+
def self.get_named_security_info(path, type = :SE_FILE_OBJECT, info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)
security_descriptor = FFI::MemoryPointer.new :pointer
hr = GetNamedSecurityInfoW(path.to_wstring, type, info, nil, nil, nil, nil, security_descriptor)
diff --git a/lib/chef/win32/security/token.rb b/lib/chef/win32/security/token.rb
index ded4fc080e..9e494a73b9 100644
--- a/lib/chef/win32/security/token.rb
+++ b/lib/chef/win32/security/token.rb
@@ -58,6 +58,14 @@ class Chef
Chef::ReservedNames::Win32::Security::adjust_token_privileges(self, privileges_struct)
end
end
+
+ def duplicate_token(security_impersonation_level)
+ duplicate_token_handle = FFI::Buffer.new(:ulong)
+ unless Chef::ReservedNames::Win32::API::Security.DuplicateToken(handle.handle, security_impersonation_level, duplicate_token_handle)
+ raise Chef::ReservedNames::Win32::Error.raise!
+ end
+ Token.new(Handle.new(duplicate_token_handle.read_ulong))
+ end
end
end
end
diff --git a/lib/chef/win32/version.rb b/lib/chef/win32/version.rb
index d16bd8c12f..6a5bd35a26 100644
--- a/lib/chef/win32/version.rb
+++ b/lib/chef/win32/version.rb
@@ -126,14 +126,10 @@ class Chef
# https://github.com/ruby/ruby/commit/588504b20f5cc880ad51827b93e571e32446e5db
# https://github.com/ruby/ruby/commit/27ed294c7134c0de582007af3c915a635a6506cd
- WIN32OLE.ole_initialize
-
wmi = WmiLite::Wmi.new
os_info = wmi.first_of('Win32_OperatingSystem')
os_version = os_info['version']
- WIN32OLE.ole_uninitialize
-
# The operating system version is a string in the following form
# that can be split into components based on the '.' delimiter:
# MajorVersionNumber.MinorVersionNumber.BuildNumber