diff options
Diffstat (limited to 'lib/chef')
-rw-r--r-- | lib/chef/dsl/rest_resource.rb | 9 | ||||
-rw-r--r-- | lib/chef/mixin/checksum.rb | 6 | ||||
-rw-r--r-- | lib/chef/provider/file.rb | 4 | ||||
-rw-r--r-- | lib/chef/provider/package/windows.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider/user.rb | 22 | ||||
-rw-r--r-- | lib/chef/provider/user/aix.rb | 5 | ||||
-rw-r--r-- | lib/chef/provider/user/linux.rb | 7 | ||||
-rw-r--r-- | lib/chef/resource/_rest_resource.rb | 5 | ||||
-rw-r--r-- | lib/chef/resource/windows_package.rb | 6 | ||||
-rw-r--r-- | lib/chef/resource/windows_user_privilege.rb | 62 | ||||
-rw-r--r-- | lib/chef/version.rb | 2 | ||||
-rw-r--r-- | lib/chef/win32/handle.rb | 13 |
12 files changed, 98 insertions, 45 deletions
diff --git a/lib/chef/dsl/rest_resource.rb b/lib/chef/dsl/rest_resource.rb index 96eba24eac..2c435930e9 100644 --- a/lib/chef/dsl/rest_resource.rb +++ b/lib/chef/dsl/rest_resource.rb @@ -31,13 +31,20 @@ class Chef # URL to collection def rest_api_collection(rest_api_collection = NOT_PASSED) - @rest_api_collection = rest_api_collection if rest_api_collection != NOT_PASSED + if rest_api_collection != NOT_PASSED + raise ArgumentError, "You must pass an absolute path to rest_api_collection" unless rest_api_collection.start_with? "/" + + @rest_api_collection = rest_api_collection + end + @rest_api_collection end # RFC6570-Templated URL to document def rest_api_document(rest_api_document = NOT_PASSED, first_element_only: false) if rest_api_document != NOT_PASSED + raise ArgumentError, "You must pass an absolute path to rest_api_document" unless rest_api_document.start_with? "/" + @rest_api_document = rest_api_document @rest_api_document_first_element_only = first_element_only end diff --git a/lib/chef/mixin/checksum.rb b/lib/chef/mixin/checksum.rb index 083e524d63..10ecac0b36 100644 --- a/lib/chef/mixin/checksum.rb +++ b/lib/chef/mixin/checksum.rb @@ -31,6 +31,12 @@ class Chef checksum.slice(0, 6) end + + def checksum_match?(ref_checksum, diff_checksum) + return false if ref_checksum.nil? || diff_checksum.nil? + + ref_checksum.casecmp?(diff_checksum) + end end end end diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb index 4ac86a6c8a..02611af4eb 100644 --- a/lib/chef/provider/file.rb +++ b/lib/chef/provider/file.rb @@ -336,7 +336,7 @@ class Chef end def do_validate_content - if new_resource.checksum && tempfile && ( new_resource.checksum != tempfile_checksum ) + if new_resource.checksum && tempfile && !checksum_match?(new_resource.checksum, tempfile_checksum) raise Chef::Exceptions::ChecksumMismatch.new(short_cksum(new_resource.checksum), short_cksum(tempfile_checksum)) end @@ -450,7 +450,7 @@ class Chef def contents_changed? logger.trace "calculating checksum of #{tempfile.path} to compare with #{current_resource.checksum}" - tempfile_checksum != current_resource.checksum + !checksum_match?(tempfile_checksum, current_resource.checksum) end def tempfile diff --git a/lib/chef/provider/package/windows.rb b/lib/chef/provider/package/windows.rb index 4350eb6d12..5581469062 100644 --- a/lib/chef/provider/package/windows.rb +++ b/lib/chef/provider/package/windows.rb @@ -38,7 +38,7 @@ class Chef def define_resource_requirements if new_resource.checksum requirements.assert(:install) do |a| - a.assertion { new_resource.checksum == checksum(source_location) } + a.assertion { checksum_match?(new_resource.checksum, checksum(source_location)) } a.failure_message Chef::Exceptions::Package, "Checksum on resource (#{short_cksum(new_resource.checksum)}) does not match checksum on content (#{short_cksum(source_location)})" end end diff --git a/lib/chef/provider/user.rb b/lib/chef/provider/user.rb index 2abd7f5f3c..3d18c0df82 100644 --- a/lib/chef/provider/user.rb +++ b/lib/chef/provider/user.rb @@ -72,7 +72,18 @@ class Chef @shadow_lib_ok = false else @shadow_info = Shadow::Passwd.getspnam(new_resource.username) - current_resource.password(@shadow_info.sp_pwdp) if new_resource.password && current_resource.password == "x" + # This conditional remains in place until we can sort out whether we need it. + # Currently removing it causes tests to fail, but that /seems/ to be mocking/setup issues. + # Some notes for context: + # 1. Ruby's ETC.getpwnam makes use of /etc/passwd file (https://github.com/ruby/etc/blob/master/ext/etc/etc.c), + # which returns "x" for a nil password. on AIX it returns a "*" + # (https://www.ibm.com/docs/bg/aix/7.2?topic=passwords-using-etcpasswd-file) + # 2. On AIX platforms ruby_shadow does not work as it does not + # store encrypted passwords in the /etc/passwd file but in /etc/security/passwd file. + # The AIX provider for user currently declares it does not support ruby-shadow. + if new_resource.password && current_resource.password == "x" + current_resource.password(@shadow_info.sp_pwdp) + end end convert_group_name if new_resource.gid @@ -81,6 +92,13 @@ class Chef current_resource end + # An overridable for platforms that do not support ruby shadow. This way we + # can verify that the platform supports ruby shadow before requiring that + # it be available. + def supports_ruby_shadow? + true + end + def load_shadow_options unless @shadow_info.nil? current_resource.inactive(@shadow_info.sp_inact&.to_i) @@ -102,7 +120,7 @@ class Chef a.whyrun "group name #{new_resource.gid} does not exist. This will cause group assignment to fail. Assuming this group will have been created previously." end requirements.assert(:all_actions) do |a| - a.assertion { @shadow_lib_ok } + a.assertion { !supports_ruby_shadow? || @shadow_lib_ok } a.failure_message Chef::Exceptions::MissingLibrary, "You must have ruby-shadow installed for password support!" a.whyrun "ruby-shadow is not installed. Attempts to set user password will cause failure. Assuming that this gem will have been previously installed." \ "Note that user update converge may report false-positive on the basis of mismatched password. " diff --git a/lib/chef/provider/user/aix.rb b/lib/chef/provider/user/aix.rb index 740f9943d3..997bd6bac5 100644 --- a/lib/chef/provider/user/aix.rb +++ b/lib/chef/provider/user/aix.rb @@ -23,6 +23,11 @@ class Chef provides :user, os: "aix" provides :aix_user + # The ruby-shadow gem is not supported on aix. + def supports_ruby_shadow? + false + end + def create_user shell_out!("useradd", universal_options, useradd_options, new_resource.username) add_password diff --git a/lib/chef/provider/user/linux.rb b/lib/chef/provider/user/linux.rb index ab411d769a..7ef2f79eed 100644 --- a/lib/chef/provider/user/linux.rb +++ b/lib/chef/provider/user/linux.rb @@ -29,7 +29,10 @@ class Chef end def compare_user - super + user_changed = super + + @change_desc ||= [] + %i{expire_date inactive}.each do |user_attrib| new_val = new_resource.send(user_attrib) cur_val = current_resource.send(user_attrib) @@ -37,6 +40,8 @@ class Chef @change_desc << "change #{user_attrib} from #{cur_val} to #{new_val}" end end + + user_changed || !@change_desc.empty? end def create_user diff --git a/lib/chef/resource/_rest_resource.rb b/lib/chef/resource/_rest_resource.rb index f14e586eb2..8e72073b88 100644 --- a/lib/chef/resource/_rest_resource.rb +++ b/lib/chef/resource/_rest_resource.rb @@ -15,6 +15,7 @@ # limitations under the License. # +require "addressable/template" unless defined?(Addressable::Template) require "rest-client" unless defined?(RestClient) require "jmespath" unless defined?(JMESPath) require "chef/dsl/rest_resource" unless defined?(Chef::DSL::RestResource) @@ -221,7 +222,9 @@ action_class do response = rest_postprocess(response) first_only = current_resource.class.rest_api_document_first_element_only - first_only && response.is_a?(Array) ? response.first : response + response.data = response.data.first if first_only && response.data.is_a?(Array) + + response rescue RestClient::Exception => e rest_errorhandler(e) end diff --git a/lib/chef/resource/windows_package.rb b/lib/chef/resource/windows_package.rb index 2e10dde43d..8aab488eb4 100644 --- a/lib/chef/resource/windows_package.rb +++ b/lib/chef/resource/windows_package.rb @@ -78,7 +78,7 @@ class Chef ```ruby windows_package '7zip' do source 'http://www.7-zip.org/a/7z938-x64.msi' - checksum '7c8e873991c82ad9cfc123415254ea6101e9a645e12977dcd518979e50fdedf3' + checksum '7c8e873991c82ad9cfcdbdf45254ea6101e9a645e12977dcd518979e50fdedf3' end ``` @@ -91,7 +91,7 @@ class Chef source 'http://www.7-zip.org/a/7z938-x64.msi' remote_file_attributes ({ :path => 'C:\\7zip.msi', - :checksum => '7c8e873991c82ad9cfc123415254ea6101e9a645e12977dcd518979e50fdedf3' + :checksum => '7c8e873991c82ad9cfcdbdf45254ea6101e9a645e12977dcd518979e50fdedf3' }) end ``` @@ -100,7 +100,7 @@ class Chef ```ruby windows_package 'Mercurial 3.6.1 (64-bit)' do - source 'http://mercurial.selenic.com/release/windows/Mercurial-3.6.1-x64.exe' + source 'https://www.mercurial-scm.org/release/windows/Mercurial-3.6.1-x64.exe' checksum 'febd29578cb6736163d232708b834a2ddd119aa40abc536b2c313fc5e1b5831d' end ``` diff --git a/lib/chef/resource/windows_user_privilege.rb b/lib/chef/resource/windows_user_privilege.rb index 251382e46f..ac017a1599 100644 --- a/lib/chef/resource/windows_user_privilege.rb +++ b/lib/chef/resource/windows_user_privilege.rb @@ -23,7 +23,7 @@ class Chef class WindowsUserPrivilege < Chef::Resource provides :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\n For list of principals to use with :add action Ref: https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/special-identities" + description "The windows_user_privilege resource allows to add a privilege to a principal or (User/Group).\n Ref: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment" introduced "16.0" @@ -38,23 +38,32 @@ class Chef end ``` - **Add the SeDenyRemoteInteractiveLogonRight Privilege to the Builtin Guests and Local Accounts User Groups**: + **Provide only the Builtin Guests and Administrator Groups with the SeCreatePageFile Privilege**: + + ```ruby + windows_user_privilege 'Create Pagefile' do + privilege 'SeCreatePagefilePrivilege' + users ['BUILTIN\\Guests', 'BUILTIN\\Administrators'] + action :set + end + ``` + + **Add the SeDenyRemoteInteractiveLogonRight Privilege to the 'Remote interactive logon' principal**: ```ruby windows_user_privilege 'Remote interactive logon' do privilege 'SeDenyRemoteInteractiveLogonRight' - users ['Builtin\\Guests', 'NT AUTHORITY\\Local Account'] action :add end ``` - **Provide only the Builtin Guests and Administrator Groups with the SeCreatePageFile Privilege**: + **Add to the Builtin Guests Group the SeCreatePageFile Privilege**: ```ruby - windows_user_privilege 'Create Pagefile' do + windows_user_privilege 'Guests add Create Pagefile' do + principal 'BUILTIN\\Guests' privilege 'SeCreatePagefilePrivilege' - users ['BUILTIN\\Guests', 'BUILTIN\\Administrators'] - action :set + action :add end ``` @@ -89,6 +98,7 @@ class Chef SeCreateSymbolicLinkPrivilege SeCreateTokenPrivilege SeDebugPrivilege + SeDelegateSessionUserImpersonatePrivilege SeDenyBatchLogonRight SeDenyInteractiveLogonRight SeDenyNetworkLogonRight @@ -125,20 +135,20 @@ class Chef }.freeze 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 + description: "An optional property to add the privilege for given principal. Use only with add and remove action. Principal can either be a User/Group or one of special identities found here Ref: https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/special-identities", + name_property: true property :users, [Array, String], - description: "An optional property to set the privilege for given users. Use only with set action.", - coerce: proc { |v| Array(v) } + description: "An optional property to set the privilege for given users. Use only with set action.", + coerce: proc { |v| Array(v) } property :privilege, [Array, String], - description: "One or more privileges to set for users.", - required: true, - coerce: proc { |v| Array(v) }, - callbacks: { - "Privilege property restricted to the following values: #{PRIVILEGE_OPTS}" => lambda { |n| (n - PRIVILEGE_OPTS).empty? }, - }, identity: true + description: "One or more privileges to set for principal or users/groups. For more information on what each privilege does Ref: https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment", + required: true, + coerce: proc { |v| Array(v) }, + callbacks: { + "Privilege property restricted to the following values: #{PRIVILEGE_OPTS}" => lambda { |n| (n - PRIVILEGE_OPTS).empty? }, + }, identity: true load_current_value do |new_resource| if new_resource.principal && (new_resource.action.include?(:add) || new_resource.action.include?(:remove)) @@ -146,15 +156,15 @@ class Chef end end - action :add, description: "Add a user privilege." 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) + action :add, description: "Add a privileges to a principal." do + ([*new_resource.privilege] - [*current_resource.privilege]).each do |principal_right| + converge_by("adding principal '#{new_resource.principal}' privilege #{principal_right}") do + Chef::ReservedNames::Win32::Security.add_account_right(new_resource.principal, principal_right) end end end - action :set, description: "Set the privileges that are listed in the `privilege` property for only the users listed in the `users` property." do + action :set, description: "Set the privileges that are listed in the `privilege` property for only the users listed in the `users` property. All other users not listed with given privilege will be have the privilege removed." do if new_resource.users.nil? || new_resource.users.empty? raise Chef::Exceptions::ValidationFailed, "Users are required property with set action." end @@ -203,7 +213,7 @@ class Chef end end - action :remove, description: "Remove a user privilege" do + action :remove, description: "Remove a principal privilege" do curr_res_privilege = current_resource.privilege missing_res_privileges = (new_resource.privilege - curr_res_privilege) @@ -211,9 +221,9 @@ class Chef 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) + (new_resource.privilege - missing_res_privileges).each do |principal_right| + converge_by("removing principal #{new_resource.principal} from privilege #{principal_right}") do + Chef::ReservedNames::Win32::Security.remove_account_right(new_resource.principal, principal_right) end end end diff --git a/lib/chef/version.rb b/lib/chef/version.rb index 69ed8c0242..75c998e853 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("..", __dir__) - VERSION = Chef::VersionString.new("18.0.144") + VERSION = Chef::VersionString.new("18.0.172") end # diff --git a/lib/chef/win32/handle.rb b/lib/chef/win32/handle.rb index 1b0257ed68..a677b4021e 100644 --- a/lib/chef/win32/handle.rb +++ b/lib/chef/win32/handle.rb @@ -26,10 +26,6 @@ class Chef class Handle extend Chef::ReservedNames::Win32::API::Process - # See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx - # The handle value returned by the GetCurrentProcess function is the pseudo handle (HANDLE)-1 (which is 0xFFFFFFFF) - CURRENT_PROCESS_HANDLE = 4294967295 - def initialize(handle) @handle = handle ObjectSpace.define_finalizer(self, Handle.close_handle_finalizer(handle)) @@ -38,13 +34,16 @@ class Chef attr_reader :handle def self.close_handle_finalizer(handle) + proc { close_handle(handle) } + end + + def self.close_handle(handle) # According to http://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx, it is not necessary # to close the pseudo handle returned by the GetCurrentProcess function. The docs also say that it doesn't hurt to call # CloseHandle on it. However, doing so from inside of Ruby always seems to produce an invalid handle error. - proc { close_handle(handle) unless handle == CURRENT_PROCESS_HANDLE } - end + # The recommendation is to use GetCurrentProcess instead of the const (HANDLE)-1, to ensure we're making the correct comparison. + return if handle == GetCurrentProcess() - def self.close_handle(handle) unless CloseHandle(handle) Chef::ReservedNames::Win32::Error.raise! end |