chef 17.10.0 → 17.10.95

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Rakefile +2 -2
  4. data/chef-universal-mingw32.gemspec +2 -2
  5. data/chef.gemspec +5 -5
  6. data/lib/chef/client.rb +17 -2
  7. data/lib/chef/compliance/input_collection.rb +1 -1
  8. data/lib/chef/compliance/profile_collection.rb +1 -1
  9. data/lib/chef/compliance/waiver_collection.rb +1 -1
  10. data/lib/chef/dsl/secret.rb +113 -5
  11. data/lib/chef/mixin/checksum.rb +6 -0
  12. data/lib/chef/mixin/properties.rb +6 -0
  13. data/lib/chef/node/attribute.rb +20 -3
  14. data/lib/chef/node/mixin/deep_merge_cache.rb +4 -4
  15. data/lib/chef/provider/file.rb +2 -2
  16. data/lib/chef/provider/package/chocolatey.rb +18 -1
  17. data/lib/chef/provider/package/powershell.rb +1 -1
  18. data/lib/chef/provider/package/windows.rb +1 -1
  19. data/lib/chef/provider/user.rb +5 -1
  20. data/lib/chef/resource/chef_client_config.rb +5 -0
  21. data/lib/chef/resource/locale.rb +5 -2
  22. data/lib/chef/resource/macos_userdefaults.rb +9 -5
  23. data/lib/chef/resource/rhsm_register.rb +19 -0
  24. data/lib/chef/resource/support/client.erb +1 -2
  25. data/lib/chef/resource/windows_certificate.rb +54 -43
  26. data/lib/chef/resource/windows_pagefile.rb +28 -21
  27. data/lib/chef/resource/windows_user_privilege.rb +36 -26
  28. data/lib/chef/resource.rb +2 -1
  29. data/lib/chef/run_context.rb +16 -0
  30. data/lib/chef/secret_fetcher/hashi_vault.rb +1 -1
  31. data/lib/chef/version.rb +1 -1
  32. data/lib/chef/win32/version.rb +2 -1
  33. data/spec/data/trusted_certs/example.crt +29 -20
  34. data/spec/data/trusted_certs/example_no_cn.crt +30 -34
  35. data/spec/data/trusted_certs/opscode.pem +33 -54
  36. data/spec/functional/resource/chocolatey_package_spec.rb +32 -20
  37. data/spec/functional/resource/macos_userdefaults_spec.rb +4 -4
  38. data/spec/functional/resource/windows_certificate_spec.rb +41 -13
  39. data/spec/functional/resource/windows_font_spec.rb +1 -1
  40. data/spec/functional/resource/windows_pagefile_spec.rb +31 -4
  41. data/spec/functional/resource/yum_package_spec.rb +1 -1
  42. data/spec/functional/shell_spec.rb +6 -0
  43. data/spec/unit/client_spec.rb +6 -3
  44. data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +1 -1
  45. data/spec/unit/daemon_spec.rb +1 -5
  46. data/spec/unit/dsl/secret_spec.rb +127 -23
  47. data/spec/unit/mixin/checksum_spec.rb +28 -0
  48. data/spec/unit/provider/package/chocolatey_spec.rb +19 -3
  49. data/spec/unit/provider/package/rubygems_spec.rb +1 -1
  50. data/spec/unit/provider/user/linux_spec.rb +55 -0
  51. data/spec/unit/resource/chef_client_config_spec.rb +8 -0
  52. data/spec/unit/resource/macos_user_defaults_spec.rb +4 -4
  53. data/spec/unit/resource_spec.rb +22 -1
  54. data/spec/unit/run_context_spec.rb +16 -0
  55. metadata +28 -34
  56. /data/spec/functional/assets/chocolatey_feed/{test-A.1.0.nupkg → test-A.1.0.0.nupkg} +0 -0
  57. /data/spec/functional/assets/chocolatey_feed/{test-A.1.5.nupkg → test-A.1.5.0.nupkg} +0 -0
  58. /data/spec/functional/assets/chocolatey_feed/{test-A.2.0.nupkg → test-A.2.0.0.nupkg} +0 -0
  59. /data/spec/functional/assets/chocolatey_feed/{test-B.1.0.nupkg → test-B.1.0.0.nupkg} +0 -0
  60. /data/spec/functional/assets/yumrepo/repodata/{4632d67cb92636e7575d911c24f0e04d3505a944e97c483abe0c3e73a7c62d33-filelists.sqlite.bz2 → 01a3b-filelists.sqlite.bz2} +0 -0
  61. /data/spec/functional/assets/yumrepo/repodata/{bdb4f5f1492a3b9532f22c43110a81500dd744f23da0aec5c33b2a41317c737d-filelists.xml.gz → 401dc-filelists.xml.gz} +0 -0
  62. /data/spec/functional/assets/yumrepo/repodata/{a845d418f919d2115ab95a56b2c76f6825ad0d0bede49181a55c04f58995d057-primary.sqlite.bz2 → 5dc1e-primary.sqlite.bz2} +0 -0
  63. /data/spec/functional/assets/yumrepo/repodata/{74599b793e54d877323837d2d81a1c3c594c44e4335f9528234bb490f7b9b439-other.xml.gz → 6bf96-other.xml.gz} +0 -0
  64. /data/spec/functional/assets/yumrepo/repodata/{af9b7cf9ef23bd7b43068d74a460f3b5d06753d638e58e4a0c9edc35bfb9cdc4-other.sqlite.bz2 → 7c365-other.sqlite.bz2} +0 -0
  65. /data/spec/functional/assets/yumrepo/repodata/{c10d1d34ce99e02f12ec96ef68360543ab1bb7c3cb81a4a2bf78df7d8597e9df-primary.xml.gz → dabe2-primary.xml.gz} +0 -0
