diff options
author | Tim Smith <tsmith@chef.io> | 2020-02-03 13:17:03 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-03 13:17:03 -0800 |
commit | 49808f67bb58afab477b86b785b4ad0ba005f5c9 (patch) | |
tree | 467123cb736aa9e10071ffb09e7cd0b4c1f5a96e | |
parent | b515d50aaf7c7d6834724e709803b2883a6f484d (diff) | |
parent | 8c92999af412aa07698f3a946d454c2b7c944e2d (diff) | |
download | chef-49808f67bb58afab477b86b785b4ad0ba005f5c9.tar.gz |
Merge pull request #9323 from chef/backport_mac_user
mac_user: fixing gid and system properties, and adding hidden property
-rw-r--r-- | lib/chef/provider/user/mac.rb | 62 | ||||
-rw-r--r-- | lib/chef/resource/user/mac_user.rb | 5 |
2 files changed, 57 insertions, 10 deletions
diff --git a/lib/chef/provider/user/mac.rb b/lib/chef/provider/user/mac.rb index af4ada643f..c570399ca3 100644 --- a/lib/chef/provider/user/mac.rb +++ b/lib/chef/provider/user/mac.rb @@ -52,6 +52,10 @@ class Chef current_resource.shell(user_plist[:shell][0]) current_resource.comment(user_plist[:comment][0]) + if user_plist[:is_hidden] + current_resource.hidden(user_plist[:is_hidden][0] == "1" ? true : false) + end + shadow_hash = user_plist[:shadow_hash] if shadow_hash current_resource.password(shadow_hash[0]["SALTED-SHA512-PBKDF2"]["entropy"].string.unpack("H*")[0]) @@ -137,7 +141,7 @@ class Chef def create_user cmd = [-"-addUser", new_resource.username] cmd += ["-fullName", new_resource.comment] if prop_is_set?(:comment) - cmd += ["-UID", new_resource.uid] if prop_is_set?(:uid) + cmd += ["-UID", prop_is_set?(:uid) ? new_resource.uid : get_free_uid] cmd += ["-shell", new_resource.shell] cmd += ["-home", new_resource.home] cmd += ["-admin"] if new_resource.admin @@ -165,6 +169,10 @@ class Chef reload_user_plist reload_admin_group_plist + if prop_is_set?(:hidden) + set_hidden + end + if prop_is_set?(:password) converge_by("set password") { set_password } end @@ -196,7 +204,7 @@ class Chef end.run_action(group_action) converge_by("create primary group ID") do - run_dscl("create", "/Users/#{new_resource.username}", "PrimaryGroupID", new_resource.gid) + run_dscl("create", "/Users/#{new_resource.username}", "PrimaryGroupID", group_id) end end @@ -208,7 +216,7 @@ class Chef end def compare_user - %i{comment shell uid gid salt password admin secure_token}.any? { |m| diverged?(m) } + %i{comment shell uid gid salt password admin secure_token hidden}.any? { |m| diverged?(m) } end def manage_user @@ -272,7 +280,13 @@ class Chef if diverged?(:gid) converge_by("alter group membership") do - run_dscl("create", "/Users/#{new_resource.username}", "PrimaryGroupID", new_resource.gid) + run_dscl("create", "/Users/#{new_resource.username}", "PrimaryGroupID", group_id) + end + end + + if diverged?(:hidden) + converge_by("alter hidden") do + set_hidden end end @@ -336,6 +350,8 @@ class Chef user_group_diverged? when :secure_token secure_token_diverged? + when :hidden + hidden_diverged? else # Other fields are have been set on current resource so just compare # them. @@ -343,6 +359,24 @@ class Chef end end + # Find the next available uid on the system. + # Starting with 200 if `system` is set, 501 otherwise. + def get_free_uid(search_limit = 1000) + uid = nil + base_uid = new_resource.system ? 200 : 501 + next_uid_guess = base_uid + users_uids = run_dscl("list", "/Users", "uid") + while next_uid_guess < search_limit + base_uid + if users_uids =~ Regexp.new("#{Regexp.escape(next_uid_guess.to_s)}\n") + next_uid_guess += 1 + else + uid = next_uid_guess + break + end + end + uid || raise("uid not found. Exhausted. Searched #{search_limit} times") + end + # Attempt to resolve the group name, gid, and the action required for # associated group resource. If a group exists we'll modify it, otherwise # create it. @@ -410,12 +444,21 @@ class Chef return false unless prop_is_set?(:gid) group_name, group_id = user_group_info + current_resource.gid != group_id.to_i + end - if current_resource.gid.is_a?(String) - current_resource.gid != group_name - else - current_resource.gid != group_id.to_i - end + def hidden_diverged? + return false unless prop_is_set?(:hidden) + + (current_resource.hidden ? 1 : 0) != hidden_value.to_i + end + + def set_hidden + run_dscl("create", "/Users/#{new_resource.username}", "IsHidden", hidden_value.to_i) + end + + def hidden_value + new_resource.hidden ? 1 : 0 end def password_diverged? @@ -593,6 +636,7 @@ class Chef auth_authority: "dsAttrTypeStandard:AuthenticationAuthority", shadow_hash: "dsAttrTypeNative:ShadowHashData", group_members: "dsAttrTypeStandard:GroupMembers", + is_hidden: "dsAttrTypeNative:IsHidden", }.freeze attr_accessor :plist_hash, :property_map diff --git a/lib/chef/resource/user/mac_user.rb b/lib/chef/resource/user/mac_user.rb index 0892dea077..6f40287951 100644 --- a/lib/chef/resource/user/mac_user.rb +++ b/lib/chef/resource/user/mac_user.rb @@ -1,6 +1,6 @@ # # Author:: Ryan Cragun (<ryan@chef.io>) -# Copyright:: Copyright 2019, Chef Software Inc. +# Copyright:: Copyright 2019-2020, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -100,6 +100,9 @@ class Chef property :admin, [TrueClass, FalseClass], description: "Create the user as an admin", default: false + # Hide a user account in the macOS login window + property :hidden, [TrueClass, FalseClass, nil], description: "Hide account from loginwindow and system preferences", default: nil, introduced: "15.8" + # TCC on macOS >= 10.14 requires admin credentials of an Admin user that # has SecureToken enabled in order to toggle SecureToken. property :admin_username, String, description: "Admin username for superuser actions" |