diff options
Diffstat (limited to 'lib/chef/provider/user/useradd.rb')
-rw-r--r-- | lib/chef/provider/user/useradd.rb | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/chef/provider/user/useradd.rb b/lib/chef/provider/user/useradd.rb new file mode 100644 index 0000000000..489632f722 --- /dev/null +++ b/lib/chef/provider/user/useradd.rb @@ -0,0 +1,144 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'pathname' +require 'chef/provider/user' + +class Chef + class Provider + class User + class Useradd < Chef::Provider::User + UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:password, "-p"], [:shell, "-s"], [:uid, "-u"]] + + def create_user + command = compile_command("useradd") do |useradd| + useradd << universal_options + useradd << useradd_options + end + run_command(:command => command) + end + + def manage_user + command = compile_command("usermod") do |u| + u << universal_options + end + run_command(:command => command) + end + + def remove_user + command = "userdel" + command << " -r" if managing_home_dir? + command << " #{@new_resource.username}" + run_command(:command => command) + end + + def check_lock + status = popen4("passwd -S #{@new_resource.username}") do |pid, stdin, stdout, stderr| + status_line = stdout.gets.split(' ') + case status_line[1] + when /^P/ + @locked = false + when /^N/ + @locked = false + when /^L/ + @locked = true + end + end + + unless status.exitstatus == 0 + raise_lock_error = false + # we can get an exit code of 1 even when it's successful on rhel/centos (redhat bug 578534) + if status.exitstatus == 1 && ['redhat', 'centos'].include?(node[:platform]) + passwd_version_status = popen4('rpm -q passwd') do |pid, stdin, stdout, stderr| + passwd_version = stdout.gets.chomp + + unless passwd_version == 'passwd-0.73-1' + raise_lock_error = true + end + end + else + raise_lock_error = true + end + + raise Chef::Exceptions::User, "Cannot determine if #{@new_resource} is locked!" if raise_lock_error + end + + @locked + end + + def lock_user + run_command(:command => "usermod -L #{@new_resource.username}") + end + + def unlock_user + run_command(:command => "usermod -U #{@new_resource.username}") + end + + def compile_command(base_command) + yield base_command + base_command << " #{@new_resource.username}" + base_command + end + + def universal_options + opts = '' + + UNIVERSAL_OPTIONS.each do |field, option| + if @current_resource.send(field) != @new_resource.send(field) + if @new_resource.send(field) + Chef::Log.debug("#{@new_resource} setting #{field} to #{@new_resource.send(field)}") + opts << " #{option} '#{@new_resource.send(field)}'" + end + end + end + if updating_home? + if managing_home_dir? + Chef::Log.debug("#{@new_resource} managing the users home directory") + opts << " -m -d '#{@new_resource.home}'" + else + Chef::Log.debug("#{@new_resource} setting home to #{@new_resource.home}") + opts << " -d '#{@new_resource.home}'" + end + end + opts << " -o" if @new_resource.non_unique || @new_resource.supports[:non_unique] + opts + end + + def useradd_options + opts = '' + opts << " -r" if @new_resource.system + opts + end + + def updating_home? + # will return false if paths are equivalent + # Pathname#cleanpath does a better job than ::File::expand_path (on both unix and windows) + # ::File.expand_path("///tmp") == ::File.expand_path("/tmp") => false + # ::File.expand_path("\\tmp") => "C:/tmp" + return true if @current_resource.home.nil? && @new_resource.home + @new_resource.home and Pathname.new(@current_resource.home).cleanpath != Pathname.new(@new_resource.home).cleanpath + end + + def managing_home_dir? + @new_resource.manage_home || @new_resource.supports[:manage_home] + end + + end + end + end +end |