puppet 6.22.1 → 6.23.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile.lock +14 -14
- data/ext/osx/puppet.plist +2 -0
- data/lib/puppet/application/agent.rb +12 -5
- data/lib/puppet/application/apply.rb +2 -1
- data/lib/puppet/application/device.rb +2 -1
- data/lib/puppet/application/resource.rb +2 -1
- data/lib/puppet/application/script.rb +2 -1
- data/lib/puppet/configurer/downloader.rb +2 -1
- data/lib/puppet/defaults.rb +5 -3
- data/lib/puppet/file_serving/fileset.rb +14 -2
- data/lib/puppet/functions/all.rb +1 -1
- data/lib/puppet/functions/camelcase.rb +1 -1
- data/lib/puppet/functions/capitalize.rb +2 -2
- data/lib/puppet/functions/downcase.rb +2 -2
- data/lib/puppet/functions/get.rb +5 -5
- data/lib/puppet/functions/group_by.rb +13 -5
- data/lib/puppet/functions/lest.rb +1 -1
- data/lib/puppet/functions/new.rb +100 -100
- data/lib/puppet/functions/partition.rb +4 -4
- data/lib/puppet/functions/require.rb +5 -5
- data/lib/puppet/functions/sort.rb +3 -3
- data/lib/puppet/functions/tree_each.rb +7 -9
- data/lib/puppet/functions/type.rb +4 -4
- data/lib/puppet/functions/upcase.rb +2 -2
- data/lib/puppet/http/resolver/server_list.rb +15 -4
- data/lib/puppet/http/service/compiler.rb +69 -0
- data/lib/puppet/http/service/file_server.rb +2 -1
- data/lib/puppet/indirector/catalog/compiler.rb +1 -0
- data/lib/puppet/indirector/file_metadata/rest.rb +1 -0
- data/lib/puppet/parser/functions/fqdn_rand.rb +14 -6
- data/lib/puppet/pops/types/p_sem_ver_type.rb +8 -2
- data/lib/puppet/pops/types/p_sensitive_type.rb +10 -0
- data/lib/puppet/provider/package/nim.rb +11 -6
- data/lib/puppet/provider/service/systemd.rb +13 -3
- data/lib/puppet/provider/service/windows.rb +38 -0
- data/lib/puppet/provider/user/directoryservice.rb +25 -12
- data/lib/puppet/reference/configuration.rb +1 -1
- data/lib/puppet/transaction/additional_resource_generator.rb +1 -1
- data/lib/puppet/type/file.rb +19 -1
- data/lib/puppet/type/file/selcontext.rb +1 -1
- data/lib/puppet/type/service.rb +18 -38
- data/lib/puppet/type/tidy.rb +21 -2
- data/lib/puppet/type/user.rb +38 -20
- data/lib/puppet/util/selinux.rb +30 -4
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +109 -101
- data/man/man5/puppet.conf.5 +272 -252
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +1 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/ssl/127.0.0.1-key.pem +107 -57
- data/spec/fixtures/ssl/127.0.0.1.pem +52 -31
- data/spec/fixtures/ssl/bad-basic-constraints.pem +57 -35
- data/spec/fixtures/ssl/bad-int-basic-constraints.pem +57 -35
- data/spec/fixtures/ssl/ca.pem +57 -35
- data/spec/fixtures/ssl/crl.pem +28 -18
- data/spec/fixtures/ssl/ec-key.pem +11 -11
- data/spec/fixtures/ssl/ec.pem +33 -24
- data/spec/fixtures/ssl/encrypted-ec-key.pem +12 -12
- data/spec/fixtures/ssl/encrypted-key.pem +108 -58
- data/spec/fixtures/ssl/intermediate-agent-crl.pem +28 -19
- data/spec/fixtures/ssl/intermediate-agent.pem +57 -36
- data/spec/fixtures/ssl/intermediate-crl.pem +31 -21
- data/spec/fixtures/ssl/intermediate.pem +57 -36
- data/spec/fixtures/ssl/pluto-key.pem +107 -57
- data/spec/fixtures/ssl/pluto.pem +52 -30
- data/spec/fixtures/ssl/request-key.pem +107 -57
- data/spec/fixtures/ssl/request.pem +47 -26
- data/spec/fixtures/ssl/revoked-key.pem +107 -57
- data/spec/fixtures/ssl/revoked.pem +52 -30
- data/spec/fixtures/ssl/signed-key.pem +107 -57
- data/spec/fixtures/ssl/signed.pem +52 -30
- data/spec/fixtures/ssl/tampered-cert.pem +52 -30
- data/spec/fixtures/ssl/tampered-csr.pem +47 -26
- data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +107 -57
- data/spec/fixtures/ssl/unknown-127.0.0.1.pem +50 -29
- data/spec/fixtures/ssl/unknown-ca-key.pem +107 -57
- data/spec/fixtures/ssl/unknown-ca.pem +55 -33
- data/spec/integration/application/resource_spec.rb +30 -0
- data/spec/lib/puppet/test_ca.rb +2 -2
- data/spec/unit/application/agent_spec.rb +7 -2
- data/spec/unit/configurer/downloader_spec.rb +6 -0
- data/spec/unit/configurer_spec.rb +23 -0
- data/spec/unit/file_serving/fileset_spec.rb +60 -0
- data/spec/unit/gettext/config_spec.rb +12 -0
- data/spec/unit/http/service/compiler_spec.rb +123 -0
- data/spec/unit/indirector/catalog/compiler_spec.rb +14 -10
- data/spec/unit/parser/functions/fqdn_rand_spec.rb +15 -1
- data/spec/unit/pops/types/p_sem_ver_type_spec.rb +18 -0
- data/spec/unit/pops/types/p_sensitive_type_spec.rb +18 -0
- data/spec/unit/provider/package/nim_spec.rb +42 -0
- data/spec/unit/provider/service/init_spec.rb +1 -0
- data/spec/unit/provider/service/openwrt_spec.rb +3 -1
- data/spec/unit/provider/service/systemd_spec.rb +42 -8
- data/spec/unit/provider/service/windows_spec.rb +202 -0
- data/spec/unit/provider/user/directoryservice_spec.rb +67 -35
- data/spec/unit/ssl/state_machine_spec.rb +19 -5
- data/spec/unit/transaction/additional_resource_generator_spec.rb +0 -2
- data/spec/unit/transaction_spec.rb +18 -20
- data/spec/unit/type/file/selinux_spec.rb +3 -3
- data/spec/unit/type/service_spec.rb +59 -188
- data/spec/unit/type/tidy_spec.rb +17 -7
- data/spec/unit/type/user_spec.rb +45 -0
- data/spec/unit/util/selinux_spec.rb +87 -16
- data/tasks/generate_cert_fixtures.rake +2 -2
- metadata +4 -2
@@ -128,17 +128,55 @@ Puppet::Type.type(:service).provide :windows, :parent => :service do
|
|
128
128
|
services
|
129
129
|
end
|
130
130
|
|
131
|
+
def logonaccount_insync?(current)
|
132
|
+
@normalized_logon_account ||= normalize_logonaccount
|
133
|
+
@resource[:logonaccount] = @normalized_logon_account
|
134
|
+
|
135
|
+
insync = @resource[:logonaccount] == current
|
136
|
+
self.logonpassword = @resource[:logonpassword] if insync
|
137
|
+
insync
|
138
|
+
end
|
139
|
+
|
131
140
|
def logonaccount
|
132
141
|
return unless Puppet::Util::Windows::Service.exists?(@resource[:name])
|
133
142
|
Puppet::Util::Windows::Service.logon_account(@resource[:name])
|
134
143
|
end
|
135
144
|
|
136
145
|
def logonaccount=(value)
|
146
|
+
validate_logon_credentials
|
137
147
|
Puppet::Util::Windows::Service.set_startup_configuration(@resource[:name], options: {logon_account: value, logon_password: @resource[:logonpassword]})
|
138
148
|
restart if @resource[:ensure] == :running && [:running, :paused].include?(status)
|
139
149
|
end
|
140
150
|
|
141
151
|
def logonpassword=(value)
|
152
|
+
validate_logon_credentials
|
142
153
|
Puppet::Util::Windows::Service.set_startup_configuration(@resource[:name], options: {logon_password: value})
|
143
154
|
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def normalize_logonaccount
|
159
|
+
logon_account = @resource[:logonaccount].sub(/^\.\\/, "#{Puppet::Util::Windows::ADSI.computer_name}\\")
|
160
|
+
return 'LocalSystem' if Puppet::Util::Windows::User::localsystem?(logon_account)
|
161
|
+
|
162
|
+
@logonaccount_information ||= Puppet::Util::Windows::SID.name_to_principal(logon_account)
|
163
|
+
return logon_account unless @logonaccount_information
|
164
|
+
return ".\\#{@logonaccount_information.account}" if @logonaccount_information.domain == Puppet::Util::Windows::ADSI.computer_name
|
165
|
+
@logonaccount_information.domain_account
|
166
|
+
end
|
167
|
+
|
168
|
+
def validate_logon_credentials
|
169
|
+
unless Puppet::Util::Windows::User::localsystem?(@normalized_logon_account)
|
170
|
+
raise Puppet::Error.new("\"#{@normalized_logon_account}\" is not a valid account") unless @logonaccount_information && [:SidTypeUser, :SidTypeWellKnownGroup].include?(@logonaccount_information.account_type)
|
171
|
+
|
172
|
+
user_rights = Puppet::Util::Windows::User::get_rights(@logonaccount_information.domain_account) unless Puppet::Util::Windows::User::default_system_account?(@normalized_logon_account)
|
173
|
+
raise Puppet::Error.new("\"#{@normalized_logon_account}\" has the 'Log On As A Service' right set to denied.") if user_rights =~ /SeDenyServiceLogonRight/
|
174
|
+
raise Puppet::Error.new("\"#{@normalized_logon_account}\" is missing the 'Log On As A Service' right.") unless user_rights.nil? || user_rights =~ /SeServiceLogonRight/
|
175
|
+
end
|
176
|
+
|
177
|
+
is_a_predefined_local_account = Puppet::Util::Windows::User::default_system_account?(@normalized_logon_account) || @normalized_logon_account == 'LocalSystem'
|
178
|
+
account_info = @normalized_logon_account.split("\\")
|
179
|
+
able_to_logon = Puppet::Util::Windows::User.password_is?(account_info[1], @resource[:logonpassword], account_info[0]) unless is_a_predefined_local_account
|
180
|
+
raise Puppet::Error.new("The given password is invalid for user '#{@normalized_logon_account}'.") unless is_a_predefined_local_account || able_to_logon
|
181
|
+
end
|
144
182
|
end
|
@@ -435,7 +435,7 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
435
435
|
['home', 'uid', 'gid', 'comment', 'shell'].each do |setter_method|
|
436
436
|
define_method("#{setter_method}=") do |value|
|
437
437
|
if @property_hash[setter_method.intern]
|
438
|
-
if
|
438
|
+
if %w(home uid).include?(setter_method)
|
439
439
|
raise Puppet::Error, "OS X version #{self.class.get_os_version} does not allow changing #{setter_method} using puppet"
|
440
440
|
end
|
441
441
|
begin
|
@@ -536,6 +536,14 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
536
536
|
if (shadow_hash_data.class == Hash) && (shadow_hash_data.has_key?('SALTED-SHA512'))
|
537
537
|
shadow_hash_data.delete('SALTED-SHA512')
|
538
538
|
end
|
539
|
+
|
540
|
+
# Starting with macOS 11 Big Sur, the AuthenticationAuthority field
|
541
|
+
# could be missing entirely and without it the managed user cannot log in
|
542
|
+
if needs_sha512_pbkdf2_authentication_authority_to_be_added?(users_plist)
|
543
|
+
Puppet.debug("Adding 'SALTED-SHA512-PBKDF2' AuthenticationAuthority key for ShadowHash to user '#{@resource.name}'")
|
544
|
+
merge_attribute_with_dscl('Users', @resource.name, 'AuthenticationAuthority', ERB::Util.html_escape(SHA512_PBKDF2_AUTHENTICATION_AUTHORITY))
|
545
|
+
end
|
546
|
+
|
539
547
|
set_salted_pbkdf2(users_plist, shadow_hash_data, 'entropy', value)
|
540
548
|
end
|
541
549
|
end
|
@@ -562,6 +570,17 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
562
570
|
end
|
563
571
|
end
|
564
572
|
|
573
|
+
# This method will check if authentication_authority key of a user's plist
|
574
|
+
# needs SALTED_SHA512_PBKDF2 to be added. This is a valid case for macOS 11 (Big Sur)
|
575
|
+
# where users created with `dscl` started to have this field missing
|
576
|
+
def needs_sha512_pbkdf2_authentication_authority_to_be_added?(users_plist)
|
577
|
+
authority = users_plist['authentication_authority']
|
578
|
+
return false if Puppet::Util::Package.versioncmp(self.class.get_os_version, '11.0.0') < 0 && authority && authority.include?(SHA512_PBKDF2_AUTHENTICATION_AUTHORITY)
|
579
|
+
|
580
|
+
Puppet.debug("User '#{@resource.name}' is missing the 'SALTED-SHA512-PBKDF2' AuthenticationAuthority key for ShadowHash")
|
581
|
+
true
|
582
|
+
end
|
583
|
+
|
565
584
|
# This method will embed the binary plist data comprising the user's
|
566
585
|
# password hash (and Salt/Iterations value if the OS is 10.8 or greater)
|
567
586
|
# into the ShadowHashData key of the user's plist.
|
@@ -572,11 +591,7 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
572
591
|
else
|
573
592
|
users_plist['ShadowHashData'] = [binary_plist]
|
574
593
|
end
|
575
|
-
|
576
|
-
write_users_plist_to_disk(users_plist)
|
577
|
-
else
|
578
|
-
write_and_import_shadow_hash_data(users_plist['ShadowHashData'].first)
|
579
|
-
end
|
594
|
+
write_and_import_shadow_hash_data(users_plist['ShadowHashData'].first)
|
580
595
|
end
|
581
596
|
|
582
597
|
# This method writes the ShadowHashData plist in a temporary file,
|
@@ -652,12 +667,6 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
652
667
|
set_shadow_hash_data(users_plist, binary_plist)
|
653
668
|
end
|
654
669
|
|
655
|
-
# This method will accept a plist in XML format, save it to disk, convert
|
656
|
-
# the plist to a binary format, and flush the dscl cache.
|
657
|
-
def write_users_plist_to_disk(users_plist)
|
658
|
-
Puppet::Util::Plist.write_plist_file(users_plist, "#{users_plist_dir}/#{@resource.name}.plist", :binary)
|
659
|
-
end
|
660
|
-
|
661
670
|
# This is a simple wrapper method for writing values to a file.
|
662
671
|
def write_to_file(filename, value)
|
663
672
|
Puppet.deprecation_warning("Puppet::Type.type(:user).provider(:directoryservice).write_to_file is deprecated and will be removed in Puppet 5.")
|
@@ -667,4 +676,8 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
667
676
|
raise Puppet::Error, "Could not write to file #{filename}: #{detail}", detail.backtrace
|
668
677
|
end
|
669
678
|
end
|
679
|
+
|
680
|
+
private
|
681
|
+
|
682
|
+
SHA512_PBKDF2_AUTHENTICATION_AUTHORITY = ';ShadowHash;HASHLIST:<SALTED-SHA512-PBKDF2,SRP-RFC5054-4096-SHA512-PBKDF2>'
|
670
683
|
end
|
@@ -41,7 +41,7 @@ config = Puppet::Util::Reference.newreference(:configuration, :depth => 1, :doc
|
|
41
41
|
# Leave out the section information; it was apparently confusing people.
|
42
42
|
#str << "- **Section**: #{object.section}\n"
|
43
43
|
unless val == ""
|
44
|
-
str << "- *Default*:
|
44
|
+
str << "- *Default*: `#{val}`\n"
|
45
45
|
end
|
46
46
|
str << "\n"
|
47
47
|
end
|
@@ -137,7 +137,7 @@ class Puppet::Transaction::AdditionalResourceGenerator
|
|
137
137
|
else
|
138
138
|
@catalog.add_resource_after(parent_resource, res)
|
139
139
|
end
|
140
|
-
@catalog.add_edge(@catalog.container_of(parent_resource), res)
|
140
|
+
@catalog.add_edge(@catalog.container_of(parent_resource), res) if @catalog.container_of(parent_resource)
|
141
141
|
if @relationship_graph && priority
|
142
142
|
# If we have a relationship_graph we should add the resource
|
143
143
|
# to it (this is an eval_generate). If we don't, then the
|
data/lib/puppet/type/file.rb
CHANGED
@@ -220,6 +220,23 @@ Puppet::Type.newtype(:file) do
|
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
223
|
+
newparam(:max_files) do
|
224
|
+
desc "In case the resource is a directory and the recursion is enabled, puppet will
|
225
|
+
generate a new resource for each file file found, possible leading to
|
226
|
+
an excessive number of resources generated without any control.
|
227
|
+
|
228
|
+
Setting `max_files` will check the number of file resources that
|
229
|
+
will eventually be created and will raise a resource argument error if the
|
230
|
+
limit will be exceeded.
|
231
|
+
|
232
|
+
Use value `0` to log a warning instead of raising an error.
|
233
|
+
|
234
|
+
Use value `-1` to disable errors and warnings due to max files."
|
235
|
+
|
236
|
+
defaultto 0
|
237
|
+
newvalues(/^[0-9]+$/, /^-1$/)
|
238
|
+
end
|
239
|
+
|
223
240
|
newparam(:replace, :boolean => true, :parent => Puppet::Parameter::Boolean) do
|
224
241
|
desc "Whether to replace a file or symlink that already exists on the local system but
|
225
242
|
whose content doesn't match what the `source` or `content` attribute
|
@@ -576,7 +593,7 @@ Puppet::Type.newtype(:file) do
|
|
576
593
|
options = @original_parameters.merge(:path => full_path).reject { |param, value| value.nil? }
|
577
594
|
|
578
595
|
# These should never be passed to our children.
|
579
|
-
[:parent, :ensure, :recurse, :recurselimit, :target, :alias, :source].each do |param|
|
596
|
+
[:parent, :ensure, :recurse, :recurselimit, :max_files, :target, :alias, :source].each do |param|
|
580
597
|
options.delete(param) if options.include?(param)
|
581
598
|
end
|
582
599
|
|
@@ -753,6 +770,7 @@ Puppet::Type.newtype(:file) do
|
|
753
770
|
:links => self[:links],
|
754
771
|
:recurse => (self[:recurse] == :remote ? true : self[:recurse]),
|
755
772
|
:recurselimit => self[:recurselimit],
|
773
|
+
:max_files => self[:max_files],
|
756
774
|
:source_permissions => self[:source_permissions],
|
757
775
|
:ignore => self[:ignore],
|
758
776
|
:checksum_type => (self[:source] || self[:content]) ? self[:checksum] : :none,
|
data/lib/puppet/type/service.rb
CHANGED
@@ -38,6 +38,12 @@ module Puppet
|
|
38
38
|
feature :enableable, "The provider can enable and disable the service.",
|
39
39
|
:methods => [:disable, :enable, :enabled?]
|
40
40
|
|
41
|
+
feature :delayed_startable, "The provider can set service to delayed start",
|
42
|
+
:methods => [:delayed_start]
|
43
|
+
|
44
|
+
feature :manual_startable, "The provider can set service to manual start",
|
45
|
+
:methods => [:manual_start]
|
46
|
+
|
41
47
|
feature :controllable, "The provider uses a control variable."
|
42
48
|
|
43
49
|
feature :flaggable, "The provider can pass flags to the service."
|
@@ -67,7 +73,7 @@ module Puppet
|
|
67
73
|
provider.disable
|
68
74
|
end
|
69
75
|
|
70
|
-
newvalue(:manual, :event => :service_manual_start) do
|
76
|
+
newvalue(:manual, :event => :service_manual_start, :required_features => :manual_startable) do
|
71
77
|
provider.manual_start
|
72
78
|
end
|
73
79
|
|
@@ -81,8 +87,7 @@ module Puppet
|
|
81
87
|
provider.enabled?
|
82
88
|
end
|
83
89
|
|
84
|
-
|
85
|
-
newvalue(:delayed, :event => :service_delayed_start) do
|
90
|
+
newvalue(:delayed, :event => :service_delayed_start, :required_features => :delayed_startable) do
|
86
91
|
provider.delayed_start
|
87
92
|
end
|
88
93
|
|
@@ -90,12 +95,6 @@ module Puppet
|
|
90
95
|
return provider.enabled_insync?(current) if provider.respond_to?(:enabled_insync?)
|
91
96
|
super(current)
|
92
97
|
end
|
93
|
-
|
94
|
-
validate do |value|
|
95
|
-
if (value == :manual || value == :delayed) && !Puppet::Util::Platform.windows?
|
96
|
-
raise Puppet::Error.new(_("Setting enable to %{value} is only supported on Microsoft Windows.") % { value: value.to_s} )
|
97
|
-
end
|
98
|
-
end
|
99
98
|
end
|
100
99
|
|
101
100
|
# Handle whether the service should actually be running right now.
|
@@ -139,23 +138,9 @@ module Puppet
|
|
139
138
|
newproperty(:logonaccount, :required_features => :manages_logon_credentials) do
|
140
139
|
desc "Specify an account for service logon"
|
141
140
|
|
142
|
-
|
143
|
-
return
|
144
|
-
|
145
|
-
|
146
|
-
value.sub!(/^\.\\/, "#{Puppet::Util::Windows::ADSI.computer_name}\\")
|
147
|
-
user_information = Puppet::Util::Windows::SID.name_to_principal(value)
|
148
|
-
raise Puppet::Error.new("\"#{value}\" is not a valid account") unless user_information && [:SidTypeUser, :SidTypeWellKnownGroup].include?(user_information.account_type)
|
149
|
-
|
150
|
-
user_rights = Puppet::Util::Windows::User::get_rights(user_information.domain_account) unless Puppet::Util::Windows::User::default_system_account?(value)
|
151
|
-
raise Puppet::Error.new("\"#{user_information.domain_account}\" has the 'Log On As A Service' right set to denied.") if user_rights =~ /SeDenyServiceLogonRight/
|
152
|
-
raise Puppet::Error.new("\"#{user_information.domain_account}\" is missing the 'Log On As A Service' right.") unless user_rights.nil? || user_rights =~ /SeServiceLogonRight/
|
153
|
-
|
154
|
-
if user_information.domain == Puppet::Util::Windows::ADSI.computer_name
|
155
|
-
".\\#{user_information.account}"
|
156
|
-
else
|
157
|
-
user_information.domain_account
|
158
|
-
end
|
141
|
+
def insync?(current)
|
142
|
+
return provider.logonaccount_insync?(current) if provider.respond_to?(:logonaccount_insync?)
|
143
|
+
super(current)
|
159
144
|
end
|
160
145
|
end
|
161
146
|
|
@@ -163,18 +148,7 @@ module Puppet
|
|
163
148
|
desc "Specify a password for service logon. Default value is an empty string (when logonaccount is specified)."
|
164
149
|
|
165
150
|
validate do |value|
|
166
|
-
raise
|
167
|
-
raise ArgumentError, _("Passwords cannot include ':'") if value.is_a?(String) and value.include?(":")
|
168
|
-
return unless Puppet::Util::Platform.windows?
|
169
|
-
|
170
|
-
is_a_predefined_local_account = Puppet::Util::Windows::User::default_system_account?(@resource[:logonaccount]) || @resource[:logonaccount] == 'LocalSystem'
|
171
|
-
|
172
|
-
account_info = @resource[:logonaccount].split("\\")
|
173
|
-
able_to_logon = Puppet::Util::Windows::User.password_is?(account_info[1], value, account_info[0]) unless is_a_predefined_local_account
|
174
|
-
|
175
|
-
raise Puppet::Error.new("The given password is invalid for user '#{@resource[:logonaccount]}'.") unless is_a_predefined_local_account || able_to_logon
|
176
|
-
|
177
|
-
provider.logonpassword=(value)
|
151
|
+
raise ArgumentError, _("Passwords cannot include ':'") if value.is_a?(String) && value.include?(":")
|
178
152
|
end
|
179
153
|
|
180
154
|
sensitive true
|
@@ -320,5 +294,11 @@ module Puppet
|
|
320
294
|
def self.needs_ensure_retrieved
|
321
295
|
false
|
322
296
|
end
|
297
|
+
|
298
|
+
validate do
|
299
|
+
if @parameters[:logonpassword] && @parameters[:logonaccount].nil?
|
300
|
+
raise Puppet::Error.new(_"The 'logonaccount' parameter is mandatory when setting 'logonpassword'.")
|
301
|
+
end
|
302
|
+
end
|
323
303
|
end
|
324
304
|
end
|
data/lib/puppet/type/tidy.rb
CHANGED
@@ -50,6 +50,22 @@ Puppet::Type.newtype(:tidy) do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
newparam(:max_files) do
|
54
|
+
desc "In case the resource is a directory and the recursion is enabled, puppet will
|
55
|
+
generate a new resource for each file file found, possible leading to
|
56
|
+
an excessive number of resources generated without any control.
|
57
|
+
|
58
|
+
Setting `max_files` will check the number of file resources that
|
59
|
+
will eventually be created and will raise a resource argument error if the
|
60
|
+
limit will be exceeded.
|
61
|
+
|
62
|
+
Use value `0` to disable the check. In this case, a warning is logged if
|
63
|
+
the number of files exceeds 1000."
|
64
|
+
|
65
|
+
defaultto 0
|
66
|
+
newvalues(/^[0-9]+$/)
|
67
|
+
end
|
68
|
+
|
53
69
|
newparam(:matches) do
|
54
70
|
desc <<-'EOT'
|
55
71
|
One or more (shell type) file glob patterns, which restrict
|
@@ -256,9 +272,12 @@ Puppet::Type.newtype(:tidy) do
|
|
256
272
|
|
257
273
|
case self[:recurse]
|
258
274
|
when Integer, /^\d+$/
|
259
|
-
parameter = { :
|
275
|
+
parameter = { :max_files => self[:max_files],
|
276
|
+
:recurse => true,
|
277
|
+
:recurselimit => self[:recurse] }
|
260
278
|
when true, :true, :inf
|
261
|
-
parameter = { :
|
279
|
+
parameter = { :max_files => self[:max_files],
|
280
|
+
:recurse => true }
|
262
281
|
end
|
263
282
|
|
264
283
|
if parameter
|
data/lib/puppet/type/user.rb
CHANGED
@@ -67,6 +67,7 @@ module Puppet
|
|
67
67
|
newproperty(:ensure, :parent => Puppet::Property::Ensure) do
|
68
68
|
newvalue(:present, :event => :user_created) do
|
69
69
|
provider.create
|
70
|
+
@resource.generate
|
70
71
|
end
|
71
72
|
|
72
73
|
newvalue(:absent, :event => :user_removed) do
|
@@ -695,6 +696,7 @@ module Puppet
|
|
695
696
|
|
696
697
|
def generate
|
697
698
|
if !self[:purge_ssh_keys].empty?
|
699
|
+
return [] if self[:ensure] == :present && !provider.exists?
|
698
700
|
if Puppet::Type.type(:ssh_authorized_key).nil?
|
699
701
|
warning _("Ssh_authorized_key type is not available. Cannot purge SSH keys.")
|
700
702
|
else
|
@@ -743,25 +745,6 @@ module Puppet
|
|
743
745
|
end
|
744
746
|
raise ArgumentError, _("purge_ssh_keys must be true, false, or an array of file names, not %{value}") % { value: value.inspect }
|
745
747
|
end
|
746
|
-
|
747
|
-
munge do |value|
|
748
|
-
# Resolve string, boolean and symbol forms of true and false to a
|
749
|
-
# single representation.
|
750
|
-
test_sym = value.to_s.intern
|
751
|
-
value = test_sym if [:true, :false].include? test_sym
|
752
|
-
|
753
|
-
return [] if value == :false
|
754
|
-
home = resource[:home] || Dir.home(resource[:name])
|
755
|
-
|
756
|
-
return [ "#{home}/.ssh/authorized_keys" ] if value == :true
|
757
|
-
# value is an array - munge each value
|
758
|
-
[ value ].flatten.map do |entry|
|
759
|
-
# make sure frozen value is duplicated by using a gsub, second mutating gsub! is then ok
|
760
|
-
entry = entry.gsub(/^~\//, "#{home}/")
|
761
|
-
entry.gsub!(/^%h\//, "#{home}/")
|
762
|
-
entry
|
763
|
-
end
|
764
|
-
end
|
765
748
|
end
|
766
749
|
|
767
750
|
newproperty(:loginclass, :required_features => :manages_loginclass) do
|
@@ -783,7 +766,7 @@ module Puppet
|
|
783
766
|
# @see generate
|
784
767
|
# @api private
|
785
768
|
def find_unmanaged_keys
|
786
|
-
|
769
|
+
munged_unmanaged_keys.
|
787
770
|
select { |f| File.readable?(f) }.
|
788
771
|
map { |f| unknown_keys_in_file(f) }.
|
789
772
|
flatten.each do |res|
|
@@ -795,6 +778,41 @@ module Puppet
|
|
795
778
|
end
|
796
779
|
end
|
797
780
|
|
781
|
+
def munged_unmanaged_keys
|
782
|
+
value = self[:purge_ssh_keys]
|
783
|
+
|
784
|
+
# Resolve string, boolean and symbol forms of true and false to a
|
785
|
+
# single representation.
|
786
|
+
test_sym = value.to_s.intern
|
787
|
+
value = test_sym if [:true, :false].include? test_sym
|
788
|
+
|
789
|
+
return [] if value == :false
|
790
|
+
|
791
|
+
home = self[:home]
|
792
|
+
begin
|
793
|
+
home ||= provider.home
|
794
|
+
rescue
|
795
|
+
Puppet.debug("User '#{self[:name]}' does not exist")
|
796
|
+
end
|
797
|
+
|
798
|
+
if home.to_s.empty? || !Dir.exist?(home.to_s)
|
799
|
+
if value == :true || [ value ].flatten.any? { |v| v.start_with?('~/', '%h/') }
|
800
|
+
Puppet.debug("User '#{self[:name]}' has no home directory set to purge ssh keys from.")
|
801
|
+
return []
|
802
|
+
end
|
803
|
+
end
|
804
|
+
|
805
|
+
return [ "#{home}/.ssh/authorized_keys" ] if value == :true
|
806
|
+
|
807
|
+
# value is an array - munge each value
|
808
|
+
[ value ].flatten.map do |entry|
|
809
|
+
# make sure frozen value is duplicated by using a gsub, second mutating gsub! is then ok
|
810
|
+
entry = entry.gsub(/^~\//, "#{home}/")
|
811
|
+
entry.gsub!(/^%h\//, "#{home}/")
|
812
|
+
entry
|
813
|
+
end
|
814
|
+
end
|
815
|
+
|
798
816
|
# Parse an ssh authorized keys file superficially, extract the comments
|
799
817
|
# on the keys. These are considered names of possible ssh_authorized_keys
|
800
818
|
# resources. Keys that are managed by the present catalog are ignored.
|
data/lib/puppet/util/selinux.rb
CHANGED
@@ -13,6 +13,10 @@ require 'pathname'
|
|
13
13
|
|
14
14
|
module Puppet::Util::SELinux
|
15
15
|
|
16
|
+
S_IFREG = 0100000
|
17
|
+
S_IFDIR = 0040000
|
18
|
+
S_IFLNK = 0120000
|
19
|
+
|
16
20
|
def self.selinux_support?
|
17
21
|
return false unless defined?(Selinux)
|
18
22
|
if Selinux.is_selinux_enabled == 1
|
@@ -38,7 +42,7 @@ module Puppet::Util::SELinux
|
|
38
42
|
|
39
43
|
# Retrieve and return the default context of the file. If we don't have
|
40
44
|
# SELinux support or if the SELinux call fails to file a default then return nil.
|
41
|
-
def get_selinux_default_context(file)
|
45
|
+
def get_selinux_default_context(file, resource_ensure=nil)
|
42
46
|
return nil unless selinux_support?
|
43
47
|
# If the filesystem has no support for SELinux labels, return a default of nil
|
44
48
|
# instead of what matchpathcon would return
|
@@ -48,8 +52,14 @@ module Puppet::Util::SELinux
|
|
48
52
|
begin
|
49
53
|
filestat = file_lstat(file)
|
50
54
|
mode = filestat.mode
|
51
|
-
rescue Errno::EACCES
|
55
|
+
rescue Errno::EACCES
|
52
56
|
mode = 0
|
57
|
+
rescue Errno::ENOENT
|
58
|
+
if resource_ensure
|
59
|
+
mode = get_create_mode(resource_ensure)
|
60
|
+
else
|
61
|
+
mode = 0
|
62
|
+
end
|
53
63
|
end
|
54
64
|
|
55
65
|
retval = Selinux.matchpathcon(file, mode)
|
@@ -136,8 +146,8 @@ module Puppet::Util::SELinux
|
|
136
146
|
# Puppet uses. This will set the file's SELinux context to the policy's
|
137
147
|
# default context (if any) if it differs from the context currently on
|
138
148
|
# the file.
|
139
|
-
def set_selinux_default_context(file)
|
140
|
-
new_context = get_selinux_default_context(file)
|
149
|
+
def set_selinux_default_context(file, resource_ensure=nil)
|
150
|
+
new_context = get_selinux_default_context(file, resource_ensure)
|
141
151
|
return nil unless new_context
|
142
152
|
cur_context = get_selinux_current_context(file)
|
143
153
|
if new_context != cur_context
|
@@ -198,6 +208,22 @@ module Puppet::Util::SELinux
|
|
198
208
|
filesystems.include?(fstype)
|
199
209
|
end
|
200
210
|
|
211
|
+
# Get mode file type bits set based on ensure on
|
212
|
+
# the file resource. This helps SELinux determine
|
213
|
+
# what context a new resource being created should have.
|
214
|
+
def get_create_mode(resource_ensure)
|
215
|
+
mode = 0
|
216
|
+
case resource_ensure
|
217
|
+
when :present, :file
|
218
|
+
mode |= S_IFREG
|
219
|
+
when :directory
|
220
|
+
mode |= S_IFDIR
|
221
|
+
when :link
|
222
|
+
mode |= S_IFLNK
|
223
|
+
end
|
224
|
+
mode
|
225
|
+
end
|
226
|
+
|
201
227
|
# Internal helper function to read and parse /proc/mounts
|
202
228
|
def read_mounts
|
203
229
|
mounts = ""
|