chef 12.5.1-universal-mingw32 → 12.6.0-universal-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/Gemfile +6 -1
- data/README.md +6 -4
- data/Rakefile +1 -4
- data/chef-windows.gemspec +21 -0
- data/chef.gemspec +58 -0
- data/lib/chef/api_client/registration.rb +9 -4
- data/lib/chef/application.rb +3 -84
- data/lib/chef/application/apply.rb +9 -2
- data/lib/chef/application/client.rb +8 -3
- data/lib/chef/application/solo.rb +7 -1
- data/lib/chef/application/windows_service.rb +21 -6
- data/lib/chef/application/windows_service_manager.rb +2 -3
- data/lib/chef/audit/runner.rb +1 -0
- data/lib/chef/chef_class.rb +1 -11
- data/lib/chef/chef_fs/chef_fs_data_store.rb +181 -2
- data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +5 -0
- data/lib/chef/chef_fs/file_system/file_system_entry.rb +11 -7
- data/lib/chef/client.rb +28 -1
- data/lib/chef/cookbook/cookbook_collection.rb +14 -1
- data/lib/chef/cookbook/cookbook_version_loader.rb +1 -1
- data/lib/chef/cookbook/metadata.rb +115 -9
- data/lib/chef/cookbook/remote_file_vendor.rb +1 -1
- data/lib/chef/cookbook_version.rb +6 -2
- data/lib/chef/data_bag.rb +1 -1
- data/lib/chef/data_bag_item.rb +1 -1
- data/lib/chef/digester.rb +5 -1
- data/lib/chef/dsl/chef_provisioning.rb +57 -0
- data/lib/chef/dsl/cheffish.rb +64 -0
- data/lib/chef/dsl/declare_resource.rb +108 -0
- data/lib/chef/dsl/platform_introspection.rb +3 -3
- data/lib/chef/dsl/recipe.rb +3 -73
- data/lib/chef/dsl/resources.rb +27 -1
- data/lib/chef/event_dispatch/base.rb +3 -0
- data/lib/chef/event_dispatch/dispatcher.rb +5 -0
- data/lib/chef/event_dispatch/events_output_stream.rb +8 -0
- data/lib/chef/exceptions.rb +21 -1
- data/lib/chef/file_access_control/unix.rb +12 -12
- data/lib/chef/file_content_management/deploy/cp.rb +2 -2
- data/lib/chef/file_content_management/deploy/mv_unix.rb +4 -4
- data/lib/chef/file_content_management/deploy/mv_windows.rb +1 -1
- data/lib/chef/formatters/base.rb +7 -0
- data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +2 -2
- data/lib/chef/formatters/indentable_output_stream.rb +5 -0
- data/lib/chef/http.rb +19 -3
- data/lib/chef/http/decompressor.rb +2 -2
- data/lib/chef/json_compat.rb +1 -0
- data/lib/chef/knife.rb +16 -2
- data/lib/chef/knife/bootstrap.rb +55 -10
- data/lib/chef/knife/cookbook_site_install.rb +5 -1
- data/lib/chef/knife/core/bootstrap_context.rb +2 -1
- data/lib/chef/knife/core/node_presenter.rb +1 -1
- data/lib/chef/knife/ssh.rb +30 -16
- data/lib/chef/knife/ssl_check.rb +4 -2
- data/lib/chef/knife/ssl_fetch.rb +3 -2
- data/lib/chef/knife/status.rb +14 -1
- data/lib/chef/log.rb +14 -0
- data/lib/chef/mixin/get_source_from_package.rb +7 -2
- data/lib/chef/mixin/properties.rb +302 -0
- data/lib/chef/mixin/proxified_socket.rb +38 -0
- data/lib/chef/mixin/subclass_directive.rb +37 -0
- data/lib/chef/node.rb +13 -5
- data/lib/chef/platform/query_helpers.rb +14 -3
- data/lib/chef/platform/service_helpers.rb +20 -38
- data/lib/chef/policy_builder/expand_node_object.rb +3 -0
- data/lib/chef/policy_builder/policyfile.rb +1 -0
- data/lib/chef/property.rb +51 -12
- data/lib/chef/provider.rb +40 -35
- data/lib/chef/provider/deploy.rb +1 -1
- data/lib/chef/provider/dsc_resource.rb +54 -20
- data/lib/chef/provider/execute.rb +25 -4
- data/lib/chef/provider/group.rb +1 -1
- data/lib/chef/provider/lwrp_base.rb +1 -0
- data/lib/chef/provider/package.rb +76 -30
- data/lib/chef/provider/package/dpkg.rb +152 -69
- data/lib/chef/provider/package/openbsd.rb +6 -8
- data/lib/chef/provider/package/solaris.rb +2 -0
- data/lib/chef/provider/package/windows.rb +95 -14
- data/lib/chef/provider/package/windows/exe.rb +129 -0
- data/lib/chef/provider/package/windows/msi.rb +37 -13
- data/lib/chef/provider/package/windows/registry_uninstall_entry.rb +89 -0
- data/lib/chef/provider/package/yum.rb +13 -3
- data/lib/chef/provider/powershell_script.rb +3 -0
- data/lib/chef/provider/remote_file/cache_control_data.rb +37 -4
- data/lib/chef/provider/remote_file/http.rb +1 -1
- data/lib/chef/provider/script.rb +1 -0
- data/lib/chef/provider/service.rb +13 -10
- data/lib/chef/provider/service/solaris.rb +43 -17
- data/lib/chef/provider/service/upstart.rb +3 -3
- data/lib/chef/provider/user.rb +1 -1
- data/lib/chef/provider/user/dscl.rb +111 -100
- data/lib/chef/provider/user/windows.rb +5 -3
- data/lib/chef/recipe.rb +3 -5
- data/lib/chef/resource.rb +77 -320
- data/lib/chef/resource/action_class.rb +4 -0
- data/lib/chef/resource/dpkg_package.rb +4 -3
- data/lib/chef/resource/dsc_resource.rb +40 -2
- data/lib/chef/resource/execute.rb +9 -1
- data/lib/chef/resource/ksh.rb +32 -0
- data/lib/chef/resource/lwrp_base.rb +6 -10
- data/lib/chef/resource/package.rb +8 -9
- data/lib/chef/resource/registry_key.rb +1 -1
- data/lib/chef/resource/resource_notification.rb +14 -1
- data/lib/chef/resource/script.rb +1 -1
- data/lib/chef/resource/windows_package.rb +1 -1
- data/lib/chef/resource_builder.rb +14 -7
- data/lib/chef/resource_reporter.rb +6 -0
- data/lib/chef/resources.rb +1 -7
- data/lib/chef/rest.rb +1 -1
- data/lib/chef/run_context.rb +45 -2
- data/lib/chef/run_list/run_list_expansion.rb +47 -0
- data/lib/chef/runner.rb +25 -0
- data/lib/chef/search/query.rb +16 -2
- data/lib/chef/util/diff.rb +2 -2
- data/lib/chef/util/powershell/ps_credential.rb +2 -3
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/api/file.rb +51 -1
- data/lib/chef/win32/file.rb +5 -0
- data/lib/chef/win32/file/version_info.rb +93 -0
- data/lib/chef/win32/mutex.rb +1 -1
- data/spec/data/apt/chef-integration-test2-1.0/debian/changelog +5 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.debhelper.log +45 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2.substvars +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/conffiles +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/control +10 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/chef-integration-test2/DEBIAN/md5sums +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/compat +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/conffiles +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/control +13 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/copyright +34 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/files +1 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/rules +13 -0
- data/spec/data/apt/chef-integration-test2-1.0/debian/source/format +1 -0
- data/spec/data/apt/chef-integration-test2_1.0-1.debian.tar.gz +0 -0
- data/spec/data/apt/chef-integration-test2_1.0-1.dsc +18 -0
- data/spec/data/apt/chef-integration-test2_1.0-1_amd64.build +91 -0
- data/spec/data/apt/chef-integration-test2_1.0-1_amd64.changes +31 -0
- data/spec/data/apt/chef-integration-test2_1.0-1_amd64.deb +0 -0
- data/spec/data/apt/chef-integration-test2_1.0.orig.tar.gz +0 -0
- data/spec/functional/application_spec.rb +1 -1
- data/spec/functional/audit/runner_spec.rb +4 -0
- data/spec/functional/knife/ssh_spec.rb +5 -5
- data/spec/functional/notifications_spec.rb +74 -4
- data/spec/functional/resource/aix_service_spec.rb +2 -2
- data/spec/functional/resource/dpkg_package_spec.rb +339 -0
- data/spec/functional/resource/ifconfig_spec.rb +3 -1
- data/spec/functional/resource/mount_spec.rb +5 -2
- data/spec/functional/resource/package_spec.rb +1 -1
- data/spec/functional/resource/user/windows_spec.rb +8 -0
- data/spec/functional/resource/windows_package_spec.rb +177 -0
- data/spec/functional/win32/version_info_spec.rb +50 -0
- data/spec/integration/client/client_spec.rb +80 -0
- data/spec/integration/knife/download_spec.rb +9 -0
- data/spec/integration/knife/upload_spec.rb +28 -1
- data/spec/integration/recipes/lwrp_inline_resources_spec.rb +93 -23
- data/spec/integration/recipes/resource_action_spec.rb +211 -116
- data/spec/integration/recipes/resource_converge_if_changed_spec.rb +72 -0
- data/spec/integration/solo/solo_spec.rb +34 -0
- data/spec/spec_helper.rb +11 -1
- data/spec/support/platform_helpers.rb +8 -0
- data/spec/support/shared/integration/integration_helper.rb +6 -0
- data/spec/support/shared/unit/execute_resource.rb +5 -0
- data/spec/support/shared/unit/platform_introspector.rb +7 -0
- data/spec/tiny_server.rb +6 -2
- data/spec/unit/api_client/registration_spec.rb +5 -4
- data/spec/unit/application_spec.rb +1 -181
- data/spec/unit/chef_fs/file_system/cookbook_subdir_spec.rb +34 -0
- data/spec/unit/cookbook/metadata_spec.rb +122 -2
- data/spec/unit/http_spec.rb +102 -0
- data/spec/unit/knife/bootstrap_spec.rb +55 -13
- data/spec/unit/knife/core/bootstrap_context_spec.rb +10 -3
- data/spec/unit/knife/ssl_check_spec.rb +7 -3
- data/spec/unit/knife/ssl_fetch_spec.rb +2 -2
- data/spec/unit/knife/status_spec.rb +13 -13
- data/spec/unit/knife_spec.rb +26 -2
- data/spec/unit/lwrp_spec.rb +1 -1
- data/spec/unit/mixin/properties_spec.rb +97 -0
- data/spec/unit/mixin/proxified_socket_spec.rb +94 -0
- data/spec/unit/mixin/subclass_directive_spec.rb +45 -0
- data/spec/unit/node_spec.rb +9 -1
- data/spec/unit/policy_builder/policyfile_spec.rb +2 -0
- data/spec/unit/property/validation_spec.rb +14 -12
- data/spec/unit/property_spec.rb +56 -0
- data/spec/unit/provider/deploy_spec.rb +1 -1
- data/spec/unit/provider/dsc_resource_spec.rb +63 -24
- data/spec/unit/provider/execute_spec.rb +95 -28
- data/spec/unit/provider/package/dpkg_spec.rb +185 -96
- data/spec/unit/provider/package/windows/exe_spec.rb +251 -0
- data/spec/unit/provider/package/windows/msi_spec.rb +94 -10
- data/spec/unit/provider/package/windows_spec.rb +227 -26
- data/spec/unit/provider/package/yum_spec.rb +6 -0
- data/spec/unit/provider/package_spec.rb +495 -366
- data/spec/unit/provider/remote_file/cache_control_data_spec.rb +62 -36
- data/spec/unit/provider/script_spec.rb +2 -2
- data/spec/unit/provider/service/solaris_smf_service_spec.rb +110 -39
- data/spec/unit/provider/service/upstart_service_spec.rb +19 -0
- data/spec/unit/provider/user/dscl_spec.rb +14 -0
- data/spec/unit/provider/user/windows_spec.rb +2 -2
- data/spec/unit/provider/user_spec.rb +9 -0
- data/spec/unit/provider_resolver_spec.rb +6 -30
- data/spec/unit/recipe_spec.rb +46 -20
- data/spec/unit/resource/chef_gem_spec.rb +1 -1
- data/spec/unit/resource/dsc_resource_spec.rb +14 -3
- data/spec/unit/resource/ksh_spec.rb +40 -0
- data/spec/unit/resource/registry_key_spec.rb +2 -2
- data/spec/unit/resource/resource_notification_spec.rb +44 -45
- data/spec/unit/resource_reporter_spec.rb +7 -0
- data/spec/unit/resource_spec.rb +268 -253
- data/spec/unit/rest_spec.rb +2 -2
- data/spec/unit/run_list/run_list_expansion_spec.rb +18 -3
- data/spec/unit/search/query_spec.rb +19 -1
- data/spec/unit/util/powershell/ps_credential_spec.rb +8 -1
- data/spec/unit/windows_service_spec.rb +83 -38
- data/tasks/external_tests.rb +19 -9
- data/tasks/rspec.rb +1 -1
- metadata +70 -21
- data/spec/support/pedant/Gemfile +0 -3
- data/spec/support/pedant/pedant_config.rb +0 -129
- data/spec/support/pedant/run_pedant.rb +0 -63
- data/spec/support/pedant/stickywicket.pem +0 -27
- data/spec/unit/provider/package_spec.rbe +0 -0
@@ -30,7 +30,7 @@ class Chef
|
|
30
30
|
Chef::Platform::ServiceHelpers.service_resource_providers.include?(:upstart)
|
31
31
|
end
|
32
32
|
|
33
|
-
UPSTART_STATE_FORMAT = /\
|
33
|
+
UPSTART_STATE_FORMAT = /\S+ \(?(start|stop)?\)? ?[\/ ](\w+)/
|
34
34
|
|
35
35
|
def self.supports?(resource, action)
|
36
36
|
Chef::Platform::ServiceHelpers.config_for_service(resource.service_name).include?(:upstart)
|
@@ -224,10 +224,10 @@ class Chef
|
|
224
224
|
command = "/sbin/status #{@job}"
|
225
225
|
status = popen4(command) do |pid, stdin, stdout, stderr|
|
226
226
|
stdout.each_line do |line|
|
227
|
-
# rsyslog stop/waiting
|
228
227
|
# service goal/state
|
229
228
|
# OR
|
230
|
-
#
|
229
|
+
# service (instance) goal/state
|
230
|
+
# OR
|
231
231
|
# service (goal) state
|
232
232
|
line =~ UPSTART_STATE_FORMAT
|
233
233
|
data = Regexp.last_match
|
data/lib/chef/provider/user.rb
CHANGED
@@ -89,7 +89,7 @@ class Chef
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def define_resource_requirements
|
92
|
-
requirements.assert(:
|
92
|
+
requirements.assert(:create, :modify, :manage, :lock, :unlock) do |a|
|
93
93
|
a.assertion { @group_name_resolved }
|
94
94
|
a.failure_message Chef::Exceptions::User, "Couldn't lookup integer GID for group name #{@new_resource.gid}"
|
95
95
|
a.whyrun "group name #{@new_resource.gid} does not exist. This will cause group assignment to fail. Assuming this group will have been created previously."
|
@@ -44,6 +44,10 @@ class Chef
|
|
44
44
|
# This provider only supports Mac OSX versions 10.7 and above
|
45
45
|
class Dscl < Chef::Provider::User
|
46
46
|
|
47
|
+
attr_accessor :user_info
|
48
|
+
attr_accessor :authentication_authority
|
49
|
+
attr_accessor :password_shadow_conversion_algorithm
|
50
|
+
|
47
51
|
provides :user, os: "darwin"
|
48
52
|
|
49
53
|
def define_resource_requirements
|
@@ -56,19 +60,19 @@ class Chef
|
|
56
60
|
|
57
61
|
requirements.assert(:all_actions) do |a|
|
58
62
|
a.assertion { ::File.exists?("/usr/bin/dscl") }
|
59
|
-
a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/dscl' on the system for #{
|
63
|
+
a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/dscl' on the system for #{new_resource}!")
|
60
64
|
end
|
61
65
|
|
62
66
|
requirements.assert(:all_actions) do |a|
|
63
67
|
a.assertion { ::File.exists?("/usr/bin/plutil") }
|
64
|
-
a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/plutil' on the system for #{
|
68
|
+
a.failure_message(Chef::Exceptions::User, "Cannot find binary '/usr/bin/plutil' on the system for #{new_resource}!")
|
65
69
|
end
|
66
70
|
|
67
71
|
requirements.assert(:create, :modify, :manage) do |a|
|
68
72
|
a.assertion do
|
69
|
-
if
|
73
|
+
if new_resource.password && mac_osx_version_greater_than_10_7?
|
70
74
|
# SALTED-SHA512 password shadow hashes are not supported on 10.8 and above.
|
71
|
-
!salted_sha512?(
|
75
|
+
!salted_sha512?(new_resource.password)
|
72
76
|
else
|
73
77
|
true
|
74
78
|
end
|
@@ -80,10 +84,10 @@ in 'password', with the associated 'salt' and 'iterations'.")
|
|
80
84
|
|
81
85
|
requirements.assert(:create, :modify, :manage) do |a|
|
82
86
|
a.assertion do
|
83
|
-
if
|
87
|
+
if new_resource.password && mac_osx_version_greater_than_10_7? && salted_sha512_pbkdf2?(new_resource.password)
|
84
88
|
# salt and iterations should be specified when
|
85
89
|
# SALTED-SHA512-PBKDF2 password shadow hash is given
|
86
|
-
|
90
|
+
!new_resource.salt.nil? && !new_resource.iterations.nil?
|
87
91
|
else
|
88
92
|
true
|
89
93
|
end
|
@@ -94,9 +98,9 @@ in 'password', with the associated 'salt' and 'iterations'.")
|
|
94
98
|
|
95
99
|
requirements.assert(:create, :modify, :manage) do |a|
|
96
100
|
a.assertion do
|
97
|
-
if
|
101
|
+
if new_resource.password && !mac_osx_version_greater_than_10_7?
|
98
102
|
# On 10.7 SALTED-SHA512-PBKDF2 is not supported
|
99
|
-
!salted_sha512_pbkdf2?(
|
103
|
+
!salted_sha512_pbkdf2?(new_resource.password)
|
100
104
|
else
|
101
105
|
true
|
102
106
|
end
|
@@ -109,21 +113,21 @@ user password using shadow hash.")
|
|
109
113
|
end
|
110
114
|
|
111
115
|
def load_current_resource
|
112
|
-
@current_resource = Chef::Resource::User.new(
|
113
|
-
|
116
|
+
@current_resource = Chef::Resource::User.new(new_resource.username)
|
117
|
+
current_resource.username(new_resource.username)
|
114
118
|
|
115
119
|
@user_info = read_user_info
|
116
|
-
if
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
@authentication_authority = dscl_get(
|
123
|
-
|
124
|
-
if
|
120
|
+
if user_info
|
121
|
+
current_resource.uid(dscl_get(user_info, :uid))
|
122
|
+
current_resource.gid(dscl_get(user_info, :gid))
|
123
|
+
current_resource.home(dscl_get(user_info, :home))
|
124
|
+
current_resource.shell(dscl_get(user_info, :shell))
|
125
|
+
current_resource.comment(dscl_get(user_info, :comment))
|
126
|
+
@authentication_authority = dscl_get(user_info, :auth_authority)
|
127
|
+
|
128
|
+
if new_resource.password && dscl_get(user_info, :password) == "********"
|
125
129
|
# A password is set. Let's get the password information from shadow file
|
126
|
-
shadow_hash_binary = dscl_get(
|
130
|
+
shadow_hash_binary = dscl_get(user_info, :shadow_hash)
|
127
131
|
|
128
132
|
# Calling shell_out directly since we want to give an input stream
|
129
133
|
shadow_hash_xml = convert_binary_plist_to_xml(shadow_hash_binary.string)
|
@@ -132,26 +136,26 @@ user password using shadow hash.")
|
|
132
136
|
if shadow_hash["SALTED-SHA512"]
|
133
137
|
# Convert the shadow value from Base64 encoding to hex before consuming them
|
134
138
|
@password_shadow_conversion_algorithm = "SALTED-SHA512"
|
135
|
-
|
139
|
+
current_resource.password(shadow_hash["SALTED-SHA512"].string.unpack('H*').first)
|
136
140
|
elsif shadow_hash["SALTED-SHA512-PBKDF2"]
|
137
141
|
@password_shadow_conversion_algorithm = "SALTED-SHA512-PBKDF2"
|
138
142
|
# Convert the entropy from Base64 encoding to hex before consuming them
|
139
|
-
|
140
|
-
|
143
|
+
current_resource.password(shadow_hash["SALTED-SHA512-PBKDF2"]["entropy"].string.unpack('H*').first)
|
144
|
+
current_resource.iterations(shadow_hash["SALTED-SHA512-PBKDF2"]["iterations"])
|
141
145
|
# Convert the salt from Base64 encoding to hex before consuming them
|
142
|
-
|
146
|
+
current_resource.salt(shadow_hash["SALTED-SHA512-PBKDF2"]["salt"].string.unpack('H*').first)
|
143
147
|
else
|
144
148
|
raise(Chef::Exceptions::User,"Unknown shadow_hash format: #{shadow_hash.keys.join(' ')}")
|
145
149
|
end
|
146
150
|
end
|
147
151
|
|
148
|
-
convert_group_name if
|
152
|
+
convert_group_name if new_resource.gid
|
149
153
|
else
|
150
154
|
@user_exists = false
|
151
|
-
Chef::Log.debug("#{
|
155
|
+
Chef::Log.debug("#{new_resource} user does not exist")
|
152
156
|
end
|
153
157
|
|
154
|
-
|
158
|
+
current_resource
|
155
159
|
end
|
156
160
|
|
157
161
|
#
|
@@ -190,15 +194,16 @@ user password using shadow hash.")
|
|
190
194
|
# Create a user using dscl
|
191
195
|
#
|
192
196
|
def dscl_create_user
|
193
|
-
run_dscl("create /Users/#{
|
197
|
+
run_dscl("create /Users/#{new_resource.username}")
|
194
198
|
end
|
195
199
|
|
196
200
|
#
|
197
201
|
# Saves the specified Chef user `comment` into RealName attribute
|
198
|
-
# of Mac user.
|
202
|
+
# of Mac user. If `comment` is not specified, it takes `username` value.
|
199
203
|
#
|
200
204
|
def dscl_create_comment
|
201
|
-
|
205
|
+
comment = new_resource.comment || new_resource.username
|
206
|
+
run_dscl("create /Users/#{new_resource.username} RealName '#{comment}'")
|
202
207
|
end
|
203
208
|
|
204
209
|
#
|
@@ -207,13 +212,14 @@ user password using shadow hash.")
|
|
207
212
|
# from 200 if `system` is set, 500 otherwise.
|
208
213
|
#
|
209
214
|
def dscl_set_uid
|
210
|
-
|
215
|
+
# XXX: mutates the new resource
|
216
|
+
new_resource.uid(get_free_uid) if (new_resource.uid.nil? || new_resource.uid == '')
|
211
217
|
|
212
|
-
if uid_used?(
|
213
|
-
raise(Chef::Exceptions::RequestedUIDUnavailable, "uid #{
|
218
|
+
if uid_used?(new_resource.uid)
|
219
|
+
raise(Chef::Exceptions::RequestedUIDUnavailable, "uid #{new_resource.uid} is already in use")
|
214
220
|
end
|
215
221
|
|
216
|
-
run_dscl("create /Users/#{
|
222
|
+
run_dscl("create /Users/#{new_resource.username} UniqueID #{new_resource.uid}")
|
217
223
|
end
|
218
224
|
|
219
225
|
#
|
@@ -222,7 +228,7 @@ user password using shadow hash.")
|
|
222
228
|
#
|
223
229
|
def get_free_uid(search_limit=1000)
|
224
230
|
uid = nil
|
225
|
-
base_uid =
|
231
|
+
base_uid = new_resource.system ? 200 : 500
|
226
232
|
next_uid_guess = base_uid
|
227
233
|
users_uids = run_dscl("list /Users uid")
|
228
234
|
while(next_uid_guess < search_limit + base_uid)
|
@@ -248,7 +254,7 @@ user password using shadow hash.")
|
|
248
254
|
tmap
|
249
255
|
end
|
250
256
|
if uid_map[uid.to_s]
|
251
|
-
unless uid_map[uid.to_s] ==
|
257
|
+
unless uid_map[uid.to_s] == new_resource.username.to_s
|
252
258
|
return true
|
253
259
|
end
|
254
260
|
end
|
@@ -257,18 +263,23 @@ user password using shadow hash.")
|
|
257
263
|
|
258
264
|
#
|
259
265
|
# Sets the group id for the user using dscl. Fails if a group doesn't
|
260
|
-
# exist on the system with given group id.
|
266
|
+
# exist on the system with given group id. If `gid` is not specified, it
|
267
|
+
# sets a default Mac user group "staff", with id 20.
|
261
268
|
#
|
262
269
|
def dscl_set_gid
|
263
|
-
|
270
|
+
if new_resource.gid.nil?
|
271
|
+
# XXX: mutates the new resource
|
272
|
+
new_resource.gid(20)
|
273
|
+
elsif !new_resource.gid.to_s.match(/^\d+$/)
|
264
274
|
begin
|
265
|
-
possible_gid = run_dscl("read /Groups/#{
|
275
|
+
possible_gid = run_dscl("read /Groups/#{new_resource.gid} PrimaryGroupID").split(" ").last
|
266
276
|
rescue Chef::Exceptions::DsclCommandFailed => e
|
267
|
-
raise Chef::Exceptions::GroupIDNotFound.new("Group not found for #{
|
277
|
+
raise Chef::Exceptions::GroupIDNotFound.new("Group not found for #{new_resource.gid} when creating user #{new_resource.username}")
|
268
278
|
end
|
269
|
-
|
279
|
+
# XXX: mutates the new resource
|
280
|
+
new_resource.gid(possible_gid) if possible_gid && possible_gid.match(/^\d+$/)
|
270
281
|
end
|
271
|
-
run_dscl("create /Users/#{
|
282
|
+
run_dscl("create /Users/#{new_resource.username} PrimaryGroupID '#{new_resource.gid}'")
|
272
283
|
end
|
273
284
|
|
274
285
|
#
|
@@ -276,15 +287,15 @@ user password using shadow hash.")
|
|
276
287
|
# directory is managed (moved / created) for the user.
|
277
288
|
#
|
278
289
|
def dscl_set_home
|
279
|
-
if
|
280
|
-
run_dscl("delete /Users/#{
|
290
|
+
if new_resource.home.nil? || new_resource.home.empty?
|
291
|
+
run_dscl("delete /Users/#{new_resource.username} NFSHomeDirectory")
|
281
292
|
return
|
282
293
|
end
|
283
294
|
|
284
|
-
if
|
295
|
+
if new_resource.supports[:manage_home]
|
285
296
|
validate_home_dir_specification!
|
286
297
|
|
287
|
-
if (
|
298
|
+
if (current_resource.home == new_resource.home) && !new_home_exists?
|
288
299
|
ditto_home
|
289
300
|
elsif !current_home_exists? && !new_home_exists?
|
290
301
|
ditto_home
|
@@ -292,49 +303,49 @@ user password using shadow hash.")
|
|
292
303
|
move_home
|
293
304
|
end
|
294
305
|
end
|
295
|
-
run_dscl("create /Users/#{
|
306
|
+
run_dscl("create /Users/#{new_resource.username} NFSHomeDirectory '#{new_resource.home}'")
|
296
307
|
end
|
297
308
|
|
298
309
|
def validate_home_dir_specification!
|
299
|
-
unless
|
300
|
-
raise(Chef::Exceptions::InvalidHomeDirectory,"invalid path spec for User: '#{
|
310
|
+
unless new_resource.home =~ /^\//
|
311
|
+
raise(Chef::Exceptions::InvalidHomeDirectory,"invalid path spec for User: '#{new_resource.username}', home directory: '#{new_resource.home}'")
|
301
312
|
end
|
302
313
|
end
|
303
314
|
|
304
315
|
def current_home_exists?
|
305
|
-
::File.exist?("#{
|
316
|
+
::File.exist?("#{current_resource.home}")
|
306
317
|
end
|
307
318
|
|
308
319
|
def new_home_exists?
|
309
|
-
::File.exist?("#{
|
320
|
+
::File.exist?("#{new_resource.home}")
|
310
321
|
end
|
311
322
|
|
312
323
|
def ditto_home
|
313
324
|
skel = "/System/Library/User Template/English.lproj"
|
314
325
|
raise(Chef::Exceptions::User,"can't find skel at: #{skel}") unless ::File.exists?(skel)
|
315
|
-
shell_out! "ditto '#{skel}' '#{
|
316
|
-
::FileUtils.chown_R(
|
326
|
+
shell_out! "ditto '#{skel}' '#{new_resource.home}'"
|
327
|
+
::FileUtils.chown_R(new_resource.username,new_resource.gid.to_s,new_resource.home)
|
317
328
|
end
|
318
329
|
|
319
330
|
def move_home
|
320
|
-
Chef::Log.debug("#{
|
331
|
+
Chef::Log.debug("#{new_resource} moving #{self} home from #{current_resource.home} to #{new_resource.home}")
|
321
332
|
|
322
|
-
src =
|
323
|
-
FileUtils.mkdir_p(
|
333
|
+
src = current_resource.home
|
334
|
+
FileUtils.mkdir_p(new_resource.home)
|
324
335
|
files = ::Dir.glob("#{Chef::Util::PathHelper.escape_glob(src)}/*", ::File::FNM_DOTMATCH) - ["#{src}/.","#{src}/.."]
|
325
|
-
::FileUtils.mv(files
|
336
|
+
::FileUtils.mv(files,new_resource.home, :force => true)
|
326
337
|
::FileUtils.rmdir(src)
|
327
|
-
::FileUtils.chown_R(
|
338
|
+
::FileUtils.chown_R(new_resource.username,new_resource.gid.to_s,new_resource.home)
|
328
339
|
end
|
329
340
|
|
330
341
|
#
|
331
342
|
# Sets the shell for the user using dscl.
|
332
343
|
#
|
333
344
|
def dscl_set_shell
|
334
|
-
if
|
335
|
-
run_dscl("create /Users/#{
|
345
|
+
if new_resource.shell || ::File.exists?("#{new_resource.shell}")
|
346
|
+
run_dscl("create /Users/#{new_resource.username} UserShell '#{new_resource.shell}'")
|
336
347
|
else
|
337
|
-
run_dscl("create /Users/#{
|
348
|
+
run_dscl("create /Users/#{new_resource.username} UserShell '/usr/bin/false'")
|
338
349
|
end
|
339
350
|
end
|
340
351
|
|
@@ -345,7 +356,7 @@ user password using shadow hash.")
|
|
345
356
|
#
|
346
357
|
def set_password
|
347
358
|
# Return if there is no password to set
|
348
|
-
return if
|
359
|
+
return if new_resource.password.nil?
|
349
360
|
|
350
361
|
shadow_info = prepare_password_shadow_info
|
351
362
|
|
@@ -355,7 +366,7 @@ user password using shadow hash.")
|
|
355
366
|
:input => shadow_info.to_plist, :live_stream => shadow_info_binary)
|
356
367
|
command.run_command
|
357
368
|
|
358
|
-
if
|
369
|
+
if user_info.nil?
|
359
370
|
# User is just created. read_user_info() will read the fresh information
|
360
371
|
# for the user with a cache flush. However with experimentation we've seen
|
361
372
|
# that dscl cache is not immediately updated after the creation of the user
|
@@ -365,8 +376,8 @@ user password using shadow hash.")
|
|
365
376
|
end
|
366
377
|
|
367
378
|
# Replace the shadow info in user's plist
|
368
|
-
dscl_set(
|
369
|
-
save_user_info(
|
379
|
+
dscl_set(user_info, :shadow_hash, shadow_info_binary)
|
380
|
+
save_user_info(user_info)
|
370
381
|
end
|
371
382
|
|
372
383
|
#
|
@@ -379,12 +390,12 @@ user password using shadow hash.")
|
|
379
390
|
iterations = nil
|
380
391
|
|
381
392
|
if mac_osx_version_10_7?
|
382
|
-
hash_value = if salted_sha512?(
|
383
|
-
|
393
|
+
hash_value = if salted_sha512?(new_resource.password)
|
394
|
+
new_resource.password
|
384
395
|
else
|
385
396
|
# Create a random 4 byte salt
|
386
397
|
salt = OpenSSL::Random.random_bytes(4)
|
387
|
-
encoded_password = OpenSSL::Digest::SHA512.hexdigest(salt +
|
398
|
+
encoded_password = OpenSSL::Digest::SHA512.hexdigest(salt + new_resource.password)
|
388
399
|
hash_value = salt.unpack('H*').first + encoded_password
|
389
400
|
end
|
390
401
|
|
@@ -392,16 +403,16 @@ user password using shadow hash.")
|
|
392
403
|
shadow_info["SALTED-SHA512"].string = convert_to_binary(hash_value)
|
393
404
|
shadow_info
|
394
405
|
else
|
395
|
-
if salted_sha512_pbkdf2?(
|
396
|
-
entropy = convert_to_binary(
|
397
|
-
salt = convert_to_binary(
|
398
|
-
iterations =
|
406
|
+
if salted_sha512_pbkdf2?(new_resource.password)
|
407
|
+
entropy = convert_to_binary(new_resource.password)
|
408
|
+
salt = convert_to_binary(new_resource.salt)
|
409
|
+
iterations = new_resource.iterations
|
399
410
|
else
|
400
411
|
salt = OpenSSL::Random.random_bytes(32)
|
401
|
-
iterations =
|
412
|
+
iterations = new_resource.iterations # Use the default if not specified by the user
|
402
413
|
|
403
414
|
entropy = OpenSSL::PKCS5::pbkdf2_hmac(
|
404
|
-
|
415
|
+
new_resource.password,
|
405
416
|
salt,
|
406
417
|
iterations,
|
407
418
|
128,
|
@@ -427,43 +438,43 @@ user password using shadow hash.")
|
|
427
438
|
# and deleting home directory if needed.
|
428
439
|
#
|
429
440
|
def remove_user
|
430
|
-
if
|
441
|
+
if new_resource.supports[:manage_home]
|
431
442
|
# Remove home directory
|
432
|
-
FileUtils.rm_rf(
|
443
|
+
FileUtils.rm_rf(current_resource.home)
|
433
444
|
end
|
434
445
|
|
435
446
|
# Remove the user from its groups
|
436
447
|
run_dscl("list /Groups").each_line do |group|
|
437
448
|
if member_of_group?(group.chomp)
|
438
|
-
run_dscl("delete /Groups/#{group.chomp} GroupMembership '#{
|
449
|
+
run_dscl("delete /Groups/#{group.chomp} GroupMembership '#{new_resource.username}'")
|
439
450
|
end
|
440
451
|
end
|
441
452
|
|
442
453
|
# Remove user account
|
443
|
-
run_dscl("delete /Users/#{
|
454
|
+
run_dscl("delete /Users/#{new_resource.username}")
|
444
455
|
end
|
445
456
|
|
446
457
|
#
|
447
458
|
# Locks the user.
|
448
459
|
#
|
449
460
|
def lock_user
|
450
|
-
run_dscl("append /Users/#{
|
461
|
+
run_dscl("append /Users/#{new_resource.username} AuthenticationAuthority ';DisabledUser;'")
|
451
462
|
end
|
452
463
|
|
453
464
|
#
|
454
465
|
# Unlocks the user
|
455
466
|
#
|
456
467
|
def unlock_user
|
457
|
-
auth_string =
|
458
|
-
run_dscl("create /Users/#{
|
468
|
+
auth_string = authentication_authority.gsub(/AuthenticationAuthority: /,"").gsub(/;DisabledUser;/,"").strip
|
469
|
+
run_dscl("create /Users/#{new_resource.username} AuthenticationAuthority '#{auth_string}'")
|
459
470
|
end
|
460
471
|
|
461
472
|
#
|
462
473
|
# Returns true if the user is locked, false otherwise.
|
463
474
|
#
|
464
475
|
def locked?
|
465
|
-
if
|
466
|
-
!!(
|
476
|
+
if authentication_authority
|
477
|
+
!!(authentication_authority =~ /DisabledUser/ )
|
467
478
|
else
|
468
479
|
false
|
469
480
|
end
|
@@ -485,11 +496,11 @@ user password using shadow hash.")
|
|
485
496
|
# given attribute.
|
486
497
|
#
|
487
498
|
def diverged?(parameter)
|
488
|
-
parameter_updated?(parameter) && (not
|
499
|
+
parameter_updated?(parameter) && (not new_resource.send(parameter).nil?)
|
489
500
|
end
|
490
501
|
|
491
502
|
def parameter_updated?(parameter)
|
492
|
-
not (
|
503
|
+
not (new_resource.send(parameter) == current_resource.send(parameter))
|
493
504
|
end
|
494
505
|
|
495
506
|
#
|
@@ -500,11 +511,11 @@ user password using shadow hash.")
|
|
500
511
|
# type of the password specified.
|
501
512
|
#
|
502
513
|
def diverged_password?
|
503
|
-
return false if
|
514
|
+
return false if new_resource.password.nil?
|
504
515
|
|
505
516
|
# Dscl provider supports both plain text passwords and shadow hashes.
|
506
517
|
if mac_osx_version_10_7?
|
507
|
-
if salted_sha512?(
|
518
|
+
if salted_sha512?(new_resource.password)
|
508
519
|
diverged?(:password)
|
509
520
|
else
|
510
521
|
!salted_sha512_password_match?
|
@@ -514,14 +525,14 @@ user password using shadow hash.")
|
|
514
525
|
# will be updated when the user logs in. So it's possible that we will have
|
515
526
|
# SALTED-SHA512 password in the current_resource. In that case we will force
|
516
527
|
# password to be updated.
|
517
|
-
return true if salted_sha512?(
|
528
|
+
return true if salted_sha512?(current_resource.password)
|
518
529
|
|
519
530
|
# Some system users don't have salts; this can happen if the system is
|
520
531
|
# upgraded and the user hasn't logged in yet. In this case, we will force
|
521
532
|
# the password to be updated.
|
522
|
-
return true if
|
533
|
+
return true if current_resource.salt.nil?
|
523
534
|
|
524
|
-
if salted_sha512_pbkdf2?(
|
535
|
+
if salted_sha512_pbkdf2?(new_resource.password)
|
525
536
|
diverged?(:password) || diverged?(:salt) || diverged?(:iterations)
|
526
537
|
else
|
527
538
|
!salted_sha512_pbkdf2_password_match?
|
@@ -543,7 +554,7 @@ user password using shadow hash.")
|
|
543
554
|
# GroupMembership: root admin etc
|
544
555
|
members = membership_info.split(" ")
|
545
556
|
members.shift # Get rid of GroupMembership: string
|
546
|
-
members.include?(
|
557
|
+
members.include?(new_resource.username)
|
547
558
|
end
|
548
559
|
|
549
560
|
#
|
@@ -577,7 +588,7 @@ user password using shadow hash.")
|
|
577
588
|
shell_out("dscacheutil '-flushcache'")
|
578
589
|
|
579
590
|
begin
|
580
|
-
user_plist_file = "#{USER_PLIST_DIRECTORY}/#{
|
591
|
+
user_plist_file = "#{USER_PLIST_DIRECTORY}/#{new_resource.username}.plist"
|
581
592
|
user_plist_info = run_plutil("convert xml1 -o - #{user_plist_file}")
|
582
593
|
user_info = Plist::parse_xml(user_plist_info)
|
583
594
|
rescue Chef::Exceptions::PlistUtilCommandFailed
|
@@ -591,7 +602,7 @@ user password using shadow hash.")
|
|
591
602
|
# in DSCL_PROPERTY_MAP to the disk.
|
592
603
|
#
|
593
604
|
def save_user_info(user_info)
|
594
|
-
user_plist_file = "#{USER_PLIST_DIRECTORY}/#{
|
605
|
+
user_plist_file = "#{USER_PLIST_DIRECTORY}/#{new_resource.username}.plist"
|
595
606
|
Plist::Emit.save_plist(user_info, user_plist_file)
|
596
607
|
run_plutil("convert binary1 #{user_plist_file}")
|
597
608
|
end
|
@@ -673,9 +684,9 @@ user password using shadow hash.")
|
|
673
684
|
|
674
685
|
def salted_sha512_password_match?
|
675
686
|
# Salt is included in the first 4 bytes of shadow data
|
676
|
-
salt =
|
677
|
-
shadow = OpenSSL::Digest::SHA512.hexdigest(convert_to_binary(salt) +
|
678
|
-
|
687
|
+
salt = current_resource.password.slice(0,8)
|
688
|
+
shadow = OpenSSL::Digest::SHA512.hexdigest(convert_to_binary(salt) + new_resource.password)
|
689
|
+
current_resource.password == salt + shadow
|
679
690
|
end
|
680
691
|
|
681
692
|
def salted_sha512_pbkdf2?(string)
|
@@ -683,15 +694,15 @@ user password using shadow hash.")
|
|
683
694
|
end
|
684
695
|
|
685
696
|
def salted_sha512_pbkdf2_password_match?
|
686
|
-
salt = convert_to_binary(
|
697
|
+
salt = convert_to_binary(current_resource.salt)
|
687
698
|
|
688
699
|
OpenSSL::PKCS5::pbkdf2_hmac(
|
689
|
-
|
700
|
+
new_resource.password,
|
690
701
|
salt,
|
691
|
-
|
702
|
+
current_resource.iterations,
|
692
703
|
128,
|
693
704
|
OpenSSL::Digest::SHA512.new
|
694
|
-
).unpack('H*').first ==
|
705
|
+
).unpack('H*').first == current_resource.password
|
695
706
|
end
|
696
707
|
|
697
708
|
end
|