chef 18.1.0-x64-mingw-ucrt → 18.2.7-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -3
  3. data/chef-universal-mingw-ucrt.gemspec +2 -2
  4. data/chef.gemspec +1 -1
  5. data/distro/powershell/chef/chef.psm1 +459 -0
  6. data/lib/chef/application/base.rb +18 -2
  7. data/lib/chef/client.rb +23 -6
  8. data/lib/chef/http/authenticator.rb +117 -34
  9. data/lib/chef/platform/query_helpers.rb +4 -2
  10. data/lib/chef/resource/apt_repository.rb +20 -2
  11. data/lib/chef/resource/bash.rb +13 -0
  12. data/lib/chef/resource/dsc_script.rb +1 -1
  13. data/lib/chef/resource/launchd.rb +2 -2
  14. data/lib/chef/resource/macos_userdefaults.rb +9 -5
  15. data/lib/chef/resource/rhsm_register.rb +1 -1
  16. data/lib/chef/resource/selinux_fcontext.rb +1 -1
  17. data/lib/chef/resource/selinux_login.rb +129 -0
  18. data/lib/chef/resource/selinux_permissive.rb +1 -1
  19. data/lib/chef/resource/selinux_port.rb +1 -1
  20. data/lib/chef/resource/selinux_state.rb +1 -1
  21. data/lib/chef/resource/selinux_user.rb +137 -0
  22. data/lib/chef/resource/service.rb +1 -1
  23. data/lib/chef/resource/user.rb +2 -2
  24. data/lib/chef/resource/windows_user_privilege.rb +14 -10
  25. data/lib/chef/resources.rb +2 -0
  26. data/lib/chef/version.rb +1 -1
  27. data/spec/data/trusted_certs/intermediate.pem +38 -27
  28. data/spec/data/trusted_certs/opscode.pem +33 -54
  29. data/spec/functional/resource/macos_userdefaults_spec.rb +4 -4
  30. data/spec/integration/client/client_spec.rb +22 -16
  31. data/spec/spec_helper.rb +3 -3
  32. data/spec/unit/client_spec.rb +26 -2
  33. data/spec/unit/compliance/runner_spec.rb +8 -0
  34. data/spec/unit/http/authenticator_spec.rb +64 -11
  35. data/spec/unit/provider/apt_repository_spec.rb +26 -5
  36. data/spec/unit/resource/macos_user_defaults_spec.rb +4 -4
  37. data/spec/unit/resource/selinux_login_spec.rb +73 -0
  38. data/spec/unit/resource/selinux_user_spec.rb +92 -0
  39. metadata +16 -12
  40. data/lib/chef/powershell.rb +0 -81
@@ -102,12 +102,12 @@ class Chef
102
102
  self.class.get_cert_password
103
103
  end
104
104
 
105
- def encrypt_pfx_pass
106
- self.class.encrypt_pfx_pass
105
+ def encrypt_pfx_pass_with_vector
106
+ self.class.encrypt_pfx_pass_with_vector
107
107
  end
108
108
 
109
- def decrypt_pfx_pass
110
- self.class.decrypt_pfx_pass
109
+ def decrypt_pfx_pass_with_vector
110
+ self.class.decrypt_pfx_pass_with_vector
111
111
  end
112
112
 
113
113
  # Detects if a private key exists in a certificate repository like Keychain (macOS) or Certificate Store (Windows)
@@ -123,9 +123,18 @@ class Chef
123
123
  end
124
124
  end
125
125
 
126
+ def self.get_cert_user
127
+ Chef::Config[:auth_key_registry_type] == "user" ? "CurrentUser" : "LocalMachine"
128
+ end
129
+
130
+ def self.get_registry_user
131
+ Chef::Config[:auth_key_registry_type] == "user" ? "HKEY_CURRENT_USER" : "HKEY_LOCAL_MACHINE"
132
+ end
133
+
126
134
  def self.check_certstore_for_key(client_name)
135
+ store = get_cert_user
127
136
  powershell_code = <<~CODE
