puppet 3.3.2 → 3.4.0.rc1
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.
- data/CONTRIBUTING.md +22 -0
- data/Gemfile +11 -2
- data/README.md +13 -17
- data/README_DEVELOPER.md +1 -1
- data/Rakefile +1 -1
- data/examples/hiera/README.md +4 -4
- data/ext/debian/puppetmaster.init +1 -0
- data/ext/debian/rules +2 -5
- data/ext/nagios/check_puppet.rb +7 -7
- data/ext/osx/file_mapping.yaml +1 -1
- data/ext/osx/preflight.erb +34 -19
- data/ext/rack/{files/config.ru → config.ru} +0 -0
- data/ext/rack/{files/apache2.conf → example-passenger-vhost.conf} +6 -0
- data/ext/redhat/puppet.spec.erb +20 -2
- data/ext/systemd/{puppetagent.service → puppet.service} +0 -0
- data/lib/hiera_puppet.rb +2 -2
- data/lib/puppet/agent.rb +1 -6
- data/lib/puppet/application.rb +15 -2
- data/lib/puppet/application/agent.rb +2 -7
- data/lib/puppet/application/apply.rb +8 -13
- data/lib/puppet/application/cert.rb +47 -7
- data/lib/puppet/application/device.rb +1 -6
- data/lib/puppet/application/face_base.rb +1 -1
- data/lib/puppet/application/filebucket.rb +1 -1
- data/lib/puppet/application/inspect.rb +3 -12
- data/lib/puppet/application/master.rb +1 -6
- data/lib/puppet/application/queue.rb +1 -6
- data/lib/puppet/application/resource.rb +2 -6
- data/lib/puppet/coercion.rb +11 -0
- data/lib/puppet/configurer.rb +5 -3
- data/lib/puppet/configurer/downloader.rb +3 -1
- data/lib/puppet/configurer/plugin_handler.rb +10 -0
- data/lib/puppet/confine.rb +80 -0
- data/lib/puppet/{provider/confine → confine}/exists.rb +3 -3
- data/lib/puppet/{provider/confine → confine}/false.rb +2 -2
- data/lib/puppet/{provider/confine → confine}/feature.rb +2 -2
- data/lib/puppet/{provider/confine → confine}/true.rb +2 -2
- data/lib/puppet/{provider/confine → confine}/variable.rb +2 -2
- data/lib/puppet/{provider/confine_collection.rb → confine_collection.rb} +4 -4
- data/lib/puppet/{provider/confiner.rb → confiner.rb} +4 -4
- data/lib/puppet/daemon.rb +2 -6
- data/lib/puppet/data_binding.rb +2 -30
- data/lib/puppet/defaults.rb +283 -174
- data/lib/puppet/error.rb +1 -0
- data/lib/puppet/external/nagios.rb +0 -2
- data/lib/puppet/external/nagios/base.rb +4 -3
- data/lib/puppet/external/nagios/grammar.ry +173 -112
- data/lib/puppet/external/nagios/parser.rb +233 -184
- data/lib/puppet/face/file/store.rb +1 -1
- data/lib/puppet/face/module/generate.rb +5 -7
- data/lib/puppet/face/parser.rb +12 -2
- data/lib/puppet/face/plugin.rb +6 -0
- data/lib/puppet/feature/base.rb +16 -0
- data/lib/puppet/feature/external_facts.rb +5 -0
- data/lib/puppet/feature/libuser.rb +1 -1
- data/lib/puppet/feature/msgpack.rb +1 -0
- data/lib/puppet/feature/rails.rb +2 -2
- data/lib/puppet/file_bucket/dipper.rb +8 -6
- data/lib/puppet/file_bucket/file.rb +17 -1
- data/lib/puppet/file_serving/base.rb +21 -10
- data/lib/puppet/file_serving/configuration.rb +5 -7
- data/lib/puppet/file_serving/configuration/parser.rb +1 -1
- data/lib/puppet/file_serving/content.rb +1 -1
- data/lib/puppet/file_serving/fileset.rb +3 -3
- data/lib/puppet/file_serving/metadata.rb +22 -18
- data/lib/puppet/file_serving/mount/file.rb +1 -1
- data/lib/puppet/file_serving/mount/pluginfacts.rb +35 -0
- data/lib/puppet/file_system.rb +3 -0
- data/lib/puppet/file_system/file.rb +261 -0
- data/lib/puppet/file_system/file18.rb +5 -0
- data/lib/puppet/file_system/file19.rb +5 -0
- data/lib/puppet/file_system/file19windows.rb +113 -0
- data/lib/puppet/file_system/memory_file.rb +31 -0
- data/lib/puppet/file_system/tempfile.rb +20 -0
- data/lib/puppet/indirector/active_record.rb +1 -0
- data/lib/puppet/indirector/catalog/compiler.rb +28 -0
- data/lib/puppet/indirector/certificate_request/memory.rb +6 -0
- data/lib/puppet/indirector/data_binding/hiera.rb +46 -2
- data/lib/puppet/indirector/direct_file_server.rb +2 -2
- data/lib/puppet/indirector/facts/facter.rb +25 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +60 -74
- data/lib/puppet/indirector/indirection.rb +5 -1
- data/lib/puppet/indirector/json.rb +1 -1
- data/lib/puppet/indirector/key/ca.rb +4 -0
- data/lib/puppet/indirector/key/file.rb +7 -3
- data/lib/puppet/indirector/key/memory.rb +6 -0
- data/lib/puppet/indirector/node/write_only_yaml.rb +2 -2
- data/lib/puppet/indirector/request.rb +17 -11
- data/lib/puppet/indirector/resource/ral.rb +5 -0
- data/lib/puppet/indirector/resource/rest.rb +1 -0
- data/lib/puppet/indirector/resource/store_configs.rb +4 -0
- data/lib/puppet/indirector/rest.rb +2 -1
- data/lib/puppet/indirector/ssl_file.rb +7 -7
- data/lib/puppet/indirector/terminus.rb +4 -0
- data/lib/puppet/indirector/yaml.rb +3 -3
- data/lib/puppet/interface/documentation.rb +4 -11
- data/lib/puppet/module.rb +19 -6
- data/lib/puppet/module_tool/applications/builder.rb +1 -1
- data/lib/puppet/module_tool/applications/installer.rb +1 -1
- data/lib/puppet/module_tool/checksums.rb +1 -1
- data/lib/puppet/module_tool/dependency.rb +7 -3
- data/lib/puppet/module_tool/metadata.rb +6 -2
- data/lib/puppet/module_tool/tar.rb +2 -1
- data/lib/puppet/module_tool/tar/gnu.rb +6 -2
- data/lib/puppet/module_tool/tar/mini.rb +2 -0
- data/lib/puppet/module_tool/tar/solaris.rb +2 -5
- data/lib/puppet/network/authconfig.rb +0 -2
- data/lib/puppet/network/authentication.rb +1 -1
- data/lib/puppet/network/authstore.rb +6 -7
- data/lib/puppet/network/format.rb +2 -3
- data/lib/puppet/network/format_handler.rb +16 -11
- data/lib/puppet/network/format_support.rb +14 -0
- data/lib/puppet/network/formats.rb +26 -0
- data/lib/puppet/network/http/connection.rb +8 -41
- data/lib/puppet/network/http/handler.rb +28 -32
- data/lib/puppet/network/http/webrick.rb +15 -22
- data/lib/puppet/network/http_pool.rb +43 -9
- data/lib/puppet/network/rights.rb +0 -0
- data/lib/puppet/node.rb +24 -8
- data/lib/puppet/node/environment.rb +18 -20
- data/lib/puppet/node/facts.rb +23 -6
- data/lib/puppet/parameter.rb +15 -2
- data/lib/puppet/parameter/boolean.rb +5 -0
- data/lib/puppet/parameter/value_collection.rb +6 -4
- data/lib/puppet/parser/ast/resourceparam.rb +2 -1
- data/lib/puppet/parser/compiler.rb +25 -9
- data/lib/puppet/parser/files.rb +1 -1
- data/lib/puppet/parser/functions.rb +12 -21
- data/lib/puppet/parser/functions/collect.rb +6 -35
- data/lib/puppet/parser/functions/contain.rb +26 -0
- data/lib/puppet/parser/functions/create_resources.rb +5 -0
- data/lib/puppet/parser/functions/extlookup.rb +2 -2
- data/lib/puppet/parser/functions/file.rb +1 -1
- data/lib/puppet/parser/functions/{reject.rb → filter.rb} +13 -12
- data/lib/puppet/parser/functions/fqdn_rand.rb +13 -5
- data/lib/puppet/parser/functions/include.rb +18 -1
- data/lib/puppet/parser/functions/map.rb +44 -0
- data/lib/puppet/parser/functions/select.rb +6 -38
- data/lib/puppet/parser/lexer.rb +1 -1
- data/lib/puppet/parser/parser_support.rb +1 -1
- data/lib/puppet/parser/resource.rb +6 -45
- data/lib/puppet/parser/scope.rb +33 -2
- data/lib/puppet/parser/type_loader.rb +4 -60
- data/lib/puppet/pops/binder/bindings_loader.rb +1 -1
- data/lib/puppet/pops/binder/config/binder_config.rb +3 -3
- data/lib/puppet/pops/binder/hiera2/bindings_provider.rb +1 -1
- data/lib/puppet/pops/binder/scheme_handler/confdir_hiera_scheme.rb +1 -1
- data/lib/puppet/pops/binder/scheme_handler/module_hiera_scheme.rb +2 -2
- data/lib/puppet/pops/issues.rb +4 -0
- data/lib/puppet/pops/model/ast_transformer.rb +4 -1
- data/lib/puppet/pops/model/model_label_provider.rb +1 -1
- data/lib/puppet/pops/parser/egrammar.ra +5 -24
- data/lib/puppet/pops/parser/eparser.rb +859 -902
- data/lib/puppet/pops/parser/lexer.rb +48 -30
- data/lib/puppet/pops/parser/parser_support.rb +1 -1
- data/lib/puppet/pops/patterns.rb +4 -4
- data/lib/puppet/pops/utils.rb +1 -1
- data/lib/puppet/pops/validation/checker3_1.rb +25 -20
- data/lib/puppet/provider.rb +23 -6
- data/lib/puppet/provider/aixobject.rb +0 -0
- data/lib/puppet/provider/augeas/augeas.rb +21 -5
- data/lib/puppet/provider/confine.rb +5 -79
- data/lib/puppet/provider/cron/crontab.rb +0 -0
- data/lib/puppet/provider/exec.rb +9 -7
- data/lib/puppet/provider/exec/posix.rb +10 -1
- data/lib/puppet/provider/exec/windows.rb +1 -1
- data/lib/puppet/provider/file/posix.rb +1 -0
- data/lib/puppet/provider/file/windows.rb +16 -5
- data/lib/puppet/provider/group/aix.rb +0 -0
- data/lib/puppet/provider/group/windows_adsi.rb +33 -1
- data/lib/puppet/provider/macauthorization/macauthorization.rb +1 -1
- data/lib/puppet/provider/mailalias/aliases.rb +0 -0
- data/lib/puppet/provider/maillist/mailman.rb +0 -0
- data/lib/puppet/provider/mount/parsed.rb +0 -0
- data/lib/puppet/provider/nameservice/directoryservice.rb +3 -3
- data/lib/puppet/provider/package/appdmg.rb +1 -1
- data/lib/puppet/provider/package/apple.rb +1 -1
- data/lib/puppet/provider/package/apt.rb +1 -1
- data/lib/puppet/provider/package/aptitude.rb +0 -0
- data/lib/puppet/provider/package/blastwave.rb +1 -1
- data/lib/puppet/provider/package/dpkg.rb +1 -1
- data/lib/puppet/provider/package/fink.rb +1 -1
- data/lib/puppet/provider/package/freebsd.rb +0 -0
- data/lib/puppet/provider/package/gem.rb +0 -0
- data/lib/puppet/provider/package/macports.rb +0 -0
- data/lib/puppet/provider/package/msi.rb +4 -10
- data/lib/puppet/provider/package/nim.rb +8 -8
- data/lib/puppet/provider/package/openbsd.rb +1 -1
- data/lib/puppet/provider/package/opkg.rb +0 -0
- data/lib/puppet/provider/package/pacman.rb +2 -2
- data/lib/puppet/provider/package/pkgdmg.rb +1 -1
- data/lib/puppet/provider/package/pkgutil.rb +1 -1
- data/lib/puppet/provider/package/ports.rb +0 -0
- data/lib/puppet/provider/package/rpm.rb +39 -3
- data/lib/puppet/provider/package/sun.rb +3 -3
- data/lib/puppet/provider/package/sunfreeware.rb +0 -0
- data/lib/puppet/provider/package/windows.rb +12 -19
- data/lib/puppet/provider/package/windows/package.rb +1 -1
- data/lib/puppet/provider/package/yum.rb +2 -2
- data/lib/puppet/provider/parsedfile.rb +0 -0
- data/lib/puppet/provider/port/parsed.rb +0 -0
- data/lib/puppet/provider/service/base.rb +0 -0
- data/lib/puppet/provider/service/bsd.rb +3 -3
- data/lib/puppet/provider/service/daemontools.rb +8 -8
- data/lib/puppet/provider/service/debian.rb +0 -0
- data/lib/puppet/provider/service/freebsd.rb +3 -3
- data/lib/puppet/provider/service/init.rb +5 -4
- data/lib/puppet/provider/service/launchd.rb +35 -24
- data/lib/puppet/provider/service/openbsd.rb +23 -0
- data/lib/puppet/provider/service/redhat.rb +0 -0
- data/lib/puppet/provider/service/runit.rb +3 -3
- data/lib/puppet/provider/service/smf.rb +0 -0
- data/lib/puppet/provider/service/src.rb +0 -0
- data/lib/puppet/provider/service/systemd.rb +0 -0
- data/lib/puppet/provider/service/upstart.rb +3 -3
- data/lib/puppet/provider/ssh_authorized_key/parsed.rb +2 -2
- data/lib/puppet/provider/sshkey/parsed.rb +0 -0
- data/lib/puppet/provider/user/aix.rb +0 -0
- data/lib/puppet/provider/user/directoryservice.rb +1 -1
- data/lib/puppet/provider/user/useradd.rb +1 -1
- data/lib/puppet/provider/zone/solaris.rb +1 -1
- data/lib/puppet/rails/benchmark.rb +1 -1
- data/lib/puppet/reference/configuration.rb +1 -2
- data/lib/puppet/reference/indirection.rb +12 -14
- data/lib/puppet/relationship.rb +7 -4
- data/lib/puppet/reports.rb +2 -2
- data/lib/puppet/reports/rrdgraph.rb +1 -1
- data/lib/puppet/reports/store.rb +3 -3
- data/lib/puppet/reports/tagmail.rb +2 -2
- data/lib/puppet/resource.rb +66 -8
- data/lib/puppet/resource/catalog.rb +18 -25
- data/lib/puppet/resource/status.rb +10 -4
- data/lib/puppet/run.rb +6 -2
- data/lib/puppet/settings.rb +39 -119
- data/lib/puppet/settings/base_setting.rb +8 -9
- data/lib/puppet/settings/directory_setting.rb +8 -0
- data/lib/puppet/settings/file_setting.rb +35 -1
- data/lib/puppet/settings/priority_setting.rb +42 -0
- data/lib/puppet/ssl.rb +4 -0
- data/lib/puppet/ssl/certificate.rb +18 -0
- data/lib/puppet/ssl/certificate_authority.rb +101 -72
- data/lib/puppet/ssl/certificate_authority/autosign_command.rb +44 -0
- data/lib/puppet/ssl/certificate_authority/interface.rb +21 -17
- data/lib/puppet/ssl/certificate_factory.rb +38 -12
- data/lib/puppet/ssl/certificate_request.rb +201 -47
- data/lib/puppet/ssl/certificate_request_attributes.rb +34 -0
- data/lib/puppet/ssl/certificate_revocation_list.rb +2 -2
- data/lib/puppet/ssl/host.rb +21 -10
- data/lib/puppet/ssl/inventory.rb +6 -10
- data/lib/puppet/ssl/key.rb +1 -1
- data/lib/puppet/ssl/oids.rb +78 -0
- data/lib/puppet/ssl/validator.rb +41 -97
- data/lib/puppet/ssl/validator/default_validator.rb +153 -0
- data/lib/puppet/ssl/validator/no_validator.rb +17 -0
- data/lib/puppet/status.rb +4 -0
- data/lib/puppet/test/test_helper.rb +5 -0
- data/lib/puppet/transaction.rb +13 -0
- data/lib/puppet/transaction/event.rb +8 -3
- data/lib/puppet/transaction/report.rb +6 -2
- data/lib/puppet/transaction/resource_harness.rb +173 -115
- data/lib/puppet/type.rb +30 -13
- data/lib/puppet/type/augeas.rb +12 -46
- data/lib/puppet/type/component.rb +1 -7
- data/lib/puppet/type/cron.rb +0 -0
- data/lib/puppet/type/exec.rb +13 -1
- data/lib/puppet/type/file.rb +19 -10
- data/lib/puppet/type/file/checksum.rb +0 -0
- data/lib/puppet/type/file/content.rb +3 -0
- data/lib/puppet/type/file/ensure.rb +33 -15
- data/lib/puppet/type/file/group.rb +0 -0
- data/lib/puppet/type/file/mode.rb +6 -2
- data/lib/puppet/type/file/owner.rb +0 -0
- data/lib/puppet/type/file/source.rb +65 -14
- data/lib/puppet/type/file/target.rb +6 -6
- data/lib/puppet/type/file/type.rb +0 -0
- data/lib/puppet/type/filebucket.rb +0 -0
- data/lib/puppet/type/group.rb +18 -0
- data/lib/puppet/type/host.rb +0 -0
- data/lib/puppet/type/k5login.rb +4 -4
- data/lib/puppet/type/mailalias.rb +0 -0
- data/lib/puppet/type/maillist.rb +0 -0
- data/lib/puppet/type/mount.rb +15 -1
- data/lib/puppet/type/package.rb +7 -1
- data/lib/puppet/type/port.rb +0 -0
- data/lib/puppet/type/schedule.rb +9 -4
- data/lib/puppet/type/service.rb +1 -1
- data/lib/puppet/type/sshkey.rb +0 -0
- data/lib/puppet/type/tidy.rb +1 -1
- data/lib/puppet/type/user.rb +3 -0
- data/lib/puppet/type/yumrepo.rb +8 -6
- data/lib/puppet/type/zpool.rb +0 -0
- data/lib/puppet/util.rb +4 -31
- data/lib/puppet/util/adsi.rb +73 -17
- data/lib/puppet/util/autoload.rb +3 -3
- data/lib/puppet/util/backups.rb +4 -4
- data/lib/puppet/util/cacher.rb +7 -13
- data/lib/puppet/util/checksums.rb +2 -2
- data/lib/puppet/util/classgen.rb +3 -1
- data/lib/puppet/util/colors.rb +1 -0
- data/lib/puppet/util/command_line.rb +5 -0
- data/lib/puppet/util/docs.rb +33 -27
- data/lib/puppet/util/execution.rb +42 -18
- data/lib/puppet/util/filetype.rb +3 -3
- data/lib/puppet/util/instance_loader.rb +2 -2
- data/lib/puppet/util/instrumentation.rb +23 -42
- data/lib/puppet/util/instrumentation/data.rb +11 -4
- data/lib/puppet/util/instrumentation/indirection_probe.rb +11 -4
- data/lib/puppet/util/instrumentation/instrumentable.rb +7 -14
- data/lib/puppet/util/instrumentation/listener.rb +15 -8
- data/lib/puppet/util/instrumentation/listeners/log.rb +4 -10
- data/lib/puppet/util/instrumentation/listeners/performance.rb +8 -14
- data/lib/puppet/util/limits.rb +12 -0
- data/lib/puppet/util/lockfile.rb +2 -2
- data/lib/puppet/util/log.rb +14 -6
- data/lib/puppet/util/log/destinations.rb +23 -1
- data/lib/puppet/util/metric.rb +9 -3
- data/lib/puppet/util/monkey_patches.rb +7 -2
- data/lib/puppet/util/network_device/config.rb +1 -1
- data/lib/puppet/util/plugins.rb +1 -1
- data/lib/puppet/util/posix.rb +0 -0
- data/lib/puppet/util/profiler.rb +7 -2
- data/lib/puppet/util/provider_features.rb +2 -2
- data/lib/puppet/util/rdoc.rb +28 -30
- data/lib/puppet/util/rdoc/code_objects.rb +75 -25
- data/lib/puppet/util/rdoc/generators/puppet_generator.rb +1 -1
- data/lib/puppet/util/rdoc/parser.rb +12 -487
- data/lib/puppet/util/rdoc/parser/puppet_parser_core.rb +477 -0
- data/lib/puppet/util/rdoc/parser/puppet_parser_rdoc1.rb +19 -0
- data/lib/puppet/util/rdoc/parser/puppet_parser_rdoc2.rb +14 -0
- data/lib/puppet/util/reference.rb +1 -1
- data/lib/puppet/util/resource_template.rb +1 -1
- data/lib/puppet/util/selinux.rb +1 -1
- data/lib/puppet/util/storage.rb +2 -2
- data/lib/puppet/util/suidmanager.rb +1 -1
- data/lib/puppet/util/tag_set.rb +29 -0
- data/lib/puppet/util/tagging.rb +8 -24
- data/lib/puppet/util/watched_file.rb +1 -1
- data/lib/puppet/util/watcher.rb +1 -1
- data/lib/puppet/util/windows.rb +3 -0
- data/lib/puppet/util/windows/access_control_entry.rb +84 -0
- data/lib/puppet/util/windows/access_control_list.rb +106 -0
- data/lib/puppet/util/windows/file.rb +213 -0
- data/lib/puppet/util/windows/process.rb +199 -0
- data/lib/puppet/util/windows/root_certs.rb +52 -37
- data/lib/puppet/util/windows/security.rb +270 -245
- data/lib/puppet/util/windows/security_descriptor.rb +62 -0
- data/lib/puppet/util/windows/sid.rb +26 -4
- data/lib/puppet/version.rb +2 -2
- data/spec/fixtures/releases/jamtur01-apache/lib/puppet/provider/a2mod/debian.rb +1 -1
- data/spec/fixtures/unit/indirector/{hiera → data_binding/hiera}/global.yaml +0 -0
- data/spec/fixtures/unit/indirector/data_binding/hiera/invalid.yaml +1 -0
- data/spec/fixtures/unit/module/trailing-comma.json +24 -0
- data/spec/fixtures/unit/util/monkey_patches/x509.pem +32 -0
- data/spec/integration/application/apply_spec.rb +1 -1
- data/spec/integration/application/doc_spec.rb +1 -1
- data/spec/integration/configurer_spec.rb +4 -2
- data/spec/integration/data_binding.rb +100 -0
- data/spec/integration/indirector/catalog/compiler_spec.rb +16 -13
- data/spec/integration/indirector/direct_file_server_spec.rb +3 -5
- data/spec/integration/indirector/file_content/file_server_spec.rb +2 -2
- data/spec/integration/node/facts_spec.rb +1 -1
- data/spec/integration/node_spec.rb +1 -1
- data/spec/integration/parser/compiler_spec.rb +90 -0
- data/spec/integration/parser/parser_spec.rb +2 -2
- data/spec/integration/provider/cron/crontab_spec.rb +3 -5
- data/spec/integration/resource/catalog_spec.rb +1 -1
- data/spec/integration/ssl/autosign_spec.rb +90 -0
- data/spec/integration/ssl/certificate_authority_spec.rb +62 -69
- data/spec/integration/ssl/certificate_revocation_list_spec.rb +1 -1
- data/spec/integration/ssl/host_spec.rb +1 -1
- data/spec/integration/transaction_spec.rb +13 -13
- data/spec/integration/type/exec_spec.rb +2 -2
- data/spec/integration/type/file_spec.rb +287 -45
- data/spec/integration/type/tidy_spec.rb +3 -3
- data/spec/integration/util/rdoc/parser_spec.rb +236 -35
- data/spec/integration/util/settings_spec.rb +1 -1
- data/spec/integration/util/windows/process_spec.rb +22 -0
- data/spec/integration/util/windows/security_spec.rb +316 -106
- data/spec/lib/matchers/containment_matchers.rb +52 -0
- data/spec/lib/puppet_spec/compiler.rb +6 -0
- data/spec/lib/puppet_spec/files.rb +20 -21
- data/spec/shared_behaviours/documentation_on_faces.rb +3 -3
- data/spec/shared_behaviours/file_server_terminus.rb +2 -2
- data/spec/shared_contexts/platform.rb +1 -0
- data/spec/spec_helper.rb +13 -1
- data/spec/unit/agent_spec.rb +0 -12
- data/spec/unit/application/agent_spec.rb +4 -4
- data/spec/unit/application/apply_spec.rb +18 -2
- data/spec/unit/application/cert_spec.rb +8 -6
- data/spec/unit/application/device_spec.rb +1 -1
- data/spec/unit/application/filebucket_spec.rb +1 -1
- data/spec/unit/application/inspect_spec.rb +1 -1
- data/spec/unit/application_spec.rb +24 -0
- data/spec/unit/configurer/downloader_spec.rb +8 -7
- data/spec/unit/configurer/fact_handler_spec.rb +23 -0
- data/spec/unit/configurer/plugin_handler_spec.rb +7 -2
- data/spec/unit/configurer_spec.rb +15 -5
- data/spec/unit/{provider/confine → confine}/exists_spec.rb +12 -12
- data/spec/unit/{provider/confine → confine}/false_spec.rb +9 -9
- data/spec/unit/{provider/confine → confine}/feature_spec.rb +10 -10
- data/spec/unit/{provider/confine → confine}/true_spec.rb +7 -7
- data/spec/unit/{provider/confine → confine}/variable_spec.rb +16 -16
- data/spec/unit/{provider/confine_collection_spec.rb → confine_collection_spec.rb} +30 -30
- data/spec/unit/{provider/confine_spec.rb → confine_spec.rb} +11 -11
- data/spec/unit/{provider/confiner_spec.rb → confiner_spec.rb} +4 -4
- data/spec/unit/face/parser_spec.rb +54 -0
- data/spec/unit/file_bucket/dipper_spec.rb +2 -2
- data/spec/unit/file_serving/base_spec.rb +32 -9
- data/spec/unit/file_serving/configuration_spec.rb +7 -7
- data/spec/unit/file_serving/content_spec.rb +12 -7
- data/spec/unit/file_serving/fileset_spec.rb +57 -27
- data/spec/unit/file_serving/metadata_spec.rb +74 -12
- data/spec/unit/file_serving/mount/file_spec.rb +10 -10
- data/spec/unit/file_serving/mount/pluginfacts_spec.rb +73 -0
- data/spec/unit/file_system/file_spec.rb +486 -0
- data/spec/unit/file_system/tempfile_spec.rb +48 -0
- data/spec/unit/graph/relationship_graph_spec.rb +0 -6
- data/spec/unit/hiera_puppet_spec.rb +2 -2
- data/spec/unit/indirector/catalog/compiler_spec.rb +15 -19
- data/spec/unit/indirector/certificate_status/file_spec.rb +30 -40
- data/spec/unit/indirector/data_binding/hiera_spec.rb +95 -2
- data/spec/unit/indirector/direct_file_server_spec.rb +6 -6
- data/spec/unit/indirector/facts/facter_spec.rb +33 -0
- data/spec/unit/indirector/file_bucket_file/file_spec.rb +61 -52
- data/spec/unit/indirector/file_metadata/file_spec.rb +2 -2
- data/spec/unit/indirector/file_server_spec.rb +4 -4
- data/spec/unit/indirector/json_spec.rb +4 -4
- data/spec/unit/indirector/key/file_spec.rb +13 -14
- data/spec/unit/indirector/resource/ral_spec.rb +7 -0
- data/spec/unit/indirector/resource/store_configs_spec.rb +11 -0
- data/spec/unit/indirector/rest_spec.rb +7 -3
- data/spec/unit/indirector/ssl_file_spec.rb +14 -17
- data/spec/unit/indirector/yaml_spec.rb +4 -4
- data/spec/unit/module_spec.rb +43 -15
- data/spec/unit/module_tool/tar/gnu_spec.rb +2 -2
- data/spec/unit/module_tool/tar/solaris_spec.rb +2 -2
- data/spec/unit/module_tool/tar_spec.rb +45 -0
- data/spec/unit/network/authconfig_spec.rb +2 -1
- data/spec/unit/network/authentication_spec.rb +2 -2
- data/spec/unit/network/format_handler_spec.rb +2 -2
- data/spec/unit/network/formats_spec.rb +24 -0
- data/spec/unit/network/http/connection_spec.rb +76 -199
- data/spec/unit/network/http/handler_spec.rb +33 -34
- data/spec/unit/network/http_pool_spec.rb +8 -5
- data/spec/unit/node/environment_spec.rb +76 -90
- data/spec/unit/node/facts_spec.rb +20 -3
- data/spec/unit/node_spec.rb +43 -0
- data/spec/unit/parameter/boolean_spec.rb +22 -12
- data/spec/unit/parser/ast/resourceparam_spec.rb +51 -0
- data/spec/unit/parser/compiler_spec.rb +103 -35
- data/spec/unit/parser/eparser_adapter_spec.rb +12 -12
- data/spec/unit/parser/files_spec.rb +11 -11
- data/spec/unit/parser/functions/contain_spec.rb +185 -0
- data/spec/unit/parser/functions/create_resources_spec.rb +13 -5
- data/spec/unit/parser/functions/generate_spec.rb +1 -1
- data/spec/unit/parser/functions_spec.rb +2 -2
- data/spec/unit/parser/lexer_spec.rb +1 -1
- data/spec/unit/parser/methods/each_spec.rb +1 -1
- data/spec/unit/parser/methods/{select_spec.rb → filter_spec.rb} +11 -11
- data/spec/unit/parser/methods/map_spec.rb +95 -0
- data/spec/unit/parser/methods/reduce_spec.rb +12 -11
- data/spec/unit/parser/methods/shared.rb +5 -5
- data/spec/unit/parser/methods/slice_spec.rb +13 -13
- data/spec/unit/parser/parser_spec.rb +1 -1
- data/spec/unit/parser/resource/param_spec.rb +44 -0
- data/spec/unit/parser/resource_spec.rb +16 -15
- data/spec/unit/pops/model/ast_transformer_spec.rb +18 -4
- data/spec/unit/pops/parser/lexer_spec.rb +22 -5
- data/spec/unit/pops/parser/parse_calls_spec.rb +5 -5
- data/spec/unit/pops/transformer/transform_calls_spec.rb +6 -6
- data/spec/unit/pops/transformer/transform_containers_spec.rb +2 -2
- data/spec/unit/pops/validator/validator_spec.rb +31 -0
- data/spec/unit/provider/augeas/augeas_spec.rb +57 -2
- data/spec/unit/provider/exec/posix_spec.rb +8 -3
- data/spec/unit/provider/file/posix_spec.rb +2 -2
- data/spec/unit/provider/group/windows_adsi_spec.rb +70 -3
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +3 -3
- data/spec/unit/provider/package/apt_spec.rb +1 -1
- data/spec/unit/provider/package/msi_spec.rb +15 -42
- data/spec/unit/provider/package/openbsd_spec.rb +3 -3
- data/spec/unit/provider/package/rpm_spec.rb +56 -13
- data/spec/unit/provider/package/windows_spec.rb +15 -19
- data/spec/unit/provider/service/base_spec.rb +1 -1
- data/spec/unit/provider/service/daemontools_spec.rb +18 -8
- data/spec/unit/provider/service/freebsd_spec.rb +3 -3
- data/spec/unit/provider/service/gentoo_spec.rb +5 -2
- data/spec/unit/provider/service/init_spec.rb +17 -17
- data/spec/unit/provider/service/launchd_spec.rb +76 -23
- data/spec/unit/provider/service/openbsd_spec.rb +125 -0
- data/spec/unit/provider/service/openwrt_spec.rb +1 -1
- data/spec/unit/provider/service/runit_spec.rb +12 -5
- data/spec/unit/provider/service/upstart_spec.rb +4 -4
- data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +5 -5
- data/spec/unit/provider/user/directoryservice_spec.rb +4 -4
- data/spec/unit/provider/zone/solaris_spec.rb +1 -1
- data/spec/unit/provider_spec.rb +2 -2
- data/spec/unit/reports/http_spec.rb +19 -34
- data/spec/unit/reports/store_spec.rb +2 -2
- data/spec/unit/resource/catalog_spec.rb +81 -11
- data/spec/unit/resource/status_spec.rb +11 -1
- data/spec/unit/resource/type_spec.rb +30 -1
- data/spec/unit/resource_spec.rb +40 -4
- data/spec/unit/settings/file_setting_spec.rb +2 -2
- data/spec/unit/settings/path_setting_spec.rb +2 -2
- data/spec/unit/settings/priority_setting_spec.rb +66 -0
- data/spec/unit/settings_spec.rb +16 -31
- data/spec/unit/ssl/certificate_authority/autosign_command_spec.rb +30 -0
- data/spec/unit/ssl/certificate_authority_spec.rb +129 -134
- data/spec/unit/ssl/certificate_factory_spec.rb +18 -0
- data/spec/unit/ssl/certificate_request_attributes_spec.rb +61 -0
- data/spec/unit/ssl/certificate_request_spec.rb +103 -0
- data/spec/unit/ssl/certificate_spec.rb +31 -18
- data/spec/unit/ssl/host_spec.rb +34 -8
- data/spec/unit/ssl/inventory_spec.rb +27 -62
- data/spec/unit/ssl/key_spec.rb +4 -4
- data/spec/unit/ssl/oids_spec.rb +48 -0
- data/spec/unit/ssl/validator_spec.rb +49 -6
- data/spec/unit/status_spec.rb +9 -0
- data/spec/unit/transaction/event_spec.rb +1 -9
- data/spec/unit/transaction/report_spec.rb +20 -1
- data/spec/unit/transaction/resource_harness_spec.rb +60 -210
- data/spec/unit/transaction_spec.rb +54 -8
- data/spec/unit/type/component_spec.rb +2 -2
- data/spec/unit/type/exec_spec.rb +14 -7
- data/spec/unit/type/file/content_spec.rb +13 -2
- data/spec/unit/type/file/ctime_spec.rb +1 -1
- data/spec/unit/type/file/mode_spec.rb +48 -2
- data/spec/unit/type/file/mtime_spec.rb +1 -1
- data/spec/unit/type/file/source_spec.rb +177 -7
- data/spec/unit/type/file_spec.rb +63 -71
- data/spec/unit/type/group_spec.rb +20 -0
- data/spec/unit/type/k5login_spec.rb +3 -3
- data/spec/unit/type/mount_spec.rb +53 -0
- data/spec/unit/type/nagios_spec.rb +216 -0
- data/spec/unit/type/package_spec.rb +7 -1
- data/spec/unit/type/schedule_spec.rb +6 -0
- data/spec/unit/type/service_spec.rb +3 -3
- data/spec/unit/type/tidy_spec.rb +14 -14
- data/spec/unit/type/user_spec.rb +9 -0
- data/spec/unit/type_spec.rb +86 -4
- data/spec/unit/util/adsi_spec.rb +120 -12
- data/spec/unit/util/autoload_spec.rb +14 -14
- data/spec/unit/util/backups_spec.rb +29 -21
- data/spec/unit/util/checksums_spec.rb +2 -1
- data/spec/unit/util/command_line_spec.rb +41 -0
- data/spec/unit/util/docs_spec.rb +91 -0
- data/spec/unit/util/execution_spec.rb +26 -2
- data/spec/unit/util/filetype_spec.rb +7 -7
- data/spec/unit/util/lockfile_spec.rb +2 -2
- data/spec/unit/util/log/destinations_spec.rb +32 -0
- data/spec/unit/util/monkey_patches_spec.rb +41 -0
- data/spec/unit/util/pidlock_spec.rb +6 -6
- data/spec/unit/util/rdoc/parser_spec.rb +15 -13
- data/spec/unit/util/rdoc_spec.rb +18 -24
- data/spec/unit/util/resource_template_spec.rb +3 -3
- data/spec/unit/util/selinux_spec.rb +4 -2
- data/spec/unit/util/storage_spec.rb +4 -4
- data/spec/unit/util/suidmanager_spec.rb +7 -0
- data/spec/unit/util/tag_set_spec.rb +46 -0
- data/spec/unit/util/tagging_spec.rb +82 -45
- data/spec/unit/util/watcher_spec.rb +4 -1
- data/spec/unit/util/windows/access_control_entry_spec.rb +67 -0
- data/spec/unit/util/windows/access_control_list_spec.rb +133 -0
- data/spec/unit/util/windows/root_certs_spec.rb +10 -8
- data/spec/unit/util/windows/security_descriptor_spec.rb +117 -0
- data/spec/unit/util/windows/sid_spec.rb +69 -0
- data/spec/unit/util_spec.rb +7 -7
- data/tasks/ci.rake +17 -36
- metadata +2811 -2746
- checksums.yaml +0 -7
- data/examples/mac_automount.pp +0 -16
- data/examples/mcx_dock_absent.pp +0 -4
- data/examples/mcx_dock_default.pp +0 -118
- data/examples/mcx_dock_full.pp +0 -125
- data/examples/mcx_dock_invalid.pp +0 -9
- data/examples/mcx_nogroup.pp +0 -118
- data/examples/mcx_notexists_absent.pp +0 -4
- data/ext/rack/README +0 -58
- data/ext/rack/manifest.pp +0 -59
- data/lib/puppet/external/lock.rb +0 -63
- data/lib/puppet/indirector/hiera.rb +0 -39
- data/lib/puppet/parser/functions/foreach.rb +0 -95
- data/spec/integration/network/server/webrick_spec.rb +0 -76
- data/spec/integration/parser/functions_spec.rb +0 -16
- data/spec/unit/indirector/hiera_spec.rb +0 -154
- data/spec/unit/parser/methods/collect_spec.rb +0 -153
- data/spec/unit/parser/methods/foreach_spec.rb +0 -91
- data/spec/unit/parser/methods/reject_spec.rb +0 -73
- data/spec/unit/resource/resource_type.json +0 -34
@@ -8,6 +8,117 @@ module Puppet::Util::Windows::Process
|
|
8
8
|
extend ::Windows::Handle
|
9
9
|
extend ::Windows::Synchronize
|
10
10
|
|
11
|
+
module API
|
12
|
+
require 'ffi'
|
13
|
+
extend FFI::Library
|
14
|
+
ffi_convention :stdcall
|
15
|
+
|
16
|
+
ffi_lib 'kernel32'
|
17
|
+
|
18
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx
|
19
|
+
# HANDLE WINAPI GetCurrentProcess(void);
|
20
|
+
attach_function :get_current_process, :GetCurrentProcess, [], :uint
|
21
|
+
|
22
|
+
# BOOL WINAPI CloseHandle(
|
23
|
+
# _In_ HANDLE hObject
|
24
|
+
# );
|
25
|
+
attach_function :close_handle, :CloseHandle, [:uint], :bool
|
26
|
+
|
27
|
+
ffi_lib 'advapi32'
|
28
|
+
|
29
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx
|
30
|
+
# BOOL WINAPI OpenProcessToken(
|
31
|
+
# _In_ HANDLE ProcessHandle,
|
32
|
+
# _In_ DWORD DesiredAccess,
|
33
|
+
# _Out_ PHANDLE TokenHandle
|
34
|
+
# );
|
35
|
+
attach_function :open_process_token, :OpenProcessToken,
|
36
|
+
[:uint, :uint, :pointer], :bool
|
37
|
+
|
38
|
+
|
39
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa379261(v=vs.85).aspx
|
40
|
+
# typedef struct _LUID {
|
41
|
+
# DWORD LowPart;
|
42
|
+
# LONG HighPart;
|
43
|
+
# } LUID, *PLUID;
|
44
|
+
class LUID < FFI::Struct
|
45
|
+
layout :low_part, :uint,
|
46
|
+
:high_part, :int
|
47
|
+
end
|
48
|
+
|
49
|
+
# http://msdn.microsoft.com/en-us/library/Windows/desktop/aa379180(v=vs.85).aspx
|
50
|
+
# BOOL WINAPI LookupPrivilegeValue(
|
51
|
+
# _In_opt_ LPCTSTR lpSystemName,
|
52
|
+
# _In_ LPCTSTR lpName,
|
53
|
+
# _Out_ PLUID lpLuid
|
54
|
+
# );
|
55
|
+
attach_function :lookup_privilege_value, :LookupPrivilegeValueW,
|
56
|
+
[:buffer_in, :buffer_in, :pointer], :bool
|
57
|
+
|
58
|
+
Token_Information = enum(
|
59
|
+
:token_user, 1,
|
60
|
+
:token_groups,
|
61
|
+
:token_privileges,
|
62
|
+
:token_owner,
|
63
|
+
:token_primary_group,
|
64
|
+
:token_default_dacl,
|
65
|
+
:token_source,
|
66
|
+
:token_type,
|
67
|
+
:token_impersonation_level,
|
68
|
+
:token_statistics,
|
69
|
+
:token_restricted_sids,
|
70
|
+
:token_session_id,
|
71
|
+
:token_groups_and_privileges,
|
72
|
+
:token_session_reference,
|
73
|
+
:token_sandbox_inert,
|
74
|
+
:token_audit_policy,
|
75
|
+
:token_origin,
|
76
|
+
:token_elevation_type,
|
77
|
+
:token_linked_token,
|
78
|
+
:token_elevation,
|
79
|
+
:token_has_restrictions,
|
80
|
+
:token_access_information,
|
81
|
+
:token_virtualization_allowed,
|
82
|
+
:token_virtualization_enabled,
|
83
|
+
:token_integrity_level,
|
84
|
+
:token_ui_access,
|
85
|
+
:token_mandatory_policy,
|
86
|
+
:token_logon_sid,
|
87
|
+
:max_token_info_class
|
88
|
+
)
|
89
|
+
|
90
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa379263(v=vs.85).aspx
|
91
|
+
# typedef struct _LUID_AND_ATTRIBUTES {
|
92
|
+
# LUID Luid;
|
93
|
+
# DWORD Attributes;
|
94
|
+
# } LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
|
95
|
+
class LUID_And_Attributes < FFI::Struct
|
96
|
+
layout :luid, LUID,
|
97
|
+
:attributes, :uint
|
98
|
+
end
|
99
|
+
|
100
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa379630(v=vs.85).aspx
|
101
|
+
# typedef struct _TOKEN_PRIVILEGES {
|
102
|
+
# DWORD PrivilegeCount;
|
103
|
+
# LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
|
104
|
+
# } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
|
105
|
+
class Token_Privileges < FFI::Struct
|
106
|
+
layout :privilege_count, :uint,
|
107
|
+
:privileges, [LUID_And_Attributes, 1] # placeholder for offset
|
108
|
+
end
|
109
|
+
|
110
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx
|
111
|
+
# BOOL WINAPI GetTokenInformation(
|
112
|
+
# _In_ HANDLE TokenHandle,
|
113
|
+
# _In_ TOKEN_INFORMATION_CLASS TokenInformationClass,
|
114
|
+
# _Out_opt_ LPVOID TokenInformation,
|
115
|
+
# _In_ DWORD TokenInformationLength,
|
116
|
+
# _Out_ PDWORD ReturnLength
|
117
|
+
# );
|
118
|
+
attach_function :get_token_information, :GetTokenInformation,
|
119
|
+
[:uint, Token_Information, :pointer, :uint, :pointer ], :bool
|
120
|
+
end
|
121
|
+
|
11
122
|
def execute(command, arguments, stdin, stdout, stderr)
|
12
123
|
Process.create( :command_line => command, :startup_info => {:stdin => stdin, :stdout => stdout, :stderr => stderr}, :close_handles => false )
|
13
124
|
end
|
@@ -33,4 +144,92 @@ module Puppet::Util::Windows::Process
|
|
33
144
|
exit_status
|
34
145
|
end
|
35
146
|
module_function :wait_process
|
147
|
+
|
148
|
+
def get_current_process
|
149
|
+
# this pseudo-handle does not require closing per MSDN docs
|
150
|
+
API.get_current_process
|
151
|
+
end
|
152
|
+
module_function :get_current_process
|
153
|
+
|
154
|
+
def open_process_token(handle, desired_access)
|
155
|
+
token_handle_ptr = FFI::MemoryPointer.new(:uint, 1)
|
156
|
+
result = API.open_process_token(handle, desired_access, token_handle_ptr)
|
157
|
+
if !result
|
158
|
+
raise Puppet::Util::Windows::Error.new(
|
159
|
+
"OpenProcessToken(#{handle}, #{desired_access.to_s(8)}, #{token_handle_ptr})")
|
160
|
+
end
|
161
|
+
|
162
|
+
begin
|
163
|
+
yield token_handle = token_handle_ptr.read_uint
|
164
|
+
ensure
|
165
|
+
API.close_handle(token_handle)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
module_function :open_process_token
|
169
|
+
|
170
|
+
def lookup_privilege_value(name, system_name = '')
|
171
|
+
luid = FFI::MemoryPointer.new(API::LUID.size)
|
172
|
+
result = API.lookup_privilege_value(WideString.new(system_name),
|
173
|
+
WideString.new(name.to_s), luid)
|
174
|
+
|
175
|
+
return API::LUID.new(luid) if result
|
176
|
+
raise Puppet::Util::Windows::Error.new(
|
177
|
+
"LookupPrivilegeValue(#{system_name}, #{name}, #{luid})")
|
178
|
+
end
|
179
|
+
module_function :lookup_privilege_value
|
180
|
+
|
181
|
+
def get_token_information(token_handle, token_information)
|
182
|
+
# to determine buffer size
|
183
|
+
return_length_ptr = FFI::MemoryPointer.new(:uint, 1)
|
184
|
+
result = API.get_token_information(token_handle, token_information, nil, 0, return_length_ptr)
|
185
|
+
return_length = return_length_ptr.read_uint
|
186
|
+
|
187
|
+
if return_length <= 0
|
188
|
+
raise Puppet::Util::Windows::Error.new(
|
189
|
+
"GetTokenInformation(#{token_handle}, #{token_information}, nil, 0, #{return_length_ptr})")
|
190
|
+
end
|
191
|
+
|
192
|
+
# re-call API with properly sized buffer for all results
|
193
|
+
token_information_buf = FFI::MemoryPointer.new(return_length)
|
194
|
+
result = API.get_token_information(token_handle, token_information,
|
195
|
+
token_information_buf, return_length, return_length_ptr)
|
196
|
+
|
197
|
+
if !result
|
198
|
+
raise Puppet::Util::Windows::Error.new(
|
199
|
+
"GetTokenInformation(#{token_handle}, #{token_information}, #{token_information_buf}, " +
|
200
|
+
"#{return_length}, #{return_length_ptr})")
|
201
|
+
end
|
202
|
+
|
203
|
+
raw_privileges = API::Token_Privileges.new(token_information_buf)
|
204
|
+
privileges = { :count => raw_privileges[:privilege_count], :privileges => [] }
|
205
|
+
|
206
|
+
offset = token_information_buf + API::Token_Privileges.offset_of(:privileges)
|
207
|
+
privilege_ptr = FFI::Pointer.new(API::LUID_And_Attributes, offset)
|
208
|
+
|
209
|
+
# extract each instance of LUID_And_Attributes
|
210
|
+
0.upto(privileges[:count] - 1) do |i|
|
211
|
+
privileges[:privileges] << API::LUID_And_Attributes.new(privilege_ptr[i])
|
212
|
+
end
|
213
|
+
|
214
|
+
privileges
|
215
|
+
end
|
216
|
+
module_function :get_token_information
|
217
|
+
|
218
|
+
TOKEN_ALL_ACCESS = 0xF01FF
|
219
|
+
ERROR_NO_SUCH_PRIVILEGE = 1313
|
220
|
+
def process_privilege_symlink?
|
221
|
+
handle = get_current_process
|
222
|
+
open_process_token(handle, TOKEN_ALL_ACCESS) do |token_handle|
|
223
|
+
luid = lookup_privilege_value('SeCreateSymbolicLinkPrivilege')
|
224
|
+
token_info = get_token_information(token_handle, :token_privileges)
|
225
|
+
token_info[:privileges].any? { |p| p[:luid].values == luid.values }
|
226
|
+
end
|
227
|
+
rescue Puppet::Util::Windows::Error => e
|
228
|
+
if e.code == ERROR_NO_SUCH_PRIVILEGE
|
229
|
+
false # pre-Vista
|
230
|
+
else
|
231
|
+
raise e
|
232
|
+
end
|
233
|
+
end
|
234
|
+
module_function :process_privilege_symlink?
|
36
235
|
end
|
@@ -1,17 +1,16 @@
|
|
1
1
|
require 'puppet/util/windows'
|
2
2
|
require 'openssl'
|
3
|
-
require '
|
4
|
-
require 'windows/msvcrt/buffer'
|
3
|
+
require 'ffi'
|
5
4
|
|
6
5
|
# Represents a collection of trusted root certificates.
|
7
6
|
#
|
8
7
|
# @api public
|
9
8
|
class Puppet::Util::Windows::RootCerts
|
10
9
|
include Enumerable
|
10
|
+
extend FFI::Library
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
CertCloseStore = Win32API.new('crypt32', 'CertCloseStore', ['L', 'L'], 'B')
|
12
|
+
typedef :ulong, :dword
|
13
|
+
typedef :uintptr_t, :handle
|
15
14
|
|
16
15
|
def initialize(roots)
|
17
16
|
@roots = roots
|
@@ -24,10 +23,6 @@ class Puppet::Util::Windows::RootCerts
|
|
24
23
|
@roots.each {|cert| yield cert}
|
25
24
|
end
|
26
25
|
|
27
|
-
class << self
|
28
|
-
include Windows::MSVCRT::Buffer
|
29
|
-
end
|
30
|
-
|
31
26
|
# Returns a new instance.
|
32
27
|
# @return [Puppet::Util::Windows::RootCerts] object constructed from current root certificates
|
33
28
|
def self.instance
|
@@ -43,34 +38,12 @@ class Puppet::Util::Windows::RootCerts
|
|
43
38
|
|
44
39
|
# This is based on a patch submitted to openssl:
|
45
40
|
# http://www.mail-archive.com/openssl-dev@openssl.org/msg26958.html
|
46
|
-
|
47
|
-
store =
|
41
|
+
ptr = FFI::Pointer::NULL
|
42
|
+
store = CertOpenSystemStoreA(nil, "ROOT")
|
48
43
|
begin
|
49
|
-
while (
|
50
|
-
|
51
|
-
|
52
|
-
# 468 BYTE *pbCertEncoded;
|
53
|
-
# 469 DWORD cbCertEncoded;
|
54
|
-
# 470 PCERT_INFO pCertInfo;
|
55
|
-
# 471 HCERTSTORE hCertStore;
|
56
|
-
# 472 } CERT_CONTEXT, *PCERT_CONTEXT;
|
57
|
-
|
58
|
-
# buffer to hold struct above
|
59
|
-
ctx_buf = 0.chr * 5 * 8
|
60
|
-
|
61
|
-
# copy from win to ruby
|
62
|
-
memcpy(ctx_buf, context, ctx_buf.size)
|
63
|
-
|
64
|
-
# unpack structure
|
65
|
-
arr = ctx_buf.unpack('LLLLL')
|
66
|
-
|
67
|
-
# create buf of length cbCertEncoded
|
68
|
-
cert_buf = 0.chr * arr[2]
|
69
|
-
|
70
|
-
# copy pbCertEncoded from win to ruby
|
71
|
-
memcpy(cert_buf, arr[1], cert_buf.length)
|
72
|
-
|
73
|
-
# create a cert
|
44
|
+
while (ptr = CertEnumCertificatesInStore(store, ptr)) and not ptr.null?
|
45
|
+
context = CERT_CONTEXT.new(ptr)
|
46
|
+
cert_buf = context[:pbCertEncoded].read_bytes(context[:cbCertEncoded])
|
74
47
|
begin
|
75
48
|
certs << OpenSSL::X509::Certificate.new(cert_buf)
|
76
49
|
rescue => detail
|
@@ -78,9 +51,51 @@ class Puppet::Util::Windows::RootCerts
|
|
78
51
|
end
|
79
52
|
end
|
80
53
|
ensure
|
81
|
-
CertCloseStore
|
54
|
+
CertCloseStore(store, 0)
|
82
55
|
end
|
83
56
|
|
84
57
|
certs
|
85
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# typedef ULONG_PTR HCRYPTPROV_LEGACY;
|
63
|
+
# typedef void *HCERTSTORE;
|
64
|
+
|
65
|
+
class CERT_CONTEXT < FFI::Struct
|
66
|
+
layout(
|
67
|
+
:dwCertEncodingType, :dword,
|
68
|
+
:pbCertEncoded, :pointer,
|
69
|
+
:cbCertEncoded, :dword,
|
70
|
+
:pCertInfo, :pointer,
|
71
|
+
:hCertStore, :handle
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
# HCERTSTORE
|
76
|
+
# WINAPI
|
77
|
+
# CertOpenSystemStoreA(
|
78
|
+
# __in_opt HCRYPTPROV_LEGACY hProv,
|
79
|
+
# __in LPCSTR szSubsystemProtocol
|
80
|
+
# );
|
81
|
+
ffi_lib :crypt32
|
82
|
+
attach_function :CertOpenSystemStoreA, [:pointer, :string], :handle
|
83
|
+
|
84
|
+
# PCCERT_CONTEXT
|
85
|
+
# WINAPI
|
86
|
+
# CertEnumCertificatesInStore(
|
87
|
+
# __in HCERTSTORE hCertStore,
|
88
|
+
# __in_opt PCCERT_CONTEXT pPrevCertContext
|
89
|
+
# );
|
90
|
+
ffi_lib :crypt32
|
91
|
+
attach_function :CertEnumCertificatesInStore, [:handle, :pointer], :pointer
|
92
|
+
|
93
|
+
# BOOL
|
94
|
+
# WINAPI
|
95
|
+
# CertCloseStore(
|
96
|
+
# __in_opt HCERTSTORE hCertStore,
|
97
|
+
# __in DWORD dwFlags
|
98
|
+
# );
|
99
|
+
ffi_lib :crypt32
|
100
|
+
attach_function :CertCloseStore, [:handle, :dword], :bool
|
86
101
|
end
|
@@ -53,6 +53,8 @@
|
|
53
53
|
# enables Puppet to detect when file/dirs are out-of-sync,
|
54
54
|
# especially those that Puppet did not create, but is attempting
|
55
55
|
# to manage.
|
56
|
+
# * A special case of this is S_ISYSTEM_MISSING, which is set when the
|
57
|
+
# SYSTEM permissions are *not* present on the DACL.
|
56
58
|
# * On Unix, the owner and group can be modified without changing the
|
57
59
|
# mode. But on Windows, an access control entry specifies which SID
|
58
60
|
# it applies to. As a result, the set_owner and set_group methods
|
@@ -100,11 +102,13 @@ module Puppet::Util::Windows::Security
|
|
100
102
|
S_IRWXO = 0000007
|
101
103
|
S_ISVTX = 0001000
|
102
104
|
S_IEXTRA = 02000000 # represents an extra ace
|
105
|
+
S_ISYSTEM_MISSING = 04000000
|
103
106
|
|
104
107
|
# constants that are missing from Windows::Security
|
105
108
|
PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
|
106
109
|
UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
|
107
110
|
NO_INHERITANCE = 0x0
|
111
|
+
SE_DACL_PROTECTED = 0x1000
|
108
112
|
|
109
113
|
# Set the owner of the object referenced by +path+ to the specified
|
110
114
|
# +owner_sid+. The owner sid should be of the form "S-1-5-32-544"
|
@@ -112,9 +116,12 @@ module Puppet::Util::Windows::Security
|
|
112
116
|
# SE_RESTORE_NAME privilege in their process token can overwrite the
|
113
117
|
# object's owner to something other than the current user.
|
114
118
|
def set_owner(owner_sid, path)
|
115
|
-
|
119
|
+
sd = get_security_descriptor(path)
|
116
120
|
|
117
|
-
|
121
|
+
if owner_sid != sd.owner
|
122
|
+
sd.owner = owner_sid
|
123
|
+
set_security_descriptor(path, sd)
|
124
|
+
end
|
118
125
|
end
|
119
126
|
|
120
127
|
# Get the owner of the object referenced by +path+. The returned
|
@@ -125,7 +132,7 @@ module Puppet::Util::Windows::Security
|
|
125
132
|
def get_owner(path)
|
126
133
|
return unless supports_acl?(path)
|
127
134
|
|
128
|
-
|
135
|
+
get_security_descriptor(path).owner
|
129
136
|
end
|
130
137
|
|
131
138
|
# Set the owner of the object referenced by +path+ to the specified
|
@@ -134,9 +141,12 @@ module Puppet::Util::Windows::Security
|
|
134
141
|
# access to the object can change the group (regardless of whether
|
135
142
|
# the current user belongs to that group or not).
|
136
143
|
def set_group(group_sid, path)
|
137
|
-
|
144
|
+
sd = get_security_descriptor(path)
|
138
145
|
|
139
|
-
|
146
|
+
if group_sid != sd.group
|
147
|
+
sd.group = group_sid
|
148
|
+
set_security_descriptor(path, sd)
|
149
|
+
end
|
140
150
|
end
|
141
151
|
|
142
152
|
# Get the group of the object referenced by +path+. The returned
|
@@ -147,7 +157,7 @@ module Puppet::Util::Windows::Security
|
|
147
157
|
def get_group(path)
|
148
158
|
return unless supports_acl?(path)
|
149
159
|
|
150
|
-
|
160
|
+
get_security_descriptor(path).group
|
151
161
|
end
|
152
162
|
|
153
163
|
def supports_acl?(path)
|
@@ -163,31 +173,6 @@ module Puppet::Util::Windows::Security
|
|
163
173
|
(flags.unpack('L')[0] & Windows::File::FILE_PERSISTENT_ACLS) != 0
|
164
174
|
end
|
165
175
|
|
166
|
-
def change_sid(old_sid, new_sid, info, path)
|
167
|
-
if old_sid != new_sid
|
168
|
-
mode = get_mode(path)
|
169
|
-
|
170
|
-
string_to_sid_ptr(new_sid) do |psid|
|
171
|
-
with_privilege(SE_RESTORE_NAME) do
|
172
|
-
open_file(path, WRITE_OWNER) do |handle|
|
173
|
-
set_security_info(handle, info, psid)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
# rebuild dacl now that sid has changed
|
179
|
-
set_mode(mode, path)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def get_sid(info, path)
|
184
|
-
with_privilege(SE_BACKUP_NAME) do
|
185
|
-
open_file(path, READ_CONTROL) do |handle|
|
186
|
-
get_security_info(handle, info)
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
176
|
def get_attributes(path)
|
192
177
|
attributes = GetFileAttributes(path)
|
193
178
|
|
@@ -222,6 +207,10 @@ module Puppet::Util::Windows::Security
|
|
222
207
|
(FILE_GENERIC_EXECUTE & ~FILE_READ_ATTRIBUTES) => S_IXOTH
|
223
208
|
}
|
224
209
|
|
210
|
+
def get_aces_for_path_by_sid(path, sid)
|
211
|
+
get_security_descriptor(path).dacl.select { |ace| ace.sid == sid }
|
212
|
+
end
|
213
|
+
|
225
214
|
# Get the mode of the object referenced by +path+. The returned
|
226
215
|
# integer value represents the POSIX-style read, write, and execute
|
227
216
|
# modes for the user, group, and other classes, e.g. 0640. Any user
|
@@ -231,58 +220,61 @@ module Puppet::Util::Windows::Security
|
|
231
220
|
def get_mode(path)
|
232
221
|
return unless supports_acl?(path)
|
233
222
|
|
234
|
-
owner_sid = get_owner(path)
|
235
|
-
group_sid = get_group(path)
|
236
223
|
well_known_world_sid = Win32::Security::SID::Everyone
|
237
224
|
well_known_nobody_sid = Win32::Security::SID::Nobody
|
225
|
+
well_known_system_sid = Win32::Security::SID::LocalSystem
|
238
226
|
|
239
|
-
|
240
|
-
open_file(path, READ_CONTROL) do |handle|
|
241
|
-
mode = 0
|
242
|
-
|
243
|
-
get_dacl(handle).each do |ace|
|
244
|
-
case ace[:sid]
|
245
|
-
when owner_sid
|
246
|
-
MASK_TO_MODE.each_pair do |k,v|
|
247
|
-
if (ace[:mask] & k) == k
|
248
|
-
mode |= (v << 6)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
when group_sid
|
252
|
-
MASK_TO_MODE.each_pair do |k,v|
|
253
|
-
if (ace[:mask] & k) == k
|
254
|
-
mode |= (v << 3)
|
255
|
-
end
|
256
|
-
end
|
257
|
-
when well_known_world_sid
|
258
|
-
MASK_TO_MODE.each_pair do |k,v|
|
259
|
-
if (ace[:mask] & k) == k
|
260
|
-
mode |= (v << 6) | (v << 3) | v
|
261
|
-
end
|
262
|
-
end
|
263
|
-
if File.directory?(path) and (ace[:mask] & (FILE_WRITE_DATA | FILE_EXECUTE | FILE_DELETE_CHILD)) == (FILE_WRITE_DATA | FILE_EXECUTE)
|
264
|
-
mode |= S_ISVTX;
|
265
|
-
end
|
266
|
-
when well_known_nobody_sid
|
267
|
-
if (ace[:mask] & FILE_APPEND_DATA).nonzero?
|
268
|
-
mode |= S_ISVTX
|
269
|
-
end
|
270
|
-
else
|
271
|
-
#puts "Warning, unable to map SID into POSIX mode: #{ace[:sid]}"
|
272
|
-
mode |= S_IEXTRA
|
273
|
-
end
|
227
|
+
mode = S_ISYSTEM_MISSING
|
274
228
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
229
|
+
sd = get_security_descriptor(path)
|
230
|
+
sd.dacl.each do |ace|
|
231
|
+
next if ace.inherit_only?
|
232
|
+
|
233
|
+
case ace.sid
|
234
|
+
when sd.owner
|
235
|
+
MASK_TO_MODE.each_pair do |k,v|
|
236
|
+
if (ace.mask & k) == k
|
237
|
+
mode |= (v << 6)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
when sd.group
|
241
|
+
MASK_TO_MODE.each_pair do |k,v|
|
242
|
+
if (ace.mask & k) == k
|
243
|
+
mode |= (v << 3)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
when well_known_world_sid
|
247
|
+
MASK_TO_MODE.each_pair do |k,v|
|
248
|
+
if (ace.mask & k) == k
|
249
|
+
mode |= (v << 6) | (v << 3) | v
|
279
250
|
end
|
280
251
|
end
|
252
|
+
if File.directory?(path) && (ace.mask & (FILE_WRITE_DATA | FILE_EXECUTE | FILE_DELETE_CHILD)) == (FILE_WRITE_DATA | FILE_EXECUTE)
|
253
|
+
mode |= S_ISVTX;
|
254
|
+
end
|
255
|
+
when well_known_nobody_sid
|
256
|
+
if (ace.mask & FILE_APPEND_DATA).nonzero?
|
257
|
+
mode |= S_ISVTX
|
258
|
+
end
|
259
|
+
when well_known_system_sid
|
260
|
+
else
|
261
|
+
#puts "Warning, unable to map SID into POSIX mode: #{ace.sid}"
|
262
|
+
mode |= S_IEXTRA
|
263
|
+
end
|
281
264
|
|
282
|
-
|
283
|
-
mode
|
265
|
+
if ace.sid == well_known_system_sid
|
266
|
+
mode &= ~S_ISYSTEM_MISSING
|
267
|
+
end
|
268
|
+
|
269
|
+
# if owner and group the same, then user and group modes are the OR of both
|
270
|
+
if sd.owner == sd.group
|
271
|
+
mode |= ((mode & S_IRWXG) << 3) | ((mode & S_IRWXU) >> 3)
|
272
|
+
#puts "owner: #{sd.group}, 0x#{ace.mask.to_s(16)}, #{mode.to_s(8)}"
|
284
273
|
end
|
285
274
|
end
|
275
|
+
|
276
|
+
#puts "get_mode: #{mode.to_s(8)}"
|
277
|
+
mode
|
286
278
|
end
|
287
279
|
|
288
280
|
MODE_TO_MASK = {
|
@@ -305,15 +297,16 @@ module Puppet::Util::Windows::Security
|
|
305
297
|
# privileges in their process token can change the mode for objects
|
306
298
|
# that they do not have read and write access to.
|
307
299
|
def set_mode(mode, path, protected = true)
|
308
|
-
|
309
|
-
group_sid = get_group(path)
|
300
|
+
sd = get_security_descriptor(path)
|
310
301
|
well_known_world_sid = Win32::Security::SID::Everyone
|
311
302
|
well_known_nobody_sid = Win32::Security::SID::Nobody
|
303
|
+
well_known_system_sid = Win32::Security::SID::LocalSystem
|
312
304
|
|
313
305
|
owner_allow = STANDARD_RIGHTS_ALL | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES
|
314
306
|
group_allow = STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | SYNCHRONIZE
|
315
307
|
other_allow = STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | SYNCHRONIZE
|
316
308
|
nobody_allow = 0
|
309
|
+
system_allow = 0
|
317
310
|
|
318
311
|
MODE_TO_MASK.each do |k,v|
|
319
312
|
if ((mode >> 6) & k) == k
|
@@ -331,22 +324,29 @@ module Puppet::Util::Windows::Security
|
|
331
324
|
nobody_allow |= FILE_APPEND_DATA;
|
332
325
|
end
|
333
326
|
|
327
|
+
# caller is NOT managing SYSTEM by using group or owner, so set to FULL
|
328
|
+
if ! [sd.owner, sd.group].include? well_known_system_sid
|
329
|
+
# we don't check S_ISYSTEM_MISSING bit, but automatically carry over existing SYSTEM perms
|
330
|
+
# by default set SYSTEM perms to full
|
331
|
+
system_allow = FILE_ALL_ACCESS
|
332
|
+
end
|
333
|
+
|
334
334
|
isdir = File.directory?(path)
|
335
335
|
|
336
336
|
if isdir
|
337
337
|
if (mode & (S_IWUSR | S_IXUSR)) == (S_IWUSR | S_IXUSR)
|
338
338
|
owner_allow |= FILE_DELETE_CHILD
|
339
339
|
end
|
340
|
-
if (mode & (S_IWGRP | S_IXGRP)) == (S_IWGRP | S_IXGRP)
|
340
|
+
if (mode & (S_IWGRP | S_IXGRP)) == (S_IWGRP | S_IXGRP) && (mode & S_ISVTX) == 0
|
341
341
|
group_allow |= FILE_DELETE_CHILD
|
342
342
|
end
|
343
|
-
if (mode & (S_IWOTH | S_IXOTH)) == (S_IWOTH | S_IXOTH)
|
343
|
+
if (mode & (S_IWOTH | S_IXOTH)) == (S_IWOTH | S_IXOTH) && (mode & S_ISVTX) == 0
|
344
344
|
other_allow |= FILE_DELETE_CHILD
|
345
345
|
end
|
346
346
|
end
|
347
347
|
|
348
348
|
# if owner and group the same, then map group permissions to the one owner ACE
|
349
|
-
isownergroup =
|
349
|
+
isownergroup = sd.owner == sd.group
|
350
350
|
if isownergroup
|
351
351
|
owner_allow |= group_allow
|
352
352
|
end
|
@@ -357,64 +357,37 @@ module Puppet::Util::Windows::Security
|
|
357
357
|
remove_attributes(path, FILE_ATTRIBUTE_READONLY)
|
358
358
|
end
|
359
359
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
end
|
368
|
-
|
369
|
-
#puts "ace: other #{well_known_world_sid}, mask 0x#{other_allow.to_s(16)}"
|
370
|
-
add_access_allowed_ace(acl, other_allow, well_known_world_sid)
|
360
|
+
dacl = Puppet::Util::Windows::AccessControlList.new
|
361
|
+
dacl.allow(sd.owner, owner_allow)
|
362
|
+
unless isownergroup
|
363
|
+
dacl.allow(sd.group, group_allow)
|
364
|
+
end
|
365
|
+
dacl.allow(well_known_world_sid, other_allow)
|
366
|
+
dacl.allow(well_known_nobody_sid, nobody_allow)
|
371
367
|
|
372
|
-
|
373
|
-
|
368
|
+
# TODO: system should be first?
|
369
|
+
dacl.allow(well_known_system_sid, system_allow)
|
374
370
|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
371
|
+
# add inherit-only aces for child dirs and files that are created within the dir
|
372
|
+
if isdir
|
373
|
+
inherit = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE
|
374
|
+
dacl.allow(Win32::Security::SID::CreatorOwner, owner_allow, inherit)
|
375
|
+
dacl.allow(Win32::Security::SID::CreatorGroup, group_allow, inherit)
|
380
376
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
end
|
377
|
+
inherit = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE
|
378
|
+
dacl.allow(Win32::Security::SID::CreatorOwner, owner_allow & ~FILE_EXECUTE, inherit)
|
379
|
+
dacl.allow(Win32::Security::SID::CreatorGroup, group_allow & ~FILE_EXECUTE, inherit)
|
385
380
|
end
|
386
381
|
|
382
|
+
new_sd = Puppet::Util::Windows::SecurityDescriptor.new(sd.owner, sd.group, dacl, protected)
|
383
|
+
set_security_descriptor(path, new_sd)
|
384
|
+
|
387
385
|
nil
|
388
386
|
end
|
389
387
|
|
390
|
-
|
391
|
-
|
392
|
-
def set_acl(path, protected = true)
|
393
|
-
with_privilege(SE_BACKUP_NAME) do
|
394
|
-
with_privilege(SE_RESTORE_NAME) do
|
395
|
-
open_file(path, READ_CONTROL | WRITE_DAC) do |handle|
|
396
|
-
acl = 0.chr * 1024 # This can be increased later as needed
|
397
|
-
|
398
|
-
unless InitializeAcl(acl, acl.size, ACL_REVISION)
|
399
|
-
raise Puppet::Util::Windows::Error.new("Failed to initialize ACL")
|
400
|
-
end
|
401
|
-
|
402
|
-
raise Puppet::Util::Windows::Error.new("Invalid DACL") unless IsValidAcl(acl)
|
403
|
-
|
404
|
-
yield acl
|
405
|
-
|
406
|
-
# protected means the object does not inherit aces from its parent
|
407
|
-
info = DACL_SECURITY_INFORMATION
|
408
|
-
info |= protected ? PROTECTED_DACL_SECURITY_INFORMATION : UNPROTECTED_DACL_SECURITY_INFORMATION
|
409
|
-
|
410
|
-
# set the DACL
|
411
|
-
set_security_info(handle, info, acl)
|
412
|
-
end
|
413
|
-
end
|
414
|
-
end
|
415
|
-
end
|
388
|
+
def add_access_allowed_ace(acl, mask, sid, inherit = nil)
|
389
|
+
inherit ||= NO_INHERITANCE
|
416
390
|
|
417
|
-
def add_access_allowed_ace(acl, mask, sid, inherit = NO_INHERITANCE)
|
418
391
|
string_to_sid_ptr(sid) do |sid_ptr|
|
419
392
|
raise Puppet::Util::Windows::Error.new("Invalid SID") unless IsValidSid(sid_ptr)
|
420
393
|
|
@@ -434,126 +407,68 @@ module Puppet::Util::Windows::Security
|
|
434
407
|
end
|
435
408
|
end
|
436
409
|
|
437
|
-
def
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
410
|
+
def parse_dacl(dacl_ptr)
|
411
|
+
# REMIND: need to handle NULL DACL
|
412
|
+
raise Puppet::Util::Windows::Error.new("Invalid DACL") unless IsValidAcl(dacl_ptr)
|
413
|
+
|
414
|
+
# ACL structure, size and count are the important parts. The
|
415
|
+
# size includes both the ACL structure and all the ACEs.
|
416
|
+
#
|
417
|
+
# BYTE AclRevision
|
418
|
+
# BYTE Padding1
|
419
|
+
# WORD AclSize
|
420
|
+
# WORD AceCount
|
421
|
+
# WORD Padding2
|
422
|
+
acl_buf = 0.chr * 8
|
423
|
+
memcpy(acl_buf, dacl_ptr, acl_buf.size)
|
424
|
+
ace_count = acl_buf.unpack('CCSSS')[3]
|
425
|
+
|
426
|
+
dacl = Puppet::Util::Windows::AccessControlList.new
|
427
|
+
|
428
|
+
# deny all
|
429
|
+
return dacl if ace_count == 0
|
430
|
+
|
431
|
+
0.upto(ace_count - 1) do |i|
|
432
|
+
ace_ptr = [0].pack('L')
|
433
|
+
|
434
|
+
next unless GetAce(dacl_ptr, i, ace_ptr)
|
435
|
+
|
436
|
+
# ACE structures vary depending on the type. All structures
|
437
|
+
# begin with an ACE header, which specifies the type, flags
|
438
|
+
# and size of what follows. We are only concerned with
|
439
|
+
# ACCESS_ALLOWED_ACE and ACCESS_DENIED_ACEs, which have the
|
440
|
+
# same structure:
|
444
441
|
#
|
445
|
-
# BYTE
|
446
|
-
# BYTE
|
447
|
-
# WORD
|
448
|
-
#
|
449
|
-
#
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
# BYTE C AceFlags
|
472
|
-
# WORD S AceSize
|
473
|
-
# DWORD L ACCESS_MASK
|
474
|
-
# DWORD L Sid
|
475
|
-
# .. ...
|
476
|
-
# DWORD L Sid
|
477
|
-
|
478
|
-
ace_buf = 0.chr * 8
|
479
|
-
memcpy(ace_buf, ace_ptr.unpack('L')[0], ace_buf.size)
|
480
|
-
|
481
|
-
ace_type, ace_flags, size, mask = ace_buf.unpack('CCSL')
|
482
|
-
|
483
|
-
# skip aces that only serve to propagate inheritance
|
484
|
-
next if (ace_flags & INHERIT_ONLY_ACE).nonzero?
|
485
|
-
|
486
|
-
case ace_type
|
487
|
-
when ACCESS_ALLOWED_ACE_TYPE
|
488
|
-
sid_ptr = ace_ptr.unpack('L')[0] + 8 # address of ace_ptr->SidStart
|
489
|
-
raise Puppet::Util::Windows::Error.new("Failed to read DACL, invalid SID") unless IsValidSid(sid_ptr)
|
490
|
-
sid = sid_ptr_to_string(sid_ptr)
|
491
|
-
dacl << {:sid => sid, :type => ace_type, :mask => mask}
|
492
|
-
else
|
493
|
-
Puppet.warning "Unsupported access control entry type: 0x#{ace_type.to_s(16)}"
|
494
|
-
end
|
442
|
+
# BYTE C AceType
|
443
|
+
# BYTE C AceFlags
|
444
|
+
# WORD S AceSize
|
445
|
+
# DWORD L ACCESS_MASK
|
446
|
+
# DWORD L Sid
|
447
|
+
# .. ...
|
448
|
+
# DWORD L Sid
|
449
|
+
|
450
|
+
ace_buf = 0.chr * 8
|
451
|
+
memcpy(ace_buf, ace_ptr.unpack('L')[0], ace_buf.size)
|
452
|
+
|
453
|
+
ace_type, ace_flags, size, mask = ace_buf.unpack('CCSL')
|
454
|
+
|
455
|
+
case ace_type
|
456
|
+
when ACCESS_ALLOWED_ACE_TYPE
|
457
|
+
sid_ptr = ace_ptr.unpack('L')[0] + 8 # address of ace_ptr->SidStart
|
458
|
+
raise Puppet::Util::Windows::Error.new("Failed to read DACL, invalid SID") unless IsValidSid(sid_ptr)
|
459
|
+
sid = sid_ptr_to_string(sid_ptr)
|
460
|
+
dacl.allow(sid, mask, ace_flags)
|
461
|
+
when ACCESS_DENIED_ACE_TYPE
|
462
|
+
sid_ptr = ace_ptr.unpack('L')[0] + 8 # address of ace_ptr->SidStart
|
463
|
+
raise Puppet::Util::Windows::Error.new("Failed to read DACL, invalid SID") unless IsValidSid(sid_ptr)
|
464
|
+
sid = sid_ptr_to_string(sid_ptr)
|
465
|
+
dacl.deny(sid, mask, ace_flags)
|
466
|
+
else
|
467
|
+
Puppet.warning "Unsupported access control entry type: 0x#{ace_type.to_s(16)}"
|
495
468
|
end
|
496
|
-
|
497
|
-
dacl
|
498
469
|
end
|
499
|
-
end
|
500
470
|
|
501
|
-
|
502
|
-
dacl = [0].pack('L')
|
503
|
-
sd = [0].pack('L')
|
504
|
-
|
505
|
-
rv = GetSecurityInfo(
|
506
|
-
handle,
|
507
|
-
SE_FILE_OBJECT,
|
508
|
-
DACL_SECURITY_INFORMATION,
|
509
|
-
nil,
|
510
|
-
nil,
|
511
|
-
dacl, #dacl
|
512
|
-
nil, #sacl
|
513
|
-
sd) #sec desc
|
514
|
-
raise Puppet::Util::Windows::Error.new("Failed to get DACL") unless rv == ERROR_SUCCESS
|
515
|
-
begin
|
516
|
-
yield dacl.unpack('L')[0]
|
517
|
-
ensure
|
518
|
-
LocalFree(sd.unpack('L')[0])
|
519
|
-
end
|
520
|
-
end
|
521
|
-
|
522
|
-
# Set the security info on the specified handle.
|
523
|
-
def set_security_info(handle, info, ptr)
|
524
|
-
rv = SetSecurityInfo(
|
525
|
-
handle,
|
526
|
-
SE_FILE_OBJECT,
|
527
|
-
info,
|
528
|
-
(info & OWNER_SECURITY_INFORMATION) == OWNER_SECURITY_INFORMATION ? ptr : nil,
|
529
|
-
(info & GROUP_SECURITY_INFORMATION) == GROUP_SECURITY_INFORMATION ? ptr : nil,
|
530
|
-
(info & DACL_SECURITY_INFORMATION) == DACL_SECURITY_INFORMATION ? ptr : nil,
|
531
|
-
nil)
|
532
|
-
raise Puppet::Util::Windows::Error.new("Failed to set security information") unless rv == ERROR_SUCCESS
|
533
|
-
end
|
534
|
-
|
535
|
-
# Get the SID string, e.g. "S-1-5-32-544", for the specified handle
|
536
|
-
# and type of information (owner, group).
|
537
|
-
def get_security_info(handle, info)
|
538
|
-
sid = [0].pack('L')
|
539
|
-
sd = [0].pack('L')
|
540
|
-
|
541
|
-
rv = GetSecurityInfo(
|
542
|
-
handle,
|
543
|
-
SE_FILE_OBJECT,
|
544
|
-
info, # security info
|
545
|
-
info == OWNER_SECURITY_INFORMATION ? sid : nil,
|
546
|
-
info == GROUP_SECURITY_INFORMATION ? sid : nil,
|
547
|
-
nil, #dacl
|
548
|
-
nil, #sacl
|
549
|
-
sd) #sec desc
|
550
|
-
raise Puppet::Util::Windows::Error.new("Failed to get security information") unless rv == ERROR_SUCCESS
|
551
|
-
|
552
|
-
begin
|
553
|
-
return sid_ptr_to_string(sid.unpack('L')[0])
|
554
|
-
ensure
|
555
|
-
LocalFree(sd.unpack('L')[0])
|
556
|
-
end
|
471
|
+
dacl
|
557
472
|
end
|
558
473
|
|
559
474
|
# Open an existing file with the specified access mode, and execute a
|
@@ -565,7 +480,7 @@ module Puppet::Util::Windows::Security
|
|
565
480
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
566
481
|
0, # security_attributes
|
567
482
|
OPEN_EXISTING,
|
568
|
-
FILE_FLAG_BACKUP_SEMANTICS,
|
483
|
+
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
|
569
484
|
0) # template
|
570
485
|
raise Puppet::Util::Windows::Error.new("Failed to open '#{path}'") if handle == INVALID_HANDLE_VALUE
|
571
486
|
begin
|
@@ -620,4 +535,114 @@ module Puppet::Util::Windows::Security
|
|
620
535
|
CloseHandle(token)
|
621
536
|
end
|
622
537
|
end
|
538
|
+
|
539
|
+
def get_security_descriptor(path)
|
540
|
+
sd = nil
|
541
|
+
|
542
|
+
with_privilege(SE_BACKUP_NAME) do
|
543
|
+
open_file(path, READ_CONTROL) do |handle|
|
544
|
+
owner_sid = [0].pack('L')
|
545
|
+
group_sid = [0].pack('L')
|
546
|
+
dacl = [0].pack('L')
|
547
|
+
ppsd = [0].pack('L')
|
548
|
+
|
549
|
+
rv = GetSecurityInfo(
|
550
|
+
handle,
|
551
|
+
SE_FILE_OBJECT,
|
552
|
+
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
553
|
+
owner_sid,
|
554
|
+
group_sid,
|
555
|
+
dacl,
|
556
|
+
nil, #sacl
|
557
|
+
ppsd) #sec desc
|
558
|
+
raise Puppet::Util::Windows::Error.new("Failed to get security information") unless rv == ERROR_SUCCESS
|
559
|
+
|
560
|
+
begin
|
561
|
+
owner = sid_ptr_to_string(owner_sid.unpack('L')[0])
|
562
|
+
group = sid_ptr_to_string(group_sid.unpack('L')[0])
|
563
|
+
|
564
|
+
control = FFI::MemoryPointer.new(:uint16, 1)
|
565
|
+
revision = FFI::MemoryPointer.new(:uint32, 1)
|
566
|
+
ffsd = FFI::Pointer.new(ppsd.unpack('L')[0])
|
567
|
+
|
568
|
+
if ! API.get_security_descriptor_control(ffsd, control, revision)
|
569
|
+
raise Puppet::Util::Windows::Error.new("Failed to get security descriptor control")
|
570
|
+
end
|
571
|
+
|
572
|
+
protect = (control.read_uint16 & SE_DACL_PROTECTED) == SE_DACL_PROTECTED
|
573
|
+
|
574
|
+
dacl = parse_dacl(dacl.unpack('L')[0])
|
575
|
+
sd = Puppet::Util::Windows::SecurityDescriptor.new(owner, group, dacl, protect)
|
576
|
+
ensure
|
577
|
+
LocalFree(ppsd.unpack('L')[0])
|
578
|
+
end
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
sd
|
583
|
+
end
|
584
|
+
|
585
|
+
# setting DACL requires both READ_CONTROL and WRITE_DACL access rights,
|
586
|
+
# and their respective privileges, SE_BACKUP_NAME and SE_RESTORE_NAME.
|
587
|
+
def set_security_descriptor(path, sd)
|
588
|
+
# REMIND: FFI
|
589
|
+
acl = 0.chr * 1024 # This can be increased later as neede
|
590
|
+
unless InitializeAcl(acl, acl.size, ACL_REVISION)
|
591
|
+
raise Puppet::Util::Windows::Error.new("Failed to initialize ACL")
|
592
|
+
end
|
593
|
+
|
594
|
+
raise Puppet::Util::Windows::Error.new("Invalid DACL") unless IsValidAcl(acl)
|
595
|
+
|
596
|
+
with_privilege(SE_BACKUP_NAME) do
|
597
|
+
with_privilege(SE_RESTORE_NAME) do
|
598
|
+
open_file(path, READ_CONTROL | WRITE_DAC | WRITE_OWNER) do |handle|
|
599
|
+
string_to_sid_ptr(sd.owner) do |ownersid|
|
600
|
+
string_to_sid_ptr(sd.group) do |groupsid|
|
601
|
+
sd.dacl.each do |ace|
|
602
|
+
case ace.type
|
603
|
+
when ACCESS_ALLOWED_ACE_TYPE
|
604
|
+
#puts "ace: allow, sid #{sid_to_name(ace.sid)}, mask 0x#{ace.mask.to_s(16)}"
|
605
|
+
add_access_allowed_ace(acl, ace.mask, ace.sid, ace.flags)
|
606
|
+
when ACCESS_DENIED_ACE_TYPE
|
607
|
+
#puts "ace: deny, sid #{sid_to_name(ace.sid)}, mask 0x#{ace.mask.to_s(16)}"
|
608
|
+
add_access_denied_ace(acl, ace.mask, ace.sid)
|
609
|
+
else
|
610
|
+
raise "We should never get here"
|
611
|
+
# TODO: this should have been a warning in an earlier commit
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
# protected means the object does not inherit aces from its parent
|
616
|
+
flags = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
|
617
|
+
flags |= sd.protect ? PROTECTED_DACL_SECURITY_INFORMATION : UNPROTECTED_DACL_SECURITY_INFORMATION
|
618
|
+
|
619
|
+
rv = SetSecurityInfo(handle,
|
620
|
+
SE_FILE_OBJECT,
|
621
|
+
flags,
|
622
|
+
ownersid,
|
623
|
+
groupsid,
|
624
|
+
acl,
|
625
|
+
nil)
|
626
|
+
raise Puppet::Util::Windows::Error.new("Failed to set security information") unless rv == ERROR_SUCCESS
|
627
|
+
end
|
628
|
+
end
|
629
|
+
end
|
630
|
+
end
|
631
|
+
end
|
632
|
+
end
|
633
|
+
|
634
|
+
module API
|
635
|
+
extend FFI::Library
|
636
|
+
ffi_lib 'kernel32'
|
637
|
+
ffi_convention :stdcall
|
638
|
+
|
639
|
+
# typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
|
640
|
+
# BOOL WINAPI GetSecurityDescriptorControl(
|
641
|
+
# _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
642
|
+
# _Out_ PSECURITY_DESCRIPTOR_CONTROL pControl,
|
643
|
+
# _Out_ LPDWORD lpdwRevision
|
644
|
+
# );
|
645
|
+
ffi_lib :advapi32
|
646
|
+
attach_function :get_security_descriptor_control, :GetSecurityDescriptorControl, [:pointer, :pointer, :pointer], :bool
|
647
|
+
end
|
623
648
|
end
|