@@ -29,7 +29,6 @@ require "chef-utils/dist" unless defined?(ChefUtils::Dist)
29
29
  class Chef
30
30
  class Resource
31
31
  class WindowsCertificate < Chef::Resource
32
- unified_mode true
33
32
 
34
33
  provides :windows_certificate
35
34
 
@@ -129,14 +128,14 @@ class Chef
129
128
  end
130
129
 
131
130
  action :delete, description: "Deletes a certificate." do
132
- cert_obj = fetch_cert
131
+ cert_is_valid = verify_cert
133
132
 
134
- if cert_obj
133
+ if cert_is_valid == true
135
134
  converge_by("Deleting certificate #{new_resource.source} from Store #{new_resource.store_name}") do
136
135
  delete_cert
137
136
  end
138
137
  else
139
- Chef::Log.debug("Certificate not found")
138
+ Chef::Log.debug("Certificate Not Found")
140
139
  end
141
140
  end
142
141
 
@@ -146,17 +145,25 @@ class Chef
146
145
  end
147
146
 
148
147
  if ::File.extname(new_resource.output_path) == ".pfx"
149
- powershell_exec!(pfx_ps_cmd(resolve_thumbprint(new_resource.source), store_location: ps_cert_location, store_name: new_resource.store_name, output_path: new_resource.output_path, password: new_resource.pfx_password ))
148
+
149
+ validated_thumbprint = validate_thumbprint(new_resource.source)
150
+ if validated_thumbprint != false # is the thumbprint valid
151
+ cert_obj = powershell_exec!(pfx_ps_cmd(validate_thumbprint(new_resource.source), store_location: ps_cert_location, store_name: new_resource.store_name, output_path: new_resource.output_path, password: new_resource.pfx_password ))
152
+ else
153
+ message = "While fetching the certificate, was passed the following invalid certificate thumbprint : #{new_resource.source}\n"
154
+ raise Chef::Exceptions::InvalidKeyAttribute, message
155
+ end
156
+
150
157
  else
151
158
  cert_obj = fetch_cert
152
159
  end
153
160
 
154
- if cert_obj
161
+ if cert_obj != false && cert_obj != "Certificate Not Found"
155
162
  converge_by("Fetching certificate #{new_resource.source} from Store \\#{ps_cert_location}\\#{new_resource.store_name}") do
156
163
  export_cert(cert_obj, output_path: new_resource.output_path, store_name: new_resource.store_name , store_location: ps_cert_location, pfx_password: new_resource.pfx_password)
157
164
  end
158
165
  else
159
- Chef::Log.debug("Certificate not found")
166
+ Chef::Log.debug("Certificate Not Found")
160
167
  end
161
168
  end
162
169
 
@@ -187,7 +194,7 @@ class Chef
187
194
 
188
195
  def delete_cert
189
196
  store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location)
190
- store.delete(resolve_thumbprint(new_resource.source))
197
+ store.delete(validate_thumbprint(new_resource.source))
191
198
  end
192
199
 
193
200
  def fetch_cert
@@ -196,17 +203,16 @@ class Chef
196
203
  fetch_key
197
204
 
198
205
  else
199
- store.get(resolve_thumbprint(new_resource.source), store_name: new_resource.store_name, store_location: native_cert_location)
206
+ store.get(validate_thumbprint(new_resource.source))
200
207
  end
201
208
  end
202
209
 
203
210
  def fetch_key
204
211
  require "openssl" unless defined?(OpenSSL)
205
212
  file_name = ::File.basename(new_resource.output_path, ::File.extname(new_resource.output_path))
206
- directory = ::File.dirname(new_resource.output_path)
207
213
  pfx_file = file_name + ".pfx"
208
214
  new_pfx_output_path = ::File.join(Chef::FileCache.create_cache_path("pfx_files"), pfx_file)
209
- powershell_exec(pfx_ps_cmd(resolve_thumbprint(new_resource.source), store_location: ps_cert_location, store_name: new_resource.store_name, output_path: new_pfx_output_path, password: new_resource.pfx_password ))
215
+ powershell_exec(pfx_ps_cmd(validate_thumbprint(new_resource.source), store_location: ps_cert_location, store_name: new_resource.store_name, output_path: new_pfx_output_path, password: new_resource.pfx_password ))
210
216
  pkcs12 = OpenSSL::PKCS12.new(::File.binread(new_pfx_output_path), new_resource.pfx_password)
211
217
  f = ::File.open(new_resource.output_path, "w")
