summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/puppet/util/suidmanager.rb12
-rwxr-xr-xspec/unit/util/suidmanager_spec.rb22
2 files changed, 32 insertions, 2 deletions
diff --git a/lib/puppet/util/suidmanager.rb b/lib/puppet/util/suidmanager.rb
index 2e12b220f..697bce111 100644
--- a/lib/puppet/util/suidmanager.rb
+++ b/lib/puppet/util/suidmanager.rb
@@ -82,13 +82,21 @@ module Puppet::Util::SUIDManager
begin
Process::UID.change_privilege(uid)
rescue NotImplementedError
+ # If changing uid, we must be root. So initgroups first here.
initgroups(uid)
Process.euid = uid
Process.uid = uid
end
else
- initgroups(uid)
- Process.euid = uid
+ # If we're already root, initgroups before changing euid. If we're not,
+ # change euid (to root) first.
+ if Process.euid == 0
+ initgroups(uid)
+ Process.euid = uid
+ else
+ Process.euid = uid
+ initgroups(uid)
+ end
end
end
module_function :change_user
diff --git a/spec/unit/util/suidmanager_spec.rb b/spec/unit/util/suidmanager_spec.rb
index f58f6c708..fc70e1718 100755
--- a/spec/unit/util/suidmanager_spec.rb
+++ b/spec/unit/util/suidmanager_spec.rb
@@ -134,6 +134,28 @@ describe Puppet::Util::SUIDManager do
xids[:euid].should == 42
xids[:uid].should == 0
end
+
+ it "should set euid before groups if changing to root" do
+ Process.stubs(:euid).returns 50
+
+ when_not_root = sequence 'when_not_root'
+
+ Process.expects(:euid=).in_sequence(when_not_root)
+ Puppet::Util::SUIDManager.expects(:initgroups).in_sequence(when_not_root)
+
+ Puppet::Util::SUIDManager.change_user(0, false)
+ end
+
+ it "should set groups before euid if changing from root" do
+ Process.stubs(:euid).returns 0
+
+ when_root = sequence 'when_root'
+
+ Puppet::Util::SUIDManager.expects(:initgroups).in_sequence(when_root)
+ Process.expects(:euid=).in_sequence(when_root)
+
+ Puppet::Util::SUIDManager.change_user(50, false)
+ end
end
end