diff --git a/spec/unit/util/suidmanager_spec.rb b/spec/unit/util/suidmanager_spec.rb new file mode 100755 index 000000000..19ddc2b4d --- /dev/null +++ b/spec/unit/util/suidmanager_spec.rb @@ -0,0 +1,113 @@ +#!/usr/bin/env rspec + +require 'spec_helper' + +describe Puppet::Util::SUIDManager do + let :user do + Puppet::Type.type(:user).new(:name => 'name', :uid => 42, :gid => 42) + end + + let :xids do + Hash.new {|h,k| 0} + end + + before :each do + Puppet::Util::SUIDManager.stubs(:convert_xid).returns(42) + Puppet::Util::SUIDManager.stubs(:initgroups) + + [:euid, :egid, :uid, :gid, :groups].each do |id| + Process.stubs("#{id}=").with {|value| xids[id] = value} + end + end + + describe "#uid" do + it "should allow setting euid/egid" do + Puppet::Util::SUIDManager.egid = user[:gid] + Puppet::Util::SUIDManager.euid = user[:uid] + + xids[:egid].should == user[:gid] + xids[:euid].should == user[:uid] + end + end + + describe "#asuser" do + it "should set euid/egid when root" do + Process.stubs(:uid).returns(0) + + Process.stubs(:euid).returns(50) + Process.stubs(:egid).returns(50) + + yielded = false + Puppet::Util::SUIDManager.asuser(user[:uid], user[:gid]) do + xids[:egid].should == user[:gid] + xids[:euid].should == user[:uid] + yielded = true + end + + xids[:egid].should == 50 + xids[:euid].should == 50 + + # It's possible asuser could simply not yield, so the assertions in the + # block wouldn't fail. So verify those actually got checked. + yielded.should be_true + end + + it "should not get or set euid/egid when not root" do + Process.stubs(:uid).returns(1) + + Process.stubs(:euid).returns(50) + Process.stubs(:egid).returns(50) + + Puppet::Util::SUIDManager.asuser(user[:uid], user[:gid]) {} + + xids.should be_empty + end + end + + describe "when running commands" do + before :each do + # We want to make sure $CHILD_STATUS is set + Kernel.system '' if $CHILD_STATUS.nil? + end + + describe "with #system" do + it "should set euid/egid when root" do + Process.stubs(:uid).returns(0) + Process.stubs(:groups=) + Process.expects(:euid).returns(99997) + Process.expects(:egid).returns(99996) + + Process.expects(:euid=).with(uid) + Process.expects(:egid=).with(gid) + + Kernel.expects(:system).with('blah') + Puppet::Util::SUIDManager.system('blah', user[:uid], user[:gid]) + + xids[:egid].should == 99996 + xids[:euid].should == 99997 + end + + it "should not get or set euid/egid when not root" do + Process.stubs(:uid).returns(1) + Kernel.expects(:system).with('blah') + + Puppet::Util::SUIDManager.system('blah', user[:uid], user[:gid]) + + xids.should be_empty + end + end + + describe "with #run_and_capture" do + it "should capture the output and return process status" do + Puppet::Util. + expects(:execute). + with('yay', :combine => true, :failonfail => false, :uid => user[:uid], :gid => user[:gid]). + returns('output') + output = Puppet::Util::SUIDManager.run_and_capture 'yay', user[:uid], user[:gid] + + output.first.should == 'output' + output.last.should be_a(Process::Status) + end + end + end +end diff --git a/test/puppet/tc_suidmanager.rb b/test/puppet/tc_suidmanager.rb deleted file mode 100755 index eeb56f2c9..000000000 --- a/test/puppet/tc_suidmanager.rb +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env ruby - -require File.dirname(__FILE__) + '/../lib/puppettest' - -require 'puppet' -require 'puppettest' -require 'test/unit' -require 'mocha' - -class TestSUIDManager < Test::Unit::TestCase - include PuppetTest - - def setup - the_id = 42 - Puppet::Util::SUIDManager.stubs(:convert_xid).returns(the_id) - Puppet::Util::SUIDManager.stubs(:initgroups) - @user = stub('user', :uid => the_id, :gid => the_id, :name => 'name') - super - end - - def test_metaprogramming_function_additions - # NOTE: the way that we are dynamically generating the methods in - # SUIDManager for the UID/GID calls was causing problems due to the - # modification of a closure. Should the bug rear itself again, this - # test will fail. - Process.expects(:uid).times(2) - - assert_nothing_raised do - Puppet::Util::SUIDManager.uid - Puppet::Util::SUIDManager.uid - end - end - - def test_id_set - Process.expects(:euid=).with(@user.uid) - Process.expects(:egid=).with(@user.gid) - - assert_nothing_raised do - Puppet::Util::SUIDManager.egid = @user.gid - Puppet::Util::SUIDManager.euid = @user.uid - end - end - - def test_utiluid - assert_not_equal(nil, Puppet::Util.uid(nonrootuser.name)) - end - - def test_asuser_as_root - Process.stubs(:uid).returns(0) - expects_id_set_and_revert @user.uid, @user.gid - Puppet::Util::SUIDManager.asuser @user.uid, @user.gid do end - rescue Errno::EPERM - end - - def test_asuser_as_nonroot - Process.stubs(:uid).returns(1) - expects_no_id_set - Puppet::Util::SUIDManager.asuser @user.uid, @user.gid do end - end - - - def test_system_as_root - Process.stubs(:uid).returns(0) - set_exit_status! - expects_id_set_and_revert @user.uid, @user.gid - Kernel.expects(:system).with('blah') - Puppet::Util::SUIDManager.system('blah', @user.uid, @user.gid) - end - - def test_system_as_nonroot - Process.stubs(:uid).returns(1) - set_exit_status! - expects_no_id_set - Kernel.expects(:system).with('blah') - Puppet::Util::SUIDManager.system('blah', @user.uid, @user.gid) - end - - def test_run_and_capture - if (RUBY_VERSION <=> "1.8.4") < 0 - warn "Cannot run this test on ruby < 1.8.4" - else - set_exit_status! - Puppet::Util. - expects(:execute). - with('yay',:combine => true, :failonfail => false, :uid => @user.uid, :gid => @user.gid). - returns('output') - output = Puppet::Util::SUIDManager.run_and_capture 'yay', @user.uid, @user.gid - - assert_equal 'output', output.first - assert_kind_of Process::Status, output.last - end - end - - private - - def expects_id_set_and_revert(uid, gid) - Process.stubs(:groups=) - Process.expects(:euid).returns(99997) - Process.expects(:egid).returns(99996) - - Process.expects(:euid=).with(uid) - Process.expects(:egid=).with(gid) - - Process.expects(:euid=).with(99997) - Process.expects(:egid=).with(99996) - end - - def expects_no_id_set - Process.expects(:egid).never - Process.expects(:euid).never - Process.expects(:egid=).never - Process.expects(:euid=).never - end - - def set_exit_status! - # We want to make sure $CHILD_STATUS is set, this is the only way I know how. - Kernel.system '' if $CHILD_STATUS.nil? - end -end -