212
218
  f.write(pkcs12.key.to_s)
@@ -245,10 +251,6 @@ class Chef
245
251
  ::File.file?(source)
246
252
  end
247
253
 
248
- def is_file?(source)
249
- ::File.file?(source)
250
- end
251
-
252
254
  # Thumbprints should be exactly 40 Hex characters
253
255
  def valid_thumbprint?(string)
254
256
  string.match?(/[0-9A-Fa-f]/) && string.length == 40
@@ -261,29 +263,29 @@ class Chef
261
263
  GETTHUMBPRINTCODE
262
264
  end
263
265
 
264
- def resolve_thumbprint(thumbprint)
265
- return thumbprint if valid_thumbprint?(thumbprint)
266
-
267
- powershell_exec!(get_thumbprint(new_resource.store_name, ps_cert_location, new_resource.source)).result
266
+ def validate_thumbprint(thumbprint)
267
+ # valid_thumbprint can return false under at least 2 conditions:
268
+ # one is that the thumbprint is in fact busted
269
+ # the second is that the thumbprint is valid but belongs to an expired certificate already installed
270
+ results = valid_thumbprint?(thumbprint)
271
+ results == true ? thumbprint : false
268
272
  end
269
273
 
270
- # Checks whether a certificate with the given thumbprint
271
- # is already present and valid in certificate store
272
- # If the certificate is not present, verify_cert returns a String: "Certificate not found"
273
- # But if it is present but expired, it returns a Boolean: false
274
- # Otherwise, it returns a Boolean: true
275
- # updated this method to accept either a subject name or a thumbprint - 1/29/2021
276
-
274
+ # Checks to make sure whether the cert is found or not
275
+ # if it IS found, is it still valid - has it expired?
277
276
  def verify_cert(thumbprint = new_resource.source)
278
277
  store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location)
279
- if new_resource.pfx_password.nil?
280
- store.valid?(resolve_thumbprint(thumbprint), store_location: native_cert_location, store_name: new_resource.store_name )
278
+ validated_thumbprint = validate_thumbprint(thumbprint)
279
+ if validated_thumbprint != false
280
+ result = store.valid?(thumbprint)
281
+ result == ( "Certificate Not Found" || "Certificate Has Expired" ) ? false : true
281
282
  else
282
- store.valid?(resolve_thumbprint(thumbprint), store_location: native_cert_location, store_name: new_resource.store_name)
283
+ message = "While verifying the certificate, was passed the following invalid certificate thumbprint : #{thumbprint}\n"
284
+ raise Chef::Exceptions::InvalidKeyAttribute, message
283
285
  end
284
286
  end
285
287
 
286
- # this array structure is solving 2 problems. The first is that we need to have support for both the CurrentUser AND LocalMachine stores
288
+ # this structure is solving 2 problems. The first is that we need to have support for both the CurrentUser AND LocalMachine stores
287
289
  # Secondly, we need to pass the proper constant name for each store to win32-certstore but also pass the short name to powershell scripts used here
288
290
  def ps_cert_location
289
291
  new_resource.user_store ? "CurrentUser" : "LocalMachine"
@@ -436,7 +438,7 @@ class Chef
436
438
  end
437
439
 
438
440
  def export_cert(cert_obj, output_path:, store_name:, store_location:, pfx_password:)
439
- # Delete the cert if it exists. This is non-destructive in that it only removes the file and not the entire path.
441
+ # Delete the cert if it exists on disk already.
440
442
  # We want to ensure we're not randomly loading an old stinky cert.
441
443
  if ::File.exists?(output_path)
442
444
  ::File.delete(output_path)
@@ -460,7 +462,20 @@ class Chef
460
462
  cert_out = shell_out("openssl x509 -text -inform DER -in #{cert_obj} -outform CRT").stdout
461
463
  out_file.puts(cert_out)
462
464
  when ".pfx"
463
- pfx_ps_cmd(resolve_thumbprint(new_resource.source), store_location: store_location, store_name: store_name, output_path: output_path, password: pfx_password )
465
+ validated_thumbprint = validate_thumbprint(new_resource.source)
466
+ if validated_thumbprint != false # is the thumbprint valid
467
+ store = ::Win32::Certstore.open(new_resource.store_name, store_location: native_cert_location)
468
+ result = store.valid?(new_resource.source) # is there a cert in the store matching that thumbprint
469
+ temp = result == ( "Certificate Not Found" || "Certificate Has Expired" ) ? false : true
470
+ if temp == true
471
+ pfx_ps_cmd(validate_thumbprint(new_resource.source), store_location: store_location, store_name: store_name, output_path: output_path, password: pfx_password )
472
+ else
473
+ Chef::Log.debug("The requested certificate is not found or has expired")
474
+ end
475
+ else
476
+ message = "While exporting the pfx, was passed the following invalid certificate thumbprint : #{new_resource.source}\n"
477
+ raise Chef::Exceptions::InvalidKeyAttribute, message
478
+ end
464
479
  when ".p7b"
465
480
  cert_out = shell_out("openssl pkcs7 -export -nokeys -in #{cert_obj.to_pem} -outform P7B").stdout
466
481
  out_file.puts(cert_out)
