summaryrefslogtreecommitdiff
path: root/lib/chef
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef')
-rw-r--r--lib/chef/dsl/rest_resource.rb9
-rw-r--r--lib/chef/mixin/checksum.rb6
-rw-r--r--lib/chef/provider/file.rb4
-rw-r--r--lib/chef/provider/package/windows.rb2
-rw-r--r--lib/chef/provider/user.rb22
-rw-r--r--lib/chef/provider/user/aix.rb5
-rw-r--r--lib/chef/provider/user/linux.rb7
-rw-r--r--lib/chef/resource/_rest_resource.rb5
-rw-r--r--lib/chef/resource/windows_package.rb6
-rw-r--r--lib/chef/resource/windows_user_privilege.rb62
-rw-r--r--lib/chef/version.rb2
-rw-r--r--lib/chef/win32/handle.rb13
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