128
- $cert = Get-ChildItem -path cert:\\LocalMachine\\My -Recurse -Force | Where-Object { $_.Subject -Match "chef-#{client_name}" } -ErrorAction Stop
137
+ $cert = Get-ChildItem -path cert:\\#{store}\\My -Recurse -Force | Where-Object { $_.Subject -Match "chef-#{client_name}" } -ErrorAction Stop
129
138
  if (($cert.HasPrivateKey -eq $true) -and ($cert.PrivateKey.Key.ExportPolicy -ne "NonExportable")) {
130
139
  return $true
131
140
  }
@@ -164,49 +173,86 @@ class Chef
164
173
  end
165
174
 
166
175
  def self.get_cert_password
176
+ store = get_registry_user
167
177
  @win32registry = Chef::Win32::Registry.new
168
- path = "HKEY_LOCAL_MACHINE\\Software\\Progress\\Authentication"
178
+ path = "#{store}\\Software\\Progress\\Authentication"
169
179
  # does the registry key even exist?
170
- present = @win32registry.get_values(path)
171
- if present.nil? || present.empty?
180
+ # password_blob should be an array of hashes
181
+ password_blob = @win32registry.get_values(path)
182
+ if password_blob.nil? || password_blob.empty?
172
183
  raise Chef::Exceptions::Win32RegKeyMissing
173
184
  end
174
185
 
175
- present.each do |secret|
176
- if secret[:name] == "PfxPass"
177
- password = decrypt_pfx_pass(secret[:data])
178
- return password
186
+ # Did someone have just the password stored in the registry?
187
+ raw_data = password_blob.map { |x| x[:data] }
188
+ vector = raw_data[2]
189
+ if !!vector
190
+ decrypted_password = decrypt_pfx_pass_with_vector(password_blob)
191
+ else
192
+ decrypted_password = decrypt_pfx_pass_with_password(password_blob)
193
+ if !!decrypted_password
194
+ migrate_pass_to_use_vector(decrypted_password)
195
+ else
196
+ Chef::Log.error("Failed to retrieve certificate password")
179
197
  end
180
198
  end
181
-
182
- raise Chef::Exceptions::Win32RegKeyMissing
183
-
199
+ decrypted_password
184
200
  rescue Chef::Exceptions::Win32RegKeyMissing
185
201
  # if we don't have a password, log that and generate one
186
- Chef::Log.warn "Authentication Hive and values not present in registry, creating them now"
187
- new_path = "HKEY_LOCAL_MACHINE\\Software\\Progress\\Authentication"
202
+ store = get_registry_user
203
+ new_path = "#{store}\\Software\\Progress\\Authentication"
188
204
  unless @win32registry.key_exists?(new_path)
189
205
  @win32registry.create_key(new_path, true)
190
206
  end
191
- require "securerandom" unless defined?(SecureRandom)
192
- size = 14
193
- password = SecureRandom.alphanumeric(size)
194
- encrypted_pass = encrypt_pfx_pass(password)
195
- values = { name: "PfxPass", type: :string, data: encrypted_pass }
196
- @win32registry.set_value(new_path, values)
197
- password
207
+ create_and_store_new_password
198
208
  end
199
209
 
200
- def self.encrypt_pfx_pass(password)
210
+ def self.encrypt_pfx_pass_with_vector(password)
201
211
  powershell_code = <<~CODE
202
- $encrypted_string = ConvertTo-SecureString "#{password}" -AsPlainText -Force
203
- $secure_string = ConvertFrom-SecureString $encrypted_string
204
- return $secure_string
212
+ $AES = [System.Security.Cryptography.Aes]::Create()
213
+ $key_temp = [System.Convert]::ToBase64String($AES.Key)
214
+ $iv_temp = [System.Convert]::ToBase64String($AES.IV)
215
+ $encryptor = $AES.CreateEncryptor()
216
+ [System.Byte[]]$Bytes = [System.Text.Encoding]::Unicode.GetBytes("#{password}")
217
+ $EncryptedBytes = $encryptor.TransformFinalBlock($Bytes,0,$Bytes.Length)
218
+ $EncryptedBase64String = [System.Convert]::ToBase64String($EncryptedBytes)
219
+ # create array of encrypted pass, key, iv
220
+ $password_blob = @($EncryptedBase64String, $key_temp, $iv_temp)
221
+ return $password_blob
205
222
  CODE