@@ -481,14 +496,11 @@ class Chef
481
496
  #
482
497
  def import_certificates(cert_objs, is_pfx, store_name: new_resource.store_name, store_location: native_cert_location)
483
498
  [cert_objs].flatten.each do |cert_obj|
484
- # thumbprint = OpenSSL::Digest.new("SHA1", cert_obj.to_der).to_s
485
- # pkcs = OpenSSL::PKCS12.new(cert_obj, new_resource.pfx_password)
486
- # cert = OpenSSL::X509::Certificate.new(pkcs.certificate.to_pem)
487
499
  thumbprint = OpenSSL::Digest.new("SHA1", cert_obj.to_der).to_s
488
- if is_pfx
489
- if verify_cert(thumbprint) == true
490
- Chef::Log.debug("Certificate is already present")
491
- else
500
+ if verify_cert(thumbprint) == true
501
+ Chef::Log.debug("Certificate is already present")
502
+ elsif verify_cert(thumbprint) == false # Not found already in the CertStore
503
+ if is_pfx
492
504
  if is_file?(new_resource.source)
493
505
  converge_by("Creating a PFX #{new_resource.source} for Store #{new_resource.store_name}") do
494
506
  add_pfx_cert(new_resource.source)
@@ -502,15 +514,14 @@ class Chef
502
514
  message << exception.message
503
515
  raise Chef::Exceptions::ArgumentError, message
504
516
  end
505
- end
506
- else
507
- if verify_cert(thumbprint) == true
508
- Chef::Log.debug("Certificate is already present")
509
517
  else
510
518
  converge_by("Creating a certificate #{new_resource.source} for Store #{new_resource.store_name}") do
511
519
  add_cert(cert_obj)
512
520
  end
513
521
  end
522
+ else
523
+ message = "Certificate could not be imported"
524
+ raise Chef::Exceptions::CertificateNotImportable, message
514
525
  end
515
526
  end
516
527
  end
@@ -88,7 +88,7 @@ class Chef
88
88
  if automatic_managed
89
89
  set_automatic_managed unless automatic_managed?
90
90
  elsif automatic_managed == false
91
- unset_automatic_managed if automatic_managed?
91
+ unset_automatic_managed
92
92
  else
93
93
  pagefile = clarify_pagefile_name
94
94
  initial_size = new_resource.initial_size
@@ -149,10 +149,12 @@ class Chef
149
149
  def exists?(pagefile)
150
150
  @exists ||= begin
151
151
  logger.trace("Checking if #{pagefile} exists by running: Get-CimInstance Win32_PagefileSetting | Where-Object { $_.name -eq $($pagefile)} ")
152
- cmd = "$page_file_name = '#{pagefile}';"
153
- cmd << "$pagefile = Get-CimInstance Win32_PagefileSetting | Where-Object { $_.name -eq $($page_file_name)};"
154
- cmd << "if ([string]::IsNullOrEmpty($pagefile)) { return $false } else { return $true }"
155
- powershell_exec!(cmd).result
152
+ powershell_code = <<~CODE
153
+ $page_file_name = '#{pagefile}';
154
+ $pagefile = Get-CimInstance Win32_PagefileSetting | Where-Object { $_.name -eq $($page_file_name)}
155
+ if ([string]::IsNullOrEmpty($pagefile)) { return $false } else { return $true }
156
+ CODE
157
+ powershell_exec!(powershell_code).result
156
158
  end
157
159
  end
158
160
 
@@ -164,13 +166,17 @@ class Chef
164
166
  # @return [Boolean]
165
167
  def max_and_min_set?(pagefile, min, max)
166
168
  logger.trace("Checking if #{pagefile} has max and initial disk size values set")
