chef 11.18.12-x86-mingw32 → 12.0.0.alpha.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +10 -0
- data/README.md +1 -1
- data/distro/common/html/_sources/index.txt +5 -2
- data/distro/common/html/_sources/knife_serve.txt +19 -0
- data/distro/common/html/_sources/knife_ssl_check.txt +2 -2
- data/distro/common/html/_sources/knife_ssl_fetch.txt +2 -2
- data/distro/common/html/_static/basic.css +1 -1
- data/distro/common/html/_static/doctools.js +1 -1
- data/distro/common/html/_static/searchtools.js +1 -1
- data/distro/common/html/_static/websupport.js +1 -1
- data/distro/common/html/ctl_chef_client.html +19 -9
- data/distro/common/html/ctl_chef_server.html +7 -1
- data/distro/common/html/ctl_chef_shell.html +3 -4
- data/distro/common/html/ctl_chef_solo.html +12 -7
- data/distro/common/html/index.html +19 -12
- data/distro/common/html/knife.html +1 -2
- data/distro/common/html/knife_bootstrap.html +16 -5
- data/distro/common/html/knife_client.html +8 -5
- data/distro/common/html/knife_common_options.html +11 -12
- data/distro/common/html/knife_configure.html +2 -3
- data/distro/common/html/knife_cookbook.html +16 -17
- data/distro/common/html/knife_cookbook_site.html +19 -18
- data/distro/common/html/knife_data_bag.html +6 -7
- data/distro/common/html/knife_delete.html +2 -3
- data/distro/common/html/knife_deps.html +2 -3
- data/distro/common/html/knife_diff.html +3 -4
- data/distro/common/html/knife_download.html +6 -7
- data/distro/common/html/knife_edit.html +0 -1
- data/distro/common/html/knife_environment.html +3 -4
- data/distro/common/html/knife_exec.html +0 -1
- data/distro/common/html/knife_index_rebuild.html +0 -1
- data/distro/common/html/knife_list.html +5 -6
- data/distro/common/html/knife_node.html +13 -6
- data/distro/common/html/knife_raw.html +0 -1
- data/distro/common/html/knife_recipe_list.html +0 -1
- data/distro/common/html/knife_role.html +1 -2
- data/distro/common/html/knife_search.html +2 -3
- data/distro/common/html/knife_serve.html +79 -0
- data/distro/common/html/knife_show.html +1 -2
- data/distro/common/html/knife_ssh.html +2 -3
- data/distro/common/html/knife_ssl_check.html +12 -9
- data/distro/common/html/knife_ssl_fetch.html +9 -10
- data/distro/common/html/knife_status.html +2 -3
- data/distro/common/html/knife_tag.html +0 -1
- data/distro/common/html/knife_upload.html +3 -4
- data/distro/common/html/knife_user.html +2 -3
- data/distro/common/html/knife_using.html +0 -1
- data/distro/common/html/knife_xargs.html +3 -4
- data/distro/common/html/search.html +0 -1
- data/distro/common/html/searchindex.js +1 -1
- data/lib/chef/api_client.rb +1 -1
- data/lib/chef/application.rb +24 -67
- data/lib/chef/application/client.rb +1 -1
- data/lib/chef/application/knife.rb +1 -1
- data/lib/chef/chef_fs/chef_fs_data_store.rb +2 -3
- data/lib/chef/chef_fs/command_line.rb +2 -3
- data/lib/chef/chef_fs/data_handler/group_data_handler.rb +1 -5
- data/lib/chef/chef_fs/file_system/acl_entry.rb +1 -2
- data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +1 -2
- data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +2 -2
- data/lib/chef/chef_fs/file_system/rest_list_dir.rb +2 -3
- data/lib/chef/chef_fs/file_system/rest_list_entry.rb +4 -5
- data/lib/chef/config.rb +26 -2
- data/lib/chef/config_fetcher.rb +1 -1
- data/lib/chef/cookbook/cookbook_version_loader.rb +4 -4
- data/lib/chef/cookbook/metadata.rb +1 -1
- data/lib/chef/cookbook/synchronizer.rb +50 -8
- data/lib/chef/cookbook_uploader.rb +9 -23
- data/lib/chef/cookbook_version.rb +3 -2
- data/lib/chef/data_bag.rb +1 -1
- data/lib/chef/data_bag_item.rb +1 -1
- data/lib/chef/dsl/recipe.rb +1 -14
- data/lib/chef/encrypted_data_bag_item/decryptor.rb +3 -3
- data/lib/chef/environment.rb +1 -1
- data/lib/chef/exceptions.rb +2 -24
- data/lib/chef/file_content_management/tempfile.rb +8 -1
- data/lib/chef/formatters/base.rb +0 -7
- data/lib/chef/http.rb +12 -19
- data/lib/chef/http/json_input.rb +12 -1
- data/lib/chef/json_compat.rb +45 -64
- data/lib/chef/knife.rb +2 -5
- data/lib/chef/knife/bootstrap.rb +2 -2
- data/lib/chef/knife/bootstrap/archlinux-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/centos5-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/chef-aix.erb +2 -2
- data/lib/chef/knife/bootstrap/chef-full.erb +2 -2
- data/lib/chef/knife/bootstrap/fedora13-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +2 -2
- data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +2 -2
- data/lib/chef/knife/cookbook_site_download.rb +1 -1
- data/lib/chef/knife/cookbook_site_install.rb +10 -34
- data/lib/chef/knife/cookbook_site_list.rb +1 -1
- data/lib/chef/knife/cookbook_site_search.rb +1 -1
- data/lib/chef/knife/cookbook_site_share.rb +3 -3
- data/lib/chef/knife/cookbook_site_show.rb +3 -3
- data/lib/chef/knife/cookbook_site_unshare.rb +1 -1
- data/lib/chef/knife/cookbook_upload.rb +1 -1
- data/lib/chef/knife/core/subcommand_loader.rb +0 -24
- data/lib/chef/knife/core/ui.rb +8 -7
- data/lib/chef/knife/deps.rb +2 -3
- data/lib/chef/knife/serve.rb +2 -1
- data/lib/chef/local_mode.rb +105 -0
- data/lib/chef/mixin/file_class.rb +1 -4
- data/lib/chef/mixin/shell_out.rb +15 -0
- data/lib/chef/mixin/windows_architecture_helper.rb +0 -16
- data/lib/chef/node.rb +1 -1
- data/lib/chef/platform/query_helpers.rb +1 -5
- data/lib/chef/policy_builder/expand_node_object.rb +3 -0
- data/lib/chef/provider.rb +2 -0
- data/lib/chef/provider/cookbook_file.rb +0 -1
- data/lib/chef/provider/deploy.rb +0 -1
- data/lib/chef/provider/deploy/revision.rb +1 -1
- data/lib/chef/provider/env.rb +10 -25
- data/lib/chef/provider/env/windows.rb +23 -10
- data/lib/chef/provider/execute.rb +0 -3
- data/lib/chef/provider/file.rb +0 -3
- data/lib/chef/provider/git.rb +0 -6
- data/lib/chef/provider/group/dscl.rb +9 -27
- data/lib/chef/provider/group/gpasswd.rb +0 -3
- data/lib/chef/provider/group/groupmod.rb +0 -4
- data/lib/chef/provider/group/suse.rb +0 -3
- data/lib/chef/provider/group/usermod.rb +0 -3
- data/lib/chef/provider/link.rb +22 -5
- data/lib/chef/provider/log.rb +15 -4
- data/lib/chef/provider/mdadm.rb +0 -3
- data/lib/chef/provider/mount/mount.rb +0 -2
- data/lib/chef/provider/mount/solaris.rb +0 -2
- data/lib/chef/provider/package.rb +0 -1
- data/lib/chef/provider/package/apt.rb +0 -3
- data/lib/chef/provider/package/dpkg.rb +0 -1
- data/lib/chef/provider/package/easy_install.rb +0 -4
- data/lib/chef/provider/package/freebsd/base.rb +0 -3
- data/lib/chef/provider/package/freebsd/pkgng.rb +0 -2
- data/lib/chef/provider/package/freebsd/port.rb +0 -2
- data/lib/chef/provider/package/ips.rb +0 -3
- data/lib/chef/provider/package/paludis.rb +0 -5
- data/lib/chef/provider/package/portage.rb +0 -2
- data/lib/chef/provider/package/rpm.rb +2 -4
- data/lib/chef/provider/package/rubygems.rb +0 -4
- data/lib/chef/provider/package/smartos.rb +0 -3
- data/lib/chef/provider/package/windows/msi.rb +0 -2
- data/lib/chef/provider/package/yum.rb +0 -4
- data/lib/chef/provider/package/zypper.rb +0 -3
- data/lib/chef/provider/registry_key.rb +0 -2
- data/lib/chef/provider/remote_directory.rb +0 -1
- data/lib/chef/provider/remote_file.rb +0 -1
- data/lib/chef/provider/remote_file/cache_control_data.rb +1 -3
- data/lib/chef/provider/remote_file/content.rb +0 -1
- data/lib/chef/provider/remote_file/fetcher.rb +0 -2
- data/lib/chef/provider/remote_file/ftp.rb +0 -1
- data/lib/chef/provider/resource_update.rb +0 -3
- data/lib/chef/provider/service/freebsd.rb +0 -3
- data/lib/chef/provider/service/init.rb +0 -3
- data/lib/chef/provider/service/macosx.rb +0 -1
- data/lib/chef/provider/service/redhat.rb +0 -2
- data/lib/chef/provider/service/simple.rb +0 -3
- data/lib/chef/provider/service/solaris.rb +0 -3
- data/lib/chef/provider/service/systemd.rb +15 -14
- data/lib/chef/provider/service/windows.rb +0 -3
- data/lib/chef/provider/subversion.rb +0 -2
- data/lib/chef/provider/template.rb +0 -2
- data/lib/chef/provider/template/content.rb +0 -1
- data/lib/chef/provider/user/dscl.rb +156 -549
- data/lib/chef/provider/user/solaris.rb +0 -1
- data/lib/chef/provider/user/useradd.rb +0 -3
- data/lib/chef/provider/whyrun_safe_ruby_block.rb +1 -1
- data/lib/chef/providers.rb +0 -1
- data/lib/chef/resource.rb +1 -4
- data/lib/chef/resource/freebsd_package.rb +2 -10
- data/lib/chef/resource/lwrp_base.rb +1 -12
- data/lib/chef/resource/user.rb +0 -18
- data/lib/chef/resource_collection.rb +1 -1
- data/lib/chef/resource_reporter.rb +10 -10
- data/lib/chef/resources.rb +0 -1
- data/lib/chef/role.rb +3 -3
- data/lib/chef/run_list.rb +1 -1
- data/lib/chef/tasks/chef_repo.rake +131 -264
- data/lib/chef/user.rb +1 -1
- data/lib/chef/util/path_helper.rb +2 -2
- data/lib/chef/version.rb +9 -1
- data/lib/chef/win32/api/system.rb +0 -9
- data/spec/data/bootstrap/test-hints.erb +1 -1
- data/spec/data/bootstrap/test.erb +1 -1
- data/spec/functional/dsl/reboot_pending_spec.rb +53 -58
- data/spec/functional/knife/cookbook_delete_spec.rb +3 -3
- data/spec/functional/knife/exec_spec.rb +1 -1
- data/spec/functional/mixin/shell_out_spec.rb +48 -0
- data/spec/functional/resource/base.rb +0 -10
- data/spec/functional/resource/group_spec.rb +1 -5
- data/spec/functional/resource/link_spec.rb +8 -0
- data/spec/functional/resource/{user/useradd_spec.rb → user_spec.rb} +1 -1
- data/spec/integration/knife/chef_fs_data_store_spec.rb +3 -3
- data/spec/integration/knife/chef_repo_path_spec.rb +1 -6
- data/spec/integration/knife/chef_repository_file_system_spec.rb +1 -1
- data/spec/integration/knife/chefignore_spec.rb +1 -1
- data/spec/integration/knife/common_options_spec.rb +50 -3
- data/spec/integration/knife/cookbook_api_ipv6_spec.rb +1 -1
- data/spec/integration/knife/delete_spec.rb +1 -1
- data/spec/integration/knife/deps_spec.rb +1 -1
- data/spec/integration/knife/diff_spec.rb +3 -3
- data/spec/integration/knife/download_spec.rb +3 -3
- data/spec/integration/knife/list_spec.rb +1 -1
- data/spec/integration/knife/raw_spec.rb +1 -11
- data/spec/integration/knife/redirection_spec.rb +1 -1
- data/spec/integration/knife/serve_spec.rb +2 -2
- data/spec/integration/knife/show_spec.rb +1 -1
- data/spec/integration/knife/upload_spec.rb +9 -9
- data/spec/spec_helper.rb +0 -9
- data/spec/support/pedant/pedant_config.rb +2 -1
- data/spec/support/pedant/run_pedant.rb +2 -1
- data/spec/support/platform_helpers.rb +5 -24
- data/spec/support/shared/integration/integration_helper.rb +2 -1
- data/spec/support/shared/matchers.rb +17 -0
- data/spec/tiny_server.rb +1 -2
- data/spec/unit/api_client_spec.rb +3 -3
- data/spec/unit/application_spec.rb +9 -32
- data/spec/unit/config_fetcher_spec.rb +1 -1
- data/spec/unit/cookbook/metadata_spec.rb +3 -7
- data/spec/unit/cookbook/synchronizer_spec.rb +441 -226
- data/spec/unit/cookbook_loader_spec.rb +1 -1
- data/spec/unit/cookbook_uploader_spec.rb +160 -0
- data/spec/unit/cookbook_version_spec.rb +0 -4
- data/spec/unit/data_bag_item_spec.rb +1 -5
- data/spec/unit/data_bag_spec.rb +1 -5
- data/spec/unit/deprecation_spec.rb +1 -1
- data/spec/unit/dsl/recipe_spec.rb +12 -0
- data/spec/unit/encrypted_data_bag_item_spec.rb +7 -14
- data/spec/unit/environment_spec.rb +3 -7
- data/spec/unit/exceptions_spec.rb +0 -6
- data/spec/unit/http/json_input_spec.rb +128 -0
- data/spec/unit/json_compat_spec.rb +17 -58
- data/spec/unit/knife/client_create_spec.rb +3 -3
- data/spec/unit/knife/configure_client_spec.rb +6 -5
- data/spec/unit/knife/cookbook_delete_spec.rb +1 -1
- data/spec/unit/knife/cookbook_download_spec.rb +5 -5
- data/spec/unit/knife/cookbook_metadata_from_file_spec.rb +1 -0
- data/spec/unit/knife/cookbook_metadata_spec.rb +1 -1
- data/spec/unit/knife/cookbook_site_download_spec.rb +10 -11
- data/spec/unit/knife/cookbook_site_install_spec.rb +116 -161
- data/spec/unit/knife/cookbook_site_share_spec.rb +8 -8
- data/spec/unit/knife/cookbook_upload_spec.rb +3 -2
- data/spec/unit/knife/core/bootstrap_context_spec.rb +3 -3
- data/spec/unit/knife/core/subcommand_loader_spec.rb +1 -66
- data/spec/unit/knife/data_bag_from_file_spec.rb +2 -1
- data/spec/unit/knife/tag_create_spec.rb +3 -3
- data/spec/unit/knife/tag_delete_spec.rb +3 -3
- data/spec/unit/knife/user_create_spec.rb +1 -1
- data/spec/unit/knife_spec.rb +14 -14
- data/spec/unit/lwrp_spec.rb +1 -21
- data/spec/unit/mixin/shell_out_spec.rb +92 -0
- data/spec/unit/node_spec.rb +0 -4
- data/spec/unit/platform/query_helpers_spec.rb +0 -23
- data/spec/unit/provider/env/windows_spec.rb +34 -70
- data/spec/unit/provider/env_spec.rb +11 -76
- data/spec/unit/provider/group/dscl_spec.rb +1 -38
- data/spec/unit/provider/log_spec.rb +18 -0
- data/spec/unit/provider/package/rpm_spec.rb +0 -12
- data/spec/unit/provider/remote_file/cache_control_data_spec.rb +1 -1
- data/spec/unit/provider/service/systemd_service_spec.rb +44 -27
- data/spec/unit/provider/user/dscl_spec.rb +264 -660
- data/spec/unit/provider/user/useradd_spec.rb +0 -1
- data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +2 -2
- data/spec/unit/provider_spec.rb +12 -0
- data/spec/unit/recipe_spec.rb +0 -41
- data/spec/unit/resource_collection_spec.rb +1 -5
- data/spec/unit/resource_reporter_spec.rb +3 -51
- data/spec/unit/resource_spec.rb +3 -14
- data/spec/unit/rest_spec.rb +1 -4
- data/spec/unit/role_spec.rb +0 -10
- data/spec/unit/run_list_spec.rb +1 -5
- data/spec/unit/user_spec.rb +1 -5
- metadata +20 -100
- data/lib/chef/mixin/windows_env_helper.rb +0 -56
- data/lib/chef/provider/dsc_script.rb +0 -175
- data/lib/chef/resource/dsc_script.rb +0 -126
- data/lib/chef/streaming_cookbook_uploader.rb +0 -205
- data/lib/chef/util/dsc/configuration_generator.rb +0 -115
- data/lib/chef/util/dsc/lcm_output_parser.rb +0 -133
- data/lib/chef/util/dsc/local_configuration_manager.rb +0 -141
- data/lib/chef/util/dsc/resource_info.rb +0 -26
- data/lib/chef/util/powershell/cmdlet.rb +0 -136
- data/lib/chef/util/powershell/cmdlet_result.rb +0 -46
- data/spec/data/mac_users/10.7-8.plist.xml +0 -559
- data/spec/data/mac_users/10.7-8.shadow.xml +0 -11
- data/spec/data/mac_users/10.7.plist.xml +0 -559
- data/spec/data/mac_users/10.7.shadow.xml +0 -11
- data/spec/data/mac_users/10.8.plist.xml +0 -559
- data/spec/data/mac_users/10.8.shadow.xml +0 -21
- data/spec/data/mac_users/10.9.plist.xml +0 -560
- data/spec/data/mac_users/10.9.shadow.xml +0 -21
- data/spec/functional/provider/whyrun_safe_ruby_block_spec.rb +0 -51
- data/spec/functional/resource/dsc_script_spec.rb +0 -382
- data/spec/functional/resource/env_spec.rb +0 -182
- data/spec/functional/resource/user/dscl_spec.rb +0 -199
- data/spec/functional/util/powershell/cmdlet_spec.rb +0 -113
- data/spec/support/lib/chef/resource/zen_follower.rb +0 -46
- data/spec/support/shared/shared_examples.rb +0 -10
- data/spec/unit/chef_fs/data_handler/group_handler_spec.rb +0 -63
- data/spec/unit/formatters/base_spec.rb +0 -48
- data/spec/unit/provider/dsc_script_spec.rb +0 -174
- data/spec/unit/resource/dsc_script_spec.rb +0 -98
- data/spec/unit/util/dsc/configuration_generator_spec.rb +0 -171
- data/spec/unit/util/dsc/lcm_output_parser_spec.rb +0 -169
- data/spec/unit/util/dsc/local_configuration_manager_spec.rb +0 -139
- data/spec/unit/util/powershell/cmdlet_spec.rb +0 -106
@@ -140,7 +140,7 @@ class Chef
|
|
140
140
|
|
141
141
|
def load_data
|
142
142
|
Chef::JSONCompat.from_json(load_json_data)
|
143
|
-
rescue Chef::Exceptions::FileNotFound, FFI_Yajl::ParseError,
|
143
|
+
rescue Chef::Exceptions::FileNotFound, FFI_Yajl::ParseError, JSON::ParserError
|
144
144
|
false
|
145
145
|
end
|
146
146
|
|
@@ -161,5 +161,3 @@ class Chef
|
|
161
161
|
end
|
162
162
|
end
|
163
163
|
end
|
164
|
-
|
165
|
-
|
@@ -16,7 +16,6 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require 'chef/mixin/shell_out'
|
20
19
|
require 'chef/resource/service'
|
21
20
|
require 'chef/provider/service/init'
|
22
21
|
require 'chef/mixin/command'
|
@@ -26,8 +25,6 @@ class Chef
|
|
26
25
|
class Service
|
27
26
|
class Freebsd < Chef::Provider::Service::Init
|
28
27
|
|
29
|
-
include Chef::Mixin::ShellOut
|
30
|
-
|
31
28
|
def load_current_resource
|
32
29
|
@current_resource = Chef::Resource::Service.new(@new_resource.name)
|
33
30
|
@current_resource.service_name(@new_resource.service_name)
|
@@ -16,7 +16,6 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require 'chef/mixin/shell_out'
|
20
19
|
require 'chef/provider/service/simple'
|
21
20
|
require 'chef/mixin/command'
|
22
21
|
|
@@ -25,8 +24,6 @@ class Chef
|
|
25
24
|
class Service
|
26
25
|
class Init < Chef::Provider::Service::Simple
|
27
26
|
|
28
|
-
include Chef::Mixin::ShellOut
|
29
|
-
|
30
27
|
def initialize(new_resource, run_context)
|
31
28
|
super
|
32
29
|
@init_command = "/etc/init.d/#{@new_resource.service_name}"
|
@@ -17,13 +17,11 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'chef/provider/service/init'
|
20
|
-
require 'chef/mixin/shell_out'
|
21
20
|
|
22
21
|
class Chef
|
23
22
|
class Provider
|
24
23
|
class Service
|
25
24
|
class Redhat < Chef::Provider::Service::Init
|
26
|
-
include Chef::Mixin::ShellOut
|
27
25
|
|
28
26
|
CHKCONFIG_ON = /\d:on/
|
29
27
|
CHKCONFIG_MISSING = /No such/
|
@@ -16,7 +16,6 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require 'chef/mixin/shell_out'
|
20
19
|
require 'chef/provider/service'
|
21
20
|
require 'chef/resource/service'
|
22
21
|
require 'chef/mixin/command'
|
@@ -26,8 +25,6 @@ class Chef
|
|
26
25
|
class Service
|
27
26
|
class Simple < Chef::Provider::Service
|
28
27
|
|
29
|
-
include Chef::Mixin::ShellOut
|
30
|
-
|
31
28
|
def load_current_resource
|
32
29
|
@current_resource = Chef::Resource::Service.new(@new_resource.name)
|
33
30
|
@current_resource.service_name(@new_resource.service_name)
|
@@ -16,7 +16,6 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require 'chef/mixin/shell_out'
|
20
19
|
require 'chef/provider/service'
|
21
20
|
require 'chef/resource/service'
|
22
21
|
require 'chef/mixin/command'
|
@@ -25,7 +24,6 @@ class Chef
|
|
25
24
|
class Provider
|
26
25
|
class Service
|
27
26
|
class Solaris < Chef::Provider::Service
|
28
|
-
include Chef::Mixin::ShellOut
|
29
27
|
attr_reader :maintenance
|
30
28
|
|
31
29
|
def initialize(new_resource, run_context=nil)
|
@@ -35,7 +33,6 @@ class Chef
|
|
35
33
|
@maintenace = false
|
36
34
|
end
|
37
35
|
|
38
|
-
|
39
36
|
def load_current_resource
|
40
37
|
@current_resource = Chef::Resource::Service.new(@new_resource.name)
|
41
38
|
@current_resource.service_name(@new_resource.service_name)
|
@@ -18,7 +18,6 @@
|
|
18
18
|
|
19
19
|
require 'chef/resource/service'
|
20
20
|
require 'chef/provider/service/simple'
|
21
|
-
require 'chef/mixin/command'
|
22
21
|
|
23
22
|
class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
24
23
|
def load_current_resource
|
@@ -29,11 +28,9 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
29
28
|
if @new_resource.status_command
|
30
29
|
Chef::Log.debug("#{@new_resource} you have specified a status command, running..")
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
rescue Chef::Exceptions::Exec
|
31
|
+
unless shell_out_with_systems_locale(@new_resource.status_command).error?
|
32
|
+
@current_resource.running(true)
|
33
|
+
else
|
37
34
|
@status_check_success = false
|
38
35
|
@current_resource.running(false)
|
39
36
|
@current_resource.enabled(false)
|
@@ -64,7 +61,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
64
61
|
if @new_resource.start_command
|
65
62
|
super
|
66
63
|
else
|
67
|
-
|
64
|
+
shell_out_with_systems_locale("/bin/systemctl start #{@new_resource.service_name}")
|
68
65
|
end
|
69
66
|
end
|
70
67
|
end
|
@@ -76,7 +73,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
76
73
|
if @new_resource.stop_command
|
77
74
|
super
|
78
75
|
else
|
79
|
-
|
76
|
+
shell_out_with_systems_locale("/bin/systemctl stop #{@new_resource.service_name}")
|
80
77
|
end
|
81
78
|
end
|
82
79
|
end
|
@@ -85,7 +82,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
85
82
|
if @new_resource.restart_command
|
86
83
|
super
|
87
84
|
else
|
88
|
-
|
85
|
+
shell_out_with_systems_locale("/bin/systemctl restart #{@new_resource.service_name}")
|
89
86
|
end
|
90
87
|
end
|
91
88
|
|
@@ -93,23 +90,27 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
93
90
|
if @new_resource.reload_command
|
94
91
|
super
|
95
92
|
else
|
96
|
-
|
93
|
+
if @current_resource.running
|
94
|
+
shell_out_with_systems_locale("/bin/systemctl reload #{@new_resource.service_name}")
|
95
|
+
else
|
96
|
+
start_service
|
97
|
+
end
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
100
101
|
def enable_service
|
101
|
-
|
102
|
+
shell_out_with_systems_locale("/bin/systemctl enable #{@new_resource.service_name}")
|
102
103
|
end
|
103
104
|
|
104
105
|
def disable_service
|
105
|
-
|
106
|
+
shell_out_with_systems_locale("/bin/systemctl disable #{@new_resource.service_name}")
|
106
107
|
end
|
107
108
|
|
108
109
|
def is_active?
|
109
|
-
|
110
|
+
shell_out_with_systems_locale("/bin/systemctl is-active #{@new_resource.service_name} --quiet").exitstatus == 0
|
110
111
|
end
|
111
112
|
|
112
113
|
def is_enabled?
|
113
|
-
|
114
|
+
shell_out_with_systems_locale("/bin/systemctl is-enabled #{@new_resource.service_name} --quiet").exitstatus == 0
|
114
115
|
end
|
115
116
|
end
|
@@ -18,7 +18,6 @@
|
|
18
18
|
# limitations under the License.
|
19
19
|
#
|
20
20
|
|
21
|
-
require 'chef/mixin/shell_out'
|
22
21
|
require 'chef/provider/service/simple'
|
23
22
|
if RUBY_PLATFORM =~ /mswin|mingw32|windows/
|
24
23
|
require 'win32/service'
|
@@ -26,8 +25,6 @@ end
|
|
26
25
|
|
27
26
|
class Chef::Provider::Service::Windows < Chef::Provider::Service
|
28
27
|
|
29
|
-
include Chef::Mixin::ShellOut
|
30
|
-
|
31
28
|
#Win32::Service.get_start_type
|
32
29
|
AUTO_START = 'auto start'
|
33
30
|
DISABLED = 'disabled'
|
@@ -16,7 +16,6 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
|
20
19
|
#TODO subversion and git should both extend from a base SCM provider.
|
21
20
|
|
22
21
|
require 'chef/log'
|
@@ -199,7 +198,6 @@ class Chef
|
|
199
198
|
['svn', *args].compact.join(" ")
|
200
199
|
end
|
201
200
|
|
202
|
-
|
203
201
|
def target_dir_non_existent_or_empty?
|
204
202
|
!::File.exist?(@new_resource.destination) || Dir.entries(@new_resource.destination).sort == ['.','..']
|
205
203
|
end
|
@@ -16,214 +16,40 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require 'mixlib/shellout'
|
20
19
|
require 'chef/provider/user'
|
21
20
|
require 'openssl'
|
22
|
-
require 'plist'
|
23
21
|
|
24
22
|
class Chef
|
25
23
|
class Provider
|
26
24
|
class User
|
27
|
-
#
|
28
|
-
# The most tricky bit of this provider is the way it deals with user passwords.
|
29
|
-
# Mac OS X has different password shadow calculations based on the version.
|
30
|
-
# < 10.7 => password shadow calculation format SALTED-SHA1
|
31
|
-
# => stored in: /var/db/shadow/hash/#{guid}
|
32
|
-
# => shadow binary length 68 bytes
|
33
|
-
# => First 4 bytes salt / Next 64 bytes shadow value
|
34
|
-
# = 10.7 => password shadow calculation format SALTED-SHA512
|
35
|
-
# => stored in: /var/db/dslocal/nodes/Default/users/#{name}.plist
|
36
|
-
# => shadow binary length 68 bytes
|
37
|
-
# => First 4 bytes salt / Next 64 bytes shadow value
|
38
|
-
# > 10.7 => password shadow calculation format SALTED-SHA512-PBKDF2
|
39
|
-
# => stored in: /var/db/dslocal/nodes/Default/users/#{name}.plist
|
40
|
-
# => shadow binary length 128 bytes
|
41
|
-
# => Salt / Iterations are stored seperately in the same file
|
42
|
-
#
|
43
|
-
# This provider only supports Mac OSX versions 10.7 and above
|
44
25
|
class Dscl < Chef::Provider::User
|
45
|
-
include Chef::Mixin::ShellOut
|
46
26
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
requirements.assert(:all_actions) do |a|
|
51
|
-
a.assertion { mac_osx_version_less_than_10_7? == false }
|
52
|
-
a.failure_message(Chef::Exceptions::User, "Chef::Provider::User::Dscl only supports Mac OS X versions 10.7 and above.")
|
53
|
-
end
|
54
|
-
|
55
|
-
requirements.assert(:all_actions) do |a|
|
56
|
-
a.assertion { ::File.exists?("/usr/bin/dscl") }
|
57
|
-
a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/dscl' on the system for #{@new_resource}!")
|
58
|
-
end
|
59
|
-
|
60
|
-
requirements.assert(:all_actions) do |a|
|
61
|
-
a.assertion { ::File.exists?("/usr/bin/plutil") }
|
62
|
-
a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/plutil' on the system for #{@new_resource}!")
|
63
|
-
end
|
64
|
-
|
65
|
-
requirements.assert(:create, :modify, :manage) do |a|
|
66
|
-
a.assertion do
|
67
|
-
if @new_resource.password && mac_osx_version_greater_than_10_7?
|
68
|
-
# SALTED-SHA512 password shadow hashes are not supported on 10.8 and above.
|
69
|
-
!salted_sha512?(@new_resource.password)
|
70
|
-
else
|
71
|
-
true
|
72
|
-
end
|
73
|
-
end
|
74
|
-
a.failure_message(Chef::Exceptions::User, "SALTED-SHA512 passwords are not supported on Mac 10.8 and above. \
|
75
|
-
If you want to set the user password using shadow info make sure you specify a SALTED-SHA512-PBKDF2 shadow hash \
|
76
|
-
in 'password', with the associated 'salt' and 'iterations'.")
|
77
|
-
end
|
78
|
-
|
79
|
-
requirements.assert(:create, :modify, :manage) do |a|
|
80
|
-
a.assertion do
|
81
|
-
if @new_resource.password && mac_osx_version_greater_than_10_7? && salted_sha512_pbkdf2?(@new_resource.password)
|
82
|
-
# salt and iterations should be specified when
|
83
|
-
# SALTED-SHA512-PBKDF2 password shadow hash is given
|
84
|
-
!@new_resource.salt.nil? && !@new_resource.iterations.nil?
|
85
|
-
else
|
86
|
-
true
|
87
|
-
end
|
88
|
-
end
|
89
|
-
a.failure_message(Chef::Exceptions::User, "SALTED-SHA512-PBKDF2 shadow hash is given without associated \
|
90
|
-
'salt' and 'iterations'. Please specify 'salt' and 'iterations' in order to set the user password using shadow hash.")
|
91
|
-
end
|
92
|
-
|
93
|
-
requirements.assert(:create, :modify, :manage) do |a|
|
94
|
-
a.assertion do
|
95
|
-
if @new_resource.password && !mac_osx_version_greater_than_10_7?
|
96
|
-
# On 10.7 SALTED-SHA512-PBKDF2 is not supported
|
97
|
-
!salted_sha512_pbkdf2?(@new_resource.password)
|
98
|
-
else
|
99
|
-
true
|
100
|
-
end
|
101
|
-
end
|
102
|
-
a.failure_message(Chef::Exceptions::User, "SALTED-SHA512-PBKDF2 shadow hashes are not supported on \
|
103
|
-
Mac OS X version 10.7. Please specify a SALTED-SHA512 shadow hash in 'password' attribute to set the \
|
104
|
-
user password using shadow hash.")
|
105
|
-
end
|
27
|
+
NFS_HOME_DIRECTORY = %r{^NFSHomeDirectory: (.*)$}
|
28
|
+
AUTHENTICATION_AUTHORITY = %r{^AuthenticationAuthority: (.*)$}
|
106
29
|
|
30
|
+
def dscl(*args)
|
31
|
+
shell_out("dscl . -#{args.join(' ')}")
|
107
32
|
end
|
108
33
|
|
109
|
-
def
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
@current_resource.uid(dscl_get(@user_info, :uid))
|
116
|
-
@current_resource.gid(dscl_get(@user_info, :gid))
|
117
|
-
@current_resource.home(dscl_get(@user_info, :home))
|
118
|
-
@current_resource.shell(dscl_get(@user_info, :shell))
|
119
|
-
@current_resource.comment(dscl_get(@user_info, :comment))
|
120
|
-
@authentication_authority = dscl_get(@user_info, :auth_authority)
|
121
|
-
|
122
|
-
if @new_resource.password && dscl_get(@user_info, :password) == "********"
|
123
|
-
# A password is set. Let's get the password information from shadow file
|
124
|
-
shadow_hash_binary = dscl_get(@user_info, :shadow_hash)
|
125
|
-
|
126
|
-
# Calling shell_out directly since we want to give an input stream
|
127
|
-
shadow_hash_xml = convert_binary_plist_to_xml(shadow_hash_binary.string)
|
128
|
-
shadow_hash = Plist::parse_xml(shadow_hash_xml)
|
129
|
-
|
130
|
-
if shadow_hash["SALTED-SHA512"]
|
131
|
-
# Convert the shadow value from Base64 encoding to hex before consuming them
|
132
|
-
@password_shadow_conversion_algorithm = "SALTED-SHA512"
|
133
|
-
@current_resource.password(shadow_hash["SALTED-SHA512"].string.unpack('H*').first)
|
134
|
-
elsif shadow_hash["SALTED-SHA512-PBKDF2"]
|
135
|
-
@password_shadow_conversion_algorithm = "SALTED-SHA512-PBKDF2"
|
136
|
-
# Convert the entropy from Base64 encoding to hex before consuming them
|
137
|
-
@current_resource.password(shadow_hash["SALTED-SHA512-PBKDF2"]["entropy"].string.unpack('H*').first)
|
138
|
-
@current_resource.iterations(shadow_hash["SALTED-SHA512-PBKDF2"]["iterations"])
|
139
|
-
# Convert the salt from Base64 encoding to hex before consuming them
|
140
|
-
@current_resource.salt(shadow_hash["SALTED-SHA512-PBKDF2"]["salt"].string.unpack('H*').first)
|
141
|
-
else
|
142
|
-
raise(Chef::Exceptions::User,"Unknown shadow_hash format: #{shadow_hash.keys.join(' ')}")
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
convert_group_name if @new_resource.gid
|
147
|
-
else
|
148
|
-
@user_exists = false
|
149
|
-
Chef::Log.debug("#{@new_resource} user does not exist")
|
150
|
-
end
|
151
|
-
|
152
|
-
@current_resource
|
153
|
-
end
|
154
|
-
|
155
|
-
#
|
156
|
-
# Provider Actions
|
157
|
-
#
|
158
|
-
|
159
|
-
def create_user
|
160
|
-
dscl_create_user
|
161
|
-
# set_password modifies the plist file of the user directly. So update
|
162
|
-
# the password first before making any modifications to the user.
|
163
|
-
set_password
|
164
|
-
dscl_create_comment
|
165
|
-
dscl_set_uid
|
166
|
-
dscl_set_gid
|
167
|
-
dscl_set_home
|
168
|
-
dscl_set_shell
|
169
|
-
end
|
170
|
-
|
171
|
-
def manage_user
|
172
|
-
# set_password modifies the plist file of the user directly. So update
|
173
|
-
# the password first before making any modifications to the user.
|
174
|
-
set_password if diverged_password?
|
175
|
-
dscl_create_user if diverged?(:username)
|
176
|
-
dscl_create_comment if diverged?(:comment)
|
177
|
-
dscl_set_uid if diverged?(:uid)
|
178
|
-
dscl_set_gid if diverged?(:gid)
|
179
|
-
dscl_set_home if diverged?(:home)
|
180
|
-
dscl_set_shell if diverged?(:shell)
|
181
|
-
end
|
182
|
-
|
183
|
-
#
|
184
|
-
# Action Helpers
|
185
|
-
#
|
186
|
-
|
187
|
-
#
|
188
|
-
# Create a user using dscl
|
189
|
-
#
|
190
|
-
def dscl_create_user
|
191
|
-
run_dscl("create /Users/#{@new_resource.username}")
|
192
|
-
end
|
193
|
-
|
194
|
-
#
|
195
|
-
# Saves the specified Chef user `comment` into RealName attribute
|
196
|
-
# of Mac user.
|
197
|
-
#
|
198
|
-
def dscl_create_comment
|
199
|
-
run_dscl("create /Users/#{@new_resource.username} RealName '#{@new_resource.comment}'")
|
34
|
+
def safe_dscl(*args)
|
35
|
+
result = dscl(*args)
|
36
|
+
return "" if ( args.first =~ /^delete/ ) && ( result.exitstatus != 0 )
|
37
|
+
raise(Chef::Exceptions::DsclCommandFailed,"dscl error: #{result.inspect}") unless result.exitstatus == 0
|
38
|
+
raise(Chef::Exceptions::DsclCommandFailed,"dscl error: #{result.inspect}") if result.stdout =~ /No such key: /
|
39
|
+
return result.stdout
|
200
40
|
end
|
201
41
|
|
202
|
-
#
|
203
|
-
#
|
204
|
-
#
|
205
|
-
#
|
206
|
-
#
|
207
|
-
def dscl_set_uid
|
208
|
-
@new_resource.uid(get_free_uid) if (@new_resource.uid.nil? || @new_resource.uid == '')
|
209
|
-
|
210
|
-
if uid_used?(@new_resource.uid)
|
211
|
-
raise(Chef::Exceptions::RequestedUIDUnavailable, "uid #{@new_resource.uid} is already in use")
|
212
|
-
end
|
213
|
-
|
214
|
-
run_dscl("create /Users/#{@new_resource.username} UniqueID #{@new_resource.uid}")
|
215
|
-
end
|
42
|
+
# This is handled in providers/group.rb by Etc.getgrnam()
|
43
|
+
# def user_exists?(user)
|
44
|
+
# users = safe_dscl("list /Users")
|
45
|
+
# !! ( users =~ Regexp.new("\n#{user}\n") )
|
46
|
+
# end
|
216
47
|
|
217
|
-
#
|
218
|
-
# Find the next available uid on the system. starting with 200 if `system` is set,
|
219
|
-
# 500 otherwise.
|
220
|
-
#
|
48
|
+
# get a free UID greater than 200
|
221
49
|
def get_free_uid(search_limit=1000)
|
222
|
-
uid = nil
|
223
|
-
|
224
|
-
next_uid_guess
|
225
|
-
users_uids = run_dscl("list /Users uid")
|
226
|
-
while(next_uid_guess < search_limit + base_uid)
|
50
|
+
uid = nil; next_uid_guess = 200
|
51
|
+
users_uids = safe_dscl("list /Users uid")
|
52
|
+
while(next_uid_guess < search_limit + 200)
|
227
53
|
if users_uids =~ Regexp.new("#{Regexp.escape(next_uid_guess.to_s)}\n")
|
228
54
|
next_uid_guess += 1
|
229
55
|
else
|
@@ -234,41 +60,22 @@ user password using shadow hash.")
|
|
234
60
|
return uid || raise("uid not found. Exhausted. Searched #{search_limit} times")
|
235
61
|
end
|
236
62
|
|
237
|
-
#
|
238
|
-
# Returns true if uid is in use by a different account, false otherwise.
|
239
|
-
#
|
240
63
|
def uid_used?(uid)
|
241
64
|
return false unless uid
|
242
|
-
users_uids =
|
65
|
+
users_uids = safe_dscl("list /Users uid")
|
243
66
|
!! ( users_uids =~ Regexp.new("#{Regexp.escape(uid.to_s)}\n") )
|
244
67
|
end
|
245
68
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
def dscl_set_gid
|
251
|
-
unless @new_resource.gid && @new_resource.gid.to_s.match(/^\d+$/)
|
252
|
-
begin
|
253
|
-
possible_gid = run_dscl("read /Groups/#{@new_resource.gid} PrimaryGroupID").split(" ").last
|
254
|
-
rescue Chef::Exceptions::DsclCommandFailed => e
|
255
|
-
raise Chef::Exceptions::GroupIDNotFound.new("Group not found for #{@new_resource.gid} when creating user #{@new_resource.username}")
|
256
|
-
end
|
257
|
-
@new_resource.gid(possible_gid) if possible_gid && possible_gid.match(/^\d+$/)
|
69
|
+
def set_uid
|
70
|
+
@new_resource.uid(get_free_uid) if (@new_resource.uid.nil? || @new_resource.uid == '')
|
71
|
+
if uid_used?(@new_resource.uid)
|
72
|
+
raise(Chef::Exceptions::RequestedUIDUnavailable, "uid #{@new_resource.uid} is already in use")
|
258
73
|
end
|
259
|
-
|
74
|
+
safe_dscl("create /Users/#{@new_resource.username} UniqueID #{@new_resource.uid}")
|
260
75
|
end
|
261
76
|
|
262
|
-
|
263
|
-
|
264
|
-
# directory is managed (moved / created) for the user.
|
265
|
-
#
|
266
|
-
def dscl_set_home
|
267
|
-
if @new_resource.home.nil? || @new_resource.home.empty?
|
268
|
-
run_dscl("delete /Users/#{@new_resource.username} NFSHomeDirectory")
|
269
|
-
return
|
270
|
-
end
|
271
|
-
|
77
|
+
def modify_home
|
78
|
+
return safe_dscl("delete /Users/#{@new_resource.username} NFSHomeDirectory") if (@new_resource.home.nil? || @new_resource.home.empty?)
|
272
79
|
if @new_resource.supports[:manage_home]
|
273
80
|
validate_home_dir_specification!
|
274
81
|
|
@@ -280,399 +87,199 @@ user password using shadow hash.")
|
|
280
87
|
move_home
|
281
88
|
end
|
282
89
|
end
|
283
|
-
|
90
|
+
safe_dscl("create /Users/#{@new_resource.username} NFSHomeDirectory '#{@new_resource.home}'")
|
284
91
|
end
|
285
92
|
|
286
|
-
def
|
287
|
-
|
288
|
-
raise(Chef::Exceptions::InvalidHomeDirectory,"invalid path spec for User: '#{@new_resource.username}', home directory: '#{@new_resource.home}'")
|
289
|
-
end
|
93
|
+
def osx_shadow_hash?(string)
|
94
|
+
return !! ( string =~ /^[[:xdigit:]]{1240}$/ )
|
290
95
|
end
|
291
96
|
|
292
|
-
def
|
293
|
-
|
97
|
+
def osx_salted_sha1?(string)
|
98
|
+
return !! ( string =~ /^[[:xdigit:]]{48}$/ )
|
294
99
|
end
|
295
100
|
|
296
|
-
def
|
297
|
-
|
298
|
-
end
|
299
|
-
|
300
|
-
def ditto_home
|
301
|
-
skel = "/System/Library/User Template/English.lproj"
|
302
|
-
raise(Chef::Exceptions::User,"can't find skel at: #{skel}") unless ::File.exists?(skel)
|
303
|
-
shell_out! "ditto '#{skel}' '#{@new_resource.home}'"
|
304
|
-
::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
|
305
|
-
end
|
306
|
-
|
307
|
-
def move_home
|
308
|
-
Chef::Log.debug("#{@new_resource} moving #{self} home from #{@current_resource.home} to #{@new_resource.home}")
|
309
|
-
|
310
|
-
src = @current_resource.home
|
311
|
-
FileUtils.mkdir_p(@new_resource.home)
|
312
|
-
files = ::Dir.glob("#{src}/*", ::File::FNM_DOTMATCH) - ["#{src}/.","#{src}/.."]
|
313
|
-
::FileUtils.mv(files,@new_resource.home, :force => true)
|
314
|
-
::FileUtils.rmdir(src)
|
315
|
-
::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
|
101
|
+
def guid
|
102
|
+
safe_dscl("read /Users/#{@new_resource.username} GeneratedUID").gsub(/GeneratedUID: /,"").strip
|
316
103
|
end
|
317
104
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
if @new_resource.shell || ::File.exists?("#{@new_resource.shell}")
|
323
|
-
run_dscl("create /Users/#{@new_resource.username} UserShell '#{@new_resource.shell}'")
|
105
|
+
def shadow_hash_set?
|
106
|
+
user_data = safe_dscl("read /Users/#{@new_resource.username}")
|
107
|
+
if user_data =~ /AuthenticationAuthority: / && user_data =~ /ShadowHash/
|
108
|
+
true
|
324
109
|
else
|
325
|
-
|
110
|
+
false
|
326
111
|
end
|
327
112
|
end
|
328
113
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
# hash data.
|
333
|
-
#
|
334
|
-
def set_password
|
335
|
-
# Return if there is no password to set
|
336
|
-
return if @new_resource.password.nil?
|
337
|
-
|
338
|
-
shadow_info = prepare_password_shadow_info
|
339
|
-
|
340
|
-
# Shadow info is saved as binary plist. Convert the info to binary plist.
|
341
|
-
shadow_info_binary = StringIO.new
|
342
|
-
command = Mixlib::ShellOut.new("plutil -convert binary1 -o - -",
|
343
|
-
:input => shadow_info.to_plist, :live_stream => shadow_info_binary)
|
344
|
-
command.run_command
|
345
|
-
|
346
|
-
if @user_info.nil?
|
347
|
-
# User is just created. read_user_info() will read the fresh information
|
348
|
-
# for the user with a cache flush. However with experimentation we've seen
|
349
|
-
# that dscl cache is not immediately updated after the creation of the user
|
350
|
-
# This is odd and needs to be investigated further.
|
351
|
-
sleep 3
|
352
|
-
@user_info = read_user_info
|
353
|
-
end
|
354
|
-
|
355
|
-
# Replace the shadow info in user's plist
|
356
|
-
dscl_set(@user_info, :shadow_hash, shadow_info_binary)
|
357
|
-
save_user_info(@user_info)
|
358
|
-
end
|
114
|
+
def modify_password
|
115
|
+
if @new_resource.password
|
116
|
+
shadow_hash = nil
|
359
117
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
def prepare_password_shadow_info
|
364
|
-
shadow_info = { }
|
365
|
-
entropy = nil
|
366
|
-
salt = nil
|
367
|
-
iterations = nil
|
368
|
-
|
369
|
-
if mac_osx_version_10_7?
|
370
|
-
hash_value = if salted_sha512?(@new_resource.password)
|
371
|
-
@new_resource.password
|
118
|
+
Chef::Log.debug("#{new_resource} updating password")
|
119
|
+
if osx_shadow_hash?(@new_resource.password)
|
120
|
+
shadow_hash = @new_resource.password.upcase
|
372
121
|
else
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
122
|
+
if osx_salted_sha1?(@new_resource.password)
|
123
|
+
salted_sha1 = @new_resource.password.upcase
|
124
|
+
else
|
125
|
+
hex_salt = ""
|
126
|
+
OpenSSL::Random.random_bytes(10).each_byte { |b| hex_salt << b.to_i.to_s(16) }
|
127
|
+
hex_salt = hex_salt.slice(0...8)
|
128
|
+
salt = [hex_salt].pack("H*")
|
129
|
+
sha1 = ::OpenSSL::Digest::SHA1.hexdigest(salt+@new_resource.password)
|
130
|
+
salted_sha1 = (hex_salt+sha1).upcase
|
131
|
+
end
|
132
|
+
shadow_hash = String.new("00000000"*155)
|
133
|
+
shadow_hash[168] = salted_sha1
|
377
134
|
end
|
378
135
|
|
379
|
-
|
380
|
-
|
381
|
-
shadow_info
|
382
|
-
else
|
383
|
-
if salted_sha512_pbkdf2?(@new_resource.password)
|
384
|
-
entropy = convert_to_binary(@new_resource.password)
|
385
|
-
salt = convert_to_binary(@new_resource.salt)
|
386
|
-
iterations = @new_resource.iterations
|
387
|
-
else
|
388
|
-
salt = OpenSSL::Random.random_bytes(32)
|
389
|
-
iterations = @new_resource.iterations # Use the default if not specified by the user
|
390
|
-
|
391
|
-
entropy = OpenSSL::PKCS5::pbkdf2_hmac(
|
392
|
-
@new_resource.password,
|
393
|
-
salt,
|
394
|
-
iterations,
|
395
|
-
128,
|
396
|
-
OpenSSL::Digest::SHA512.new
|
397
|
-
)
|
136
|
+
::File.open("/var/db/shadow/hash/#{guid}",'w',0600) do |output|
|
137
|
+
output.puts shadow_hash
|
398
138
|
end
|
399
139
|
|
400
|
-
|
401
|
-
|
402
|
-
pbkdf_info["entropy"].string = entropy
|
403
|
-
pbkdf_info["salt"] = StringIO.new
|
404
|
-
pbkdf_info["salt"].string = salt
|
405
|
-
pbkdf_info["iterations"] = iterations
|
406
|
-
|
407
|
-
shadow_info["SALTED-SHA512-PBKDF2"] = pbkdf_info
|
408
|
-
end
|
409
|
-
|
410
|
-
shadow_info
|
411
|
-
end
|
412
|
-
|
413
|
-
#
|
414
|
-
# Removes the user from the system after removing user from his groups
|
415
|
-
# and deleting home directory if needed.
|
416
|
-
#
|
417
|
-
def remove_user
|
418
|
-
if @new_resource.supports[:manage_home]
|
419
|
-
# Remove home directory
|
420
|
-
FileUtils.rm_rf(@current_resource.home)
|
421
|
-
end
|
422
|
-
|
423
|
-
# Remove the user from its groups
|
424
|
-
run_dscl("list /Groups").each_line do |group|
|
425
|
-
if member_of_group?(group.chomp)
|
426
|
-
run_dscl("delete /Groups/#{group.chomp} GroupMembership '#{@new_resource.username}'")
|
140
|
+
unless shadow_hash_set?
|
141
|
+
safe_dscl("append /Users/#{@new_resource.username} AuthenticationAuthority ';ShadowHash;'")
|
427
142
|
end
|
428
143
|
end
|
429
|
-
|
430
|
-
# Remove user account
|
431
|
-
run_dscl("delete /Users/#{@new_resource.username}")
|
432
144
|
end
|
433
145
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
def lock_user
|
438
|
-
run_dscl("append /Users/#{@new_resource.username} AuthenticationAuthority ';DisabledUser;'")
|
439
|
-
end
|
440
|
-
|
441
|
-
#
|
442
|
-
# Unlocks the user
|
443
|
-
#
|
444
|
-
def unlock_user
|
445
|
-
auth_string = @authentication_authority.gsub(/AuthenticationAuthority: /,"").gsub(/;DisabledUser;/,"").strip
|
446
|
-
run_dscl("create /Users/#{@new_resource.username} AuthenticationAuthority '#{auth_string}'")
|
146
|
+
def load_current_resource
|
147
|
+
super
|
148
|
+
raise Chef::Exceptions::User, "Could not find binary /usr/bin/dscl for #{@new_resource}" unless ::File.exists?("/usr/bin/dscl")
|
447
149
|
end
|
448
150
|
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
end
|
151
|
+
def create_user
|
152
|
+
dscl_create_user
|
153
|
+
dscl_create_comment
|
154
|
+
set_uid
|
155
|
+
dscl_set_gid
|
156
|
+
modify_home
|
157
|
+
dscl_set_shell
|
158
|
+
modify_password
|
458
159
|
end
|
459
160
|
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
161
|
+
def manage_user
|
162
|
+
dscl_create_user if diverged?(:username)
|
163
|
+
dscl_create_comment if diverged?(:comment)
|
164
|
+
set_uid if diverged?(:uid)
|
165
|
+
dscl_set_gid if diverged?(:gid)
|
166
|
+
modify_home if diverged?(:home)
|
167
|
+
dscl_set_shell if diverged?(:shell)
|
168
|
+
modify_password if diverged?(:password)
|
465
169
|
end
|
466
170
|
|
467
|
-
|
468
|
-
|
469
|
-
#
|
470
|
-
|
471
|
-
#
|
472
|
-
# Returns true if the system state and desired state is different for
|
473
|
-
# given attribute.
|
474
|
-
#
|
475
|
-
def diverged?(parameter)
|
476
|
-
parameter_updated?(parameter) && (not @new_resource.send(parameter).nil?)
|
171
|
+
def dscl_create_user
|
172
|
+
safe_dscl("create /Users/#{@new_resource.username}")
|
477
173
|
end
|
478
174
|
|
479
|
-
def
|
480
|
-
|
175
|
+
def dscl_create_comment
|
176
|
+
safe_dscl("create /Users/#{@new_resource.username} RealName '#{@new_resource.comment}'")
|
481
177
|
end
|
482
178
|
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
#
|
490
|
-
def diverged_password?
|
491
|
-
return false if @new_resource.password.nil?
|
492
|
-
|
493
|
-
# Dscl provider supports both plain text passwords and shadow hashes.
|
494
|
-
if mac_osx_version_10_7?
|
495
|
-
if salted_sha512?(@new_resource.password)
|
496
|
-
diverged?(:password)
|
497
|
-
else
|
498
|
-
!salted_sha512_password_match?
|
499
|
-
end
|
500
|
-
else
|
501
|
-
# When a system is upgraded to a version 10.7+ shadow hashes of the users
|
502
|
-
# will be updated when the user logs in. So it's possible that we will have
|
503
|
-
# SALTED-SHA512 password in the current_resource. In that case we will force
|
504
|
-
# password to be updated.
|
505
|
-
return true if salted_sha512?(@current_resource.password)
|
506
|
-
|
507
|
-
if salted_sha512_pbkdf2?(@new_resource.password)
|
508
|
-
diverged?(:password) || diverged?(:salt) || diverged?(:iterations)
|
509
|
-
else
|
510
|
-
!salted_sha512_pbkdf2_password_match?
|
179
|
+
def dscl_set_gid
|
180
|
+
unless @new_resource.gid && @new_resource.gid.to_s.match(/^\d+$/)
|
181
|
+
begin
|
182
|
+
possible_gid = safe_dscl("read /Groups/#{@new_resource.gid} PrimaryGroupID").split(" ").last
|
183
|
+
rescue Chef::Exceptions::DsclCommandFailed => e
|
184
|
+
raise Chef::Exceptions::GroupIDNotFound.new("Group not found for #{@new_resource.gid} when creating user #{@new_resource.username}")
|
511
185
|
end
|
186
|
+
@new_resource.gid(possible_gid) if possible_gid && possible_gid.match(/^\d+$/)
|
512
187
|
end
|
188
|
+
safe_dscl("create /Users/#{@new_resource.username} PrimaryGroupID '#{@new_resource.gid}'")
|
513
189
|
end
|
514
190
|
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
begin
|
521
|
-
membership_info = run_dscl("read /Groups/#{group_name}")
|
522
|
-
rescue Chef::Exceptions::DsclCommandFailed
|
523
|
-
# Raised if the group doesn't contain any members
|
191
|
+
def dscl_set_shell
|
192
|
+
if @new_resource.password || ::File.exists?("#{@new_resource.shell}")
|
193
|
+
safe_dscl("create /Users/#{@new_resource.username} UserShell '#{@new_resource.shell}'")
|
194
|
+
else
|
195
|
+
safe_dscl("create /Users/#{@new_resource.username} UserShell '/usr/bin/false'")
|
524
196
|
end
|
525
|
-
# Output is something like:
|
526
|
-
# GroupMembership: root admin etc
|
527
|
-
members = membership_info.split(" ")
|
528
|
-
members.shift # Get rid of GroupMembership: string
|
529
|
-
members.include?(@new_resource.username)
|
530
197
|
end
|
531
198
|
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
:shell => "shell",
|
542
|
-
:comment => "realname",
|
543
|
-
:password => "passwd",
|
544
|
-
:auth_authority => "authentication_authority",
|
545
|
-
:shadow_hash => "ShadowHashData"
|
546
|
-
}.freeze
|
547
|
-
|
548
|
-
# Directory where the user plist files are stored for versions 10.7 and above
|
549
|
-
USER_PLIST_DIRECTORY = "/var/db/dslocal/nodes/Default/users".freeze
|
550
|
-
|
551
|
-
#
|
552
|
-
# Reads the user plist and returns a hash keyed with DSCL properties specified
|
553
|
-
# in DSCL_PROPERTY_MAP. Return nil if the user is not found.
|
554
|
-
#
|
555
|
-
def read_user_info
|
556
|
-
user_info = nil
|
557
|
-
|
558
|
-
# We flush the cache here in order to make sure that we read fresh information
|
559
|
-
# for the user.
|
560
|
-
shell_out("dscacheutil '-flushcache'")
|
561
|
-
|
562
|
-
begin
|
563
|
-
user_plist_file = "#{USER_PLIST_DIRECTORY}/#{@new_resource.username}.plist"
|
564
|
-
user_plist_info = run_plutil("convert xml1 -o - #{user_plist_file}")
|
565
|
-
user_info = Plist::parse_xml(user_plist_info)
|
566
|
-
rescue Chef::Exceptions::PlistUtilCommandFailed
|
199
|
+
def remove_user
|
200
|
+
if @new_resource.supports[:manage_home]
|
201
|
+
user_info = safe_dscl("read /Users/#{@new_resource.username}")
|
202
|
+
if nfs_home_match = user_info.match(NFS_HOME_DIRECTORY)
|
203
|
+
#nfs_home = safe_dscl("read /Users/#{@new_resource.username} NFSHomeDirectory")
|
204
|
+
#nfs_home.gsub!(/NFSHomeDirectory: /,"").gsub!(/\n$/,"")
|
205
|
+
nfs_home = nfs_home_match[1]
|
206
|
+
FileUtils.rm_rf(nfs_home)
|
207
|
+
end
|
567
208
|
end
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
Plist::Emit.save_plist(user_info, user_plist_file)
|
579
|
-
run_plutil("convert binary1 #{user_plist_file}")
|
580
|
-
end
|
581
|
-
|
582
|
-
#
|
583
|
-
# Sets a value in user information hash using Chef attributes as keys.
|
584
|
-
#
|
585
|
-
def dscl_set(user_hash, key, value)
|
586
|
-
raise "Unknown dscl key #{key}" unless DSCL_PROPERTY_MAP.keys.include?(key)
|
587
|
-
user_hash[DSCL_PROPERTY_MAP[key]] = [ value ]
|
588
|
-
user_hash
|
589
|
-
end
|
590
|
-
|
591
|
-
#
|
592
|
-
# Gets a value from user information hash using Chef attributes as keys.
|
593
|
-
#
|
594
|
-
def dscl_get(user_hash, key)
|
595
|
-
raise "Unknown dscl key #{key}" unless DSCL_PROPERTY_MAP.keys.include?(key)
|
596
|
-
# DSCL values are set as arrays
|
597
|
-
value = user_hash[DSCL_PROPERTY_MAP[key]]
|
598
|
-
value.nil? ? value : value.first
|
209
|
+
# remove the user from its groups
|
210
|
+
groups = []
|
211
|
+
Etc.group do |group|
|
212
|
+
groups << group.name if group.mem.include?(@new_resource.username)
|
213
|
+
end
|
214
|
+
groups.each do |group_name|
|
215
|
+
safe_dscl("delete /Groups/#{group_name} GroupMembership '#{@new_resource.username}'")
|
216
|
+
end
|
217
|
+
# remove user account
|
218
|
+
safe_dscl("delete /Users/#{@new_resource.username}")
|
599
219
|
end
|
600
220
|
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
node[:platform_version]
|
221
|
+
def locked?
|
222
|
+
user_info = safe_dscl("read /Users/#{@new_resource.username}")
|
223
|
+
if auth_authority_md = AUTHENTICATION_AUTHORITY.match(user_info)
|
224
|
+
!!(auth_authority_md[1] =~ /DisabledUser/ )
|
225
|
+
else
|
226
|
+
false
|
227
|
+
end
|
609
228
|
end
|
610
229
|
|
611
|
-
def
|
612
|
-
|
230
|
+
def check_lock
|
231
|
+
return @locked = locked?
|
613
232
|
end
|
614
233
|
|
615
|
-
def
|
616
|
-
|
617
|
-
# Make integer comparison in order not to report 10.10 less than 10.7
|
618
|
-
(versions[0].to_i <= 10 && versions[1].to_i < 7)
|
234
|
+
def lock_user
|
235
|
+
safe_dscl("append /Users/#{@new_resource.username} AuthenticationAuthority ';DisabledUser;'")
|
619
236
|
end
|
620
237
|
|
621
|
-
def
|
622
|
-
|
623
|
-
|
624
|
-
(
|
238
|
+
def unlock_user
|
239
|
+
auth_info = safe_dscl("read /Users/#{@new_resource.username} AuthenticationAuthority")
|
240
|
+
auth_string = auth_info.gsub(/AuthenticationAuthority: /,"").gsub(/;DisabledUser;/,"").strip#.gsub!(/[; ]*$/,"")
|
241
|
+
safe_dscl("create /Users/#{@new_resource.username} AuthenticationAuthority '#{auth_string}'")
|
625
242
|
end
|
626
243
|
|
627
|
-
def
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
raise(Chef::Exceptions::DsclCommandFailed,"dscl error: #{result.inspect}") if result.stdout =~ /No such key: /
|
632
|
-
result.stdout
|
244
|
+
def validate_home_dir_specification!
|
245
|
+
unless @new_resource.home =~ /^\//
|
246
|
+
raise(Chef::Exceptions::InvalidHomeDirectory,"invalid path spec for User: '#{@new_resource.username}', home directory: '#{@new_resource.home}'")
|
247
|
+
end
|
633
248
|
end
|
634
249
|
|
635
|
-
def
|
636
|
-
|
637
|
-
raise(Chef::Exceptions::PlistUtilCommandFailed,"plutil error: #{result.inspect}") unless result.exitstatus == 0
|
638
|
-
result.stdout
|
250
|
+
def current_home_exists?
|
251
|
+
::File.exist?("#{@current_resource.home}")
|
639
252
|
end
|
640
253
|
|
641
|
-
def
|
642
|
-
|
254
|
+
def new_home_exists?
|
255
|
+
::File.exist?("#{@new_resource.home}")
|
643
256
|
end
|
644
257
|
|
645
|
-
def
|
646
|
-
|
258
|
+
def ditto_home
|
259
|
+
skel = "/System/Library/User Template/English.lproj"
|
260
|
+
raise(Chef::Exceptions::User,"can't find skel at: #{skel}") unless ::File.exists?(skel)
|
261
|
+
shell_out! "ditto '#{skel}' '#{@new_resource.home}'"
|
262
|
+
::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
|
647
263
|
end
|
648
264
|
|
649
|
-
def
|
650
|
-
|
651
|
-
end
|
265
|
+
def move_home
|
266
|
+
Chef::Log.debug("#{@new_resource} moving #{self} home from #{@current_resource.home} to #{@new_resource.home}")
|
652
267
|
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
268
|
+
src = @current_resource.home
|
269
|
+
FileUtils.mkdir_p(@new_resource.home)
|
270
|
+
files = ::Dir.glob("#{src}/*", ::File::FNM_DOTMATCH) - ["#{src}/.","#{src}/.."]
|
271
|
+
::FileUtils.mv(files,@new_resource.home, :force => true)
|
272
|
+
::FileUtils.rmdir(src)
|
273
|
+
::FileUtils.chown_R(@new_resource.username,@new_resource.gid.to_s,@new_resource.home)
|
658
274
|
end
|
659
275
|
|
660
|
-
def
|
661
|
-
|
276
|
+
def diverged?(parameter)
|
277
|
+
parameter_updated?(parameter) && (not @new_resource.send(parameter).nil?)
|
662
278
|
end
|
663
279
|
|
664
|
-
def
|
665
|
-
|
666
|
-
|
667
|
-
OpenSSL::PKCS5::pbkdf2_hmac(
|
668
|
-
@new_resource.password,
|
669
|
-
salt,
|
670
|
-
@current_resource.iterations,
|
671
|
-
128,
|
672
|
-
OpenSSL::Digest::SHA512.new
|
673
|
-
).unpack('H*').first == @current_resource.password
|
280
|
+
def parameter_updated?(parameter)
|
281
|
+
not (@new_resource.send(parameter) == @current_resource.send(parameter))
|
674
282
|
end
|
675
|
-
|
676
283
|
end
|
677
284
|
end
|
678
285
|
end
|