puppet 6.4.3-universal-darwin → 6.4.4-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 +9 -9
- data/Gemfile +2 -2
- data/Gemfile.lock +23 -23
- data/ext/project_data.yaml +2 -2
- data/install.rb +3 -21
- data/lib/puppet/application/agent.rb +12 -0
- data/lib/puppet/application/device.rb +14 -4
- data/lib/puppet/application/resource.rb +4 -4
- data/lib/puppet/defaults.rb +12 -0
- data/lib/puppet/face/config.rb +10 -48
- data/lib/puppet/face/facts.rb +1 -1
- data/lib/puppet/face/help.rb +1 -1
- data/lib/puppet/face/plugin.rb +9 -2
- data/lib/puppet/indirector/catalog/compiler.rb +11 -5
- data/lib/puppet/module_tool/tar/mini.rb +11 -1
- data/lib/puppet/network/http/factory.rb +1 -11
- data/lib/puppet/provider/file/posix.rb +5 -0
- data/lib/puppet/provider/nameservice.rb +10 -3
- data/lib/puppet/provider/package/dnf.rb +1 -1
- data/lib/puppet/provider/package/pip.rb +2 -2
- data/lib/puppet/provider/package/rpm.rb +51 -13
- data/lib/puppet/provider/package/yum.rb +8 -4
- data/lib/puppet/provider/service/launchd.rb +20 -5
- data/lib/puppet/provider/service/systemd.rb +5 -10
- data/lib/puppet/provider/service/windows.rb +8 -0
- data/lib/puppet/provider/user/pw.rb +12 -3
- data/lib/puppet/provider/user/user_role_add.rb +4 -0
- data/lib/puppet/provider/user/useradd.rb +23 -7
- data/lib/puppet/resource.rb +17 -0
- data/lib/puppet/settings.rb +40 -0
- data/lib/puppet/type/exec.rb +14 -6
- data/lib/puppet/type/package.rb +10 -0
- data/lib/puppet/type/service.rb +7 -2
- data/lib/puppet/util/execution.rb +4 -3
- data/lib/puppet/util/http_proxy.rb +19 -5
- data/lib/puppet/util/selinux.rb +5 -1
- data/lib/puppet/util/windows/security.rb +2 -0
- data/lib/puppet/util/windows/service.rb +149 -4
- data/lib/puppet/util/windows/sid.rb +1 -0
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +168 -152
- data/man/man5/puppet.conf.5 +18 -2
- 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 +3 -3
- data/spec/integration/provider/service/systemd_spec.rb +8 -5
- data/spec/integration/type/file_spec.rb +28 -0
- data/spec/integration/util/execution_spec.rb +27 -0
- data/spec/unit/application/agent_spec.rb +20 -8
- data/spec/unit/application/device_spec.rb +27 -1
- data/spec/unit/face/facts_spec.rb +9 -0
- data/spec/unit/face/plugin_spec.rb +8 -0
- data/spec/unit/indirector/catalog/compiler_spec.rb +62 -5
- data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
- data/spec/unit/network/http/api/indirected_routes_spec.rb +25 -10
- data/spec/unit/network/http/factory_spec.rb +27 -5
- data/spec/unit/pops/validator/validator_spec.rb +7 -0
- data/spec/unit/provider/package/aptrpm_spec.rb +1 -1
- data/spec/unit/provider/package/dnf_spec.rb +7 -0
- data/spec/unit/provider/package/dpkg_spec.rb +2 -2
- data/spec/unit/provider/package/pip_spec.rb +8 -0
- data/spec/unit/provider/package/rpm_spec.rb +150 -16
- data/spec/unit/provider/package/yum_spec.rb +7 -0
- data/spec/unit/provider/service/launchd_spec.rb +28 -0
- data/spec/unit/provider/service/systemd_spec.rb +14 -0
- data/spec/unit/provider/service/windows_spec.rb +20 -0
- data/spec/unit/provider/user/pw_spec.rb +37 -0
- data/spec/unit/provider/user/useradd_spec.rb +42 -0
- data/spec/unit/resource_spec.rb +26 -1
- data/spec/unit/transaction_spec.rb +18 -0
- data/spec/unit/type/exec_spec.rb +9 -0
- data/spec/unit/type/file/source_spec.rb +4 -4
- data/spec/unit/type/schedule_spec.rb +3 -1
- data/spec/unit/type/service_spec.rb +16 -0
- data/spec/unit/util/http_proxy_spec.rb +40 -1
- data/spec/unit/util/log_spec.rb +27 -1
- data/spec/unit/util/windows/service_spec.rb +9 -0
- metadata +3 -7
- data/ext/windows/eventlog/Rakefile +0 -32
- data/ext/windows/eventlog/puppetres.dll +0 -0
- data/ext/windows/eventlog/puppetres.mc +0 -18
@@ -202,6 +202,10 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd, :source =>
|
|
202
202
|
shadow_entry[5].empty? ? -1 : shadow_entry[5]
|
203
203
|
end
|
204
204
|
|
205
|
+
def has_sensitive_data?(property = nil)
|
206
|
+
false
|
207
|
+
end
|
208
|
+
|
205
209
|
# Read in /etc/shadow, find the line for our used and rewrite it with the
|
206
210
|
# new pw. Smooth like 80 grit sandpaper.
|
207
211
|
#
|
@@ -147,19 +147,35 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
|
|
147
147
|
# validproperties is a list of properties in undefined order
|
148
148
|
# sort them to have a predictable command line in tests
|
149
149
|
Puppet::Type.type(:user).validproperties.sort.each do |property|
|
150
|
-
|
151
|
-
next if
|
152
|
-
next if (property == :groups) && @resource.forcelocal?
|
153
|
-
next if (property == :expiry) && @resource.forcelocal?
|
150
|
+
value = get_value_for_property(property)
|
151
|
+
next if value.nil?
|
154
152
|
# the value needs to be quoted, mostly because -c might
|
155
153
|
# have spaces in it
|
156
|
-
|
157
|
-
cmd << flag(property) << munge(property, value)
|
158
|
-
end
|
154
|
+
cmd << flag(property) << munge(property, value)
|
159
155
|
end
|
160
156
|
cmd
|
161
157
|
end
|
162
158
|
|
159
|
+
def get_value_for_property(property)
|
160
|
+
return nil if property == :ensure
|
161
|
+
return nil if property_manages_password_age?(property)
|
162
|
+
return nil if property == :groups and @resource.forcelocal?
|
163
|
+
return nil if property == :expiry and @resource.forcelocal?
|
164
|
+
value = @resource.should(property)
|
165
|
+
return nil if !value || value == ""
|
166
|
+
|
167
|
+
value
|
168
|
+
end
|
169
|
+
|
170
|
+
def has_sensitive_data?(property = nil)
|
171
|
+
#Check for sensitive values?
|
172
|
+
properties = property ? [property] : Puppet::Type.type(:user).validproperties
|
173
|
+
properties.any? do |prop|
|
174
|
+
p = @resource.parameter(prop)
|
175
|
+
p && p.respond_to?(:is_sensitive) && p.is_sensitive
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
163
179
|
def addcmd
|
164
180
|
if @resource.forcelocal?
|
165
181
|
cmd = [command(:localadd)]
|
data/lib/puppet/resource.rb
CHANGED
@@ -427,6 +427,8 @@ class Puppet::Resource
|
|
427
427
|
end
|
428
428
|
|
429
429
|
# Convert our resource to yaml for Hiera purposes.
|
430
|
+
#
|
431
|
+
# @deprecated Use {to_hiera_hash} instead.
|
430
432
|
def to_hierayaml
|
431
433
|
# Collect list of attributes to align => and move ensure first
|
432
434
|
attr = parameters.keys
|
@@ -446,6 +448,21 @@ class Puppet::Resource
|
|
446
448
|
" %s:\n%s" % [self.title, attributes]
|
447
449
|
end
|
448
450
|
|
451
|
+
# Convert our resource to a hiera hash suitable for serialization.
|
452
|
+
def to_hiera_hash
|
453
|
+
# to_data_hash converts to safe Data types, e.g. no symbols, unicode replacement character
|
454
|
+
h = to_data_hash
|
455
|
+
|
456
|
+
params = h['parameters'] || {}
|
457
|
+
value = params.delete('ensure')
|
458
|
+
|
459
|
+
res = {}
|
460
|
+
res['ensure'] = value if value
|
461
|
+
res.merge!(Hash[params.sort])
|
462
|
+
|
463
|
+
return { h['title'] => res }
|
464
|
+
end
|
465
|
+
|
449
466
|
# Convert our resource to Puppet code.
|
450
467
|
def to_manifest
|
451
468
|
# Collect list of attributes to align => and move ensure first
|
data/lib/puppet/settings.rb
CHANGED
@@ -84,6 +84,46 @@ class Puppet::Settings
|
|
84
84
|
"puppet.conf"
|
85
85
|
end
|
86
86
|
|
87
|
+
def stringify_settings(section, settings = :all)
|
88
|
+
values_from_the_selected_section =
|
89
|
+
values(nil, section.to_sym)
|
90
|
+
|
91
|
+
loader_settings = {
|
92
|
+
:environmentpath => values_from_the_selected_section.interpolate(:environmentpath),
|
93
|
+
:basemodulepath => values_from_the_selected_section.interpolate(:basemodulepath),
|
94
|
+
}
|
95
|
+
|
96
|
+
Puppet.override(Puppet.base_context(loader_settings),
|
97
|
+
_("New environment loaders generated from the requested section.")) do
|
98
|
+
# And now we can lookup values that include those from environments configured from
|
99
|
+
# the requested section
|
100
|
+
values = values(Puppet[:environment].to_sym, section.to_sym)
|
101
|
+
|
102
|
+
to_be_rendered = {}
|
103
|
+
settings = Puppet.settings.to_a.collect(&:first) if settings == :all
|
104
|
+
settings.sort.each do |setting_name|
|
105
|
+
to_be_rendered[setting_name] = values.print(setting_name.to_sym)
|
106
|
+
end
|
107
|
+
|
108
|
+
stringifyhash(to_be_rendered)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def stringifyhash(hash)
|
113
|
+
newhash = {}
|
114
|
+
hash.each do |key, val|
|
115
|
+
key = key.to_s
|
116
|
+
if val.is_a? Hash
|
117
|
+
newhash[key] = stringifyhash(val)
|
118
|
+
elsif val.is_a? Symbol
|
119
|
+
newhash[key] = val.to_s
|
120
|
+
else
|
121
|
+
newhash[key] = val
|
122
|
+
end
|
123
|
+
end
|
124
|
+
newhash
|
125
|
+
end
|
126
|
+
|
87
127
|
# Create a new collection of config settings.
|
88
128
|
def initialize
|
89
129
|
@config = {}
|
data/lib/puppet/type/exec.rb
CHANGED
@@ -457,9 +457,13 @@ module Puppet
|
|
457
457
|
return false
|
458
458
|
end
|
459
459
|
|
460
|
-
|
461
|
-
self.debug(
|
462
|
-
|
460
|
+
if sensitive
|
461
|
+
self.debug("[output redacted]")
|
462
|
+
else
|
463
|
+
output.split(/\n/).each { |line|
|
464
|
+
self.debug(line)
|
465
|
+
}
|
466
|
+
end
|
463
467
|
|
464
468
|
status.exitstatus != 0
|
465
469
|
end
|
@@ -509,9 +513,13 @@ module Puppet
|
|
509
513
|
return false
|
510
514
|
end
|
511
515
|
|
512
|
-
|
513
|
-
self.debug(
|
514
|
-
|
516
|
+
if sensitive
|
517
|
+
self.debug("[output redacted]")
|
518
|
+
else
|
519
|
+
output.split(/\n/).each { |line|
|
520
|
+
self.debug(line)
|
521
|
+
}
|
522
|
+
end
|
515
523
|
|
516
524
|
status.exitstatus == 0
|
517
525
|
end
|
data/lib/puppet/type/package.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
# Define the different packaging systems. Each package system is implemented
|
2
3
|
# in a module, which then gets used to individually extend each package object.
|
3
4
|
# This allows packages to exist on the same machine using different packaging
|
@@ -56,6 +57,7 @@ module Puppet
|
|
56
57
|
a user or another package. Held is considered a superset of
|
57
58
|
installed.",
|
58
59
|
:methods => [:hold]
|
60
|
+
feature :install_only, "The provider accepts options to only install packages never update (kernels, etc.)"
|
59
61
|
feature :install_options, "The provider accepts options to be
|
60
62
|
passed to the installer command."
|
61
63
|
feature :uninstall_options, "The provider accepts options to be
|
@@ -487,6 +489,14 @@ module Puppet
|
|
487
489
|
which type of package you want."
|
488
490
|
end
|
489
491
|
|
492
|
+
newparam(:install_only, :boolean => false, :parent => Puppet::Parameter::Boolean, :required_features => :install_only) do
|
493
|
+
desc <<-EOT
|
494
|
+
It should be set for packages that should only ever be installed,
|
495
|
+
never updated. Kernels in particular fall into this category.
|
496
|
+
EOT
|
497
|
+
defaultto false
|
498
|
+
end
|
499
|
+
|
490
500
|
newparam(:install_options, :parent => Puppet::Parameter::PackageOptions, :required_features => :install_options) do
|
491
501
|
desc <<-EOT
|
492
502
|
An array of additional options to pass when installing a package. These
|
data/lib/puppet/type/service.rb
CHANGED
@@ -75,6 +75,11 @@ module Puppet
|
|
75
75
|
provider.enabled?
|
76
76
|
end
|
77
77
|
|
78
|
+
# This only works on Windows systems.
|
79
|
+
newvalue(:delayed, :event => :service_delayed_start) do
|
80
|
+
provider.delayed_start
|
81
|
+
end
|
82
|
+
|
78
83
|
# This only makes sense on systemd systems. Static services cannot be enabled
|
79
84
|
# or disabled manually.
|
80
85
|
def insync?(current)
|
@@ -87,8 +92,8 @@ module Puppet
|
|
87
92
|
end
|
88
93
|
|
89
94
|
validate do |value|
|
90
|
-
if value == :manual && !Puppet::Util::Platform.windows?
|
91
|
-
raise Puppet::Error.new(_("Setting enable to
|
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} )
|
92
97
|
end
|
93
98
|
end
|
94
99
|
end
|
@@ -162,15 +162,16 @@ module Puppet::Util::Execution
|
|
162
162
|
|
163
163
|
options = default_options.merge(options)
|
164
164
|
|
165
|
-
if
|
166
|
-
command_str = '[redacted]'
|
167
|
-
elsif command.is_a?(Array)
|
165
|
+
if command.is_a?(Array)
|
168
166
|
command = command.flatten.map(&:to_s)
|
169
167
|
command_str = command.join(" ")
|
170
168
|
elsif command.is_a?(String)
|
171
169
|
command_str = command
|
172
170
|
end
|
173
171
|
|
172
|
+
# do this after processing 'command' array or string
|
173
|
+
command_str = '[redacted]' if options[:sensitive]
|
174
|
+
|
174
175
|
user_log_s = ''
|
175
176
|
if options[:uid]
|
176
177
|
user_log_s << " uid=#{options[:uid]}"
|
@@ -33,7 +33,7 @@ module Puppet::Util::HttpProxy
|
|
33
33
|
# .example.com
|
34
34
|
# We'll accommodate both here.
|
35
35
|
def self.no_proxy?(dest)
|
36
|
-
unless
|
36
|
+
unless no_proxy = self.no_proxy
|
37
37
|
return false
|
38
38
|
end
|
39
39
|
|
@@ -45,7 +45,7 @@ module Puppet::Util::HttpProxy
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
no_proxy.split(/\s*,\s*/).each do |d|
|
49
49
|
host, port = d.split(':')
|
50
50
|
host = Regexp.escape(host).gsub('\*', '.*')
|
51
51
|
|
@@ -127,6 +127,20 @@ module Puppet::Util::HttpProxy
|
|
127
127
|
return Puppet.settings[:http_proxy_password]
|
128
128
|
end
|
129
129
|
|
130
|
+
def self.no_proxy
|
131
|
+
no_proxy_env = ENV["no_proxy"] || ENV["NO_PROXY"]
|
132
|
+
|
133
|
+
if no_proxy_env
|
134
|
+
return no_proxy_env
|
135
|
+
end
|
136
|
+
|
137
|
+
if Puppet.settings[:no_proxy] == 'none'
|
138
|
+
return nil
|
139
|
+
end
|
140
|
+
|
141
|
+
return Puppet.settings[:no_proxy]
|
142
|
+
end
|
143
|
+
|
130
144
|
# Return a Net::HTTP::Proxy object.
|
131
145
|
#
|
132
146
|
# This method optionally configures SSL correctly if the URI scheme is
|
@@ -181,7 +195,7 @@ module Puppet::Util::HttpProxy
|
|
181
195
|
headers.merge!({"Accept-Encoding" => Puppet::Network::HTTP::Compression::ACCEPT_ENCODING})
|
182
196
|
end
|
183
197
|
|
184
|
-
response = proxy.send(:head, current_uri
|
198
|
+
response = proxy.send(:head, current_uri, headers)
|
185
199
|
Puppet.debug("HTTP HEAD request to #{current_uri} returned #{response.code} #{response.message}")
|
186
200
|
|
187
201
|
if [301, 302, 307].include?(response.code.to_i)
|
@@ -192,9 +206,9 @@ module Puppet::Util::HttpProxy
|
|
192
206
|
|
193
207
|
if method != :head
|
194
208
|
if block_given?
|
195
|
-
response = proxy.send("request_#{method}".to_sym, current_uri
|
209
|
+
response = proxy.send("request_#{method}".to_sym, current_uri, headers, &block)
|
196
210
|
else
|
197
|
-
response = proxy.send(method, current_uri
|
211
|
+
response = proxy.send(method, current_uri, headers)
|
198
212
|
end
|
199
213
|
|
200
214
|
Puppet.debug("HTTP #{method.to_s.upcase} request to #{current_uri} returned #{response.code} #{response.message}")
|
data/lib/puppet/util/selinux.rb
CHANGED
@@ -13,7 +13,7 @@ require 'pathname'
|
|
13
13
|
|
14
14
|
module Puppet::Util::SELinux
|
15
15
|
|
16
|
-
def selinux_support?
|
16
|
+
def self.selinux_support?
|
17
17
|
return false unless defined?(Selinux)
|
18
18
|
if Selinux.is_selinux_enabled == 1
|
19
19
|
return true
|
@@ -21,6 +21,10 @@ module Puppet::Util::SELinux
|
|
21
21
|
false
|
22
22
|
end
|
23
23
|
|
24
|
+
def selinux_support?
|
25
|
+
Puppet::Util::SELinux.selinux_support?
|
26
|
+
end
|
27
|
+
|
24
28
|
# Retrieve and return the full context of the file. If we don't have
|
25
29
|
# SELinux support or if the SELinux call fails then return nil.
|
26
30
|
def get_selinux_current_context(file)
|
@@ -200,6 +200,7 @@ module Puppet::Util::Windows::Security
|
|
200
200
|
well_known_world_sid = Puppet::Util::Windows::SID::Everyone
|
201
201
|
well_known_nobody_sid = Puppet::Util::Windows::SID::Nobody
|
202
202
|
well_known_system_sid = Puppet::Util::Windows::SID::LocalSystem
|
203
|
+
well_known_app_packages_sid = Puppet::Util::Windows::SID::AllAppPackages
|
203
204
|
|
204
205
|
mode = S_ISYSTEM_MISSING
|
205
206
|
|
@@ -234,6 +235,7 @@ module Puppet::Util::Windows::Security
|
|
234
235
|
if (ace.mask & FILE::FILE_APPEND_DATA).nonzero?
|
235
236
|
mode |= S_ISVTX
|
236
237
|
end
|
238
|
+
when well_known_app_packages_sid
|
237
239
|
when well_known_system_sid
|
238
240
|
else
|
239
241
|
#puts "Warning, unable to map SID into POSIX mode: #{ace.sid}"
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
require 'puppet/util/windows'
|
2
3
|
require 'ffi'
|
3
4
|
|
@@ -180,7 +181,30 @@ module Puppet::Util::Windows
|
|
180
181
|
# // Value to indicate no change to an optional parameter
|
181
182
|
# //
|
182
183
|
# #define SERVICE_NO_CHANGE 0xffffffff
|
183
|
-
|
184
|
+
# https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-changeserviceconfig2w
|
185
|
+
SERVICE_CONFIG_DESCRIPTION = 0x00000001
|
186
|
+
SERVICE_CONFIG_FAILURE_ACTIONS = 0x00000002
|
187
|
+
SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 0x00000003
|
188
|
+
SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 0x00000004
|
189
|
+
SERVICE_CONFIG_SERVICE_SID_INFO = 0x00000005
|
190
|
+
SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 0x00000006
|
191
|
+
SERVICE_CONFIG_PRESHUTDOWN_INFO = 0x00000007
|
192
|
+
SERVICE_CONFIG_TRIGGER_INFO = 0x00000008
|
193
|
+
SERVICE_CONFIG_PREFERRED_NODE = 0x00000009
|
194
|
+
SERVICE_CONFIG_LAUNCH_PROTECTED = 0x00000012
|
195
|
+
SERVICE_NO_CHANGE = 0xffffffff
|
196
|
+
SERVICE_CONFIG_TYPES = {
|
197
|
+
SERVICE_CONFIG_DESCRIPTION => :SERVICE_CONFIG_DESCRIPTION,
|
198
|
+
SERVICE_CONFIG_FAILURE_ACTIONS => :SERVICE_CONFIG_FAILURE_ACTIONS,
|
199
|
+
SERVICE_CONFIG_DELAYED_AUTO_START_INFO => :SERVICE_CONFIG_DELAYED_AUTO_START_INFO,
|
200
|
+
SERVICE_CONFIG_FAILURE_ACTIONS_FLAG => :SERVICE_CONFIG_FAILURE_ACTIONS_FLAG,
|
201
|
+
SERVICE_CONFIG_SERVICE_SID_INFO => :SERVICE_CONFIG_SERVICE_SID_INFO,
|
202
|
+
SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO => :SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO,
|
203
|
+
SERVICE_CONFIG_PRESHUTDOWN_INFO => :SERVICE_CONFIG_PRESHUTDOWN_INFO,
|
204
|
+
SERVICE_CONFIG_TRIGGER_INFO => :SERVICE_CONFIG_TRIGGER_INFO,
|
205
|
+
SERVICE_CONFIG_PREFERRED_NODE => :SERVICE_CONFIG_PREFERRED_NODE,
|
206
|
+
SERVICE_CONFIG_LAUNCH_PROTECTED => :SERVICE_CONFIG_LAUNCH_PROTECTED,
|
207
|
+
}
|
184
208
|
|
185
209
|
# Service enum codes
|
186
210
|
# https://docs.microsoft.com/en-us/windows/desktop/api/winsvc/nf-winsvc-enumservicesstatusexa
|
@@ -219,6 +243,19 @@ module Puppet::Util::Windows
|
|
219
243
|
)
|
220
244
|
end
|
221
245
|
|
246
|
+
# https://docs.microsoft.com/en-us/windows/win32/api/winsvc/ns-winsvc-service_delayed_auto_start_info
|
247
|
+
# typedef struct _SERVICE_DELAYED_AUTO_START_INFO {
|
248
|
+
# BOOL fDelayedAutostart;
|
249
|
+
# } SERVICE_DELAYED_AUTO_START_INFO, *LPSERVICE_DELAYED_AUTO_START_INFO;
|
250
|
+
class SERVICE_DELAYED_AUTO_START_INFO < FFI::Struct
|
251
|
+
layout(:fDelayedAutostart, :int)
|
252
|
+
alias aset []=
|
253
|
+
# Intercept the accessor so that we can handle either true/false or 1/0.
|
254
|
+
# Since there is only one member, there’s no need to check the key name.
|
255
|
+
def []=(key, value)
|
256
|
+
[0, false].include?(value) ? aset(key, 0) : aset(key, 1)
|
257
|
+
end
|
258
|
+
end
|
222
259
|
|
223
260
|
# https://docs.microsoft.com/en-us/windows/desktop/api/winsvc/ns-winsvc-_enum_service_status_processw
|
224
261
|
# typedef struct _ENUM_SERVICE_STATUS_PROCESSW {
|
@@ -377,6 +414,7 @@ module Puppet::Util::Windows
|
|
377
414
|
module_function :service_state
|
378
415
|
|
379
416
|
# Query the configuration of a service using QueryServiceConfigW
|
417
|
+
# or QueryServiceConfig2W
|
380
418
|
#
|
381
419
|
# @param [String] service_name name of the service to query
|
382
420
|
# @return [QUERY_SERVICE_CONFIGW.struct] the configuration of the service
|
@@ -387,6 +425,14 @@ module Puppet::Util::Windows
|
|
387
425
|
start_type = SERVICE_START_TYPES[config[:dwStartType]]
|
388
426
|
end
|
389
427
|
end
|
428
|
+
# if the service has type AUTO_START, check if it's a delayed service
|
429
|
+
if start_type == :SERVICE_AUTO_START
|
430
|
+
open_service(service_name, SC_MANAGER_CONNECT, SERVICE_QUERY_CONFIG) do |service|
|
431
|
+
query_config2(service, SERVICE_CONFIG_DELAYED_AUTO_START_INFO) do |config|
|
432
|
+
return :SERVICE_DELAYED_AUTO_START if config[:fDelayedAutostart] == 1
|
433
|
+
end
|
434
|
+
end
|
435
|
+
end
|
390
436
|
if start_type.nil?
|
391
437
|
raise Puppet::Error.new(_("Unknown start type '%{start_type}' for '%{service_name}'") % { start_type: start_type.to_s, service_name: service_name})
|
392
438
|
end
|
@@ -396,11 +442,12 @@ module Puppet::Util::Windows
|
|
396
442
|
|
397
443
|
# Change the startup mode of a windows service
|
398
444
|
#
|
399
|
-
# @param [
|
400
|
-
# @param [
|
445
|
+
# @param [String] service_name the name of the service to modify
|
446
|
+
# @param [Integer] startup_type a code corresponding to a start type for
|
401
447
|
# windows service, see the "Service start type codes" section in the
|
402
448
|
# Puppet::Util::Windows::Service file for the list of available codes
|
403
|
-
|
449
|
+
# @param [Bool] delayed whether the service should be started with a delay
|
450
|
+
def set_startup_mode(service_name, startup_type, delayed=false)
|
404
451
|
startup_code = SERVICE_START_TYPES.key(startup_type)
|
405
452
|
if startup_code.nil?
|
406
453
|
raise Puppet::Error.new(_("Unknown start type %{start_type}") % {startup_type: startup_type.to_s})
|
@@ -427,6 +474,7 @@ module Puppet::Util::Windows
|
|
427
474
|
raise Puppet::Util::Windows::Error.new(_("Failed to update service configuration"))
|
428
475
|
end
|
429
476
|
end
|
477
|
+
set_startup_mode_delayed(service_name, delayed)
|
430
478
|
end
|
431
479
|
module_function :set_startup_mode
|
432
480
|
|
@@ -709,6 +757,82 @@ module Puppet::Util::Windows
|
|
709
757
|
end
|
710
758
|
private :query_config
|
711
759
|
|
760
|
+
# @api private
|
761
|
+
# perform QueryServiceConfig2W on a windows service and return the
|
762
|
+
# result
|
763
|
+
#
|
764
|
+
# @param [:handle] service handle of the service to query
|
765
|
+
# @param [Integer] info_level the configuration information to be queried
|
766
|
+
# @return [QUERY_SERVICE_CONFIG2W struct] the result of the query
|
767
|
+
def query_config2(service, info_level, &block)
|
768
|
+
config = nil
|
769
|
+
size_required = nil
|
770
|
+
# Fetch the bytes of memory required to be allocated
|
771
|
+
# for QueryServiceConfig2W to return succesfully. This
|
772
|
+
# is done by sending NULL and 0 for the pointer and size
|
773
|
+
# respectively, letting the command fail, then reading the
|
774
|
+
# value of pcbBytesNeeded
|
775
|
+
FFI::MemoryPointer.new(:lpword) do |bytes_pointer|
|
776
|
+
# return value will be false from this call, since it's designed
|
777
|
+
# to fail. Just ignore it
|
778
|
+
QueryServiceConfig2W(service, info_level, FFI::Pointer::NULL, 0, bytes_pointer)
|
779
|
+
size_required = bytes_pointer.read_dword
|
780
|
+
FFI::MemoryPointer.new(size_required) do |ssp_ptr|
|
781
|
+
# We need to supply the appropriate struct to be created based on
|
782
|
+
# the info_level
|
783
|
+
case info_level
|
784
|
+
when SERVICE_CONFIG_DELAYED_AUTO_START_INFO
|
785
|
+
config = SERVICE_DELAYED_AUTO_START_INFO.new(ssp_ptr)
|
786
|
+
end
|
787
|
+
success = QueryServiceConfig2W(
|
788
|
+
service,
|
789
|
+
info_level,
|
790
|
+
ssp_ptr,
|
791
|
+
size_required,
|
792
|
+
bytes_pointer
|
793
|
+
)
|
794
|
+
if success == FFI::WIN32_FALSE
|
795
|
+
raise Puppet::Util::Windows::Error.new(_("Service query for %{parameter_name} failed") % { parameter_name: SERVICE_CONFIG_TYPES[info_level] } )
|
796
|
+
end
|
797
|
+
yield config
|
798
|
+
end
|
799
|
+
end
|
800
|
+
end
|
801
|
+
private :query_config2
|
802
|
+
|
803
|
+
# @api private
|
804
|
+
# Sets an optional parameter on a service by calling
|
805
|
+
# ChangeServiceConfig2W
|
806
|
+
#
|
807
|
+
# @param [String] service_name name of service
|
808
|
+
# @param [Integer] change parameter to change
|
809
|
+
# @param [struct] value appropriate struct based on the parameter to change
|
810
|
+
def set_optional_parameter(service_name, change, value)
|
811
|
+
open_service(service_name, SC_MANAGER_CONNECT, SERVICE_CHANGE_CONFIG) do |service|
|
812
|
+
success = ChangeServiceConfig2W(
|
813
|
+
service,
|
814
|
+
change, # dwInfoLevel
|
815
|
+
value, # lpInfo
|
816
|
+
)
|
817
|
+
if success == FFI::WIN32_FALSE
|
818
|
+
raise Puppet::Util::windows::Error.new(_("Failed to update service %{change} configuration") % { change: change } )
|
819
|
+
end
|
820
|
+
end
|
821
|
+
end
|
822
|
+
private :set_optional_parameter
|
823
|
+
|
824
|
+
# @api private
|
825
|
+
# Controls the delayed auto-start setting of a service
|
826
|
+
#
|
827
|
+
# @param [String] service_name name of service
|
828
|
+
# @param [Bool] delayed whether the service should be started with a delay or not
|
829
|
+
def set_startup_mode_delayed(service_name, delayed)
|
830
|
+
delayed_start = SERVICE_DELAYED_AUTO_START_INFO.new
|
831
|
+
delayed_start[:fDelayedAutostart] = delayed
|
832
|
+
set_optional_parameter(service_name, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, delayed_start)
|
833
|
+
end
|
834
|
+
private :set_startup_mode_delayed
|
835
|
+
|
712
836
|
# @api private
|
713
837
|
# Sends a service control signal to a service
|
714
838
|
#
|
@@ -905,6 +1029,18 @@ module Puppet::Util::Windows
|
|
905
1029
|
attach_function_private :QueryServiceConfigW,
|
906
1030
|
[:handle, :lpbyte, :dword, :lpdword], :win32_bool
|
907
1031
|
|
1032
|
+
# https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-queryserviceconfig2w
|
1033
|
+
# BOOL QueryServiceConfig2W(
|
1034
|
+
# SC_HANDLE hService,
|
1035
|
+
# DWORD dwInfoLevel,
|
1036
|
+
# LPBYTE lpBuffer,
|
1037
|
+
# DWORD cbBufSize,
|
1038
|
+
# LPDWORD pcbBytesNeeded
|
1039
|
+
# );
|
1040
|
+
ffi_lib :advapi32
|
1041
|
+
attach_function_private :QueryServiceConfig2W,
|
1042
|
+
[:handle, :dword, :lpbyte, :dword, :lpdword], :win32_bool
|
1043
|
+
|
908
1044
|
# https://docs.microsoft.com/en-us/windows/desktop/api/Winsvc/nf-winsvc-startservicew
|
909
1045
|
# BOOL StartServiceW(
|
910
1046
|
# SC_HANDLE hService,
|
@@ -955,6 +1091,15 @@ module Puppet::Util::Windows
|
|
955
1091
|
:lpcwstr
|
956
1092
|
], :win32_bool
|
957
1093
|
|
1094
|
+
# https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-changeserviceconfig2w
|
1095
|
+
# BOOL ChangeServiceConfig2W(
|
1096
|
+
# SC_HANDLE hService,
|
1097
|
+
# DWORD dwInfoLevel,
|
1098
|
+
# LPVOID lpInfo
|
1099
|
+
# );
|
1100
|
+
ffi_lib :advapi32
|
1101
|
+
attach_function_private :ChangeServiceConfig2W,
|
1102
|
+
[:handle, :dword, :lpvoid], :win32_bool
|
958
1103
|
|
959
1104
|
# https://docs.microsoft.com/en-us/windows/desktop/api/winsvc/nf-winsvc-enumservicesstatusexw
|
960
1105
|
# BOOL EnumServicesStatusExW(
|