167
- cmd = "$page_file = '#{pagefile}';"
168
- cmd << "$driveLetter = $page_file.split(':')[0];"
169
- cmd << "$page_file_settings = Get-CimInstance -ClassName Win32_PageFileSetting -Filter \"SettingID='pagefile.sys @ $($driveLetter):'\" -Property * -ErrorAction Stop;"
170
- cmd << "if ($page_file_settings.InitialSize -eq #{min} -and $page_file_settings.MaximumSize -eq #{max})"
171
- cmd << "{ return $true }"
172
- cmd << "else { return $false }"
173
- powershell_exec!(cmd).result
169
+
170
+ powershell_code = <<-CODE
171
+ $page_file = '#{pagefile}';
172
+ $driveLetter = $page_file.split(':')[0];
173
+ $page_file_settings = Get-CimInstance -ClassName Win32_PageFileSetting -Filter "SettingID='pagefile.sys @ $($driveLetter):'" -Property * -ErrorAction Stop;
174
+ if ($page_file_settings.InitialSize -eq #{min} -and $page_file_settings.MaximumSize -eq #{max})
175
+ { return $true }
176
+ else
177
+ { return $false }
178
+ CODE
179
+ powershell_exec!(powershell_code).result
174
180
  end
175
181
 
176
182
  # create a pagefile
@@ -225,12 +231,14 @@ class Chef
225
231
 
226
232
  # turn off automatic management of all pagefiles by Windows
227
233
  def unset_automatic_managed
228
- converge_by("Turn off Automatically Managed on pagefiles") do
229
- logger.trace("Running Set-CimInstance -InputObject $sys -Property @{AutomaticManagedPagefile=$false} -PassThru")
230
- powershell_exec! <<~EOH
231
- $sys = Get-CimInstance Win32_ComputerSystem -Property *
232
- Set-CimInstance -InputObject $sys -Property @{AutomaticManagedPagefile=$false} -PassThru
233
- EOH
234
+ if automatic_managed?
235
+ converge_by("Turn off Automatically Managed on pagefiles") do
236
+ logger.trace("Running Set-CimInstance -InputObject $sys -Property @{AutomaticManagedPagefile=$false} -PassThru")
237
+ powershell_exec! <<~EOH
238
+ $sys = Get-CimInstance Win32_ComputerSystem -Property *
239
+ Set-CimInstance -InputObject $sys -Property @{AutomaticManagedPagefile=$false} -PassThru
240
+ EOH
241
+ end
234
242
  end
235
243
  end
236
244
 
@@ -240,14 +248,13 @@ class Chef
240
248
  # @param [String] min the minimum size of the pagefile
241
249
  # @param [String] max the minimum size of the pagefile
242
250
  def set_custom_size(pagefile, min, max)
251
+ unset_automatic_managed
243
252
  converge_by("set #{pagefile} to InitialSize=#{min} & MaximumSize=#{max}") do
244
253
  logger.trace("Set-CimInstance -Property @{InitialSize = #{min} MaximumSize = #{max}")
245
254
  powershell_exec! <<~EOD
246
255
  $page_file = "#{pagefile}"
247
256
  $driveLetter = $page_file.split(':')[0]
248
- Get-CimInstance -ClassName Win32_PageFileSetting -Filter "SettingID='pagefile.sys @ $($driveLetter):'" -ErrorAction Stop | Set-CimInstance -Property @{
249
- InitialSize = #{min}
250
- MaximumSize = #{max}}
257
+ Get-CimInstance -ClassName Win32_PageFileSetting -Filter "SettingID='pagefile.sys @ $($driveLetter):'" -ErrorAction Stop | Set-CimInstance -Property @{InitialSize = #{min}; MaximumSize = #{max};}
251
258
  EOD
252
259
  end
253
260
  end
@@ -24,7 +24,7 @@ class Chef
24
24
  unified_mode true
25
25
 
26
26
  provides :windows_user_privilege
27
- 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"
27
+ 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"
28
28
 
29
29
  introduced "16.0"
30
30
 
@@ -39,23 +39,32 @@ class Chef
39
39
  end
40
40
  ```
41
41
 
42
- **Add the SeDenyRemoteInteractiveLogonRight Privilege to the Builtin Guests and Local Accounts User Groups**:
42
+ **Provide only the Builtin Guests and Administrator Groups with the SeCreatePageFile Privilege**:
43
+
44
+ ```ruby
45
+ windows_user_privilege 'Create Pagefile' do
46
+ privilege 'SeCreatePagefilePrivilege'
47
+ users ['BUILTIN\\Guests', 'BUILTIN\\Administrators']
48
+ action :set
49
+ end
50
+ ```
51
+
52
+ **Add the SeDenyRemoteInteractiveLogonRight Privilege to the 'Remote interactive logon' principal**:
43
53
 
44
54
  ```ruby
45
55
  windows_user_privilege 'Remote interactive logon' do
46
56
  privilege 'SeDenyRemoteInteractiveLogonRight'
47
- users ['Builtin\\Guests', 'NT AUTHORITY\\Local Account']
48
57
  action :add
49
58
  end
50
59
  ```
51
60
 
52
- **Provide only the Builtin Guests and Administrator Groups with the SeCreatePageFile Privilege**:
61
+ **Add to the Builtin Guests Group the SeCreatePageFile Privilege**:
53
62
 
54
63
  ```ruby
55
- windows_user_privilege 'Create Pagefile' do
64
+ windows_user_privilege 'Guests add Create Pagefile' do
65
+ principal 'BUILTIN\\Guests'
56
66
  privilege 'SeCreatePagefilePrivilege'
57
- users ['BUILTIN\\Guests', 'BUILTIN\\Administrators']
58
- action :set
67
+ action :add
59
68
  end
60
69
  ```
61
70
 
@@ -90,6 +99,7 @@ class Chef
90
99
  SeCreateSymbolicLinkPrivilege
91
100
  SeCreateTokenPrivilege
92
101
  SeDebugPrivilege
102
+ SeDelegateSessionUserImpersonatePrivilege
93
103
  SeDenyBatchLogonRight
94
104
  SeDenyInteractiveLogonRight
95
105
  SeDenyNetworkLogonRight
@@ -126,20 +136,20 @@ class Chef
126
136
  }.freeze
127
137
 
128
138
  property :principal, String,
129
- description: "An optional property to add the user to the given privilege. Use only with add and remove action.",
130
- name_property: true
139
+ 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",
140
+ name_property: true
131
141
 
132
142
  property :users, [Array, String],
133
- description: "An optional property to set the privilege for given users. Use only with set action.",
134
- coerce: proc { |v| Array(v) }
143
+ description: "An optional property to set the privilege for given users. Use only with set action.",
144
+ coerce: proc { |v| Array(v) }
135
145
 
136
146
  property :privilege, [Array, String],
137
- description: "One or more privileges to set for users.",
138
- required: true,
139
- coerce: proc { |v| Array(v) },
140
- callbacks: {
141
- "Privilege property restricted to the following values: #{PRIVILEGE_OPTS}" => lambda { |n| (n - PRIVILEGE_OPTS).empty? },
142
- }, identity: true
147
+ 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",
148
+ required: true,
149
+ coerce: proc { |v| Array(v) },
150
+ callbacks: {
151
+ "Privilege property restricted to the following values: #{PRIVILEGE_OPTS}" => lambda { |n| (n - PRIVILEGE_OPTS).empty? },
152
+ }, identity: true
143
153
 
144
154
  load_current_value do |new_resource|
145
155
  if new_resource.principal && (new_resource.action.include?(:add) || new_resource.action.include?(:remove))
@@ -147,15 +157,15 @@ class Chef
147
157
  end
148
158
  end
149
159
 
150
- action :add, description: "Add a user privilege." do
151
- ([*new_resource.privilege] - [*current_resource.privilege]).each do |user_right|
152
- converge_by("adding user '#{new_resource.principal}' privilege #{user_right}") do
153
- Chef::ReservedNames::Win32::Security.add_account_right(new_resource.principal, user_right)
160
+ action :add, description: "Add a privileges to a principal." do
161
+ ([*new_resource.privilege] - [*current_resource.privilege]).each do |principal_right|
162
+ converge_by("adding principal '#{new_resource.principal}' privilege #{principal_right}") do
163
+ Chef::ReservedNames::Win32::Security.add_account_right(new_resource.principal, principal_right)
154
164
  end
155
165
  end
156
166
  end
157
167
 
158
- action :set, description: "Set the privileges that are listed in the `privilege` property for only the users listed in the `users` property." do
168
+ 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
159
169
  if new_resource.users.nil? || new_resource.users.empty?
160
170
  raise Chef::Exceptions::ValidationFailed, "Users are required property with set action."
161
171
  end
@@ -204,7 +214,7 @@ class Chef
204
214
  end
205
215
  end
206
216
 
207
- action :remove, description: "Remove a user privilege" do
217
+ action :remove, description: "Remove a principal privilege" do
208
218
  curr_res_privilege = current_resource.privilege
209
219
  missing_res_privileges = (new_resource.privilege - curr_res_privilege)
210
220
 
@@ -212,9 +222,9 @@ class Chef
212
222
  Chef::Log.info("User \'#{new_resource.principal}\' for Privilege: #{missing_res_privileges.join(", ")} not found. Nothing to remove.")
213
223
  end
214
224
 
215
- (new_resource.privilege - missing_res_privileges).each do |user_right|
216
- converge_by("removing user #{new_resource.principal} from privilege #{user_right}") do
217
- Chef::ReservedNames::Win32::Security.remove_account_right(new_resource.principal, user_right)
225
+ (new_resource.privilege - missing_res_privileges).each do |principal_right|
226
+ converge_by("removing principal #{new_resource.principal} from privilege #{principal_right}") do
227
+ Chef::ReservedNames::Win32::Security.remove_account_right(new_resource.principal, principal_right)
218
228
  end
219
229
  end
220
230
  end
data/lib/chef/resource.rb CHANGED
@@ -660,7 +660,8 @@ class Chef
660
660
  text << "#{resource_name}(\"#{name}\") do\n"
661
661
 
662
662
  all_props = {}
663
- self.class.state_properties.map do |p|
663
+
664
+ self.class.sensitive_properties.map do |p|
664
665
 
665
666
  all_props[p.name.to_s] = p.sensitive? ? '"*sensitive value suppressed*"' : value_to_text(p.get(self))
666
667
  rescue Chef::Exceptions::ValidationFailed
@@ -145,6 +145,16 @@ class Chef
145
145
  #
146
146
  attr_accessor :input_collection
147
147
 
148
+ #
149
+ # @return [Symbol, nil]
150
+ #
151
+ attr_accessor :default_secret_service
152
+
153
+ #
154
+ # @return [Hash<Symbol,Object>]
155
+ #
156
+ attr_accessor :default_secret_config
157
+
148
158
  # Pointer back to the Chef::Runner that created this
149
159
  #
150
160
  attr_accessor :runner
@@ -222,6 +232,8 @@ class Chef
222
232
  @input_collection = Chef::Compliance::InputCollection.new(events)
223
233
  @waiver_collection = Chef::Compliance::WaiverCollection.new(events)
224
234
  @profile_collection = Chef::Compliance::ProfileCollection.new(events)
235
+ @default_secret_service = nil
236
+ @default_secret_config = {}
225
237
 
226
238
  initialize_child_state
227
239
  end
@@ -693,6 +705,10 @@ class Chef
693
705
  cookbook_collection
694
706
  cookbook_collection=
695
707
  cookbook_compiler
708
+ default_secret_config
709
+ default_secret_config=
710
+ default_secret_service
711
+ default_secret_service=
696
712
  definitions
697
713
  events
698
714
  events=
@@ -112,7 +112,7 @@ class Chef
112
112
  raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide the authenticating Vault role name in the configuration as :role_name")
113
113
  end
114
114
 
115
- Vault.auth.aws_iam(config[:role_name], Aws::InstanceProfileCredentials.new)
115
+ Vault.auth.aws_iam(config[:role_name], Aws::InstanceProfileCredentials.new, Vault.address)
116
116
  else
117
117
  raise Chef::Exceptions::Secret::ConfigurationInvalid.new("Invalid :auth_method provided. You gave #{config[:auth_method]}, expected one of :#{SUPPORTED_AUTH_TYPES.join(", :")} ")
118
118
  end
data/lib/chef/version.rb CHANGED
@@ -23,7 +23,7 @@ require_relative "version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("..", __dir__)
26
- VERSION = Chef::VersionString.new("17.10.0")
26
+ VERSION = Chef::VersionString.new("17.10.95")
27
27
  end
28
28
 
29
29
  #
@@ -51,7 +51,8 @@ class Chef
51
51
  WIN_VERSIONS = {
52
52
  "Windows Server 2022" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 20348 } },
53
53
  "Windows Server 2019" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number >= 17763 && build_number < 20348 } },
54
- "Windows 10" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION } },
54
+ "Windows 11" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION && build_number >= 22000 } },
55
+ "Windows 10" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION && build_number >= 19044 && build_number < 22000 } },
55
56
  "Windows Server 2016" => { major: 10, minor: 0, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION && build_number <= 14393 } },
56
57
  "Windows 8.1" => { major: 6, minor: 3, callable: lambda { |product_type, suite_mask, build_number| product_type == VER_NT_WORKSTATION } },
57
58
  "Windows Server 2012 R2" => { major: 6, minor: 3, callable: lambda { |product_type, suite_mask, build_number| product_type != VER_NT_WORKSTATION } },
@@ -1,22 +1,31 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIIDkjCCAnoCCQDihI8kxGYTFTANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
3
- VVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMRAwDgYDVQQKEwdZb3VD
4
- b3JwMRMwEQYDVQQLEwpPcGVyYXRpb25zMRYwFAYDVQQDEw1leGFtcGxlLmxvY2Fs
5
- MR0wGwYJKoZIhvcNAQkBFg5tZUBleGFtcGxlLmNvbTAeFw0xMzEwMTcxODAxMzVa
6
- Fw0yMzEwMTUxODAxMzVaMIGKMQswCQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAO
7
- BgNVBAcTB1NlYXR0bGUxEDAOBgNVBAoTB1lvdUNvcnAxEzARBgNVBAsTCk9wZXJh
8
- dGlvbnMxFjAUBgNVBAMTDWV4YW1wbGUubG9jYWwxHTAbBgkqhkiG9w0BCQEWDm1l
9
- QGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyKBo
10
- U+Bdni0xZK/NCzdLdi2X+TyW5eahbYMx+r1GDcVqCICvrthBCVLVFsQ8rvOHwTPi
11
- AxQJGxb9TLSXRgXQSlH6FLjIUceuOtpan3qYVJ1v7AxY4DgNvYBpbtJz5MQedJnT
12
- g2F+rXzkwaD6CWBqWHeGU0oP3r7bq1AMD6XEsK2w2/zHtG7TEnL45ARv1PsyrU5M
13
- ZAW/XyoMyq1k2Lpv7YR5kAvTq1+4RSt/it2RFE7R0AVbaQ0MeAnllfySiHHHlaOT
14
- FVd/qPSiGISxsUmmzA3Z08+0sfJwkrnJXbLscCBYndd7gMGgtczGjJtul0Ch3GFa
15
- /Pn5McjwF272+usJ1wIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCzPePWifWNECsG
16
- nL8on1AtFMkczE1/pdRS4YUl/Tc926MpezptSja8rL31+4Bom37/wYPG7HygtAQl
17
- R4FHpAtuqJKPOfjUmDNsIXRFnytrnflTpctDu/Nbj4PDCy01k/sTDUQt+s+lEBL8
18
- M8ArmfLZ8PCfAwnXmJQ5rggDFKqegjt6z1RsSglbMiASE7+KkpBnzaqH6fET6IQz
19
- WgAjv6WdRfwgfJjOTSX4XMpCSet9KaWmXExKrxiVng2Uu6E+ShVAyKaGMuc1B7VA
20
- oxnnVaVapFv5lOWucQr4KkC7EgaUZnyt8duOc8+Yvd+y3Xd2dcHUnmegRxly4jRV
21
- /lXbFAUb
2
+ MIIFPTCCAyWgAwIBAgIUPv2sKSZA+KW0a4LxgUhiZG48AkswDQYJKoZIhvcNAQEL
3
+ BQAwFzEVMBMGA1UEAwwMZXhhbXBsZS4uY29tMB4XDTIzMTAxNjE2MzM1M1oXDTMz
4
+ MTAxMzE2MzM1M1owFzEVMBMGA1UEAwwMZXhhbXBsZS4uY29tMIICIjANBgkqhkiG
5
+ 9w0BAQEFAAOCAg8AMIICCgKCAgEA1NKZJQY7B8xGnaERMX4laepq3u00q1nSDS6j
6
+ 03qd1zZkW+ofMFlH5plBvULNO1jdAH9WwyMAwLu87R1QOx9fEz06J81Wtu7jheOU
7
+ EHzn6NwWkUaX+j1oaIHIXrYnrUn5sW8w2wFEky82gPEG5SiZ6otKV2whX1ckSa3W
8
+ ReFihEO/2/zxOEA0QzfIxFDW92wyAMDNM2/O/AMQB2jVxtWhYiqePXVUfQrIrLW1
9
+ ytNmIWl7hoIHfVPgEoGLRe7kbT/QMTCd/lNrzF/rxUo+Aohq3WmVOdUCL4KdDnKS
10
+ tlQFf8L4+9t19KiM9xX4GRMk9WWONk8rHln842ziv00bgD0rB3yZHlHJfGpkLdKv
11
+ VZgcMHp31ZqVFzHapqHmXBVyEqxRIZSkZX4PN5bEdigz3Exf/vys+NAZKyJw35tn
12
+ kF0+V/+vLlbvqZz98DDj+/KGgy7vaF3tBYBAC4px5yvnicDlBZS0GlrF1fufWQRQ
13
+ 94n8LVcG47XjaEOufpzj5Xm6ZzTYDyiqO1+mszU6BQH8W8N+sZ+q7hPBkgRZ/WJF
14
+ gXzNh5KPeDv47oXadYXOqNzXR7wkC11H5hmgQFrDCjuc0zTi/y7Iq+NxpkuQJIDD
15
+ /4yNVTHM6GZSeBDH7rpkjL6coShU6fu2QxSofltpz4QxNtbquRtt3A2Se7obhC9g
16
+ OeZfIqsCAwEAAaOBgDB+MB0GA1UdDgQWBBQ8JrC+u1bsL4QTJuIkH4MyZ2+ZWzAf
17
+ BgNVHSMEGDAWgBQ8JrC+u1bsL4QTJuIkH4MyZ2+ZWzAPBgNVHRMBAf8EBTADAQH/
18
+ MCsGA1UdEQQkMCKCC2V4YW1wbGUuY29tgg0qLmV4YW1wbGUuY29thwQKAAABMA0G
19
+ CSqGSIb3DQEBCwUAA4ICAQAVFkQdpfoxzNu2VyhCtrCT8a1PA7Ko+ziPR0GWBxag
20
+ kB3NRGzCVXENuX8OjLAsBRrYDTeUwIZJD2MWLqkhqs+8Bw08c9jdyezeWmgAL0I8
21
+ aTiPET3CwVME78JPvxAJjmdayYFanniAbE3GMk+Bf2pvFTdPI8etY6Brv+uqBbyb
22
+ 9pFspp2U05KRqTukVW2YJnWKfMR4VIBzOEA1maGwVMgnC3YPm3qsYqxXqr/jLDCg
23
+ /EFoozne5/mNmvhSKWOUB1gsuv+3wiUOL6aZETY7RJPQADpHhJntCSeapb5DWhyr
24
+ ZzUPGHbAyWqbfwmt7b9Pga4fQOihxi4Nf2ZnnMy32HQVqz2sOU7Fo/5rfejEQfGP
25
+ jxt9b69Hydc3MQJF+eQVYS+NzaZyCX05kLqcGmIP4WKhjx3BkMaZVwjmYfE9WgKR
26
+ Lcwq0aoz4Guh7Q0yICUc0PvxWLAkiXYFhthg05ZplTd+HgY3XCdO4DyG7lgL4b9t
27
+ T6oqZv/7ivJbwTrvQXr6gGPhVq+120/mEw2qsdaQAp8v1ac5UgdCTViDkT45Ivox
28
+ dS8VaqlVymvnLWAXtN92kQeb7bAhRmMZMNpFicFm8VS+alfijQDwhW5kOGpqtCrO
29
+ f3QWYOehrqmHIuKw4ZhCYIy/OWkHR2j5iiZl8RFN2KhHZwLcmQTyxLaBk3SX1kCl
30
+ qA==
22
31
  -----END CERTIFICATE-----
@@ -1,36 +1,32 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- s1OiWnMV3shxVccqzenDBww5rSou9Ab/VqujKisJ54dXyHukYMxh9MJwlRDsy0FB
10
- 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
- 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
- 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
- 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
- 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
- 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
- MVS4OrThLwgazfQu/BlOvJpQfcNPI/VP9c41yHKpeoIh6oxNDc/212/wwgwPgD83
17
- 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
- +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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 7G7Z/yw8XhoQiDJaPHF6XavC3dYvi51cehnPR4E6Jok23kbJEe3Qw5Yh747JjSsS
29
- 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
- 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
- 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
- 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
- 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
- 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
35
- oYdVLVWSjyoA2l4Xb4LdexAgCg==
2
+ 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
36
32
  -----END CERTIFICATE-----