summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@chef.io>2015-09-02 13:53:29 +0100
committerThom May <thom@chef.io>2015-09-02 13:54:01 +0100
commit4c727e5b396f8e3e75aec999e46a6b1eb9f0f991 (patch)
treec6961c21f23c0309944d02fa9127ff3bc5cfc625
parent9b102712b7e28e7dda2033096dcef9179c7ed1a1 (diff)
parentc9a7f550d8c01f56f980a2a6fb09b4260518c755 (diff)
downloadchef-4c727e5b396f8e3e75aec999e46a6b1eb9f0f991.tar.gz
Merge pull request #3091 from bahamas10/dave-1426551202
fix locking/unlocking users on SmartOS
-rw-r--r--lib/chef/provider/user/solaris.rb36
-rw-r--r--spec/unit/provider/user/solaris_spec.rb75
2 files changed, 98 insertions, 13 deletions
diff --git a/lib/chef/provider/user/solaris.rb b/lib/chef/provider/user/solaris.rb
index b242095f0c..c16db22ad4 100644
--- a/lib/chef/provider/user/solaris.rb
+++ b/lib/chef/provider/user/solaris.rb
@@ -1,7 +1,9 @@
#
# Author:: Stephen Nelson-Smith (<sns@opscode.com>)
# Author:: Jon Ramsey (<jonathon.ramsey@gmail.com>)
+# Author:: Dave Eddy (<dave@daveeddy.com>)
# Copyright:: Copyright (c) 2012 Opscode, Inc.
+# Copyright:: Copyright 2015, Dave Eddy
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +25,6 @@ class Chef
class User
class Solaris < Chef::Provider::User::Useradd
provides :user, platform: %w(omnios solaris2)
-
UNIVERSAL_OPTIONS = [[:comment, "-c"], [:gid, "-g"], [:shell, "-s"], [:uid, "-u"]]
attr_writer :password_file
@@ -43,6 +44,32 @@ class Chef
super
end
+ def check_lock
+ shadow_line = shell_out!('getent', 'shadow', new_resource.username).stdout.strip rescue nil
+
+ # if the command fails we return nil, this can happen if the user
+ # in question doesn't exist
+ return nil if shadow_line.nil?
+
+ # convert "dave:NP:16507::::::\n" to "NP"
+ fields = shadow_line.split(':')
+
+ # '*LK*...' and 'LK' are both considered locked,
+ # so look for LK at the beginning of the shadow entry
+ # optionally surrounded by '*'
+ @locked = !!fields[1].match(/^\*?LK\*?/)
+
+ @locked
+ end
+
+ def lock_user
+ shell_out!('passwd', '-l', new_resource.username)
+ end
+
+ def unlock_user
+ shell_out!('passwd', '-u', new_resource.username)
+ end
+
private
def manage_password
@@ -67,9 +94,10 @@ class Chef
buffer.close
# FIXME: mostly duplicates code with file provider deploying a file
- mode = ::File.stat(@password_file).mode & 07777
- uid = ::File.stat(@password_file).uid
- gid = ::File.stat(@password_file).gid
+ s = ::File.stat(@password_file)
+ mode = s.mode & 07777
+ uid = s.uid
+ gid = s.gid
FileUtils.chown uid, gid, buffer.path
FileUtils.chmod mode, buffer.path
diff --git a/spec/unit/provider/user/solaris_spec.rb b/spec/unit/provider/user/solaris_spec.rb
index ef62fd1d5a..a3c17a9a56 100644
--- a/spec/unit/provider/user/solaris_spec.rb
+++ b/spec/unit/provider/user/solaris_spec.rb
@@ -1,7 +1,9 @@
#
# Author:: Adam Jacob (<adam@opscode.com>)
# Author:: Daniel DeLeo (<dan@opscode.com>)
+# Author:: Dave Eddy (<dave@daveeddy.com>)
# Copyright:: Copyright (c) 2008, 2010 Opscode, Inc.
+# Copyright:: Copyright (c) 2015, Dave Eddy
#
# License:: Apache License, Version 2.0
#
@@ -18,6 +20,9 @@
# limitations under the License.
#
+ShellCmdResult = Struct.new(:stdout, :stderr, :exitstatus)
+
+require 'mixlib/shellout'
require 'spec_helper'
describe Chef::Provider::User::Solaris do
@@ -31,15 +36,6 @@ describe Chef::Provider::User::Solaris do
p
end
- supported_useradd_options = {
- 'comment' => "-c",
- 'gid' => "-g",
- 'uid' => "-u",
- 'shell' => "-s"
- }
-
- include_examples "a useradd-based user provider", supported_useradd_options
-
describe "when we want to set a password" do
before(:each) do
@node = Chef::Node.new
@@ -77,4 +73,65 @@ describe Chef::Provider::User::Solaris do
end
end
+ describe 'when managing user locked status' do
+ before(:each) do
+ @node = Chef::Node.new
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, {}, @events)
+
+ @new_resource = Chef::Resource::User.new('dave')
+ @current_resource = @new_resource.dup
+
+ @provider = Chef::Provider::User::Solaris.new(@new_resource, @run_context)
+ @provider.current_resource = @current_resource
+ end
+ describe 'when determining if the user is locked' do
+
+ # locked shadow lines
+ [
+ 'dave:LK:::::::',
+ 'dave:*LK*:::::::',
+ 'dave:*LK*foobar:::::::',
+ 'dave:*LK*bahamas10:::::::',
+ 'dave:*LK*L....:::::::',
+ ].each do |shadow|
+ it "should return true if user is locked with #{shadow}" do
+ shell_return = ShellCmdResult.new(shadow + "\n", '', 0)
+ expect(provider).to receive(:shell_out!).with('getent', 'shadow', @new_resource.username).and_return(shell_return)
+ expect(provider.check_lock).to eql(true)
+ end
+ end
+
+ # unlocked shadow lines
+ [
+ 'dave:NP:::::::',
+ 'dave:*NP*:::::::',
+ 'dave:foobar:::::::',
+ 'dave:bahamas10:::::::',
+ 'dave:L...:::::::',
+ ].each do |shadow|
+ it "should return false if user is unlocked with #{shadow}" do
+ shell_return = ShellCmdResult.new(shadow + "\n", '', 0)
+ expect(provider).to receive(:shell_out!).with('getent', 'shadow', @new_resource.username).and_return(shell_return)
+ expect(provider.check_lock).to eql(false)
+ end
+ end
+ end
+
+ describe 'when locking the user' do
+ it 'should run passwd -l with the new resources username' do
+ shell_return = ShellCmdResult.new('', '', 0)
+ expect(provider).to receive(:shell_out!).with('passwd', '-l', @new_resource.username).and_return(shell_return)
+ provider.lock_user
+ end
+ end
+
+ describe 'when unlocking the user' do
+ it 'should run passwd -u with the new resources username' do
+ shell_return = ShellCmdResult.new('', '', 0)
+ expect(provider).to receive(:shell_out!).with('passwd', '-u', @new_resource.username).and_return(shell_return)
+ provider.unlock_user
+ end
+ end
+ end
end