206
223
  powershell_exec!(powershell_code).result
207
224
  end
208
225
 
209
- def self.decrypt_pfx_pass(password)
226
+ def self.decrypt_pfx_pass_with_vector(password_blob)
227
+ raw_data = password_blob.map { |x| x[:data] }
228
+ password = raw_data[0]
229
+ key = raw_data[1]
230
+ vector = raw_data[2]
231
+
232
+ powershell_code = <<~CODE
233
+ $KeyBytes = [System.Convert]::FromBase64String("#{key}")
234
+ $IVBytes = [System.Convert]::FromBase64String("#{vector}")
235
+ $aes = [System.Security.Cryptography.Aes]::Create()
236
+ $aes.Key = $KeyBytes
237
+ $aes.IV = $IVBytes
238
+ $EncryptedBytes = [System.Convert]::FromBase64String("#{password}")
239
+ $Decryptor = $aes.CreateDecryptor()
240
+ $DecryptedBytes = $Decryptor.TransformFinalBlock($EncryptedBytes,0,$EncryptedBytes.Length)
241
+ $DecryptedString = [System.Text.Encoding]::Unicode.GetString($DecryptedBytes)
242
+ return $DecryptedString
243
+ CODE
244
+ results = powershell_exec!(powershell_code).result
245
+ end
246
+
247
+ def self.decrypt_pfx_pass_with_password(password_blob)
248
+ password = ""
249
+ password_blob.each do |secret|
250
+ if secret[:name] == "PfxPass"
251
+ password = secret[:data]
252
+ else
253
+ Chef::Log.error("Failed to retrieve a password for the private key")
254
+ end
255
+ end
210
256
  powershell_code = <<~CODE
211
257
  $secure_string = "#{password}" | ConvertTo-SecureString
212
258
  $string = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($secure_string))))
@@ -215,14 +261,49 @@ class Chef
215
261
  powershell_exec!(powershell_code).result
216
262
  end
217
263
 
218
- def self.retrieve_certificate_key(client_name)
219
- require "openssl" unless defined?(OpenSSL)
264
+ def self.migrate_pass_to_use_vector(password)
265
+ store = get_cert_user
266
+ corrected_store = (store == "CurrentUser" ? "HKCU" : "HKLM")
267
+ powershell_code = <<~CODE
268
+ Remove-ItemProperty -Path "#{corrected_store}:\\Software\\Progress\\Authentication" -Name "PfXPass"
269
+ CODE
270
+ powershell_exec!(powershell_code)
271
+ create_and_store_new_password(password)
272
+ end
220
273
 
274
+ # This method name is a bit of a misnomer. We call it to legit create a new password using the vector format.
275
+ # But we also call it with a password that needs to be migrated to use the vector format too.
276
+ def self.create_and_store_new_password(password = nil)
277
+ @win32registry = Chef::Win32::Registry.new
278
+ store = get_registry_user
279
+ path = "#{store}\\Software\\Progress\\Authentication"
280
+ if password.nil?
281
+ require "securerandom" unless defined?(SecureRandom)
282
+ size = 14
283
+ password = SecureRandom.alphanumeric(size)
284
+ end
285
+ encrypted_blob = encrypt_pfx_pass_with_vector(password)
286
+ encrypted_password = encrypted_blob[0]
287
+ key = encrypted_blob[1]
288
+ vector = encrypted_blob[2]
289
+ values = [
290
+ { name: "PfxPass", type: :string, data: encrypted_password },
291
+ { name: "PfxKey", type: :string, data: key },
292
+ { name: "PfxIV", type: :string, data: vector },
293
+ ]
294
+ values.each do |i|
295
+ @win32registry.set_value(path, i)
296
+ end
297
+ password
298
+ end
299
+
300
+ def self.retrieve_certificate_key(client_name)
221
301
  if ChefUtils.windows?
