puppet 6.0.5-universal-darwin → 6.0.7-universal-darwin
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/CODEOWNERS +30 -0
- data/Gemfile.lock +14 -14
- data/lib/puppet.rb +4 -4
- data/lib/puppet/application.rb +1 -1
- data/lib/puppet/application/filebucket.rb +6 -1
- data/lib/puppet/configurer.rb +6 -6
- data/lib/puppet/confine/boolean.rb +45 -0
- data/lib/puppet/confine/false.rb +7 -1
- data/lib/puppet/confine/true.rb +7 -1
- data/lib/puppet/defaults.rb +21 -29
- data/lib/puppet/functions/call.rb +2 -1
- data/lib/puppet/network/http/connection.rb +15 -5
- data/lib/puppet/pops/issues.rb +4 -0
- data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +60 -4
- data/lib/puppet/pops/model/factory.rb +38 -4
- data/lib/puppet/pops/parser/egrammar.ra +2 -2
- data/lib/puppet/pops/parser/heredoc_support.rb +17 -7
- data/lib/puppet/pops/parser/lexer2.rb +6 -1
- data/lib/puppet/pops/parser/locator.rb +106 -86
- data/lib/puppet/pops/parser/parser_support.rb +11 -2
- data/lib/puppet/pops/types/type_mismatch_describer.rb +1 -1
- data/lib/puppet/provider/file/windows.rb +49 -1
- data/lib/puppet/provider/group/windows_adsi.rb +4 -1
- data/lib/puppet/provider/package/windows.rb +5 -1
- data/lib/puppet/provider/service/upstart.rb +16 -6
- data/lib/puppet/settings.rb +10 -5
- data/lib/puppet/transaction.rb +8 -6
- data/lib/puppet/transaction/resource_harness.rb +1 -0
- data/lib/puppet/type/exec.rb +27 -5
- data/lib/puppet/type/file/mode.rb +6 -1
- data/lib/puppet/type/filebucket.rb +12 -8
- data/lib/puppet/util/command_line.rb +5 -1
- data/lib/puppet/util/log.rb +7 -2
- data/lib/puppet/util/pidlock.rb +14 -1
- data/lib/puppet/util/windows/process.rb +73 -5
- data/lib/puppet/util/windows/security.rb +29 -8
- data/lib/puppet/version.rb +1 -1
- data/locales/ja/puppet.po +149 -132
- data/locales/puppet.pot +197 -148
- data/man/man5/puppet.conf.5 +14 -6
- 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 +6 -2
- 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/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/bad_func_load2.rb +11 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/bad_func_load3.rb +11 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/bad_func_load4.rb +11 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/bad_func_load5.rb +12 -0
- data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/good_func_load.rb +9 -0
- data/spec/integration/provider/file/windows_spec.rb +162 -0
- data/spec/integration/type/file_spec.rb +0 -19
- data/spec/unit/application_spec.rb +8 -1
- data/spec/unit/configurer_spec.rb +6 -7
- data/spec/unit/confine/false_spec.rb +27 -0
- data/spec/unit/confine/true_spec.rb +27 -0
- data/spec/unit/defaults_spec.rb +0 -14
- data/spec/unit/network/http/connection_spec.rb +1 -1
- data/spec/unit/pops/loaders/loaders_spec.rb +70 -3
- data/spec/unit/pops/parser/locator_spec.rb +45 -0
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +111 -15
- data/spec/unit/pops/types/type_mismatch_describer_spec.rb +9 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +7 -1
- data/spec/unit/provider/package/windows_spec.rb +12 -1
- data/spec/unit/provider/service/systemd_spec.rb +7 -5
- data/spec/unit/settings_spec.rb +36 -0
- data/spec/unit/transaction/resource_harness_spec.rb +26 -0
- data/spec/unit/transaction_spec.rb +29 -0
- data/spec/unit/type/exec_spec.rb +47 -0
- data/spec/unit/type/filebucket_spec.rb +8 -6
- data/spec/unit/util/command_line_spec.rb +23 -2
- data/spec/unit/util/execution_spec.rb +2 -2
- data/spec/unit/util/log_spec.rb +15 -0
- data/spec/unit/util/pidlock_spec.rb +21 -1
- data/spec/unit/util/storage_spec.rb +19 -19
- metadata +16 -3
- data/MAINTAINERS +0 -47
@@ -67,7 +67,10 @@ Puppet::Type.type(:group).provide :windows_adsi do
|
|
67
67
|
|
68
68
|
def members
|
69
69
|
@members ||= Puppet::Util::Windows::ADSI::Group.name_sid_hash(group.members)
|
70
|
-
|
70
|
+
|
71
|
+
# @members.keys returns an array of SIDs. We need to convert those SIDs into
|
72
|
+
# names so that `puppet resource` prints the right output.
|
73
|
+
members_to_s(@members.keys).split(',')
|
71
74
|
end
|
72
75
|
|
73
76
|
def members=(members)
|
@@ -63,7 +63,11 @@ Puppet::Type.type(:package).provide(:windows, :parent => Puppet::Provider::Packa
|
|
63
63
|
installer = Puppet::Provider::Package::Windows::Package.installer_class(resource)
|
64
64
|
|
65
65
|
command = [installer.install_command(resource), install_options].flatten.compact.join(' ')
|
66
|
-
|
66
|
+
working_dir = File.dirname(resource[:source])
|
67
|
+
if !Puppet::FileSystem.exist?(working_dir) && resource[:source] =~ /\.msi"?\Z/i
|
68
|
+
working_dir = nil
|
69
|
+
end
|
70
|
+
output = execute(command, :failonfail => false, :combine => true, :cwd => working_dir, :suppress_window => true)
|
67
71
|
|
68
72
|
check_result(output.exitstatus)
|
69
73
|
end
|
@@ -28,12 +28,22 @@ Puppet::Type.type(:service).provide :upstart, :parent => :debian do
|
|
28
28
|
# We only want to use upstart as our provider if the upstart daemon is running.
|
29
29
|
# This can be checked by running `initctl version --quiet` on a machine that has
|
30
30
|
# upstart installed.
|
31
|
-
confine :true =>
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
confine :true => lambda {
|
32
|
+
# Puppet::Util::Execution.execute does not currently work on jRuby.
|
33
|
+
# Unfortunately, since this confine is invoked whenever we check for
|
34
|
+
# provider suitability and since provider suitability is still checked
|
35
|
+
# on the master, this confine will still be invoked on the master. Thus
|
36
|
+
# to avoid raising an exception, we do an early return if we're running
|
37
|
+
# on jRuby.
|
38
|
+
next false if Puppet::Util::Platform.jruby?
|
39
|
+
|
40
|
+
begin
|
41
|
+
initctl('version', '--quiet')
|
42
|
+
true
|
43
|
+
rescue
|
44
|
+
false
|
45
|
+
end
|
46
|
+
}
|
37
47
|
|
38
48
|
# upstart developer haven't implemented initctl enable/disable yet:
|
39
49
|
# http://www.linuxplanet.com/linuxplanet/tutorials/7033/2/
|
data/lib/puppet/settings.rb
CHANGED
@@ -255,7 +255,7 @@ class Puppet::Settings
|
|
255
255
|
@global_defaults_initialized
|
256
256
|
end
|
257
257
|
|
258
|
-
def initialize_global_settings(args = [])
|
258
|
+
def initialize_global_settings(args = [], require_config = true)
|
259
259
|
raise Puppet::DevError, _("Attempting to initialize global default settings more than once!") if global_defaults_initialized?
|
260
260
|
|
261
261
|
# The first two phases of the lifecycle of a puppet application are:
|
@@ -264,7 +264,7 @@ class Puppet::Settings
|
|
264
264
|
# 2) Parse the puppet config file(s).
|
265
265
|
|
266
266
|
parse_global_options(args)
|
267
|
-
parse_config_files
|
267
|
+
parse_config_files(require_config)
|
268
268
|
|
269
269
|
@global_defaults_initialized = true
|
270
270
|
end
|
@@ -590,14 +590,19 @@ class Puppet::Settings
|
|
590
590
|
end
|
591
591
|
|
592
592
|
# Parse the configuration file. Just provides thread safety.
|
593
|
-
def parse_config_files
|
593
|
+
def parse_config_files(require_config = true)
|
594
594
|
file = which_configuration_file
|
595
595
|
if Puppet::FileSystem.exist?(file)
|
596
596
|
begin
|
597
597
|
text = read_file(file)
|
598
598
|
rescue => detail
|
599
|
-
|
600
|
-
|
599
|
+
message = _("Could not load %{file}: %{detail}") % { file: file, detail: detail}
|
600
|
+
if require_config
|
601
|
+
Puppet.log_and_raise(detail, message)
|
602
|
+
else
|
603
|
+
Puppet.log_exception(detail, message)
|
604
|
+
return
|
605
|
+
end
|
601
606
|
end
|
602
607
|
else
|
603
608
|
return
|
data/lib/puppet/transaction.rb
CHANGED
@@ -358,15 +358,17 @@ class Puppet::Transaction
|
|
358
358
|
Puppet.debug "Prefetching #{provider_class.name} resources for #{type_name}"
|
359
359
|
begin
|
360
360
|
provider_class.prefetch(resources)
|
361
|
-
rescue
|
362
|
-
if !detail.is_a?(LoadError) && !detail.is_a?(Puppet::MissingCommand)
|
363
|
-
raise unless Puppet.settings[:future_features]
|
364
|
-
|
365
|
-
@prefetch_failed_providers[type_name][provider_class.name] = true
|
366
|
-
end
|
361
|
+
rescue LoadError, Puppet::MissingCommand => detail
|
367
362
|
#TRANSLATORS `prefetch` is a function name and should not be translated
|
368
363
|
message = _("Could not prefetch %{type_name} provider '%{name}': %{detail}") % { type_name: type_name, name: provider_class.name, detail: detail }
|
369
364
|
Puppet.log_exception(detail, message)
|
365
|
+
rescue StandardError => detail
|
366
|
+
message = _("Could not prefetch %{type_name} provider '%{name}': %{detail}") % { type_name: type_name, name: provider_class.name, detail: detail }
|
367
|
+
Puppet.log_exception(detail, message)
|
368
|
+
|
369
|
+
raise unless Puppet.settings[:future_features]
|
370
|
+
|
371
|
+
@prefetch_failed_providers[type_name][provider_class.name] = true
|
370
372
|
end
|
371
373
|
@prefetched_providers[type_name][provider_class.name] = true
|
372
374
|
end
|
@@ -161,6 +161,7 @@ class Puppet::Transaction::ResourceHarness
|
|
161
161
|
name = param.name.to_s
|
162
162
|
event.message ||= _("could not create change error message for %{name}") % { name: name }
|
163
163
|
event.calculate_corrective_change(@persistence.get_system_value(context.resource.ref, name))
|
164
|
+
event.message << ' (corrective)' if event.corrective_change
|
164
165
|
context.record(event)
|
165
166
|
event.send_log
|
166
167
|
context.synced_params << param.name
|
data/lib/puppet/type/exec.rb
CHANGED
@@ -581,7 +581,15 @@ module Puppet
|
|
581
581
|
val = @parameters[check].value
|
582
582
|
val = [val] unless val.is_a? Array
|
583
583
|
val.each do |value|
|
584
|
-
|
584
|
+
if !@parameters[check].check(value)
|
585
|
+
# Give a debug message so users can figure out what command would have been
|
586
|
+
# but don't print sensitive commands or parameters in the clear
|
587
|
+
cmdstring = @parameters[:command].sensitive ? "[command redacted]" : @parameters[:command].value
|
588
|
+
|
589
|
+
debug(_("'%{cmd}' won't be executed because of failed check '%{check}'") % { cmd: cmdstring, check: check })
|
590
|
+
|
591
|
+
return false
|
592
|
+
end
|
585
593
|
end
|
586
594
|
end
|
587
595
|
}
|
@@ -614,11 +622,25 @@ module Puppet
|
|
614
622
|
|
615
623
|
private
|
616
624
|
def set_sensitive_parameters(sensitive_parameters)
|
617
|
-
#
|
618
|
-
|
619
|
-
|
620
|
-
|
625
|
+
# If any are sensitive, mark all as sensitive
|
626
|
+
sensitive = false
|
627
|
+
parameters_to_check = [:command, :unless, :onlyif]
|
628
|
+
|
629
|
+
parameters_to_check.each do |p|
|
630
|
+
if sensitive_parameters.include?(p)
|
631
|
+
sensitive_parameters.delete(p)
|
632
|
+
sensitive = true
|
633
|
+
end
|
621
634
|
end
|
635
|
+
|
636
|
+
if sensitive
|
637
|
+
parameters_to_check.each do |p|
|
638
|
+
if parameters.include?(p)
|
639
|
+
parameter(p).sensitive = true
|
640
|
+
end
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
622
644
|
super(sensitive_parameters)
|
623
645
|
end
|
624
646
|
end
|
@@ -116,8 +116,13 @@ module Puppet
|
|
116
116
|
# If we're not following links and we're a link, then we just turn
|
117
117
|
# off mode management entirely.
|
118
118
|
def insync?(currentvalue)
|
119
|
+
if provider.respond_to?(:munge_windows_system_group)
|
120
|
+
munged_mode = provider.munge_windows_system_group(currentvalue, @should)
|
121
|
+
return false if munged_mode.nil?
|
122
|
+
currentvalue = munged_mode
|
123
|
+
end
|
119
124
|
if stat = @resource.stat and stat.ftype == "link" and @resource[:links] != :follow
|
120
|
-
self.debug "Not managing symlink mode"
|
125
|
+
self.debug _("Not managing symlink mode")
|
121
126
|
return true
|
122
127
|
else
|
123
128
|
return super(currentvalue)
|
@@ -42,19 +42,23 @@ module Puppet
|
|
42
42
|
end
|
43
43
|
|
44
44
|
newparam(:server) do
|
45
|
-
desc "The server providing the remote filebucket service.
|
46
|
-
value of the `server` setting (that is, the currently configured
|
47
|
-
puppet master server).
|
45
|
+
desc "The server providing the remote filebucket service.
|
48
46
|
|
49
|
-
This setting is _only_ consulted if the `path` attribute is set to `false`.
|
50
|
-
|
47
|
+
This setting is _only_ consulted if the `path` attribute is set to `false`.
|
48
|
+
|
49
|
+
If this attribute is not specified, the first entry in the `server_list`
|
50
|
+
configuration setting is used, followed by the value of the `server` setting
|
51
|
+
if `server_list` is not set."
|
51
52
|
end
|
52
53
|
|
53
54
|
newparam(:port) do
|
54
|
-
desc "The port on which the remote server is listening.
|
55
|
-
|
55
|
+
desc "The port on which the remote server is listening.
|
56
|
+
|
57
|
+
This setting is _only_ consulted if the `path` attribute is set to `false`.
|
56
58
|
|
57
|
-
|
59
|
+
If this attribute is not specified, the first entry in the `server_list`
|
60
|
+
configuration setting is used, followed by the value of the `masterport`
|
61
|
+
setting if `server_list` is not set."
|
58
62
|
end
|
59
63
|
|
60
64
|
newparam(:path) do
|
@@ -64,8 +64,12 @@ module Puppet
|
|
64
64
|
#
|
65
65
|
# @return [void]
|
66
66
|
def execute
|
67
|
+
require_config = true
|
68
|
+
if @argv.first =~ /help|-h|--help|-V|--version/
|
69
|
+
require_config = false
|
70
|
+
end
|
67
71
|
Puppet::Util.exit_on_fail(_("Could not initialize global default settings")) do
|
68
|
-
Puppet.initialize_settings(args)
|
72
|
+
Puppet.initialize_settings(args, require_config)
|
69
73
|
end
|
70
74
|
|
71
75
|
setpriority(Puppet[:priority])
|
data/lib/puppet/util/log.rb
CHANGED
@@ -60,7 +60,7 @@ class Puppet::Util::Log
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def self.close_all
|
63
|
-
destinations.keys.each { |dest|
|
63
|
+
@destinations.keys.each { |dest|
|
64
64
|
close(dest)
|
65
65
|
}
|
66
66
|
#TRANSLATORS "Log.close_all" is a method name and should not be translated
|
@@ -147,7 +147,12 @@ class Puppet::Util::Log
|
|
147
147
|
Puppet.log_exception(detail)
|
148
148
|
|
149
149
|
# If this was our only destination, then add the console back in.
|
150
|
-
|
150
|
+
if destinations.empty? && dest.intern != :console
|
151
|
+
newdestination(:console)
|
152
|
+
end
|
153
|
+
|
154
|
+
# Re-raise (end exit Puppet) because we could not set up logging correctly.
|
155
|
+
raise detail
|
151
156
|
end
|
152
157
|
end
|
153
158
|
|
data/lib/puppet/util/pidlock.rb
CHANGED
@@ -54,7 +54,20 @@ class Puppet::Util::Pidlock
|
|
54
54
|
begin
|
55
55
|
Process.kill(0, lock_pid)
|
56
56
|
rescue *errors
|
57
|
-
@lockfile.unlock
|
57
|
+
return @lockfile.unlock
|
58
|
+
end
|
59
|
+
|
60
|
+
# Ensure the process associated with this pid is our process. If
|
61
|
+
# not, we can unlock the lockfile. For now this is only done on
|
62
|
+
# POSIX and Windows platforms (PUP-9247).
|
63
|
+
if Puppet.features.posix?
|
64
|
+
procname = Puppet::Util::Execution.execute(["ps", "-p", lock_pid, "-o", "comm="]).strip
|
65
|
+
@lockfile.unlock unless procname =~ /puppet(-.*)?$/
|
66
|
+
elsif Puppet.features.microsoft_windows?
|
67
|
+
# On Windows, we're checking if the filesystem path name of the running
|
68
|
+
# process is our vendored ruby:
|
69
|
+
exe_path = Puppet::Util::Windows::Process::get_process_image_name_by_pid(lock_pid)
|
70
|
+
@lockfile.unlock unless exe_path =~ /Puppet\\puppet\\bin\\ruby.exe/
|
58
71
|
end
|
59
72
|
end
|
60
73
|
private :clear_if_stale
|
@@ -10,6 +10,10 @@ module Puppet::Util::Windows::Process
|
|
10
10
|
WAIT_INTERVAL = 200
|
11
11
|
# https://docs.microsoft.com/en-us/windows/desktop/ProcThread/process-creation-flags
|
12
12
|
CREATE_NO_WINDOW = 0x08000000
|
13
|
+
# https://docs.microsoft.com/en-us/windows/desktop/ProcThread/process-security-and-access-rights
|
14
|
+
PROCESS_QUERY_INFORMATION = 0x0400
|
15
|
+
# https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
|
16
|
+
MAX_PATH_LENGTH = 32767
|
13
17
|
|
14
18
|
def execute(command, arguments, stdin, stdout, stderr)
|
15
19
|
create_args = {
|
@@ -24,12 +28,10 @@ module Puppet::Util::Windows::Process
|
|
24
28
|
if arguments[:suppress_window]
|
25
29
|
create_args[:creation_flags] = CREATE_NO_WINDOW
|
26
30
|
end
|
27
|
-
|
28
|
-
|
29
|
-
Dir.chdir(cwd) { Process.create(create_args) }
|
30
|
-
else
|
31
|
-
Process.create(create_args)
|
31
|
+
if arguments[:cwd]
|
32
|
+
create_args[:cwd] = arguments[:cwd]
|
32
33
|
end
|
34
|
+
Process.create(create_args)
|
33
35
|
end
|
34
36
|
module_function :execute
|
35
37
|
|
@@ -62,6 +64,26 @@ module Puppet::Util::Windows::Process
|
|
62
64
|
end
|
63
65
|
module_function :get_current_process
|
64
66
|
|
67
|
+
def open_process(desired_access, inherit_handle, process_id, &block)
|
68
|
+
phandle = nil
|
69
|
+
inherit = inherit_handle ? FFI::WIN32_TRUE : FFI::WIN32_FALSE
|
70
|
+
begin
|
71
|
+
phandle = OpenProcess(desired_access, inherit, process_id)
|
72
|
+
if phandle == FFI::Pointer::NULL_HANDLE
|
73
|
+
raise Puppet::Util::Windows::Error.new(
|
74
|
+
"OpenProcess(#{desired_access.to_s(8)}, #{inherit}, #{process_id})")
|
75
|
+
end
|
76
|
+
|
77
|
+
yield phandle
|
78
|
+
ensure
|
79
|
+
FFI::WIN32.CloseHandle(phandle) if phandle
|
80
|
+
end
|
81
|
+
|
82
|
+
# phandle has had CloseHandle called against it, so nothing to return
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
module_function :open_process
|
86
|
+
|
65
87
|
def open_process_token(handle, desired_access, &block)
|
66
88
|
token_handle = nil
|
67
89
|
begin
|
@@ -97,6 +119,32 @@ module Puppet::Util::Windows::Process
|
|
97
119
|
end
|
98
120
|
module_function :with_process_token
|
99
121
|
|
122
|
+
def get_process_image_name_by_pid(pid)
|
123
|
+
image_name = ""
|
124
|
+
|
125
|
+
open_process(PROCESS_QUERY_INFORMATION, false, pid) do |phandle|
|
126
|
+
|
127
|
+
FFI::MemoryPointer.new(:dword, 1) do |exe_name_length_ptr|
|
128
|
+
# Add 1 for the null terminator, and UTF is 2 bytes/char:
|
129
|
+
max_path_length = (MAX_PATH_LENGTH + 1) * 2
|
130
|
+
exe_name_length_ptr.write_dword(max_path_length)
|
131
|
+
FFI::MemoryPointer.new(max_path_length) do |exe_name_ptr|
|
132
|
+
use_win32_path_format = 0
|
133
|
+
result = QueryFullProcessImageNameW(phandle, use_win32_path_format, exe_name_ptr, exe_name_length_ptr)
|
134
|
+
if result == FFI::WIN32_FALSE
|
135
|
+
raise Puppet::Util::Windows::Error.new(
|
136
|
+
"QueryFullProcessImageNameW(phandle, #{use_win32_path_format}, " +
|
137
|
+
"exe_name_ptr, #{max_path_length}")
|
138
|
+
end
|
139
|
+
image_name = exe_name_ptr.read_wide_string(MAX_PATH_LENGTH + 1)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
image_name
|
145
|
+
end
|
146
|
+
module_function :get_process_image_name_by_pid
|
147
|
+
|
100
148
|
def lookup_privilege_value(name, system_name = '', &block)
|
101
149
|
FFI::MemoryPointer.new(LUID.size) do |luid_ptr|
|
102
150
|
result = LookupPrivilegeValueW(
|
@@ -366,6 +414,16 @@ module Puppet::Util::Windows::Process
|
|
366
414
|
attach_function_private :SetEnvironmentVariableW,
|
367
415
|
[:lpcwstr, :lpcwstr], :win32_bool
|
368
416
|
|
417
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx
|
418
|
+
# HANDLE WINAPI OpenProcess(
|
419
|
+
# _In_ DWORD DesiredAccess,
|
420
|
+
# _In_ BOOL InheritHandle,
|
421
|
+
# _In_ DWORD ProcessId
|
422
|
+
# );
|
423
|
+
ffi_lib :kernel32
|
424
|
+
attach_function_private :OpenProcess,
|
425
|
+
[:dword, :win32_bool, :dword], :handle
|
426
|
+
|
369
427
|
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx
|
370
428
|
# BOOL WINAPI OpenProcessToken(
|
371
429
|
# _In_ HANDLE ProcessHandle,
|
@@ -376,6 +434,16 @@ module Puppet::Util::Windows::Process
|
|
376
434
|
attach_function_private :OpenProcessToken,
|
377
435
|
[:handle, :dword, :phandle], :win32_bool
|
378
436
|
|
437
|
+
# https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-queryfullprocessimagenamew
|
438
|
+
# BOOL WINAPI QueryFullProcessImageName(
|
439
|
+
# _In_ HANDLE hProcess,
|
440
|
+
# _In_ DWORD dwFlags,
|
441
|
+
# _Out_ LPWSTR lpExeName,
|
442
|
+
# _In_ PDWORD lpdwSize,
|
443
|
+
# );
|
444
|
+
ffi_lib :kernel32
|
445
|
+
attach_function_private :QueryFullProcessImageNameW,
|
446
|
+
[:handle, :dword, :lpwstr, :pdword], :win32_bool
|
379
447
|
|
380
448
|
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa379261(v=vs.85).aspx
|
381
449
|
# typedef struct _LUID {
|
@@ -274,7 +274,7 @@ module Puppet::Util::Windows::Security
|
|
274
274
|
# mode. Only a user with the SE_BACKUP_NAME and SE_RESTORE_NAME
|
275
275
|
# privileges in their process token can change the mode for objects
|
276
276
|
# that they do not have read and write access to.
|
277
|
-
def set_mode(mode, path, protected = true)
|
277
|
+
def set_mode(mode, path, protected = true, managing_owner = false, managing_group = false)
|
278
278
|
sd = get_security_descriptor(path)
|
279
279
|
well_known_world_sid = Puppet::Util::Windows::SID::Everyone
|
280
280
|
well_known_nobody_sid = Puppet::Util::Windows::SID::Nobody
|
@@ -319,6 +319,8 @@ module Puppet::Util::Windows::Security
|
|
319
319
|
nobody_allow |= FILE::FILE_APPEND_DATA;
|
320
320
|
end
|
321
321
|
|
322
|
+
isownergroup = sd.owner == sd.group
|
323
|
+
|
322
324
|
# caller is NOT managing SYSTEM by using group or owner, so set to FULL
|
323
325
|
if ! [sd.owner, sd.group].include? well_known_system_sid
|
324
326
|
# we don't check S_ISYSTEM_MISSING bit, but automatically carry over existing SYSTEM perms
|
@@ -328,15 +330,35 @@ module Puppet::Util::Windows::Security
|
|
328
330
|
# It is possible to set SYSTEM with a mode other than Full Control (7) however this makes no sense and in practical terms
|
329
331
|
# should not be done. We can trap these instances and correct them before being applied.
|
330
332
|
if (sd.owner == well_known_system_sid) && (owner_allow != FILE::FILE_ALL_ACCESS)
|
331
|
-
#
|
332
|
-
|
333
|
-
|
333
|
+
# If owner and group are both SYSTEM but group is unmanaged the control rights of system will be set to FullControl by
|
334
|
+
# the unmanaged group, so there is no need for the warning
|
335
|
+
if managing_owner && (!isownergroup || managing_group)
|
336
|
+
#TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
|
337
|
+
Puppet.warning _("Setting control rights for %{path} owner SYSTEM to less than Full Control rights. Setting SYSTEM rights to less than Full Control may have unintented consequences for operations on this file") % { path: path }
|
338
|
+
elsif managing_owner && isownergroup
|
339
|
+
#TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
|
340
|
+
Puppet.debug _("%{path} owner and group both set to user SYSTEM, but group is not managed directly: SYSTEM user rights will be set to FullControl by group") % { path: path }
|
341
|
+
else
|
342
|
+
#TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
|
343
|
+
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 }
|
344
|
+
owner_allow = FILE::FILE_ALL_ACCESS
|
345
|
+
end
|
334
346
|
end
|
335
347
|
|
336
348
|
if (sd.group == well_known_system_sid) && (group_allow != FILE::FILE_ALL_ACCESS)
|
337
|
-
#
|
338
|
-
|
339
|
-
|
349
|
+
# If owner and group are both SYSTEM but owner is unmanaged the control rights of system will be set to FullControl by
|
350
|
+
# the unmanaged owner, so there is no need for the warning.
|
351
|
+
if managing_group && (!isownergroup || managing_owner)
|
352
|
+
#TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
|
353
|
+
Puppet.warning _("Setting control rights for %{path} group SYSTEM to less than Full Control rights. Setting SYSTEM rights to less than Full Control may have unintented consequences for operations on this file") % { path: path }
|
354
|
+
elsif managing_group && isownergroup
|
355
|
+
#TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
|
356
|
+
Puppet.debug _("%{path} owner and group both set to user SYSTEM, but owner is not managed directly: SYSTEM user rights will be set to FullControl by owner") % { path: path }
|
357
|
+
else
|
358
|
+
#TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
|
359
|
+
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 }
|
360
|
+
group_allow = FILE::FILE_ALL_ACCESS
|
361
|
+
end
|
340
362
|
end
|
341
363
|
end
|
342
364
|
|
@@ -353,7 +375,6 @@ module Puppet::Util::Windows::Security
|
|
353
375
|
end
|
354
376
|
|
355
377
|
# if owner and group the same, then map group permissions to the one owner ACE
|
356
|
-
isownergroup = sd.owner == sd.group
|
357
378
|
if isownergroup
|
358
379
|
owner_allow |= group_allow
|
359
380
|
end
|