puppet 6.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/Gemfile.lock +20 -20
- data/Guardfile.example +76 -0
- data/LICENSE +189 -4
- data/README.md +3 -3
- data/Rakefile +5 -2
- data/ext/solaris/smf/svc-puppetd +8 -1
- data/ext/solaris/smf/svc-puppetmasterd +8 -1
- data/lib/puppet/application/apply.rb +100 -59
- data/lib/puppet/application/cert.rb +4 -114
- data/lib/puppet/application/device.rb +48 -32
- data/lib/puppet/application/script.rb +1 -1
- data/lib/puppet/application/ssl.rb +135 -51
- data/lib/puppet/application.rb +5 -0
- data/lib/puppet/configurer.rb +2 -3
- data/lib/puppet/defaults.rb +33 -49
- data/lib/puppet/etc.rb +20 -0
- data/lib/puppet/face/config.rb +3 -3
- data/lib/puppet/face/key.rb +1 -1
- data/lib/puppet/face/node/clean.rb +0 -1
- data/lib/puppet/feature/base.rb +1 -1
- data/lib/puppet/file_bucket/dipper.rb +1 -1
- data/lib/puppet/file_serving/fileset.rb +1 -1
- data/lib/puppet/functions/abs.rb +1 -1
- data/lib/puppet/functions/new.rb +1 -1
- data/lib/puppet/module/task.rb +29 -38
- data/lib/puppet/pal/catalog_compiler.rb +96 -0
- data/lib/puppet/pal/compiler.rb +221 -0
- data/lib/puppet/pal/function_signature.rb +52 -0
- data/lib/puppet/pal/json_catalog_encoder.rb +67 -0
- data/lib/puppet/pal/pal_api.rb +15 -0
- data/lib/puppet/pal/pal_impl.rb +523 -0
- data/lib/puppet/pal/plan_signature.rb +71 -0
- data/lib/puppet/pal/script_compiler.rb +71 -0
- data/lib/puppet/pal/task_signature.rb +58 -0
- data/lib/puppet/parser/catalog_compiler.rb +24 -0
- data/lib/puppet/parser/compiler.rb +3 -1
- data/lib/puppet/parser/functions/generate.rb +7 -6
- data/lib/puppet/plugins/configuration.rb +5 -1
- data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +3 -1
- data/lib/puppet/pops/evaluator/deferred_resolver.rb +3 -0
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -1
- data/lib/puppet/pops/evaluator/external_syntax_support.rb +3 -3
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
- data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +19 -10
- data/lib/puppet/pops/loader/task_instantiator.rb +13 -70
- data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
- data/lib/puppet/pops/parser/lexer2.rb +1 -1
- data/lib/puppet/pops/pcore.rb +10 -33
- data/lib/puppet/pops/serialization/to_data_converter.rb +9 -1
- data/lib/puppet/pops/serialization.rb +1 -0
- data/lib/puppet/pops/types/p_timespan_type.rb +2 -2
- data/lib/puppet/pops/types/string_converter.rb +18 -4
- data/lib/puppet/pops/validation/checker4_0.rb +17 -2
- data/lib/puppet/provider/exec.rb +59 -57
- data/lib/puppet/provider/group/aix.rb +18 -2
- data/lib/puppet/provider/group/windows_adsi.rb +7 -3
- data/lib/puppet/provider/nameservice.rb +1 -25
- data/lib/puppet/provider/package/dnf.rb +2 -0
- data/lib/puppet/provider/package/pkgng.rb +37 -21
- data/lib/puppet/provider/package/portage.rb +2 -2
- data/lib/puppet/provider/package/windows/exe_package.rb +16 -10
- data/lib/puppet/provider/package/windows/msi_package.rb +8 -0
- data/lib/puppet/provider/package/windows/package.rb +9 -1
- data/lib/puppet/provider/package/windows.rb +2 -2
- data/lib/puppet/provider/package/yum.rb +1 -1
- data/lib/puppet/provider/parsedfile.rb +25 -4
- data/lib/puppet/provider/service/launchd.rb +19 -3
- data/lib/puppet/provider/service/smf.rb +54 -0
- data/lib/puppet/provider/service/systemd.rb +19 -0
- data/lib/puppet/provider/service/upstart.rb +1 -0
- data/lib/puppet/provider/service/windows.rb +22 -5
- data/lib/puppet/provider/user/aix.rb +48 -2
- data/lib/puppet/provider/user/useradd.rb +2 -10
- data/lib/puppet/provider/user/windows_adsi.rb +9 -1
- data/lib/puppet/resource/catalog.rb +1 -5
- data/lib/puppet/resource.rb +3 -1
- data/lib/puppet/ssl/host.rb +26 -16
- data/lib/puppet/syntax_checkers/epp.rb +34 -0
- data/lib/puppet/syntax_checkers/pp.rb +34 -0
- data/lib/puppet/transaction/event_manager.rb +13 -1
- data/lib/puppet/transaction/persistence.rb +1 -1
- data/lib/puppet/transaction/resource_harness.rb +3 -1
- data/lib/puppet/type/group.rb +29 -1
- data/lib/puppet/type/package.rb +5 -1
- data/lib/puppet/type/resources.rb +12 -2
- data/lib/puppet/type/schedule.rb +7 -0
- data/lib/puppet/type/service.rb +12 -0
- data/lib/puppet/type/user.rb +5 -2
- data/lib/puppet/type.rb +6 -0
- data/lib/puppet/util/command_line.rb +2 -3
- data/lib/puppet/util/execution.rb +15 -1
- data/lib/puppet/util/filetype.rb +56 -8
- data/lib/puppet/util/log/destinations.rb +3 -2
- data/lib/puppet/util/logging.rb +3 -2
- data/lib/puppet/util/posix.rb +15 -0
- data/lib/puppet/util/selinux.rb +1 -1
- data/lib/puppet/util/storage.rb +12 -0
- data/lib/puppet/util/windows/adsi.rb +79 -2
- data/lib/puppet/util/windows/api_types.rb +1 -1
- data/lib/puppet/util/windows/process.rb +23 -3
- data/lib/puppet/util/windows/registry.rb +29 -5
- data/lib/puppet/util/windows/security.rb +14 -0
- data/lib/puppet/util/windows/service.rb +294 -74
- data/lib/puppet/util/windows/user.rb +3 -5
- data/lib/puppet/util.rb +7 -3
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet.rb +1 -0
- data/lib/puppet_pal.rb +5 -1099
- data/locales/ja/puppet.po +952 -986
- data/locales/puppet.pot +592 -347
- data/man/man5/puppet.conf.5 +26 -31
- 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 +4 -4
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +23 -19
- 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 +2 -2
- 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 +26 -3
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/bad_func_load.rb +11 -0
- data/spec/fixtures/unit/provider/package/pkgng/pkg.query +7 -1
- data/spec/fixtures/unit/provider/package/pkgng/pkg.query.zsh +1 -0
- data/spec/fixtures/unit/provider/service/smf/svcs_fmri.out +6 -0
- data/spec/fixtures/unit/provider/service/smf/svcs_multiple_fmris.out +13 -0
- data/spec/integration/application/apply_spec.rb +4 -1
- data/spec/integration/parser/collection_spec.rb +4 -8
- data/spec/integration/provider/service/windows_spec.rb +5 -5
- data/spec/integration/ssl/key_spec.rb +0 -4
- data/spec/integration/transaction_spec.rb +559 -0
- data/spec/integration/type/file_spec.rb +6 -6
- data/spec/integration/util/windows/registry_spec.rb +39 -0
- data/spec/integration/util/windows/security_spec.rb +10 -7
- data/spec/integration/util/windows/user_spec.rb +37 -17
- data/spec/lib/puppet/test_ca.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/agent_spec.rb +2 -2
- data/spec/unit/application/apply_spec.rb +55 -2
- data/spec/unit/application/device_spec.rb +10 -7
- data/spec/unit/application/face_base_spec.rb +1 -1
- data/spec/unit/application/lookup_spec.rb +2 -1
- data/spec/unit/application/ssl_spec.rb +178 -109
- data/spec/unit/application_spec.rb +29 -11
- data/spec/unit/configurer/downloader_spec.rb +1 -1
- data/spec/unit/configurer_spec.rb +16 -5
- data/spec/unit/etc_spec.rb +25 -0
- data/spec/unit/face/node_spec.rb +1 -3
- data/spec/unit/face/parser_spec.rb +15 -0
- data/spec/unit/file_serving/fileset_spec.rb +11 -11
- data/spec/unit/functions/logging_spec.rb +10 -3
- data/spec/unit/indirector/catalog/json_spec.rb +9 -3
- data/spec/unit/indirector/yaml_spec.rb +1 -1
- data/spec/unit/network/http/connection_spec.rb +2 -2
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +36 -0
- data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +22 -4
- data/spec/unit/pops/loaders/loader_spec.rb +9 -17
- data/spec/unit/pops/loaders/loaders_spec.rb +48 -0
- data/spec/unit/pops/loaders/module_loaders_spec.rb +7 -7
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +16 -0
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +9 -0
- data/spec/unit/pops/types/p_timespan_type_spec.rb +22 -0
- data/spec/unit/pops/types/p_timestamp_type_spec.rb +19 -0
- data/spec/unit/pops/types/string_converter_spec.rb +25 -1
- data/spec/unit/pops/types/task_spec.rb +42 -116
- data/spec/unit/pops/validator/validator_spec.rb +24 -10
- data/spec/unit/provider/exec/posix_spec.rb +24 -0
- data/spec/unit/provider/group/aix_spec.rb +20 -6
- data/spec/unit/provider/group/ldap_spec.rb +22 -25
- data/spec/unit/provider/group/pw_spec.rb +7 -10
- data/spec/unit/provider/group/windows_adsi_spec.rb +42 -33
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +97 -103
- data/spec/unit/provider/package/aix_spec.rb +5 -8
- data/spec/unit/provider/package/apt_spec.rb +3 -6
- data/spec/unit/provider/package/dnf_spec.rb +38 -25
- data/spec/unit/provider/package/dpkg_spec.rb +18 -21
- data/spec/unit/provider/package/freebsd_spec.rb +4 -7
- data/spec/unit/provider/package/gem_spec.rb +41 -41
- data/spec/unit/provider/package/hpux_spec.rb +7 -10
- data/spec/unit/provider/package/macports_spec.rb +13 -15
- data/spec/unit/provider/package/nim_spec.rb +3 -10
- data/spec/unit/provider/package/openbsd_spec.rb +14 -17
- data/spec/unit/provider/package/pip3_spec.rb +3 -6
- data/spec/unit/provider/package/pip_spec.rb +45 -49
- data/spec/unit/provider/package/pkgin_spec.rb +13 -18
- data/spec/unit/provider/package/pkgng_spec.rb +32 -27
- data/spec/unit/provider/package/puppet_gem_spec.rb +6 -9
- data/spec/unit/provider/package/tdnf_spec.rb +9 -12
- data/spec/unit/provider/package/windows/exe_package_spec.rb +3 -3
- data/spec/unit/provider/package/windows_spec.rb +4 -4
- data/spec/unit/provider/package/yum_spec.rb +30 -16
- data/spec/unit/provider/package/zypper_spec.rb +17 -19
- data/spec/unit/provider/service/bsd_spec.rb +7 -9
- data/spec/unit/provider/service/daemontools_spec.rb +12 -16
- data/spec/unit/provider/service/debian_spec.rb +6 -10
- data/spec/unit/provider/service/freebsd_spec.rb +2 -2
- data/spec/unit/provider/service/launchd_spec.rb +19 -0
- data/spec/unit/provider/service/openbsd_spec.rb +13 -17
- data/spec/unit/provider/service/rcng_spec.rb +2 -4
- data/spec/unit/provider/service/redhat_spec.rb +12 -11
- data/spec/unit/provider/service/runit_spec.rb +7 -14
- data/spec/unit/provider/service/smf_spec.rb +77 -13
- data/spec/unit/provider/service/src_spec.rb +11 -16
- data/spec/unit/provider/service/systemd_spec.rb +39 -1
- data/spec/unit/provider/service/windows_spec.rb +39 -7
- data/spec/unit/provider/user/aix_spec.rb +43 -2
- data/spec/unit/provider/user/hpux_spec.rb +3 -5
- data/spec/unit/provider/user/ldap_spec.rb +29 -32
- data/spec/unit/provider/user/pw_spec.rb +10 -13
- data/spec/unit/provider/user/useradd_spec.rb +2 -2
- data/spec/unit/provider/user/windows_adsi_spec.rb +4 -4
- data/spec/unit/puppet_pal_2pec.rb +6 -6
- data/spec/unit/puppet_pal_catalog_spec.rb +58 -0
- data/spec/unit/resource/catalog_spec.rb +2 -2
- data/spec/unit/resource_spec.rb +31 -0
- data/spec/unit/ssl/host_spec.rb +22 -1
- data/spec/unit/ssl/key_spec.rb +2 -4
- data/spec/unit/task_spec.rb +50 -5
- data/spec/unit/transaction/event_manager_spec.rb +12 -1
- data/spec/unit/transaction/persistence_spec.rb +4 -4
- data/spec/unit/transaction/resource_harness_spec.rb +18 -0
- data/spec/unit/type/group_spec.rb +11 -3
- data/spec/unit/type/resources_spec.rb +18 -0
- data/spec/unit/type/service_spec.rb +27 -1
- data/spec/unit/util/execution_spec.rb +77 -0
- data/spec/unit/util/filetype_spec.rb +13 -5
- data/spec/unit/util/log/destinations_spec.rb +10 -0
- data/spec/unit/util/logging_spec.rb +58 -41
- data/spec/unit/util/monkey_patches_spec.rb +18 -5
- data/spec/unit/util/posix_spec.rb +28 -0
- data/spec/unit/util/selinux_spec.rb +4 -0
- data/spec/unit/util/storage_spec.rb +107 -0
- data/spec/unit/util/suidmanager_spec.rb +1 -3
- data/spec/unit/util/windows/adsi_spec.rb +95 -0
- data/spec/unit/util/windows/service_spec.rb +377 -131
- metadata +24 -11
- data/ext/autotest/Rakefile +0 -8
- data/ext/autotest/config +0 -43
- data/ext/autotest/readme.rst +0 -16
- data/spec/fixtures/unit/provider/package/pkgng/pkg.info +0 -7
- data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +0 -1
- data/spec/watchr.rb +0 -137
data/lib/puppet/type/user.rb
CHANGED
|
@@ -409,7 +409,10 @@ module Puppet
|
|
|
409
409
|
resource at the same time. For instance, Puppet creates a home directory for a managed
|
|
410
410
|
user if `ensure => present` and the user does not exist at the time of the Puppet run.
|
|
411
411
|
If the home directory is then deleted manually, Puppet will not recreate it on the next
|
|
412
|
-
run.
|
|
412
|
+
run.
|
|
413
|
+
|
|
414
|
+
Note that on Windows, this manages creation/deletion of the user profile instead of the
|
|
415
|
+
home directory. The user profile is stored in the `C:\Users\<username>` directory."
|
|
413
416
|
|
|
414
417
|
defaultto false
|
|
415
418
|
|
|
@@ -555,7 +558,7 @@ module Puppet
|
|
|
555
558
|
newparam(:auth_membership) do
|
|
556
559
|
desc "Whether specified auths should be considered the **complete list**
|
|
557
560
|
(`inclusive`) or the **minimum list** (`minimum`) of auths the user
|
|
558
|
-
has."
|
|
561
|
+
has. This setting is specific to managing Solaris authorizations."
|
|
559
562
|
|
|
560
563
|
newvalues(:inclusive, :minimum)
|
|
561
564
|
|
data/lib/puppet/type.rb
CHANGED
|
@@ -391,6 +391,12 @@ class Type
|
|
|
391
391
|
@key_attributes_cache ||= key_attribute_parameters.collect { |p| p.name }
|
|
392
392
|
end
|
|
393
393
|
|
|
394
|
+
# Returns any parameters that should be included by default in puppet resource's output
|
|
395
|
+
# @return [Array<Symbol>] the parameters to include
|
|
396
|
+
def self.parameters_to_include
|
|
397
|
+
[]
|
|
398
|
+
end
|
|
399
|
+
|
|
394
400
|
# Returns a mapping from the title string to setting of attribute values.
|
|
395
401
|
# This default implementation provides a mapping of title to the one and only _namevar_ present
|
|
396
402
|
# in the type's definition.
|
|
@@ -106,7 +106,7 @@ module Puppet
|
|
|
106
106
|
def run
|
|
107
107
|
# For most applications, we want to be able to load code from the modulepath,
|
|
108
108
|
# such as apply, describe, resource, and faces.
|
|
109
|
-
# For agent, we only want to load pluginsync'ed code from libdir.
|
|
109
|
+
# For agent and device in agent mode, we only want to load pluginsync'ed code from libdir.
|
|
110
110
|
# For master, we shouldn't ever be loading per-environment code into the master's
|
|
111
111
|
# ruby process, but that requires fixing (#17210, #12173, #8750). So for now
|
|
112
112
|
# we try to restrict to only code that can be autoloaded from the node's
|
|
@@ -116,8 +116,7 @@ module Puppet
|
|
|
116
116
|
# have an appropriate application-wide current_environment set.
|
|
117
117
|
# If we cannot find the configured environment, which may not exist,
|
|
118
118
|
# we do not attempt to add plugin directories to the load path.
|
|
119
|
-
|
|
120
|
-
if @subcommand_name != 'master' and @subcommand_name != 'agent'
|
|
119
|
+
unless @subcommand_name == 'master' || @subcommand_name == 'agent' || (@subcommand_name == 'device' && (['--apply', '--facts', '--resource'] - @command_line.args).empty?)
|
|
121
120
|
if configured_environment = Puppet.lookup(:environments).get(Puppet[:environment])
|
|
122
121
|
configured_environment.each_plugin_directory do |dir|
|
|
123
122
|
$LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
@@ -114,6 +114,9 @@ module Puppet::Util::Execution
|
|
|
114
114
|
# an Array the first element should be the executable and the rest of the
|
|
115
115
|
# elements should be the individual arguments to that executable.
|
|
116
116
|
# @param options [Hash] a Hash of options
|
|
117
|
+
# @option options [String] :cwd the directory from which to run the command. Raises an error if the directory does not exist.
|
|
118
|
+
# This option is only available on the agent. It cannot be used on the master, meaning it cannot be used in, for example,
|
|
119
|
+
# regular functions, hiera backends, or report processors.
|
|
117
120
|
# @option options [Boolean] :failonfail if this value is set to true, then this method will raise an error if the
|
|
118
121
|
# command is not executed successfully.
|
|
119
122
|
# @option options [Integer, String] :uid (nil) the user id of the user that the process should be run as. Will be ignored if the
|
|
@@ -154,6 +157,7 @@ module Puppet::Util::Execution
|
|
|
154
157
|
:override_locale => true,
|
|
155
158
|
:custom_environment => {},
|
|
156
159
|
:sensitive => false,
|
|
160
|
+
:suppress_window => false,
|
|
157
161
|
}
|
|
158
162
|
|
|
159
163
|
options = default_options.merge(options)
|
|
@@ -186,6 +190,11 @@ module Puppet::Util::Execution
|
|
|
186
190
|
|
|
187
191
|
null_file = Puppet::Util::Platform.windows? ? 'NUL' : '/dev/null'
|
|
188
192
|
|
|
193
|
+
cwd = options[:cwd]
|
|
194
|
+
if cwd && ! Puppet::FileSystem.directory?(cwd)
|
|
195
|
+
raise ArgumentError, _("Working directory %{cwd} does not exist!") % { cwd: cwd }
|
|
196
|
+
end
|
|
197
|
+
|
|
189
198
|
begin
|
|
190
199
|
stdin = Puppet::FileSystem.open(options[:stdinfile] || null_file, nil, 'r')
|
|
191
200
|
# On Windows, continue to use the file-based approach to avoid breaking people's existing
|
|
@@ -320,7 +329,6 @@ module Puppet::Util::Execution
|
|
|
320
329
|
#
|
|
321
330
|
def self.execute_posix(command, options, stdin, stdout, stderr)
|
|
322
331
|
child_pid = Puppet::Util.safe_posix_fork(stdin, stdout, stderr) do
|
|
323
|
-
|
|
324
332
|
# We can't just call Array(command), and rely on it returning
|
|
325
333
|
# things like ['foo'], when passed ['foo'], because
|
|
326
334
|
# Array(command) will call command.to_a internally, which when
|
|
@@ -329,6 +337,12 @@ module Puppet::Util::Execution
|
|
|
329
337
|
command = [command].flatten
|
|
330
338
|
Process.setsid
|
|
331
339
|
begin
|
|
340
|
+
# We need to chdir to our cwd before changing privileges as there's a
|
|
341
|
+
# chance that the user may not have permissions to access the cwd, which
|
|
342
|
+
# would cause execute_posix to fail.
|
|
343
|
+
cwd = options[:cwd]
|
|
344
|
+
Dir.chdir(cwd) if cwd
|
|
345
|
+
|
|
332
346
|
Puppet::Util::SUIDManager.change_privileges(options[:uid], options[:gid], true)
|
|
333
347
|
|
|
334
348
|
# if the caller has requested that we override locale environment variables,
|
data/lib/puppet/util/filetype.rb
CHANGED
|
@@ -166,6 +166,12 @@ class Puppet::Util::FileType
|
|
|
166
166
|
end
|
|
167
167
|
|
|
168
168
|
# Handle Linux-style cron tabs.
|
|
169
|
+
#
|
|
170
|
+
# TODO: We can possibly eliminate the "-u <username>" option in cmdbase
|
|
171
|
+
# by just running crontab under <username>'s uid (like we do for suntab
|
|
172
|
+
# and aixtab). It may be worth investigating this alternative
|
|
173
|
+
# implementation in the future. This way, we can refactor all three of
|
|
174
|
+
# our cron file types into a common crontab file type.
|
|
169
175
|
newfiletype(:crontab) do
|
|
170
176
|
def initialize(user)
|
|
171
177
|
self.path = user
|
|
@@ -185,21 +191,47 @@ class Puppet::Util::FileType
|
|
|
185
191
|
|
|
186
192
|
# Read a specific @path's cron tab.
|
|
187
193
|
def read
|
|
188
|
-
|
|
194
|
+
unless Puppet::Util.uid(@path)
|
|
195
|
+
Puppet.debug _("The %{path} user does not exist. Treating their crontab file as empty in case Puppet creates them in the middle of the run.") % { path: @path }
|
|
196
|
+
|
|
197
|
+
return ""
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
Puppet::Util::Execution.execute("#{cmdbase} -l", failonfail: true, combine: true)
|
|
201
|
+
rescue => detail
|
|
202
|
+
case detail.to_s
|
|
203
|
+
when /no crontab for/
|
|
204
|
+
return ""
|
|
205
|
+
when /are not allowed to/
|
|
206
|
+
Puppet.debug _("The %{path} user is not authorized to use cron. Their crontab file is treated as empty in case Puppet authorizes them in the middle of the run (by, for example, modifying the cron.deny or cron.allow files).") % { path: @path }
|
|
207
|
+
|
|
208
|
+
return ""
|
|
209
|
+
else
|
|
210
|
+
raise FileReadError, _("Could not read crontab for %{path}: %{detail}") % { path: @path, detail: detail }, detail.backtrace
|
|
211
|
+
end
|
|
189
212
|
end
|
|
190
213
|
|
|
191
214
|
# Remove a specific @path's cron tab.
|
|
192
215
|
def remove
|
|
216
|
+
cmd = "#{cmdbase} -r"
|
|
193
217
|
if %w{Darwin FreeBSD DragonFly}.include?(Facter.value("operatingsystem"))
|
|
194
|
-
|
|
195
|
-
else
|
|
196
|
-
%x{#{cmdbase} -r 2>/dev/null}
|
|
218
|
+
cmd = "/bin/echo yes | #{cmd}"
|
|
197
219
|
end
|
|
220
|
+
|
|
221
|
+
Puppet::Util::Execution.execute(cmd, failonfail: true, combine: true)
|
|
198
222
|
end
|
|
199
223
|
|
|
200
224
|
# Overwrite a specific @path's cron tab; must be passed the @path name
|
|
201
225
|
# and the text with which to create the cron tab.
|
|
226
|
+
#
|
|
227
|
+
# TODO: We should refactor this at some point to make it identical to the
|
|
228
|
+
# :aixtab and :suntab's write methods so that, at the very least, the pipe
|
|
229
|
+
# is not created and the crontab command's errors are not swallowed.
|
|
202
230
|
def write(text)
|
|
231
|
+
unless Puppet::Util.uid(@path)
|
|
232
|
+
raise Puppet::Error, _("Cannot write the %{path} user's crontab: The user does not exist") % { path: @path }
|
|
233
|
+
end
|
|
234
|
+
|
|
203
235
|
# this file is managed by the OS and should be using system encoding
|
|
204
236
|
IO.popen("#{cmdbase()} -", "w", :encoding => Encoding.default_external) { |p|
|
|
205
237
|
p.print text
|
|
@@ -224,13 +256,21 @@ class Puppet::Util::FileType
|
|
|
224
256
|
newfiletype(:suntab) do
|
|
225
257
|
# Read a specific @path's cron tab.
|
|
226
258
|
def read
|
|
259
|
+
unless Puppet::Util.uid(@path)
|
|
260
|
+
Puppet.debug _("The %{path} user does not exist. Treating their crontab file as empty in case Puppet creates them in the middle of the run.") % { path: @path }
|
|
261
|
+
|
|
262
|
+
return ""
|
|
263
|
+
end
|
|
264
|
+
|
|
227
265
|
Puppet::Util::Execution.execute(%w{crontab -l}, cronargs)
|
|
228
266
|
rescue => detail
|
|
229
267
|
case detail.to_s
|
|
230
268
|
when /can't open your crontab/
|
|
231
269
|
return ""
|
|
232
270
|
when /you are not authorized to use cron/
|
|
233
|
-
|
|
271
|
+
Puppet.debug _("The %{path} user is not authorized to use cron. Their crontab file is treated as empty in case Puppet authorizes them in the middle of the run (by, for example, modifying the cron.deny or cron.allow files).") % { path: @path }
|
|
272
|
+
|
|
273
|
+
return ""
|
|
234
274
|
else
|
|
235
275
|
raise FileReadError, _("Could not read crontab for %{path}: %{detail}") % { path: @path, detail: detail }, detail.backtrace
|
|
236
276
|
end
|
|
@@ -267,13 +307,21 @@ class Puppet::Util::FileType
|
|
|
267
307
|
newfiletype(:aixtab) do
|
|
268
308
|
# Read a specific @path's cron tab.
|
|
269
309
|
def read
|
|
310
|
+
unless Puppet::Util.uid(@path)
|
|
311
|
+
Puppet.debug _("The %{path} user does not exist. Treating their crontab file as empty in case Puppet creates them in the middle of the run.") % { path: @path }
|
|
312
|
+
|
|
313
|
+
return ""
|
|
314
|
+
end
|
|
315
|
+
|
|
270
316
|
Puppet::Util::Execution.execute(%w{crontab -l}, cronargs)
|
|
271
317
|
rescue => detail
|
|
272
318
|
case detail.to_s
|
|
273
|
-
when /
|
|
319
|
+
when /open.*in.*directory/
|
|
320
|
+
return ""
|
|
321
|
+
when /not.*authorized.*cron/
|
|
322
|
+
Puppet.debug _("The %{path} user is not authorized to use cron. Their crontab file is treated as empty in case Puppet authorizes them in the middle of the run (by, for example, modifying the cron.deny or cron.allow files).") % { path: @path }
|
|
323
|
+
|
|
274
324
|
return ""
|
|
275
|
-
when /You are not authorized to use the cron command/
|
|
276
|
-
raise FileReadError, _("User %{path} not authorized to use cron") % { path: @path }, detail.backtrace
|
|
277
325
|
else
|
|
278
326
|
raise FileReadError, _("Could not read crontab for %{path}: %{detail}") % { path: @path, detail: detail }, detail.backtrace
|
|
279
327
|
end
|
|
@@ -77,9 +77,10 @@ Puppet::Util::Log.newdesttype :file do
|
|
|
77
77
|
|
|
78
78
|
# create the log file, if it doesn't already exist
|
|
79
79
|
need_array_start = false
|
|
80
|
+
file_exists = File.exists?(path)
|
|
80
81
|
if @json == 1
|
|
81
82
|
need_array_start = true
|
|
82
|
-
if
|
|
83
|
+
if file_exists
|
|
83
84
|
sz = File.size(path)
|
|
84
85
|
need_array_start = sz == 0
|
|
85
86
|
|
|
@@ -93,7 +94,7 @@ Puppet::Util::Log.newdesttype :file do
|
|
|
93
94
|
file.puts('[') if need_array_start
|
|
94
95
|
|
|
95
96
|
# Give ownership to the user and group puppet will run as
|
|
96
|
-
if Puppet.features.root? && !Puppet::Util::Platform.windows?
|
|
97
|
+
if Puppet.features.root? && !Puppet::Util::Platform.windows? && !file_exists
|
|
97
98
|
begin
|
|
98
99
|
FileUtils.chown(Puppet[:user], Puppet[:group], path)
|
|
99
100
|
rescue ArgumentError, Errno::EPERM
|
data/lib/puppet/util/logging.rb
CHANGED
|
@@ -49,12 +49,13 @@ module Logging
|
|
|
49
49
|
# to take advantage of the backtrace logging.
|
|
50
50
|
def log_exception(exception, message = :default, options = {})
|
|
51
51
|
trace = Puppet[:trace] || options[:trace]
|
|
52
|
+
level = options[:level] || :err
|
|
52
53
|
if message == :default && exception.is_a?(Puppet::ParseErrorWithIssue)
|
|
53
54
|
# Retain all detailed info and keep plain message and stacktrace separate
|
|
54
55
|
backtrace = []
|
|
55
56
|
build_exception_trace(backtrace, exception, trace)
|
|
56
57
|
Puppet::Util::Log.create({
|
|
57
|
-
:level =>
|
|
58
|
+
:level => level,
|
|
58
59
|
:source => log_source,
|
|
59
60
|
:message => exception.basic_message,
|
|
60
61
|
:issue_code => exception.issue_code,
|
|
@@ -66,7 +67,7 @@ module Logging
|
|
|
66
67
|
:node => exception.node
|
|
67
68
|
}.merge(log_metadata))
|
|
68
69
|
else
|
|
69
|
-
|
|
70
|
+
send_log(level, format_exception(exception, message, trace))
|
|
70
71
|
end
|
|
71
72
|
end
|
|
72
73
|
|
data/lib/puppet/util/posix.rb
CHANGED
|
@@ -9,7 +9,22 @@ module Puppet::Util::POSIX
|
|
|
9
9
|
# environment for "exec" runs
|
|
10
10
|
USER_ENV_VARS = ['HOME', 'USER', 'LOGNAME']
|
|
11
11
|
|
|
12
|
+
class << self
|
|
13
|
+
# Returns an array of all the groups that the user's a member of.
|
|
14
|
+
def groups_of(user)
|
|
15
|
+
groups = []
|
|
16
|
+
Puppet::Etc.group do |group|
|
|
17
|
+
groups << group.name if group.mem.include?(user)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
uniq_groups = groups.uniq
|
|
21
|
+
if uniq_groups != groups
|
|
22
|
+
Puppet.debug(_('Removing any duplicate group entries'))
|
|
23
|
+
end
|
|
12
24
|
|
|
25
|
+
uniq_groups
|
|
26
|
+
end
|
|
27
|
+
end
|
|
13
28
|
|
|
14
29
|
# Retrieve a field from a POSIX Etc object. The id can be either an integer
|
|
15
30
|
# or a name. This only works for users and groups. It's also broken on
|
data/lib/puppet/util/selinux.rb
CHANGED
|
@@ -190,7 +190,7 @@ module Puppet::Util::SELinux
|
|
|
190
190
|
def selinux_label_support?(file)
|
|
191
191
|
fstype = find_fs(file)
|
|
192
192
|
return false if fstype.nil?
|
|
193
|
-
filesystems = ['ext2', 'ext3', 'ext4', 'gfs', 'gfs2', 'xfs', 'jfs', 'btrfs']
|
|
193
|
+
filesystems = ['ext2', 'ext3', 'ext4', 'gfs', 'gfs2', 'xfs', 'jfs', 'btrfs', 'tmpfs']
|
|
194
194
|
filesystems.include?(fstype)
|
|
195
195
|
end
|
|
196
196
|
|
data/lib/puppet/util/storage.rb
CHANGED
|
@@ -82,6 +82,18 @@ class Puppet::Util::Storage
|
|
|
82
82
|
|
|
83
83
|
Puppet.info _("Creating state file %{file}") % { file: Puppet[:statefile] } unless Puppet::FileSystem.exist?(Puppet[:statefile])
|
|
84
84
|
|
|
85
|
+
if Puppet[:statettl] == 0 || Puppet[:statettl] == Float::INFINITY
|
|
86
|
+
Puppet.debug "Not pruning old state cache entries"
|
|
87
|
+
else
|
|
88
|
+
Puppet::Util.benchmark(:debug, "Pruned old state cache entries in %{seconds} seconds") do
|
|
89
|
+
ttl_cutoff = Time.now - Puppet[:statettl]
|
|
90
|
+
|
|
91
|
+
@@state.reject! do |k,v|
|
|
92
|
+
@@state[k][:checked] && @@state[k][:checked] < ttl_cutoff
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
85
97
|
Puppet::Util.benchmark(:debug, "Stored state in %{seconds} seconds") do
|
|
86
98
|
Puppet::Util::Yaml.dump(@@state, Puppet[:statefile])
|
|
87
99
|
end
|
|
@@ -134,7 +134,7 @@ module Puppet::Util::Windows::ADSI
|
|
|
134
134
|
|
|
135
135
|
def parse_name(name)
|
|
136
136
|
if name =~ /\//
|
|
137
|
-
raise Puppet::Error.new( _("Value must be in DOMAIN
|
|
137
|
+
raise Puppet::Error.new( _("Value must be in DOMAIN\\%{object_class} style syntax") % { object_class: @object_class } )
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
matches = name.scan(/((.*)\\)?(.*)/)
|
|
@@ -250,7 +250,7 @@ module Puppet::Util::Windows::ADSI
|
|
|
250
250
|
# ERROR_BAD_USERNAME 2202L from winerror.h
|
|
251
251
|
if e.message =~ /8007089A/m
|
|
252
252
|
raise Puppet::Error.new(
|
|
253
|
-
_("Puppet is not able to create/delete domain %{object_class}
|
|
253
|
+
_("Puppet is not able to create/delete domain %{object_class} objects with the %{object_class} resource.") % { object_class: object_class },
|
|
254
254
|
)
|
|
255
255
|
end
|
|
256
256
|
|
|
@@ -376,6 +376,83 @@ module Puppet::Util::Windows::ADSI
|
|
|
376
376
|
end
|
|
377
377
|
end
|
|
378
378
|
|
|
379
|
+
# Declare all of the available user flags on the system. Note that
|
|
380
|
+
# ADS_UF is read as ADS_UserFlag
|
|
381
|
+
# https://docs.microsoft.com/en-us/windows/desktop/api/iads/ne-iads-ads_user_flag
|
|
382
|
+
# and
|
|
383
|
+
# https://support.microsoft.com/en-us/help/305144/how-to-use-the-useraccountcontrol-flags-to-manipulate-user-account-pro
|
|
384
|
+
# for the flag values.
|
|
385
|
+
ADS_USERFLAGS = {
|
|
386
|
+
ADS_UF_SCRIPT: 0x0001,
|
|
387
|
+
ADS_UF_ACCOUNTDISABLE: 0x0002,
|
|
388
|
+
ADS_UF_HOMEDIR_REQUIRED: 0x0008,
|
|
389
|
+
ADS_UF_LOCKOUT: 0x0010,
|
|
390
|
+
ADS_UF_PASSWD_NOTREQD: 0x0020,
|
|
391
|
+
ADS_UF_PASSWD_CANT_CHANGE: 0x0040,
|
|
392
|
+
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED: 0x0080,
|
|
393
|
+
ADS_UF_TEMP_DUPLICATE_ACCOUNT: 0x0100,
|
|
394
|
+
ADS_UF_NORMAL_ACCOUNT: 0x0200,
|
|
395
|
+
ADS_UF_INTERDOMAIN_TRUST_ACCOUNT: 0x0800,
|
|
396
|
+
ADS_UF_WORKSTATION_TRUST_ACCOUNT: 0x1000,
|
|
397
|
+
ADS_UF_SERVER_TRUST_ACCOUNT: 0x2000,
|
|
398
|
+
ADS_UF_DONT_EXPIRE_PASSWD: 0x10000,
|
|
399
|
+
ADS_UF_MNS_LOGON_ACCOUNT: 0x20000,
|
|
400
|
+
ADS_UF_SMARTCARD_REQUIRED: 0x40000,
|
|
401
|
+
ADS_UF_TRUSTED_FOR_DELEGATION: 0x80000,
|
|
402
|
+
ADS_UF_NOT_DELEGATED: 0x100000,
|
|
403
|
+
ADS_UF_USE_DES_KEY_ONLY: 0x200000,
|
|
404
|
+
ADS_UF_DONT_REQUIRE_PREAUTH: 0x400000,
|
|
405
|
+
ADS_UF_PASSWORD_EXPIRED: 0x800000,
|
|
406
|
+
ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: 0x1000000
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
def userflag_set?(flag)
|
|
410
|
+
flag_value = ADS_USERFLAGS[flag] || 0
|
|
411
|
+
! (self['UserFlags'] & flag_value).zero?
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
# Common helper for set_userflags and unset_userflags.
|
|
415
|
+
#
|
|
416
|
+
# @api private
|
|
417
|
+
def op_userflags(*flags, &block)
|
|
418
|
+
# Avoid an unnecessary set + commit operation.
|
|
419
|
+
return if flags.empty?
|
|
420
|
+
|
|
421
|
+
unrecognized_flags = flags.reject { |flag| ADS_USERFLAGS.keys.include?(flag) }
|
|
422
|
+
unless unrecognized_flags.empty?
|
|
423
|
+
raise ArgumentError, _("Unrecognized ADS UserFlags: %{unrecognized_flags}") % { unrecognized_flags: unrecognized_flags.join(', ') }
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
self['UserFlags'] = flags.inject(self['UserFlags'], &block)
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def set_userflags(*flags)
|
|
430
|
+
op_userflags(*flags) { |userflags, flag| userflags | ADS_USERFLAGS[flag] }
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
def unset_userflags(*flags)
|
|
434
|
+
op_userflags(*flags) { |userflags, flag| userflags & ~ADS_USERFLAGS[flag] }
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def disabled?
|
|
438
|
+
userflag_set?(:ADS_UF_ACCOUNTDISABLE)
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
def locked_out?
|
|
442
|
+
# Note that the LOCKOUT flag is known to be inaccurate when using the
|
|
443
|
+
# LDAP IADsUser provider, but this class consistently uses the WinNT
|
|
444
|
+
# provider, which is expected to be accurate.
|
|
445
|
+
userflag_set?(:ADS_UF_LOCKOUT)
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
def expired?
|
|
449
|
+
expires = native_object.Get('AccountExpirationDate')
|
|
450
|
+
expires && expires < Time.now
|
|
451
|
+
rescue WIN32OLERuntimeError => e
|
|
452
|
+
# This OLE error code indicates the property can't be found in the cache
|
|
453
|
+
raise e unless e.message =~ /8000500D/m
|
|
454
|
+
false
|
|
455
|
+
end
|
|
379
456
|
|
|
380
457
|
# UNLEN from lmcons.h - https://stackoverflow.com/a/2155176
|
|
381
458
|
MAX_USERNAME_LENGTH = 256
|
|
@@ -58,7 +58,7 @@ module Puppet::Util::Windows::APITypes
|
|
|
58
58
|
str = get_bytes(0, char_length * 2).force_encoding('UTF-16LE')
|
|
59
59
|
str.encode(dst_encoding, str.encoding, encode_options)
|
|
60
60
|
rescue Exception => e
|
|
61
|
-
Puppet.debug "Unable to convert value #{str.dump} to encoding #{dst_encoding} due to #{e.inspect}"
|
|
61
|
+
Puppet.debug "Unable to convert value #{str.nil? ? 'nil' : str.dump} to encoding #{dst_encoding} due to #{e.inspect}"
|
|
62
62
|
raise
|
|
63
63
|
end
|
|
64
64
|
|
|
@@ -7,15 +7,35 @@ module Puppet::Util::Windows::Process
|
|
|
7
7
|
extend FFI::Library
|
|
8
8
|
|
|
9
9
|
WAIT_TIMEOUT = 0x102
|
|
10
|
+
WAIT_INTERVAL = 200
|
|
11
|
+
# https://docs.microsoft.com/en-us/windows/desktop/ProcThread/process-creation-flags
|
|
12
|
+
CREATE_NO_WINDOW = 0x08000000
|
|
10
13
|
|
|
11
14
|
def execute(command, arguments, stdin, stdout, stderr)
|
|
12
|
-
|
|
15
|
+
create_args = {
|
|
16
|
+
:command_line => command,
|
|
17
|
+
:startup_info => {
|
|
18
|
+
:stdin => stdin,
|
|
19
|
+
:stdout => stdout,
|
|
20
|
+
:stderr => stderr
|
|
21
|
+
},
|
|
22
|
+
:close_handles => false,
|
|
23
|
+
}
|
|
24
|
+
if arguments[:suppress_window]
|
|
25
|
+
create_args[:creation_flags] = CREATE_NO_WINDOW
|
|
26
|
+
end
|
|
27
|
+
cwd = arguments[:cwd]
|
|
28
|
+
if cwd
|
|
29
|
+
Dir.chdir(cwd) { Process.create(create_args) }
|
|
30
|
+
else
|
|
31
|
+
Process.create(create_args)
|
|
32
|
+
end
|
|
13
33
|
end
|
|
14
34
|
module_function :execute
|
|
15
35
|
|
|
16
36
|
def wait_process(handle)
|
|
17
|
-
while WaitForSingleObject(handle,
|
|
18
|
-
sleep(
|
|
37
|
+
while WaitForSingleObject(handle, WAIT_INTERVAL) == WAIT_TIMEOUT
|
|
38
|
+
sleep(0)
|
|
19
39
|
end
|
|
20
40
|
|
|
21
41
|
exit_status = -1
|
|
@@ -65,6 +65,28 @@ module Puppet::Util::Windows
|
|
|
65
65
|
vals
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
# Retrieve a set of values from a registry key given their names
|
|
69
|
+
# Value names listed but not found in the registry will not be added to the
|
|
70
|
+
# resultant Hashtable
|
|
71
|
+
#
|
|
72
|
+
# @param key [RegistryKey] An open handle to a Registry Key
|
|
73
|
+
# @param names [String[]] An array of names of registry values to return if they exist
|
|
74
|
+
# @return [Hashtable<String, Object>] A hashtable of all of the found values in the registry key
|
|
75
|
+
def values_by_name(key, names)
|
|
76
|
+
vals = {}
|
|
77
|
+
names.each do |name|
|
|
78
|
+
FFI::Pointer.from_string_to_wide_string(name) do |subkeyname_ptr|
|
|
79
|
+
begin
|
|
80
|
+
_, vals[name] = read(key, subkeyname_ptr)
|
|
81
|
+
rescue Puppet::Util::Windows::Error => e
|
|
82
|
+
# ignore missing names, but raise other errors
|
|
83
|
+
raise e unless e.code == Puppet::Util::Windows::Error::ERROR_FILE_NOT_FOUND
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
vals
|
|
88
|
+
end
|
|
89
|
+
|
|
68
90
|
def each_value(key, &block)
|
|
69
91
|
index = 0
|
|
70
92
|
subkey = nil
|
|
@@ -104,7 +126,7 @@ module Puppet::Util::Windows
|
|
|
104
126
|
|
|
105
127
|
if result != FFI::ERROR_SUCCESS
|
|
106
128
|
msg = _("Failed to enumerate %{key} registry keys at index %{index}") % { key: key.keyname, index: index }
|
|
107
|
-
raise Puppet::Util::Windows::Error.new(msg)
|
|
129
|
+
raise Puppet::Util::Windows::Error.new(msg, result)
|
|
108
130
|
end
|
|
109
131
|
|
|
110
132
|
filetime = FFI::WIN32::FILETIME.new(filetime_ptr)
|
|
@@ -135,7 +157,7 @@ module Puppet::Util::Windows
|
|
|
135
157
|
|
|
136
158
|
if result != FFI::ERROR_SUCCESS
|
|
137
159
|
msg = _("Failed to enumerate %{key} registry values at index %{index}") % { key: key.keyname, index: index }
|
|
138
|
-
raise Puppet::Util::Windows::Error.new(msg)
|
|
160
|
+
raise Puppet::Util::Windows::Error.new(msg, result)
|
|
139
161
|
end
|
|
140
162
|
|
|
141
163
|
subkey_length = subkey_length_ptr.read_dword
|
|
@@ -165,7 +187,7 @@ module Puppet::Util::Windows
|
|
|
165
187
|
|
|
166
188
|
if status != FFI::ERROR_SUCCESS
|
|
167
189
|
msg = _("Failed to query registry %{key} for sizes") % { key: key.keyname }
|
|
168
|
-
raise Puppet::Util::Windows::Error.new(msg)
|
|
190
|
+
raise Puppet::Util::Windows::Error.new(msg, status)
|
|
169
191
|
end
|
|
170
192
|
|
|
171
193
|
result = [
|
|
@@ -247,8 +269,10 @@ module Puppet::Util::Windows
|
|
|
247
269
|
buffer_ptr, length_ptr)
|
|
248
270
|
|
|
249
271
|
if result != FFI::ERROR_SUCCESS
|
|
250
|
-
|
|
251
|
-
|
|
272
|
+
# buffer is raw bytes, *not* chars - less a NULL terminator
|
|
273
|
+
name_length = (name_ptr.size / FFI.type_size(:wchar)) - 1 if name_ptr.size > 0
|
|
274
|
+
msg = _("Failed to read registry value %{value} at %{key}") % { value: name_ptr.read_wide_string(name_length), key: key.keyname }
|
|
275
|
+
raise Puppet::Util::Windows::Error.new(msg, result)
|
|
252
276
|
end
|
|
253
277
|
|
|
254
278
|
# allows caller to use FFI MemoryPointer helpers to read / shape
|
|
@@ -324,6 +324,20 @@ module Puppet::Util::Windows::Security
|
|
|
324
324
|
# we don't check S_ISYSTEM_MISSING bit, but automatically carry over existing SYSTEM perms
|
|
325
325
|
# by default set SYSTEM perms to full
|
|
326
326
|
system_allow = FILE::FILE_ALL_ACCESS
|
|
327
|
+
else
|
|
328
|
+
# It is possible to set SYSTEM with a mode other than Full Control (7) however this makes no sense and in practical terms
|
|
329
|
+
# should not be done. We can trap these instances and correct them before being applied.
|
|
330
|
+
if (sd.owner == well_known_system_sid) && (owner_allow != FILE::FILE_ALL_ACCESS)
|
|
331
|
+
#TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
|
|
332
|
+
Puppet.debug _("An attempt to set mode %{mode} on item %{path} would result in the owner, SYSTEM, to have less than Full Control rights. This attempt has been corrected to Full Control") % { mode: mode.to_s(8), path: path }
|
|
333
|
+
owner_allow = FILE::FILE_ALL_ACCESS
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
if (sd.group == well_known_system_sid) && (group_allow != FILE::FILE_ALL_ACCESS)
|
|
337
|
+
#TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
|
|
338
|
+
Puppet.debug _("An attempt to set mode %{mode} on item %{path} would result in the group, SYSTEM, to have less than Full Control rights. This attempt has been corrected to Full Control") % { mode: mode.to_s(8), path: path }
|
|
339
|
+
group_allow = FILE::FILE_ALL_ACCESS
|
|
340
|
+
end
|
|
327
341
|
end
|
|
328
342
|
|
|
329
343
|
# even though FILE_DELETE_CHILD only applies to directories, it can be set on files
|