302
+ require "openssl" unless defined?(OpenSSL)
222
303
  password = get_cert_password
223
304
  return false unless password
224
305
 
225
- if check_certstore_for_key(client_name)
306
+ if !!check_certstore_for_key(client_name)
226
307
  ps_blob = powershell_exec!(get_the_key_ps(client_name, password)).result
227
308
  file_path = ps_blob["PSPath"].split("::")[1]
228
309
  pkcs = OpenSSL::PKCS12.new(File.binread(file_path), password)
@@ -252,10 +333,11 @@ class Chef
252
333
  end
253
334
 
254
335
  def self.get_the_key_ps(client_name, password)
336
+ store = get_cert_user
255
337
  powershell_code = <<~CODE
256
338
  Try {
257
339
  $my_pwd = ConvertTo-SecureString -String "#{password}" -Force -AsPlainText;
258
- $cert = Get-ChildItem -path cert:\\LocalMachine\\My -Recurse | Where-Object { $_.Subject -match "chef-#{client_name}$" } -ErrorAction Stop;
340
+ $cert = Get-ChildItem -path cert:\\#{store}\\My -Recurse | Where-Object { $_.Subject -match "chef-#{client_name}$" } -ErrorAction Stop;
259
341
  $tempfile = [System.IO.Path]::GetTempPath() + "export_pfx.pfx";
260
342
  Export-PfxCertificate -Cert $cert -Password $my_pwd -FilePath $tempfile;
261
343
  }
@@ -266,8 +348,9 @@ class Chef
266
348
  end
267
349
 
268
350
  def self.delete_old_key_ps(client_name)
351
+ store = get_cert_user
269
352
  powershell_code = <<~CODE
270
- Get-ChildItem -path cert:\\LocalMachine\\My -Recurse | Where-Object { $_.Subject -match "chef-#{client_name}$" } | Remove-Item -ErrorAction Stop;
353
+ Get-ChildItem -path cert:\\#{store}\\My -Recurse | Where-Object { $_.Subject -match "chef-#{client_name}$" } | Remove-Item -ErrorAction Stop;
271
354
  CODE
272
355
  end
273
356
 
@@ -17,11 +17,14 @@
17
17
  #
18
18
 
19
19
  require "chef-utils" unless defined?(ChefUtils::CANARY)
20
+ require_relative "../mixin/powershell_exec"
20
21
 
21
22
  class Chef
22
23
  class Platform
23
24
 
24
25
  class << self
26
+ include Chef::Mixin::PowershellExec
27
+
25
28
  def windows?
26
29
  ChefUtils.windows?
27
30
  end
@@ -58,8 +61,7 @@ class Chef
58
61
  end
59
62
 
60
63
  def dsc_refresh_mode_disabled?(node)
61
- require_relative "../powershell"
62
- exec = Chef::PowerShell.new("Get-DscLocalConfigurationManager")
64
+ exec = powershell_exec!("Get-DscLocalConfigurationManager")
63
65
  exec.error!
64
66
  exec.result["RefreshMode"] == "Disabled"
65
67
  end
@@ -187,6 +187,24 @@ class Chef
187
187
  end.compact
188
188
  end
189
189
 
190
+ # run the specified command and extract the public key ids
191
+ # accepts the command so it can be used to extract both the current keys
192
+ # and the new keys
193
+ # @param [Array<String>] cmd the command to run
194
+ #
195
+ # @return [Array] an array of key ids
196
+ def extract_public_keys_from_cmd(*cmd)
197
+ so = shell_out(*cmd)
198
+ # Sample output
199
+ # pub:-:4096:1:D94AA3F0EFE21092:1336774248:::-:::scSC::::::23::0:
200
+ so.stdout.split(/\n/).map do |t|
201
+ if t.match(/^pub:/)
202
+ f = t.split(":")
203
+ f.slice(0, 6).join(":")
204
+ end
205
+ end.compact
206
+ end
207
+
190
208
  # validate the key against the apt keystore to see if that version is expired
