diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/node.rb | 4 | ||||
-rw-r--r-- | lib/chef/provider/group/usermod.rb | 7 | ||||
-rw-r--r-- | lib/chef/provider/mount/mount.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider/package/homebrew.rb | 3 | ||||
-rw-r--r-- | lib/chef/provider/package/zypper.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider/remote_file.rb | 4 | ||||
-rw-r--r-- | lib/chef/provider/route.rb | 6 | ||||
-rw-r--r-- | lib/chef/resource/execute.rb | 2 | ||||
-rw-r--r-- | lib/chef/resource/homebrew_package.rb | 3 | ||||
-rw-r--r-- | lib/chef/resource/hostname.rb | 4 | ||||
-rw-r--r-- | lib/chef/resource/kernel_module.rb | 4 | ||||
-rw-r--r-- | lib/chef/resource/remote_file.rb | 2 | ||||
-rw-r--r-- | lib/chef/resource/swap_file.rb | 4 | ||||
-rw-r--r-- | lib/chef/resource/timezone.rb | 4 | ||||
-rw-r--r-- | lib/chef/resource/windows_certificate.rb | 1 | ||||
-rw-r--r-- | lib/chef/resource/windows_user_privilege.rb | 157 | ||||
-rw-r--r-- | lib/chef/resources.rb | 1 | ||||
-rw-r--r-- | lib/chef/version.rb | 2 | ||||
-rw-r--r-- | lib/chef/win32/api/security.rb | 6 | ||||
-rw-r--r-- | lib/chef/win32/security.rb | 42 |
20 files changed, 228 insertions, 32 deletions
diff --git a/lib/chef/node.rb b/lib/chef/node.rb index 1e5d3a8d59..a5bf1d9b8a 100644 --- a/lib/chef/node.rb +++ b/lib/chef/node.rb @@ -2,7 +2,7 @@ # Author:: Christopher Brown (<cb@chef.io>) # Author:: Christopher Walters (<cw@chef.io>) # Author:: Tim Hinderliter (<tim@chef.io>) -# Copyright:: Copyright 2008-2019, Chef Software Inc. +# Copyright:: Copyright 2008-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -363,7 +363,7 @@ class Chef # FIXME(log): should be trace logger.debug("Platform is #{platform} version #{version}") automatic[:platform] = platform - automatic[:platform_version] = version + automatic[:platform_version] = Chef::VersionString.new(version) automatic[:chef_guid] = Chef::Config[:chef_guid] || ( Chef::Config[:chef_guid] = node_uuid ) automatic[:name] = name automatic[:chef_environment] = chef_environment diff --git a/lib/chef/provider/group/usermod.rb b/lib/chef/provider/group/usermod.rb index b4e93580ff..90386b1659 100644 --- a/lib/chef/provider/group/usermod.rb +++ b/lib/chef/provider/group/usermod.rb @@ -1,6 +1,6 @@ # # Author:: AJ Christensen (<aj@chef.io>) -# Copyright:: Copyright 2008-2019, Chef Software Inc. +# Copyright:: Copyright 2008-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -76,10 +76,7 @@ class Chef end def append_flags - case node[:platform] - when "openbsd", "netbsd", "aix", "smartos", "omnios" - "-G" - end + "-G" if platform?("openbsd", "netbsd", "aix", "smartos", "omnios") end end diff --git a/lib/chef/provider/mount/mount.rb b/lib/chef/provider/mount/mount.rb index 17b357ec70..00acb556b0 100644 --- a/lib/chef/provider/mount/mount.rb +++ b/lib/chef/provider/mount/mount.rb @@ -157,7 +157,7 @@ class Chef # Return appropriate default mount options according to the given os. def default_mount_options - node[:os] == "linux" ? "defaults" : "rw" + linux? ? "defaults" : "rw" end def enable_fs diff --git a/lib/chef/provider/package/homebrew.rb b/lib/chef/provider/package/homebrew.rb index 3d60ee4380..700fc8f721 100644 --- a/lib/chef/provider/package/homebrew.rb +++ b/lib/chef/provider/package/homebrew.rb @@ -2,8 +2,7 @@ # Author:: Joshua Timberman (<joshua@chef.io>) # Author:: Graeme Mathieson (<mathie@woss.name>) # -# Copyright 2011-2016, Chef Software Inc. -# Copyright 2014-2016, Chef Software, Inc <legal@chef.io> +# Copyright:: 2011-2016, Chef Software, Inc <legal@chef.io> # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/chef/provider/package/zypper.rb b/lib/chef/provider/package/zypper.rb index 6d464a1930..47fe7514ee 100644 --- a/lib/chef/provider/package/zypper.rb +++ b/lib/chef/provider/package/zypper.rb @@ -3,7 +3,7 @@ # Authors:: Adam Jacob (<adam@chef.io>) # Ionuț Arțăriși (<iartarisi@suse.cz>) # Copyright:: Copyright 2008-2017, Chef Software Inc. -# Copyright 2013-2016, SUSE Linux GmbH +# Copyright:: 2013-2016, SUSE Linux GmbH # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/provider/remote_file.rb b/lib/chef/provider/remote_file.rb index a2506d6a15..e0a7dfb4d4 100644 --- a/lib/chef/provider/remote_file.rb +++ b/lib/chef/provider/remote_file.rb @@ -1,7 +1,7 @@ # # Author:: Jesse Campbell (<hikeit@gmail.com>) # Author:: Adam Jacob (<adam@chef.io>) -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,7 +35,7 @@ class Chef requirements.assert(:all_actions) do |a| a.assertion do if prop - node[:platform_family] == "windows" + windows? else true end diff --git a/lib/chef/provider/route.rb b/lib/chef/provider/route.rb index 523074bdbb..484d4490bb 100644 --- a/lib/chef/provider/route.rb +++ b/lib/chef/provider/route.rb @@ -1,6 +1,7 @@ # # Author:: Bryan McLellan (btm@loftninjas.org), Jesse Nelson (spheromak@gmail.com) # Copyright:: Copyright 2009-2016, Bryan McLellan +# Copyright:: Copyright 2020, Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -95,7 +96,7 @@ class Chef end # For linux, we use /proc/net/route file to read proc table info - return if node[:os] != "linux" + return unless linux? route_file = ::File.open("/proc/net/route", "r") @@ -159,8 +160,7 @@ class Chef end def generate_config - case node[:platform_family] - when "rhel", "amazon", "fedora" + if platform_family?("rhel", "amazon", "fedora") conf = {} # walk the collection run_context.resource_collection.each do |resource| diff --git a/lib/chef/resource/execute.rb b/lib/chef/resource/execute.rb index ecb1944742..0f61aaf4c8 100644 --- a/lib/chef/resource/execute.rb +++ b/lib/chef/resource/execute.rb @@ -131,7 +131,7 @@ class Chef end def validate_identity_platform(specified_user, password = nil, specified_domain = nil, elevated = false) - if node[:platform_family] == "windows" + if windows? if specified_user && password.nil? raise ArgumentError, "A value for `password` must be specified when a value for `user` is specified on the Windows platform" end diff --git a/lib/chef/resource/homebrew_package.rb b/lib/chef/resource/homebrew_package.rb index a33bdc63d6..2261979c09 100644 --- a/lib/chef/resource/homebrew_package.rb +++ b/lib/chef/resource/homebrew_package.rb @@ -2,8 +2,7 @@ # Author:: Joshua Timberman (<joshua@chef.io>) # Author:: Graeme Mathieson (<mathie@woss.name>) # -# Copyright 2011-2020, Chef Software Inc. -# Copyright 2014-2020, Chef Software Inc.<legal@chef.io> +# Copyright:: 2011-2020, Chef Software Inc.<legal@chef.io> # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/chef/resource/hostname.rb b/lib/chef/resource/hostname.rb index ef0218ebaa..e3897b6bef 100644 --- a/lib/chef/resource/hostname.rb +++ b/lib/chef/resource/hostname.rb @@ -100,7 +100,7 @@ class Chef action :set do description "Sets the node's hostname." - if node["platform_family"] != "windows" + if !windows? ohai "reload hostname" do plugin "hostname" action :nothing @@ -143,7 +143,7 @@ class Chef not_if { shell_out!("/usr/sbin/scutil --get LocalHostName").stdout.chomp == shortname } notifies :reload, "ohai[reload hostname]" end - when node["os"] == "linux" + when linux? case when ::File.exist?("/usr/bin/hostnamectl") && !docker? # use hostnamectl whenever we find it on linux (as systemd takes over the world) diff --git a/lib/chef/resource/kernel_module.rb b/lib/chef/resource/kernel_module.rb index 3dc9c0bd4f..9b732c0218 100644 --- a/lib/chef/resource/kernel_module.rb +++ b/lib/chef/resource/kernel_module.rb @@ -3,8 +3,8 @@ # # The MIT License (MIT) # -# Copyright 2016-2018, Shopify Inc. -# Copyright 2018-2020, Chef Software Inc. +# Copyright:: 2016-2018, Shopify Inc. +# Copyright:: 2018-2020, Chef Software Inc. require_relative "../resource" diff --git a/lib/chef/resource/remote_file.rb b/lib/chef/resource/remote_file.rb index 04c582d50d..54c7786cfd 100644 --- a/lib/chef/resource/remote_file.rb +++ b/lib/chef/resource/remote_file.rb @@ -109,7 +109,7 @@ class Chef end def validate_identity_platform(specified_user, password = nil, specified_domain = nil) - if node[:platform_family] == "windows" + if windows? if specified_user && password.nil? raise ArgumentError, "A value for `remote_password` must be specified when a value for `user` is specified on the Windows platform" end diff --git a/lib/chef/resource/swap_file.rb b/lib/chef/resource/swap_file.rb index a2838c5be7..1d2713e12c 100644 --- a/lib/chef/resource/swap_file.rb +++ b/lib/chef/resource/swap_file.rb @@ -1,6 +1,6 @@ # -# Copyright 2012-2018, Seth Vargo -# Copyright 2017-2020, Chef Software Inc. +# Copyright:: 2012-2018, Seth Vargo +# Copyright:: 2017-2020, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/chef/resource/timezone.rb b/lib/chef/resource/timezone.rb index b34b0a077b..63eed848ab 100644 --- a/lib/chef/resource/timezone.rb +++ b/lib/chef/resource/timezone.rb @@ -1,8 +1,8 @@ # # Author:: Kirill Kouznetsov <agon.smith@gmail.com> # -# Copyright 2018, Kirill Kouznetsov. -# Copyright 2018-2020, Chef Software Inc. +# Copyright:: 2018, Kirill Kouznetsov. +# Copyright:: 2018-2020, Chef Software Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/chef/resource/windows_certificate.rb b/lib/chef/resource/windows_certificate.rb index cdd7ed1ef1..474f9ad69c 100644 --- a/lib/chef/resource/windows_certificate.rb +++ b/lib/chef/resource/windows_certificate.rb @@ -85,7 +85,6 @@ class Chef guard_script << cert_exists_script(hash) powershell_script "setting the acls on #{new_resource.source} in #{cert_location}\\#{new_resource.store_name}" do - guard_interpreter :powershell_script convert_boolean_return true code code_script only_if guard_script diff --git a/lib/chef/resource/windows_user_privilege.rb b/lib/chef/resource/windows_user_privilege.rb new file mode 100644 index 0000000000..685354cfb4 --- /dev/null +++ b/lib/chef/resource/windows_user_privilege.rb @@ -0,0 +1,157 @@ +# +# Author:: Jared Kauppila (<jared@kauppi.la>) +# Author:: Vasundhara Jagdale(<vasundhara.jagdale@chef.io>) +# Copyright 2008-2020, Chef Software, Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_relative "../resource" + +class Chef + class Resource + class WindowsUserPrivilege < Chef::Resource + privilege_opts = %w{SeTrustedCredManAccessPrivilege + SeNetworkLogonRight + SeTcbPrivilege + SeMachineAccountPrivilege + SeIncreaseQuotaPrivilege + SeInteractiveLogonRight + SeRemoteInteractiveLogonRight + SeBackupPrivilege + SeChangeNotifyPrivilege + SeSystemtimePrivilege + SeTimeZonePrivilege + SeCreatePagefilePrivilege + SeCreateTokenPrivilege + SeCreateGlobalPrivilege + SeCreatePermanentPrivilege + SeCreateSymbolicLinkPrivilege + SeDebugPrivilege + SeDenyNetworkLogonRight + SeDenyBatchLogonRight + SeDenyServiceLogonRight + SeDenyInteractiveLogonRight + SeDenyRemoteInteractiveLogonRight + SeEnableDelegationPrivilege + SeRemoteShutdownPrivilege + SeAuditPrivilege + SeImpersonatePrivilege + SeIncreaseWorkingSetPrivilege + SeIncreaseBasePriorityPrivilege + SeLoadDriverPrivilege + SeLockMemoryPrivilege + SeBatchLogonRight + SeServiceLogonRight + SeSecurityPrivilege + SeRelabelPrivilege + SeSystemEnvironmentPrivilege + SeManageVolumePrivilege + SeProfileSingleProcessPrivilege + SeSystemProfilePrivilege + SeUndockPrivilege + SeAssignPrimaryTokenPrivilege + SeRestorePrivilege + SeShutdownPrivilege + SeSyncAgentPrivilege + SeTakeOwnershipPrivilege + } + + resource_name :windows_user_privilege + description "The windows_user_privilege resource allows to add and set principal (User/Group) to the specified privilege. \n Ref: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment" + + introduced "16.0" + + property :principal, String, + description: "An optional property to add the user to the given privilege. Use only with add and remove action.", + name_property: true + + property :users, Array, + description: "An optional property to set the privilege for given users. Use only with set action." + + property :privilege, [Array, String], + description: "Privilege to set for users.", + required: true, + coerce: proc { |v| v.is_a?(String) ? Array[v] : v }, + callbacks: { + "Option privilege must include any of the: #{privilege_opts}" => lambda { + |v| (privilege_opts & v).size == v.size + }, + } + + load_current_value do |new_resource| + unless new_resource.principal.nil? + privilege Chef::ReservedNames::Win32::Security.get_account_right(new_resource.principal) unless new_resource.action.include?(:set) + end + end + + action :add do + ([*new_resource.privilege] - [*current_resource.privilege]).each do |user_right| + converge_by("adding user '#{new_resource.principal}' privilege #{user_right}") do + Chef::ReservedNames::Win32::Security.add_account_right(new_resource.principal, user_right) + end + end + end + + action :set do + if new_resource.users.nil? || new_resource.users.empty? + raise Chef::Exceptions::ValidationFailed, "Users are required property with set action." + end + + users = [] + + # Getting users with its domain for comparison + new_resource.users.each do |user| + user = Chef::ReservedNames::Win32::Security.lookup_account_name(user) + users << user[1].account_name if user + end + + new_resource.privilege.each do |privilege| + accounts = Chef::ReservedNames::Win32::Security.get_account_with_user_rights(privilege) + + # comparing the existing accounts for privilege with users + unless users == accounts + # Removing only accounts which is not matching with users in new_resource + (accounts - users).each do |account| + converge_by("removing user '#{account}' from privilege #{privilege}") do + Chef::ReservedNames::Win32::Security.remove_account_right(account, privilege) + end + end + + # Adding only users which is not already exist + (users - accounts).each do |user| + converge_by("adding user '#{user}' to privilege #{privilege}") do + Chef::ReservedNames::Win32::Security.add_account_right(user, privilege) + end + end + end + end + end + + action :remove do + curr_res_privilege = current_resource.privilege + missing_res_privileges = (new_resource.privilege - curr_res_privilege) + + if missing_res_privileges + Chef::Log.info("User \'#{new_resource.principal}\' for Privilege: #{missing_res_privileges.join(", ")} not found. Nothing to remove.") + end + + (new_resource.privilege - missing_res_privileges).each do |user_right| + converge_by("removing user #{new_resource.principal} from privilege #{user_right}") do + Chef::ReservedNames::Win32::Security.remove_account_right(new_resource.principal, user_right) + end + end + end + end + end +end diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index 3681d9bd54..8bdd207e84 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -158,3 +158,4 @@ require_relative "resource/windows_task" require_relative "resource/windows_uac" require_relative "resource/windows_workgroup" require_relative "resource/timezone" +require_relative "resource/windows_user_privilege" diff --git a/lib/chef/version.rb b/lib/chef/version.rb index ed17b147a6..929adc574d 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -23,7 +23,7 @@ require_relative "version_string" class Chef CHEF_ROOT = File.expand_path("../..", __FILE__) - VERSION = Chef::VersionString.new("16.0.83") + VERSION = Chef::VersionString.new("16.0.89") end # diff --git a/lib/chef/win32/api/security.rb b/lib/chef/win32/api/security.rb index b651283758..16671a9f6d 100644 --- a/lib/chef/win32/api/security.rb +++ b/lib/chef/win32/api/security.rb @@ -413,6 +413,11 @@ class Chef :Buffer, :PWSTR end + # https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-lsa_enumeration_information + class LSA_ENUMERATION_INFORMATION < FFI::Struct + layout :Sid, :PSID + end + ffi_lib "advapi32" safe_attach_function :AccessCheck, %i{pointer HANDLE DWORD pointer pointer pointer pointer pointer}, :BOOL @@ -448,6 +453,7 @@ class Chef safe_attach_function :LookupPrivilegeDisplayNameW, %i{LPCWSTR LPCWSTR LPWSTR LPDWORD LPDWORD}, :BOOL safe_attach_function :LookupPrivilegeValueW, %i{LPCWSTR LPCWSTR PLUID}, :BOOL safe_attach_function :LsaAddAccountRights, %i{pointer pointer pointer ULONG}, :NTSTATUS + safe_attach_function :LsaEnumerateAccountsWithUserRight, %i{LSA_HANDLE PLSA_UNICODE_STRING PVOID PULONG}, :NTSTATUS safe_attach_function :LsaRemoveAccountRights, %i{pointer pointer BOOL pointer ULONG}, :NTSTATUS safe_attach_function :LsaClose, [ :LSA_HANDLE ], :NTSTATUS safe_attach_function :LsaEnumerateAccountRights, %i{LSA_HANDLE PSID PLSA_UNICODE_STRING PULONG}, :NTSTATUS diff --git a/lib/chef/win32/security.rb b/lib/chef/win32/security.rb index 5b78b652eb..2c0f63684a 100644 --- a/lib/chef/win32/security.rb +++ b/lib/chef/win32/security.rb @@ -214,6 +214,41 @@ class Chef privileges end + def self.get_account_with_user_rights(privilege) + privilege_pointer = FFI::MemoryPointer.new LSA_UNICODE_STRING, 1 + privilege_lsa_string = LSA_UNICODE_STRING.new(privilege_pointer) + privilege_lsa_string[:Buffer] = FFI::MemoryPointer.from_string(privilege.to_wstring) + privilege_lsa_string[:Length] = privilege.length * 2 + privilege_lsa_string[:MaximumLength] = (privilege.length + 1) * 2 + + buffer = FFI::MemoryPointer.new(:pointer) + count = FFI::MemoryPointer.new(:ulong) + + accounts = [] + with_lsa_policy(nil) do |policy_handle, sid| + result = LsaEnumerateAccountsWithUserRight(policy_handle.read_pointer, privilege_pointer, buffer, count) + if result == 0 + win32_error = LsaNtStatusToWinError(result) + return [] if win32_error == 1313 # NO_SUCH_PRIVILEGE - https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--1300-1699- + + test_and_raise_lsa_nt_status(result) + + count.read_ulong.times do |i| + sid = LSA_ENUMERATION_INFORMATION.new(buffer.read_pointer + i * LSA_ENUMERATION_INFORMATION.size) + sid_name = lookup_account_sid(sid[:Sid]) + domain, name, use = sid_name + account_name = (!domain.nil? && domain.length > 0) ? "#{domain}\\#{name}" : name + accounts << account_name + end + end + + result = LsaFreeMemory(buffer.read_pointer) + test_and_raise_lsa_nt_status(result) + end + + accounts + end + def self.get_ace(acl, index) acl = acl.pointer if acl.respond_to?(:pointer) ace = FFI::Buffer.new :pointer @@ -616,18 +651,21 @@ class Chef end def self.with_lsa_policy(username) - sid = lookup_account_name(username)[1] + sid = lookup_account_name(username)[1] if username access = 0 access |= POLICY_CREATE_ACCOUNT access |= POLICY_LOOKUP_NAMES + access |= POLICY_VIEW_LOCAL_INFORMATION if username.nil? policy_handle = FFI::MemoryPointer.new(:pointer) result = LsaOpenPolicy(nil, LSA_OBJECT_ATTRIBUTES.new, access, policy_handle) test_and_raise_lsa_nt_status(result) + sid_pointer = username.nil? ? nil : sid.pointer + begin - yield policy_handle, sid.pointer + yield policy_handle, sid_pointer ensure result = LsaClose(policy_handle.read_pointer) test_and_raise_lsa_nt_status(result) |