bolt 0.23.0 → 0.24.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +5 -2
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +5 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +5 -8
- data/lib/bolt/applicator.rb +11 -8
- data/lib/bolt/boltdir.rb +13 -5
- data/lib/bolt/catalog.rb +22 -47
- data/lib/bolt/config.rb +1 -26
- data/lib/bolt/executor.rb +1 -1
- data/lib/bolt/outputter.rb +0 -9
- data/lib/bolt/outputter/human.rb +29 -14
- data/lib/bolt/outputter/json.rb +12 -1
- data/lib/bolt/pal.rb +12 -10
- data/lib/bolt/target.rb +0 -6
- data/lib/bolt/task.rb +53 -10
- data/lib/bolt/transport/base.rb +1 -6
- data/lib/bolt/transport/local.rb +11 -13
- data/lib/bolt/transport/local/shell.rb +2 -2
- data/lib/bolt/transport/ssh.rb +16 -11
- data/lib/bolt/transport/winrm.rb +8 -11
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_ext/schemas/task.json +12 -5
- data/libexec/apply_catalog.rb +3 -1
- data/libexec/bolt_catalog +4 -0
- data/vendored/puppet/lib/puppet.rb +2 -1
- data/vendored/puppet/lib/puppet/application/agent.rb +2 -6
- data/vendored/puppet/lib/puppet/application/apply.rb +100 -60
- data/vendored/puppet/lib/puppet/application/cert.rb +26 -291
- data/vendored/puppet/lib/puppet/application/device.rb +0 -5
- data/vendored/puppet/lib/puppet/application/lookup.rb +1 -1
- data/vendored/puppet/lib/puppet/application/ssl.rb +133 -0
- data/vendored/puppet/lib/puppet/application_support.rb +1 -2
- data/vendored/puppet/lib/puppet/configurer.rb +34 -50
- data/vendored/puppet/lib/puppet/configurer/downloader.rb +1 -1
- data/vendored/puppet/lib/puppet/configurer/plugin_handler.rb +1 -1
- data/vendored/puppet/lib/puppet/daemon.rb +1 -1
- data/vendored/puppet/lib/puppet/defaults.rb +40 -117
- data/vendored/puppet/lib/puppet/face/epp.rb +2 -2
- data/vendored/puppet/lib/puppet/face/help.rb +21 -7
- data/vendored/puppet/lib/puppet/face/node/clean.rb +14 -10
- data/vendored/puppet/lib/puppet/feature/base.rb +7 -23
- data/vendored/puppet/lib/puppet/feature/eventlog.rb +1 -1
- data/vendored/puppet/lib/puppet/file_serving/base.rb +2 -2
- data/vendored/puppet/lib/puppet/file_serving/fileset.rb +1 -1
- data/vendored/puppet/lib/puppet/file_serving/metadata.rb +2 -2
- data/vendored/puppet/lib/puppet/functions.rb +133 -0
- data/vendored/puppet/lib/puppet/functions/eyaml_lookup_key.rb +4 -5
- data/vendored/puppet/lib/puppet/functions/filter.rb +7 -6
- data/vendored/puppet/lib/puppet/functions/new.rb +37 -53
- data/vendored/puppet/lib/puppet/functions/warning.rb +1 -1
- data/vendored/puppet/lib/puppet/functions/yaml_data.rb +4 -5
- data/vendored/puppet/lib/puppet/gettext/config.rb +1 -1
- data/vendored/puppet/lib/puppet/graph.rb +0 -2
- data/vendored/puppet/lib/puppet/indirector/catalog/json.rb +14 -3
- data/vendored/puppet/lib/puppet/indirector/catalog/yaml.rb +0 -16
- data/vendored/puppet/lib/puppet/indirector/certificate/file.rb +0 -1
- data/vendored/puppet/lib/puppet/indirector/facts/yaml.rb +4 -2
- data/vendored/puppet/lib/puppet/indirector/key/file.rb +1 -6
- data/vendored/puppet/lib/puppet/indirector/node/exec.rb +1 -3
- data/vendored/puppet/lib/puppet/indirector/node/yaml.rb +0 -6
- data/vendored/puppet/lib/puppet/indirector/request.rb +1 -1
- data/vendored/puppet/lib/puppet/indirector/ssl_file.rb +3 -44
- data/vendored/puppet/lib/puppet/indirector/yaml.rb +4 -4
- data/vendored/puppet/lib/puppet/info_service/task_information_service.rb +7 -3
- data/vendored/puppet/lib/puppet/loaders.rb +1 -0
- data/vendored/puppet/lib/puppet/module/task.rb +198 -29
- data/vendored/puppet/lib/puppet/module_tool/applications/unpacker.rb +1 -1
- data/vendored/puppet/lib/puppet/network/format_support.rb +13 -8
- data/vendored/puppet/lib/puppet/network/formats.rb +93 -2
- data/vendored/puppet/lib/puppet/network/http/api/indirected_routes.rb +10 -3
- data/vendored/puppet/lib/puppet/node/facts.rb +11 -1
- data/vendored/puppet/lib/puppet/parser/catalog_compiler.rb +56 -0
- data/vendored/puppet/lib/puppet/parser/compiler.rb +3 -1
- data/vendored/puppet/lib/puppet/parser/functions.rb +3 -1
- data/vendored/puppet/lib/puppet/parser/functions/filter.rb +1 -1
- data/vendored/puppet/lib/puppet/parser/functions/generate.rb +1 -1
- data/vendored/puppet/lib/puppet/parser/functions/sprintf.rb +12 -1
- data/vendored/puppet/lib/puppet/parser/functions/tagged.rb +1 -4
- data/vendored/puppet/lib/puppet/parser/scope.rb +1 -1
- data/vendored/puppet/lib/puppet/parser/script_compiler.rb +7 -2
- data/vendored/puppet/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
- data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_converter.rb +23 -4
- data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_support.rb +3 -4
- data/vendored/puppet/lib/puppet/pops/functions/dispatch.rb +4 -0
- data/vendored/puppet/lib/puppet/pops/issues.rb +8 -0
- data/vendored/puppet/lib/puppet/pops/loader/loader.rb +2 -2
- data/vendored/puppet/lib/puppet/pops/loader/loader_paths.rb +3 -1
- data/vendored/puppet/lib/puppet/pops/loader/module_loaders.rb +30 -9
- data/vendored/puppet/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +62 -0
- data/vendored/puppet/lib/puppet/pops/loader/static_loader.rb +0 -1
- data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +13 -70
- data/vendored/puppet/lib/puppet/pops/loaders.rb +19 -29
- data/vendored/puppet/lib/puppet/pops/lookup/hiera_config.rb +1 -1
- data/vendored/puppet/lib/puppet/pops/model/model_label_provider.rb +4 -1
- data/vendored/puppet/lib/puppet/pops/pcore.rb +10 -33
- data/vendored/puppet/lib/puppet/pops/serialization.rb +2 -0
- data/vendored/puppet/lib/puppet/pops/serialization/from_data_converter.rb +2 -1
- data/vendored/puppet/lib/puppet/pops/serialization/to_data_converter.rb +11 -3
- data/vendored/puppet/lib/puppet/pops/serialization/to_stringified_converter.rb +226 -0
- data/vendored/puppet/lib/puppet/pops/types/p_object_type.rb +3 -0
- data/vendored/puppet/lib/puppet/pops/validation/checker4_0.rb +97 -47
- data/vendored/puppet/lib/puppet/pops/validation/validator_factory_4_0.rb +7 -8
- data/vendored/puppet/lib/puppet/property/keyvalue.rb +70 -8
- data/vendored/puppet/lib/puppet/provider/aix_object.rb +483 -0
- data/vendored/puppet/lib/puppet/provider/file/windows.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/group/aix.rb +51 -112
- data/vendored/puppet/lib/puppet/provider/package/gem.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/pip.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/puppet_gem.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/rpm.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/windows/package.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/zypper.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/service/systemd.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/service/windows.rb +37 -40
- data/vendored/puppet/lib/puppet/provider/user/aix.rb +142 -254
- data/vendored/puppet/lib/puppet/resource.rb +20 -3
- data/vendored/puppet/lib/puppet/resource/catalog.rb +2 -12
- data/vendored/puppet/lib/puppet/rest/routes.rb +97 -34
- data/vendored/puppet/lib/puppet/settings.rb +1 -1
- data/vendored/puppet/lib/puppet/settings/file_setting.rb +1 -1
- data/vendored/puppet/lib/puppet/ssl/base.rb +1 -9
- data/vendored/puppet/lib/puppet/ssl/certificate_request.rb +1 -13
- data/vendored/puppet/lib/puppet/ssl/certificate_request_attributes.rb +1 -1
- data/vendored/puppet/lib/puppet/ssl/host.rb +114 -232
- data/vendored/puppet/lib/puppet/ssl/key.rb +1 -5
- data/vendored/puppet/lib/puppet/ssl/oids.rb +1 -1
- data/vendored/puppet/lib/puppet/test/test_helper.rb +0 -4
- data/vendored/puppet/lib/puppet/transaction/event.rb +3 -7
- data/vendored/puppet/lib/puppet/transaction/persistence.rb +1 -1
- data/vendored/puppet/lib/puppet/type/exec.rb +18 -16
- data/vendored/puppet/lib/puppet/type/file.rb +3 -3
- data/vendored/puppet/lib/puppet/type/file/source.rb +20 -7
- data/vendored/puppet/lib/puppet/type/group.rb +3 -5
- data/vendored/puppet/lib/puppet/type/notify.rb +1 -1
- data/vendored/puppet/lib/puppet/type/package.rb +2 -5
- data/vendored/puppet/lib/puppet/type/schedule.rb +1 -1
- data/vendored/puppet/lib/puppet/type/service.rb +3 -6
- data/vendored/puppet/lib/puppet/type/tidy.rb +1 -1
- data/vendored/puppet/lib/puppet/type/user.rb +13 -20
- data/vendored/puppet/lib/puppet/util.rb +8 -9
- data/vendored/puppet/lib/puppet/util/execution.rb +3 -3
- data/vendored/puppet/lib/puppet/util/feature.rb +61 -39
- data/vendored/puppet/lib/puppet/util/log/destinations.rb +1 -1
- data/vendored/puppet/lib/puppet/util/rdoc.rb +1 -1
- data/vendored/puppet/lib/puppet/util/run_mode.rb +1 -1
- data/vendored/puppet/lib/puppet/util/storage.rb +1 -1
- data/vendored/puppet/lib/puppet/util/suidmanager.rb +7 -5
- data/vendored/puppet/lib/puppet/util/tag_set.rb +1 -1
- data/vendored/puppet/lib/puppet/util/tagging.rb +1 -1
- data/vendored/puppet/lib/puppet/util/windows.rb +18 -2
- data/vendored/puppet/lib/puppet/util/windows/adsi.rb +154 -205
- data/vendored/puppet/lib/puppet/util/windows/service.rb +770 -0
- data/vendored/puppet/lib/puppet/util/yaml.rb +41 -5
- data/vendored/puppet/lib/puppet/version.rb +1 -1
- data/vendored/puppet/lib/puppet_pal.rb +280 -24
- metadata +8 -38
- data/lib/bolt/catalog/compiler.rb +0 -48
- data/lib/bolt/catalog/loaders.rb +0 -19
- data/vendored/puppet/lib/puppet/application/ca.rb +0 -11
- data/vendored/puppet/lib/puppet/application/certificate.rb +0 -17
- data/vendored/puppet/lib/puppet/application/certificate_request.rb +0 -7
- data/vendored/puppet/lib/puppet/application/certificate_revocation_list.rb +0 -7
- data/vendored/puppet/lib/puppet/face/ca.rb +0 -266
- data/vendored/puppet/lib/puppet/face/certificate.rb +0 -167
- data/vendored/puppet/lib/puppet/face/certificate_request.rb +0 -56
- data/vendored/puppet/lib/puppet/face/certificate_revocation_list.rb +0 -56
- data/vendored/puppet/lib/puppet/graph/random_prioritizer.rb +0 -16
- data/vendored/puppet/lib/puppet/graph/title_hash_prioritizer.rb +0 -16
- data/vendored/puppet/lib/puppet/indirector/certificate/ca.rb +0 -9
- data/vendored/puppet/lib/puppet/indirector/certificate/disabled_ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/certificate_request/ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/certificate_request/disabled_ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/ca.rb +0 -8
- data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/disabled_ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/file.rb +0 -8
- data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/rest.rb +0 -11
- data/vendored/puppet/lib/puppet/indirector/certificate_status.rb +0 -4
- data/vendored/puppet/lib/puppet/indirector/certificate_status/file.rb +0 -91
- data/vendored/puppet/lib/puppet/indirector/certificate_status/rest.rb +0 -11
- data/vendored/puppet/lib/puppet/indirector/key/ca.rb +0 -16
- data/vendored/puppet/lib/puppet/indirector/key/disabled_ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/ldap.rb +0 -86
- data/vendored/puppet/lib/puppet/indirector/node/ldap.rb +0 -275
- data/vendored/puppet/lib/puppet/provider/aixobject.rb +0 -392
- data/vendored/puppet/lib/puppet/provider/cron/crontab.rb +0 -297
- data/vendored/puppet/lib/puppet/ssl/certificate_authority.rb +0 -475
- data/vendored/puppet/lib/puppet/ssl/certificate_authority/autosign_command.rb +0 -45
- data/vendored/puppet/lib/puppet/ssl/certificate_authority/interface.rb +0 -324
- data/vendored/puppet/lib/puppet/ssl/certificate_factory.rb +0 -219
- data/vendored/puppet/lib/puppet/ssl/certificate_revocation_list.rb +0 -111
- data/vendored/puppet/lib/puppet/ssl/inventory.rb +0 -55
- data/vendored/puppet/lib/puppet/type/cron.rb +0 -480
@@ -22,13 +22,12 @@ module Util
|
|
22
22
|
require 'puppet/util/posix'
|
23
23
|
extend Puppet::Util::POSIX
|
24
24
|
|
25
|
-
# Can't use Puppet.features.microsoft_windows? as it may be mocked out in a test. This can cause test recurring test failures
|
26
25
|
require 'puppet/util/windows/process' if Puppet::Util::Platform.windows?
|
27
26
|
|
28
27
|
extend Puppet::Util::SymbolicFileMode
|
29
28
|
|
30
29
|
def default_env
|
31
|
-
Puppet.
|
30
|
+
Puppet::Util::Platform.windows? ?
|
32
31
|
:windows :
|
33
32
|
:posix
|
34
33
|
end
|
@@ -272,7 +271,7 @@ module Util
|
|
272
271
|
raise
|
273
272
|
end
|
274
273
|
else
|
275
|
-
if Puppet.
|
274
|
+
if Puppet::Util::Platform.windows? && File.extname(dest).empty?
|
276
275
|
exts.each do |ext|
|
277
276
|
destext = File.expand_path(dest + ext)
|
278
277
|
return destext if FileTest.file? destext and FileTest.executable? destext
|
@@ -322,7 +321,7 @@ module Util
|
|
322
321
|
|
323
322
|
params = { :scheme => 'file' }
|
324
323
|
|
325
|
-
if Puppet.
|
324
|
+
if Puppet::Util::Platform.windows?
|
326
325
|
path = path.gsub(/\\/, '/')
|
327
326
|
|
328
327
|
if unc = /^\/\/([^\/]+)(\/.+)/.match(path)
|
@@ -356,7 +355,7 @@ module Util
|
|
356
355
|
# URI.unescape does, but returns strings in their original encoding
|
357
356
|
path = URI.unescape(uri.path.encode(Encoding::UTF_8))
|
358
357
|
|
359
|
-
if Puppet.
|
358
|
+
if Puppet::Util::Platform.windows? && uri.scheme == 'file'
|
360
359
|
if uri.host
|
361
360
|
path = "//#{uri.host}" + path # UNC
|
362
361
|
else
|
@@ -570,7 +569,7 @@ module Util
|
|
570
569
|
|
571
570
|
mode = symbolic_mode_to_int(normalize_symbolic_mode(default_mode))
|
572
571
|
else
|
573
|
-
if Puppet.
|
572
|
+
if Puppet::Util::Platform.windows?
|
574
573
|
mode = DEFAULT_WINDOWS_MODE
|
575
574
|
else
|
576
575
|
mode = DEFAULT_POSIX_MODE
|
@@ -583,9 +582,9 @@ module Util
|
|
583
582
|
tempfile = Puppet::FileSystem::Uniquefile.new(Puppet::FileSystem.basename_string(file), Puppet::FileSystem.dir_string(file))
|
584
583
|
|
585
584
|
effective_mode =
|
586
|
-
if !Puppet.
|
585
|
+
if !Puppet::Util::Platform.windows?
|
587
586
|
# Grab the current file mode, and fall back to the defaults.
|
588
|
-
|
587
|
+
|
589
588
|
if Puppet::FileSystem.exist?(file)
|
590
589
|
stat = Puppet::FileSystem.lstat(file)
|
591
590
|
tempfile.chown(stat.uid, stat.gid)
|
@@ -620,7 +619,7 @@ module Util
|
|
620
619
|
|
621
620
|
tempfile.close
|
622
621
|
|
623
|
-
if Puppet.
|
622
|
+
if Puppet::Util::Platform.windows?
|
624
623
|
# Windows ReplaceFile needs a file to exist, so touch handles this
|
625
624
|
if !Puppet::FileSystem.exist?(file)
|
626
625
|
Puppet::FileSystem.touch(file)
|
@@ -184,7 +184,7 @@ module Puppet::Util::Execution
|
|
184
184
|
Puppet.debug "Executing#{user_log_s}: '#{command_str}'"
|
185
185
|
end
|
186
186
|
|
187
|
-
null_file = Puppet.
|
187
|
+
null_file = Puppet::Util::Platform.windows? ? 'NUL' : '/dev/null'
|
188
188
|
|
189
189
|
begin
|
190
190
|
stdin = Puppet::FileSystem.open(options[:stdinfile] || null_file, nil, 'r')
|
@@ -264,7 +264,7 @@ module Puppet::Util::Execution
|
|
264
264
|
|
265
265
|
raise e
|
266
266
|
end
|
267
|
-
elsif Puppet.
|
267
|
+
elsif Puppet::Util::Platform.windows?
|
268
268
|
process_info = execute_windows(*exec_args)
|
269
269
|
begin
|
270
270
|
[stdin, stderr].each {|io| io.close rescue nil}
|
@@ -290,7 +290,7 @@ module Puppet::Util::Execution
|
|
290
290
|
if !options[:squelch]
|
291
291
|
# if we opened a pipe, we need to clean it up.
|
292
292
|
reader.close if reader
|
293
|
-
stdout.close! if Puppet.
|
293
|
+
stdout.close! if Puppet::Util::Platform.windows?
|
294
294
|
end
|
295
295
|
end
|
296
296
|
|
@@ -3,40 +3,56 @@ require 'puppet'
|
|
3
3
|
class Puppet::Util::Feature
|
4
4
|
attr_reader :path
|
5
5
|
|
6
|
-
# Create a new feature test.
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
|
6
|
+
# Create a new feature test. You have to pass the feature name, and it must be
|
7
|
+
# unique. You can pass a block to determine if the feature is present:
|
8
|
+
#
|
9
|
+
# Puppet.features.add(:myfeature) do
|
10
|
+
# # return true or false if feature is available
|
11
|
+
# # return nil if feature may become available later
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# The block should return true if the feature is available, false if it is
|
15
|
+
# not, or nil if the state is unknown. True and false values will be cached. A
|
16
|
+
# nil value will not be cached, and should be used if the feature may become
|
17
|
+
# true in the future.
|
18
|
+
#
|
19
|
+
# Features are often used to detect if a ruby library is installed. To support
|
20
|
+
# that common case, you can pass one or more ruby libraries, and the feature
|
21
|
+
# will be true if all of the libraries load successfully:
|
22
|
+
#
|
23
|
+
# Puppet.features.add(:myfeature, libs: 'mylib')
|
24
|
+
# Puppet.features.add(:myfeature, libs: ['mylib', 'myotherlib'])
|
25
|
+
#
|
26
|
+
# If the ruby library is not installed, then the failure is not cached, as
|
27
|
+
# it's assumed puppet may install the gem during catalog application.
|
28
|
+
#
|
29
|
+
# If a feature is defined using `:libs` and a block, then the block is
|
30
|
+
# used and the `:libs` are ignored.
|
31
|
+
#
|
32
|
+
# Puppet evaluates the feature test when the `Puppet.features.myfeature?`
|
33
|
+
# method is called. If the feature test was defined using a block and the
|
34
|
+
# block returns nil, then the feature test will be re-evaluated the next time
|
35
|
+
# `Puppet.features.myfeature?` is called.
|
36
|
+
#
|
37
|
+
# @param [Symbol] name The unique feature name
|
38
|
+
# @param [Hash<Symbol,Array<String>>] options The libraries to load
|
39
|
+
def add(name, options = {}, &block)
|
14
40
|
method = name.to_s + "?"
|
15
41
|
@results.delete(name)
|
16
42
|
|
17
|
-
if block_given?
|
18
|
-
begin
|
19
|
-
result = yield
|
20
|
-
rescue StandardError,ScriptError => detail
|
21
|
-
warn _("Failed to load feature test for %{name}: %{detail}") % { name: name, detail: detail }
|
22
|
-
result = false
|
23
|
-
end
|
24
|
-
@results[name] = result
|
25
|
-
end
|
26
|
-
|
27
43
|
meta_def(method) do
|
28
44
|
# we return a cached result if:
|
29
|
-
# * if
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
45
|
+
# * if we've tested this feature before
|
46
|
+
# AND
|
47
|
+
# * the result was true/false
|
48
|
+
# OR
|
49
|
+
# * we're configured to never retry
|
50
|
+
if @results.has_key?(name) &&
|
51
|
+
(!@results[name].nil? || !Puppet[:always_retry_plugins])
|
52
|
+
!!@results[name]
|
37
53
|
else
|
38
|
-
@results[name] = test(name, options)
|
39
|
-
|
54
|
+
@results[name] = test(name, options, &block)
|
55
|
+
!!@results[name]
|
40
56
|
end
|
41
57
|
end
|
42
58
|
end
|
@@ -64,16 +80,22 @@ class Puppet::Util::Feature
|
|
64
80
|
# Actually test whether the feature is present. We only want to test when
|
65
81
|
# someone asks for the feature, so we don't unnecessarily load
|
66
82
|
# files.
|
67
|
-
def test(name, options)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
83
|
+
def test(name, options, &block)
|
84
|
+
if block_given?
|
85
|
+
begin
|
86
|
+
result = yield
|
87
|
+
rescue StandardError,ScriptError => detail
|
88
|
+
warn _("Failed to load feature test for %{name}: %{detail}") % { name: name, detail: detail }
|
89
|
+
result = nil
|
90
|
+
end
|
91
|
+
@results[name] = result
|
92
|
+
result
|
93
|
+
elsif libs = options[:libs]
|
94
|
+
libs = [libs] unless libs.is_a?(Array)
|
95
|
+
libs.all? { |lib| load_library(lib, name) } ? true : nil
|
96
|
+
else
|
97
|
+
true
|
73
98
|
end
|
74
|
-
|
75
|
-
# We loaded all of the required libraries
|
76
|
-
true
|
77
99
|
end
|
78
100
|
|
79
101
|
private
|
@@ -86,10 +108,10 @@ class Puppet::Util::Feature
|
|
86
108
|
|
87
109
|
begin
|
88
110
|
require lib
|
111
|
+
true
|
89
112
|
rescue ScriptError => detail
|
90
113
|
Puppet.debug _("Failed to load library '%{lib}' for feature '%{name}': %{detail}") % { lib: lib, name: name, detail: detail }
|
91
|
-
|
114
|
+
false
|
92
115
|
end
|
93
|
-
true
|
94
116
|
end
|
95
117
|
end
|
@@ -30,7 +30,7 @@ module Puppet::Util::RDoc
|
|
30
30
|
# replacing Ruby's normal / with \. When RDoc generates relative paths it
|
31
31
|
# uses relative_path_from that will generate errors when the slashes don't
|
32
32
|
# properly match. This is a workaround for that issue.
|
33
|
-
if Puppet.
|
33
|
+
if Puppet::Util::Platform.windows? && RDoc::VERSION !~ /^[0-3]\./
|
34
34
|
options += [ "--root", Dir.pwd.gsub(/\\/, '/')]
|
35
35
|
end
|
36
36
|
options += files
|
@@ -55,7 +55,7 @@ class Puppet::Util::Storage
|
|
55
55
|
end
|
56
56
|
Puppet::Util.benchmark(:debug, "Loaded state in %{seconds} seconds") do
|
57
57
|
begin
|
58
|
-
@@state = Puppet::Util::Yaml.
|
58
|
+
@@state = Puppet::Util::Yaml.safe_load_file(filename, [Symbol, Time])
|
59
59
|
rescue Puppet::Util::Yaml::YamlLoadError => detail
|
60
60
|
Puppet.err _("Checksumfile %{filename} is corrupt (%{detail}); replacing") % { filename: filename, detail: detail }
|
61
61
|
|
@@ -47,10 +47,12 @@ module Puppet::Util::SUIDManager
|
|
47
47
|
module_function :groups=
|
48
48
|
|
49
49
|
def self.root?
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
if Puppet::Util::Platform.windows?
|
51
|
+
require 'puppet/util/windows/user'
|
52
|
+
Puppet::Util::Windows::User.admin?
|
53
|
+
else
|
54
|
+
Process.uid == 0
|
55
|
+
end
|
54
56
|
end
|
55
57
|
|
56
58
|
# Methods to handle changing uid/gid of the running process. In general,
|
@@ -61,7 +63,7 @@ module Puppet::Util::SUIDManager
|
|
61
63
|
# If running on Windows or without root, the block will be run with the
|
62
64
|
# current euid/egid.
|
63
65
|
def asuser(new_uid=nil, new_gid=nil)
|
64
|
-
return yield if Puppet.
|
66
|
+
return yield if Puppet::Util::Platform.windows?
|
65
67
|
return yield unless root?
|
66
68
|
return yield unless new_uid or new_gid
|
67
69
|
|
@@ -10,7 +10,7 @@ module Puppet::Util::Tagging
|
|
10
10
|
def tag(*ary)
|
11
11
|
@tags ||= new_tags
|
12
12
|
|
13
|
-
ary.flatten.each do |tag|
|
13
|
+
ary.flatten.compact.each do |tag|
|
14
14
|
name = tag.to_s.downcase
|
15
15
|
# Add the tag before testing if it's valid since this means that
|
16
16
|
# we never need to test the same valid tag twice. This speeds things
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'puppet/util/platform'
|
2
2
|
module Puppet::Util::Windows
|
3
3
|
module ADSI
|
4
|
-
class
|
4
|
+
class ADSIObject; end
|
5
|
+
class User < ADSIObject; end
|
5
6
|
class UserProfile; end
|
6
|
-
class Group; end
|
7
|
+
class Group < ADSIObject; end
|
7
8
|
end
|
8
9
|
module File; end
|
9
10
|
module Registry
|
@@ -14,6 +15,20 @@ module Puppet::Util::Windows
|
|
14
15
|
class EventLog; end
|
15
16
|
|
16
17
|
if Puppet::Util::Platform.windows?
|
18
|
+
require 'Win32API' # case matters in this require!
|
19
|
+
|
20
|
+
# Note: Setting codepage here globally ensures all strings returned via
|
21
|
+
# WIN32OLE (Ruby's late-bound COM support) are encoded in Encoding::UTF_8
|
22
|
+
#
|
23
|
+
# Also, this does not modify the value of WIN32OLE.locale - which defaults
|
24
|
+
# to 2048 (at least on US English Windows) and is not listed in the MS
|
25
|
+
# locales table, here: https://msdn.microsoft.com/en-us/library/ms912047(v=winembedded.10).aspx
|
26
|
+
require 'win32ole' ; WIN32OLE.codepage = WIN32OLE::CP_UTF8
|
27
|
+
# gems
|
28
|
+
require 'win32/process'
|
29
|
+
require 'win32/dir'
|
30
|
+
require 'win32/service'
|
31
|
+
|
17
32
|
# these reference platform specific gems
|
18
33
|
require 'puppet/util/windows/api_types'
|
19
34
|
require 'puppet/util/windows/string'
|
@@ -32,5 +47,6 @@ module Puppet::Util::Windows
|
|
32
47
|
require 'puppet/util/windows/adsi'
|
33
48
|
require 'puppet/util/windows/registry'
|
34
49
|
require 'puppet/util/windows/eventlog'
|
50
|
+
require 'puppet/util/windows/service'
|
35
51
|
end
|
36
52
|
end
|
@@ -106,138 +106,200 @@ module Puppet::Util::Windows::ADSI
|
|
106
106
|
[:lpwstr, :lpdword], :win32_bool
|
107
107
|
end
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
# for instance VORDEFINIERT on German Windows
|
114
|
-
Puppet::Util::Windows::SID.sid_to_name('S-1-5-32').upcase,
|
115
|
-
# localized version of NT AUTHORITY (can't use S-1-5)
|
116
|
-
# for instance AUTORITE NT on French Windows
|
117
|
-
Puppet::Util::Windows::SID.name_to_principal('SYSTEM').domain.upcase
|
118
|
-
]
|
119
|
-
end
|
109
|
+
# Common base class shared by the User and Group
|
110
|
+
# classes below.
|
111
|
+
class ADSIObject
|
112
|
+
extend Enumerable
|
120
113
|
|
121
|
-
|
122
|
-
|
114
|
+
# Define some useful class-level methods
|
115
|
+
class << self
|
116
|
+
# Is either 'user' or 'group'
|
117
|
+
attr_reader :object_class
|
118
|
+
|
119
|
+
def localized_domains
|
120
|
+
@localized_domains ||= [
|
121
|
+
# localized version of BUILTIN
|
122
|
+
# for instance VORDEFINIERT on German Windows
|
123
|
+
Puppet::Util::Windows::SID.sid_to_name('S-1-5-32').upcase,
|
124
|
+
# localized version of NT AUTHORITY (can't use S-1-5)
|
125
|
+
# for instance AUTORITE NT on French Windows
|
126
|
+
Puppet::Util::Windows::SID.name_to_principal('SYSTEM').domain.upcase
|
127
|
+
]
|
128
|
+
end
|
123
129
|
|
124
|
-
|
125
|
-
|
130
|
+
def uri(name, host = '.')
|
131
|
+
host = '.' if (localized_domains << Socket.gethostname.upcase).include?(host.upcase)
|
132
|
+
Puppet::Util::Windows::ADSI.uri(name, @object_class, host)
|
133
|
+
end
|
126
134
|
|
127
|
-
|
128
|
-
|
135
|
+
def parse_name(name)
|
136
|
+
if name =~ /\//
|
137
|
+
raise Puppet::Error.new( _("Value must be in DOMAIN\\user style syntax") )
|
138
|
+
end
|
129
139
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
end
|
140
|
+
matches = name.scan(/((.*)\\)?(.*)/)
|
141
|
+
domain = matches[0][1] || '.'
|
142
|
+
account = matches[0][2]
|
134
143
|
|
135
|
-
|
136
|
-
|
137
|
-
account = matches[0][2]
|
144
|
+
return account, domain
|
145
|
+
end
|
138
146
|
|
139
|
-
|
140
|
-
|
147
|
+
# returns Puppet::Util::Windows::SID::Principal[]
|
148
|
+
# may contain objects that represent unresolvable SIDs
|
149
|
+
def get_sids(adsi_child_collection)
|
150
|
+
sids = []
|
151
|
+
adsi_child_collection.each do |m|
|
152
|
+
sids << Puppet::Util::Windows::SID.ads_to_principal(m)
|
153
|
+
end
|
141
154
|
|
142
|
-
|
143
|
-
# may contain objects that represent unresolvable SIDs
|
144
|
-
def get_sids(adsi_child_collection)
|
145
|
-
sids = []
|
146
|
-
adsi_child_collection.each do |m|
|
147
|
-
sids << Puppet::Util::Windows::SID.ads_to_principal(m)
|
155
|
+
sids
|
148
156
|
end
|
149
157
|
|
150
|
-
|
151
|
-
|
158
|
+
def name_sid_hash(names)
|
159
|
+
return {} if names.nil? || names.empty?
|
152
160
|
|
153
|
-
|
154
|
-
|
161
|
+
sids = names.map do |name|
|
162
|
+
sid = Puppet::Util::Windows::SID.name_to_principal(name)
|
163
|
+
raise Puppet::Error.new( _("Could not resolve name: %{name}") % { name: name } ) if !sid
|
164
|
+
[sid.sid, sid]
|
165
|
+
end
|
155
166
|
|
156
|
-
|
157
|
-
sid = Puppet::Util::Windows::SID.name_to_principal(name)
|
158
|
-
raise Puppet::Error.new( _("Could not resolve name: %{name}") % { name: name } ) if !sid
|
159
|
-
[sid.sid, sid]
|
167
|
+
Hash[ sids ]
|
160
168
|
end
|
161
169
|
|
162
|
-
Hash[ sids ]
|
163
|
-
end
|
164
|
-
end
|
165
170
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
extend FFI::Library
|
171
|
+
def delete(name)
|
172
|
+
Puppet::Util::Windows::ADSI.delete(name, @object_class)
|
173
|
+
end
|
170
174
|
|
171
|
-
|
172
|
-
|
175
|
+
def exists?(name_or_sid)
|
176
|
+
well_known = false
|
177
|
+
if (sid = Puppet::Util::Windows::SID.name_to_principal(name_or_sid))
|
178
|
+
# Examples of SidType include SidTypeUser, SidTypeGroup
|
179
|
+
return true if sid.account_type == "SidType#{@object_class.capitalize}".to_sym
|
180
|
+
|
181
|
+
# 'well known group' is special as it can be a group like Everyone OR a user like SYSTEM
|
182
|
+
# so try to resolve it
|
183
|
+
# https://msdn.microsoft.com/en-us/library/cc234477.aspx
|
184
|
+
well_known = sid.account_type == :SidTypeWellKnownGroup
|
185
|
+
return false if sid.account_type != :SidTypeAlias && !well_known
|
186
|
+
name_or_sid = "#{sid.domain}\\#{sid.account}"
|
187
|
+
end
|
173
188
|
|
174
|
-
|
189
|
+
object = Puppet::Util::Windows::ADSI.connect(uri(*parse_name(name_or_sid)))
|
190
|
+
object.Class.downcase == @object_class
|
191
|
+
rescue
|
192
|
+
# special accounts like SYSTEM or special groups like Authenticated Users cannot
|
193
|
+
# resolve via monikers like WinNT://./SYSTEM,user or WinNT://./Authenticated Users,group
|
194
|
+
# -- they'll fail to connect. thus, given a validly resolved SID, this failure is
|
195
|
+
# ambiguous as it may indicate either a group like Service or an account like SYSTEM
|
196
|
+
well_known
|
197
|
+
end
|
175
198
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
199
|
+
def list_all
|
200
|
+
raise NotImplementedError, _("Subclass must implement class-level method 'list_all'!")
|
201
|
+
end
|
202
|
+
|
203
|
+
def each(&block)
|
204
|
+
objects = []
|
205
|
+
list_all.each do |o|
|
206
|
+
# Setting WIN32OLE.codepage in the microsoft_windows feature ensures
|
207
|
+
# values are returned as UTF-8
|
208
|
+
objects << new(o.name)
|
209
|
+
end
|
210
|
+
|
211
|
+
objects.each(&block)
|
212
|
+
end
|
181
213
|
end
|
182
214
|
|
183
|
-
|
184
|
-
|
215
|
+
attr_reader :name
|
216
|
+
def initialize(name, native_object = nil)
|
217
|
+
@name = name
|
218
|
+
@native_object = native_object
|
185
219
|
end
|
186
220
|
|
187
|
-
def
|
188
|
-
|
221
|
+
def object_class
|
222
|
+
self.class.object_class
|
189
223
|
end
|
190
224
|
|
191
225
|
def uri
|
192
226
|
self.class.uri(sid.account, sid.domain)
|
193
227
|
end
|
194
228
|
|
195
|
-
def
|
196
|
-
Puppet::Util::Windows::
|
229
|
+
def native_object
|
230
|
+
@native_object ||= Puppet::Util::Windows::ADSI.connect(self.class.uri(*self.class.parse_name(name)))
|
231
|
+
end
|
232
|
+
|
233
|
+
def sid
|
234
|
+
@sid ||= Puppet::Util::Windows::SID.octet_string_to_principal(native_object.objectSID)
|
197
235
|
end
|
198
236
|
|
199
237
|
def [](attribute)
|
200
|
-
# Setting WIN32OLE.codepage
|
201
|
-
|
202
|
-
native_user.Get(attribute)
|
238
|
+
# Setting WIN32OLE.codepage ensures values are returned as UTF-8
|
239
|
+
native_object.Get(attribute)
|
203
240
|
end
|
204
241
|
|
205
242
|
def []=(attribute, value)
|
206
|
-
|
243
|
+
native_object.Put(attribute, value)
|
207
244
|
end
|
208
245
|
|
209
246
|
def commit
|
210
247
|
begin
|
211
|
-
|
248
|
+
native_object.SetInfo
|
212
249
|
rescue WIN32OLERuntimeError => e
|
213
250
|
# ERROR_BAD_USERNAME 2202L from winerror.h
|
214
251
|
if e.message =~ /8007089A/m
|
215
252
|
raise Puppet::Error.new(
|
216
|
-
|
217
|
-
e
|
253
|
+
_("Puppet is not able to create/delete domain %{object_class}s with the %{object_class} resource.") % { object_class: object_class },
|
218
254
|
)
|
219
255
|
end
|
220
256
|
|
221
|
-
raise Puppet::Error.new( _("
|
257
|
+
raise Puppet::Error.new( _("%{object_class} update failed: %{error}") % { object_class: object_class.capitalize, error: e }, e )
|
222
258
|
end
|
223
259
|
self
|
224
260
|
end
|
261
|
+
end
|
262
|
+
|
263
|
+
class User < ADSIObject
|
264
|
+
extend FFI::Library
|
265
|
+
|
266
|
+
require 'puppet/util/windows/sid'
|
267
|
+
|
268
|
+
# https://msdn.microsoft.com/en-us/library/aa746340.aspx
|
269
|
+
# IADsUser interface
|
270
|
+
@object_class = 'user'
|
271
|
+
|
272
|
+
class << self
|
273
|
+
def list_all
|
274
|
+
Puppet::Util::Windows::ADSI.execquery('select name from win32_useraccount where localaccount = "TRUE"')
|
275
|
+
end
|
276
|
+
|
277
|
+
def logon(name, password)
|
278
|
+
Puppet::Util::Windows::User.password_is?(name, password)
|
279
|
+
end
|
280
|
+
|
281
|
+
def create(name)
|
282
|
+
# Windows error 1379: The specified local group already exists.
|
283
|
+
raise Puppet::Error.new(_("Cannot create user if group '%{name}' exists.") % { name: name }) if Puppet::Util::Windows::ADSI::Group.exists? name
|
284
|
+
new(name, Puppet::Util::Windows::ADSI.create(name, @object_class))
|
285
|
+
end
|
286
|
+
end
|
225
287
|
|
226
288
|
def password_is?(password)
|
227
289
|
self.class.logon(name, password)
|
228
290
|
end
|
229
291
|
|
230
292
|
def add_flag(flag_name, value)
|
231
|
-
flag =
|
293
|
+
flag = native_object.Get(flag_name) rescue 0
|
232
294
|
|
233
|
-
|
295
|
+
native_object.Put(flag_name, flag | value)
|
234
296
|
|
235
297
|
commit
|
236
298
|
end
|
237
299
|
|
238
300
|
def password=(password)
|
239
301
|
if !password.nil?
|
240
|
-
|
302
|
+
native_object.SetPassword(password)
|
241
303
|
commit
|
242
304
|
end
|
243
305
|
|
@@ -249,9 +311,8 @@ module Puppet::Util::Windows::ADSI
|
|
249
311
|
# https://msdn.microsoft.com/en-us/library/aa746342.aspx
|
250
312
|
# WIN32OLE objects aren't enumerable, so no map
|
251
313
|
groups = []
|
252
|
-
# Setting WIN32OLE.codepage
|
253
|
-
|
254
|
-
native_user.Groups.each {|g| groups << g.Name} rescue nil
|
314
|
+
# Setting WIN32OLE.codepage ensures values are returned as UTF-8
|
315
|
+
native_object.Groups.each {|g| groups << g.Name} rescue nil
|
255
316
|
groups
|
256
317
|
end
|
257
318
|
|
@@ -281,9 +342,13 @@ module Puppet::Util::Windows::ADSI
|
|
281
342
|
end
|
282
343
|
|
283
344
|
def group_sids
|
284
|
-
self.class.get_sids(
|
345
|
+
self.class.get_sids(native_object.Groups)
|
285
346
|
end
|
286
347
|
|
348
|
+
# TODO: This code's pretty similar to set_members in the Group class. Would be nice
|
349
|
+
# to refactor them into the ADSIObject class at some point. This was not done originally
|
350
|
+
# because these use different methods to do stuff that are also aliased to other methods,
|
351
|
+
# so the shared code isn't exactly a 1:1 mapping.
|
287
352
|
def set_groups(desired_groups, minimum = true)
|
288
353
|
return if desired_groups.nil?
|
289
354
|
|
@@ -311,11 +376,6 @@ module Puppet::Util::Windows::ADSI
|
|
311
376
|
end
|
312
377
|
end
|
313
378
|
|
314
|
-
def self.create(name)
|
315
|
-
# Windows error 1379: The specified local group already exists.
|
316
|
-
raise Puppet::Error.new(_("Cannot create user if group '%{name}' exists.") % { name: name }) if Puppet::Util::Windows::ADSI::Group.exists? name
|
317
|
-
new(name, Puppet::Util::Windows::ADSI.create(name, 'user'))
|
318
|
-
end
|
319
379
|
|
320
380
|
# UNLEN from lmcons.h - https://stackoverflow.com/a/2155176
|
321
381
|
MAX_USERNAME_LENGTH = 256
|
@@ -341,47 +401,6 @@ module Puppet::Util::Windows::ADSI
|
|
341
401
|
Puppet::Util::Windows::SID.name_to_principal(current_user_name)
|
342
402
|
end
|
343
403
|
|
344
|
-
def self.exists?(name_or_sid)
|
345
|
-
well_known = false
|
346
|
-
if (sid = Puppet::Util::Windows::SID.name_to_principal(name_or_sid))
|
347
|
-
return true if sid.account_type == :SidTypeUser
|
348
|
-
|
349
|
-
# 'well known group' is special as it can be a group like Everyone OR a user like SYSTEM
|
350
|
-
# so try to resolve it
|
351
|
-
# https://msdn.microsoft.com/en-us/library/cc234477.aspx
|
352
|
-
well_known = sid.account_type == :SidTypeWellKnownGroup
|
353
|
-
return false if sid.account_type != :SidTypeAlias && !well_known
|
354
|
-
name_or_sid = "#{sid.domain}\\#{sid.account}"
|
355
|
-
end
|
356
|
-
|
357
|
-
user = Puppet::Util::Windows::ADSI.connect(User.uri(*User.parse_name(name_or_sid)))
|
358
|
-
# otherwise, verify that the account is actually a User account
|
359
|
-
user.Class == 'User'
|
360
|
-
rescue
|
361
|
-
# special accounts like SYSTEM cannot resolve via moniker like WinNT://./SYSTEM,user
|
362
|
-
# and thus fail to connect - so given a validly resolved SID, this failure is ambiguous as it
|
363
|
-
# may indicate either a group like Service or an account like SYSTEM
|
364
|
-
well_known
|
365
|
-
end
|
366
|
-
|
367
|
-
|
368
|
-
def self.delete(name)
|
369
|
-
Puppet::Util::Windows::ADSI.delete(name, 'user')
|
370
|
-
end
|
371
|
-
|
372
|
-
def self.each(&block)
|
373
|
-
wql = Puppet::Util::Windows::ADSI.execquery('select name from win32_useraccount where localaccount = "TRUE"')
|
374
|
-
|
375
|
-
users = []
|
376
|
-
wql.each do |u|
|
377
|
-
# Setting WIN32OLE.codepage in the microsoft_windows feature ensures
|
378
|
-
# values are returned as UTF-8
|
379
|
-
users << new(u.name)
|
380
|
-
end
|
381
|
-
|
382
|
-
users.each(&block)
|
383
|
-
end
|
384
|
-
|
385
404
|
ffi_convention :stdcall
|
386
405
|
|
387
406
|
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx
|
@@ -410,58 +429,33 @@ module Puppet::Util::Windows::ADSI
|
|
410
429
|
end
|
411
430
|
end
|
412
431
|
|
413
|
-
class Group
|
414
|
-
extend Enumerable
|
415
|
-
extend Puppet::Util::Windows::ADSI::Shared
|
432
|
+
class Group < ADSIObject
|
416
433
|
|
417
434
|
# https://msdn.microsoft.com/en-us/library/aa706021.aspx
|
418
435
|
# IADsGroup interface
|
436
|
+
@object_class = 'group'
|
419
437
|
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
@native_group = native_group
|
425
|
-
end
|
426
|
-
|
427
|
-
def uri
|
428
|
-
self.class.uri(sid.account, sid.domain)
|
429
|
-
end
|
430
|
-
|
431
|
-
def native_group
|
432
|
-
@native_group ||= Puppet::Util::Windows::ADSI.connect(self.class.uri(*self.class.parse_name(name)))
|
433
|
-
end
|
434
|
-
|
435
|
-
def sid
|
436
|
-
@sid ||= Puppet::Util::Windows::SID.octet_string_to_principal(native_group.objectSID)
|
437
|
-
end
|
438
|
-
|
439
|
-
def commit
|
440
|
-
begin
|
441
|
-
native_group.SetInfo unless native_group.nil?
|
442
|
-
rescue WIN32OLERuntimeError => e
|
443
|
-
# ERROR_BAD_USERNAME 2202L from winerror.h
|
444
|
-
if e.message =~ /8007089A/m
|
445
|
-
raise Puppet::Error.new(
|
446
|
-
_("Puppet is not able to create/delete domain groups with the group resource."),
|
447
|
-
e
|
448
|
-
)
|
449
|
-
end
|
438
|
+
class << self
|
439
|
+
def list_all
|
440
|
+
Puppet::Util::Windows::ADSI.execquery('select name from win32_group where localaccount = "TRUE"')
|
441
|
+
end
|
450
442
|
|
451
|
-
|
443
|
+
def create(name)
|
444
|
+
# Windows error 2224: The account already exists.
|
445
|
+
raise Puppet::Error.new( _("Cannot create group if user '%{name}' exists.") % { name: name } ) if Puppet::Util::Windows::ADSI::User.exists?(name)
|
446
|
+
new(name, Puppet::Util::Windows::ADSI.create(name, @object_class))
|
452
447
|
end
|
453
|
-
self
|
454
448
|
end
|
455
449
|
|
456
450
|
def add_member_sids(*sids)
|
457
451
|
sids.each do |sid|
|
458
|
-
|
452
|
+
native_object.Add(Puppet::Util::Windows::ADSI.sid_uri(sid))
|
459
453
|
end
|
460
454
|
end
|
461
455
|
|
462
456
|
def remove_member_sids(*sids)
|
463
457
|
sids.each do |sid|
|
464
|
-
|
458
|
+
native_object.Remove(Puppet::Util::Windows::ADSI.sid_uri(sid))
|
465
459
|
end
|
466
460
|
end
|
467
461
|
|
@@ -469,7 +463,7 @@ module Puppet::Util::Windows::ADSI
|
|
469
463
|
# may contain objects that represent unresolvable SIDs
|
470
464
|
# qualified account names are returned by calling #domain_account
|
471
465
|
def members
|
472
|
-
self.class.get_sids(
|
466
|
+
self.class.get_sids(native_object.Members)
|
473
467
|
end
|
474
468
|
alias member_sids members
|
475
469
|
|
@@ -496,50 +490,5 @@ module Puppet::Util::Windows::ADSI
|
|
496
490
|
remove_member_sids(*members_to_remove)
|
497
491
|
end
|
498
492
|
end
|
499
|
-
|
500
|
-
def self.create(name)
|
501
|
-
# Windows error 2224: The account already exists.
|
502
|
-
raise Puppet::Error.new( _("Cannot create group if user '%{name}' exists.") % { name: name } ) if Puppet::Util::Windows::ADSI::User.exists? name
|
503
|
-
new(name, Puppet::Util::Windows::ADSI.create(name, 'group'))
|
504
|
-
end
|
505
|
-
|
506
|
-
def self.exists?(name_or_sid)
|
507
|
-
well_known = false
|
508
|
-
if (sid = Puppet::Util::Windows::SID.name_to_principal(name_or_sid))
|
509
|
-
return true if sid.account_type == :SidTypeGroup
|
510
|
-
|
511
|
-
# 'well known group' is special as it can be a group like Everyone OR a user like SYSTEM
|
512
|
-
# so try to resolve it
|
513
|
-
# https://msdn.microsoft.com/en-us/library/cc234477.aspx
|
514
|
-
well_known = sid.account_type == :SidTypeWellKnownGroup
|
515
|
-
return false if sid.account_type != :SidTypeAlias && !well_known
|
516
|
-
name_or_sid = "#{sid.domain}\\#{sid.account}"
|
517
|
-
end
|
518
|
-
|
519
|
-
user = Puppet::Util::Windows::ADSI.connect(Group.uri(*Group.parse_name(name_or_sid)))
|
520
|
-
user.Class == 'Group'
|
521
|
-
rescue
|
522
|
-
# special groups like Authenticated Users cannot resolve via moniker like WinNT://./Authenticated Users,group
|
523
|
-
# and thus fail to connect - so given a validly resolved SID, this failure is ambiguous as it
|
524
|
-
# may indicate either a group like Service or an account like SYSTEM
|
525
|
-
well_known
|
526
|
-
end
|
527
|
-
|
528
|
-
def self.delete(name)
|
529
|
-
Puppet::Util::Windows::ADSI.delete(name, 'group')
|
530
|
-
end
|
531
|
-
|
532
|
-
def self.each(&block)
|
533
|
-
wql = Puppet::Util::Windows::ADSI.execquery('select name from win32_group where localaccount = "TRUE"')
|
534
|
-
|
535
|
-
groups = []
|
536
|
-
wql.each do |g|
|
537
|
-
# Setting WIN32OLE.codepage in the microsoft_windows feature ensures
|
538
|
-
# values are returned as UTF-8
|
539
|
-
groups << new(g.name)
|
540
|
-
end
|
541
|
-
|
542
|
-
groups.each(&block)
|
543
|
-
end
|
544
493
|
end
|
545
494
|
end
|