191
209
  # @param [String] key
192
210
  #
@@ -222,8 +240,8 @@ class Chef
222
240
  def no_new_keys?(file)
223
241
  # Now we are using the option --with-colons that works across old os versions
224
242
  # as well as the latest (16.10). This for both `apt-key` and `gpg` commands
225
- installed_keys = extract_fingerprints_from_cmd(*LIST_APT_KEY_FINGERPRINTS)
226
- proposed_keys = extract_fingerprints_from_cmd("gpg", "--with-fingerprint", "--with-colons", file)
243
+ installed_keys = extract_public_keys_from_cmd(*LIST_APT_KEY_FINGERPRINTS)
244
+ proposed_keys = extract_public_keys_from_cmd("gpg", "--with-fingerprint", "--with-colons", file)
227
245
  (installed_keys & proposed_keys).sort == proposed_keys.sort
228
246
  end
229
247
 
@@ -43,6 +43,19 @@ class Chef
43
43
  end
44
44
  ```
45
45
 
46
+ **Using escape characters in a string of code**
47
+
48
+ In the following example, the `find` command uses an escape character (`\`). Use a second escape character (`\\`) to preserve the escape character in the code string:
49
+
50
+ ```ruby
51
+ bash 'delete some archives ' do
52
+ code <<-EOH
53
+ find ./ -name "*.tar.Z" -mtime +180 -exec rm -f {} \\;
54
+ EOH
55
+ ignore_failure true
56
+ end
57
+ ```
58
+
46
59
  **Install a file from a remote location**
47
60
 
48
61
  The following is an example of how to install the foo123 module for Nginx. This module adds shell-style functionality to an Nginx configuration file and does the following:
@@ -34,7 +34,7 @@ class Chef
34
34
  resource in #{ChefUtils::Dist::Infra::PRODUCT}, such as the Archive resource, a custom DSC resource, an existing DSC script that performs an important
35
35
  task, and so on. Use the dsc_script resource to embed the code that defines a DSC configuration directly within a #{ChefUtils::Dist::Infra::PRODUCT} recipe.
36
36
 
37
- Warning: The **dsc_script** resource may not be used with the 32 bit Chef Infra client. It must be executed from a 64 bit Chef Infra client.
37
+ Warning: The **dsc_script** resource is only available on 64-bit Chef Infra Client.
38
38
  DESC
39
39
 
40
40
  default_action :run
@@ -21,7 +21,7 @@ require_relative "../resource"
21
21
  class Chef
22
22
  class Resource
23
23
  class Launchd < Chef::Resource
24
- provides :launchd
24
+ provides :launchd, os: "darwin"
25
25
 
26
26
  description "Use the **launchd** resource to manage system-wide services (daemons) and per-user services (agents) on the macOS platform."
27
27
  introduced "12.8"
@@ -129,7 +129,7 @@ class Chef
129
129
  property :abandon_process_group, [ TrueClass, FalseClass ],
130
130
  description: "If a job dies, all remaining processes with the same process ID may be kept running. Set to true to kill all remaining processes."
131
131
 
132
- property :associated_bundle_identifiers, Hash,
132
+ property :associated_bundle_identifiers, Array,
133
133
  description: "This optional key indicates which bundles the Login Items Added by Apps panel associates with the helper executable."
134
134
 
135
135
  property :debug, [ TrueClass, FalseClass ],
@@ -50,15 +50,17 @@ class Chef
50
50
  end
51
51
  ```
52
52
 
53
- **Specifying the type of a key to skip automatic type detection**
53
+ **Setting a value for specific user and hosts**
54
54
 
55
55
  ```ruby
56
- macos_userdefaults 'Finder expanded save dialogs' do
57
- key 'NSNavPanelExpandedStateForSaveMode'
58
- value 'TRUE'
59
- type 'bool'
56
+ macos_userdefaults 'Enable macOS firewall' do
57
+ key 'globalstate'
58
+ value 1
59
+ user 'jane'
60
+ host :current
60
61
  end
61
62
  ```
63
+
62
64
  DOC
63
65
 
64
66
  property :domain, String,
@@ -79,6 +81,7 @@ class Chef
79
81
 
80
82
  property :host, [String, Symbol],
81
83
  description: "Set either :current, :all or a hostname to set the user default at the host level.",
84
+ default: :all,
82
85
  desired_state: false,
83
86
  introduced: "16.3"
84
87
 
@@ -94,6 +97,7 @@ class Chef
94
97
 
95
98
  property :user, [String, Symbol],
96
99
  description: "The system user that the default will be applied to. Set :current for current user, :all for all users or pass a valid username",
100
+ default: :current,
97
101
  desired_state: false
98
102
 
99
103
  property :sudo, [TrueClass, FalseClass],
@@ -92,7 +92,7 @@ class Chef
92
92
 
93
93
  property :release,
94
94
  [Float, String],
95
- description: "Sets the operating system minor release to use for subscriptions for the system. Products and updates are limited to the specified minor release version. This is used with the `auto_attach` option, it may also be used with activation keys. For example, `release '6.4'` will append `--release=6.4` to the register command.",
95
+ description: "Sets the operating system minor release to use for subscriptions for the system. Products and updates are limited to the specified minor release version. This is used with the `auto_attach` or `activation_key` options. For example, `release '6.4'` will append `--release=6.4` to the register command.",
96
96
  introduced: "17.8"
97
97
 
98
98
  action :register, description: "Register the node with RHSM." do
@@ -22,7 +22,7 @@ class Chef
22
22
 
23
23
  provides :selinux_fcontext
24
24
 
25
- description "Use **selinux_fcontext** resource to set the SELinux context of files with semanage fcontext."
25
+ description "Use the **selinux_fcontext** resource to set the SELinux context of files using the `semanage fcontext` command."
26
26
  introduced "18.0"
27
27
  examples <<~DOC
28
28
  **Allow http servers (e.g. nginx/apache) to modify moodle files**:
@@ -0,0 +1,129 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+
14
+ require_relative "../resource"
15
+ require_relative "selinux/common_helpers"
16
+
17
+ class Chef
18
+ class Resource
19
+ class SelinuxLogin < Chef::Resource
20
+ unified_mode true
21
+
22
+ provides :selinux_login
23
+
24
+ description "Use the **selinux_login** resource to add, update, or remove SELinux user to OS login mappings."
25
+ introduced "18.1"
26
+ examples <<~DOC
27
+ **Manage test OS user mapping with a range of s0 and associated SELinux user test_u**:
28
+
29
+ ```ruby
30
+ selinux_login 'test' do
31
+ user 'test_u'
32
+ range 's0'
33
+ end
34
+ ```
35
+ DOC
36
+
37
+ property :login, String,
38
+ name_property: true,
39
+ description: "An optional property to set the OS user login value if it differs from the resource block's name."
40
+
41
+ property :user, String,
42
+ description: "SELinux user to be mapped."
43
+
44
+ property :range, String,
45
+ description: "MLS/MCS security range for the SELinux user."
46
+
47
+ load_current_value do |new_resource|
48
+ logins = shell_out!("semanage login -l").stdout.split("\n")
49
+
50
+ current_login = logins.grep(/^#{Regexp.escape(new_resource.login)}\s+/) do |l|
51
+ l.match(/^(?<login>[^\s]+)\s+(?<user>[^\s]+)\s+(?<range>[^\s]+)/)
52
+ # match returns [<Match 'data'>] or [], shift converts that to <Match 'data'> or nil
53
+ end.shift
54
+
55
+ current_value_does_not_exist! unless current_login
56
+
57
+ # Existing resources should maintain their current configuration unless otherwise specified
58
+ new_resource.user ||= current_login[:user]
59
+ new_resource.range ||= current_login[:range]
60
+
61
+ user current_login[:user]
62
+ range current_login[:range]
63
+ end
64
+
65
+ action_class do
66
+ include Chef::SELinux::CommonHelpers
67
+
68
+ def semanage_login_args
69
+ # Generate arguments for semanage login -a or -m
70
+ args = ""
71
+
72
+ args += " -s #{new_resource.user}" if new_resource.user
73
+ args += " -r #{new_resource.range}" if new_resource.range
74
+
75
+ args
76
+ end
77
+ end
78
+
79
+ action :manage, description: "Sets the SELinux login mapping to the desired settings regardless of previous state." do
80
+ run_action(:add)
81
+ run_action(:modify)
82
+ end
83
+
84
+ # Create if doesn't exist, do not touch if user already exists
85
+ action :add, description: "Creates the SELinux login mapping if not previously created." do
86
+ raise "The user property must be populated to create a new SELinux login" if new_resource.user.to_s.empty?
87
+
88
+ if selinux_disabled?
89
+ Chef::Log.warn("Unable to add SELinux login #{new_resource.login} as SELinux is disabled")
90
+ return
91
+ end
92
+
93
+ unless current_resource
94
+ converge_if_changed do
95
+ shell_out!("semanage login -a#{semanage_login_args} #{new_resource.login}")
96
+ end
97
+ end
98
+ end
99
+
100
+ # Only modify port if it exists & doesn't have the correct context already
101
+ action :modify, description: "Updates the SELinux login mapping if previously created." do
102
+ if selinux_disabled?
103
+ Chef::Log.warn("Unable to modify SELinux login #{new_resource.login} as SELinux is disabled")
104
+ return
105
+ end
106
+
107
+ if current_resource
108
+ converge_if_changed do
109
+ shell_out!("semanage login -m#{semanage_login_args} #{new_resource.login}")
110
+ end
111
+ end
112
+ end
113
+
114
+ # Delete if exists
115
+ action :delete, description: "Removes the SELinux login mapping if previously created." do
116
+ if selinux_disabled?
117
+ Chef::Log.warn("Unable to delete SELinux login #{new_resource.login} as SELinux is disabled")
118
+ return
119
+ end
120
+
121
+ if current_resource
122
+ converge_by "deleting SELinux login #{new_resource.login}" do
123
+ shell_out!("semanage login -d #{new_resource.login}")
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -20,7 +20,7 @@ class Chef
20
20
 
21
21
  provides :selinux_permissive
22
22
 
23
- description "Use **selinux_permissive** resource to allows some types to misbehave without stopping them. Not as good as specific policies, but better than disabling SELinux entirely."
23
+ description "Use the **selinux_permissive** resource to allow some domains to misbehave without stopping them. This is not as good as setting specific policies, but better than disabling SELinux entirely."
24
24
  introduced "18.0"
25
25
  examples <<~DOC
26
26
  **Disable enforcement on Apache**:
@@ -21,7 +21,7 @@ class Chef
21
21
 
22
22
  provides :selinux_port
23
23
 
24
- description "Use **selinux_port** resource to allows assigning a network port to a certain SELinux context, e.g. for running a webserver on a non-standard port."
24
+ description "Use the **selinux_port** resource to assign a network port to a specific SELinux context. For example, running a web server on a non-standard port."
25
25
  introduced "18.0"
26
26
  examples <<~DOC
27
27
  **Allow nginx/apache to bind to port 5678 by giving it the http_port_t context**:
@@ -56,7 +56,7 @@ class Chef
56
56
 
57
57
  property :persistent, [true, false],
58
58
  default: true,
59
- description: "Persist status update to the selinux configuration file."
59
+ description: "Set the status update in the SELinux configuration file."
60
60
 
61
61
  property :policy, String,
62
62
  default: lazy { default_policy_platform },