summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Cooper <josh@puppetlabs.com>2011-08-18 10:34:18 -0700
committerJosh Cooper <josh@puppetlabs.com>2011-08-22 15:06:11 -0700
commit2ac87905708ddbc44d212e10e34d72cad09e3271 (patch)
tree9907686fa4f90f5ce4379f982808498dd3156943
parentccdd043ab309ca382dc949612d7efe3562adf5c5 (diff)
downloadpuppet-2ac87905708ddbc44d212e10e34d72cad09e3271.tar.gz
puppet-2ac87905708ddbc44d212e10e34d72cad09e3271.tar.xz
puppet-2ac87905708ddbc44d212e10e34d72cad09e3271.zip
(#8662) Fix Puppet.features.root? on Windows
This commit changes Puppet::Util::SUIDManager.root? (and Puppet.features.root?) to only return true if the user is running with elevated privileges (granted via UAC). If this check fails because elevated privileges are not supported, e.g. pre-Vista, then we fall back to checking if the user is a member of the builtin Administrators group. This means if you are logged in as Administrator on 2008, Puppet.features.root? will return false, unless you are explicitly running puppet as an administrator, e.g. runas /user:Administrator "puppet apply manifest.pp" This commit also adds tests to ensure SUIDManager.asuser is a no-op on Windows, since Windows does not (easily) support switching user contexts without providing a password.
-rw-r--r--lib/puppet/util/suidmanager.rb15
-rwxr-xr-xspec/unit/util/suidmanager_spec.rb89
2 files changed, 103 insertions, 1 deletions
diff --git a/lib/puppet/util/suidmanager.rb b/lib/puppet/util/suidmanager.rb
index 697bce111..d2772002e 100644
--- a/lib/puppet/util/suidmanager.rb
+++ b/lib/puppet/util/suidmanager.rb
@@ -37,7 +37,20 @@ module Puppet::Util::SUIDManager
module_function :groups=
def self.root?
- Process.uid == 0
+ return Process.uid == 0 unless Puppet.features.microsoft_windows?
+
+ require 'sys/admin'
+ require 'win32/security'
+
+ # if Vista or later, check for unrestricted process token
+ begin
+ return Win32::Security.elevated_security?
+ rescue Win32::Security::Error => e
+ raise e unless e.to_s =~ /Incorrect function/i
+ end
+
+ group = Sys::Admin.get_group("Administrators", :sid => Win32::Security::SID::BuiltinAdministrators)
+ group and group.members.index(Sys::Admin.get_login) != nil
end
# Runs block setting uid and gid if provided then restoring original ids
diff --git a/spec/unit/util/suidmanager_spec.rb b/spec/unit/util/suidmanager_spec.rb
index abfe3f723..474d0b2a2 100755
--- a/spec/unit/util/suidmanager_spec.rb
+++ b/spec/unit/util/suidmanager_spec.rb
@@ -66,6 +66,14 @@ describe Puppet::Util::SUIDManager do
xids.should be_empty
end
+
+ it "should not get or set euid/egid on Windows" do
+ Puppet.features.stubs(:microsoft_windows?).returns true
+
+ Puppet::Util::SUIDManager.asuser(user[:uid], user[:gid]) {}
+
+ xids.should be_empty
+ end
end
describe "#change_group" do
@@ -195,6 +203,15 @@ describe Puppet::Util::SUIDManager do
xids.should be_empty
end
+
+ it "should not get or set euid/egid on Windows" do
+ Puppet.features.stubs(:microsoft_windows?).returns true
+ 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
@@ -210,4 +227,76 @@ describe Puppet::Util::SUIDManager do
end
end
end
+
+ describe "#root?" do
+ describe "on POSIX systems" do
+ before :each do
+ Puppet.features.stubs(:posix?).returns(true)
+ Puppet.features.stubs(:microsoft_windows?).returns(false)
+ end
+
+ it "should be root if uid is 0" do
+ Process.stubs(:uid).returns(0)
+
+ Puppet::Util::SUIDManager.should be_root
+ end
+
+ it "should not be root if uid is not 0" do
+ Process.stubs(:uid).returns(1)
+
+ Puppet::Util::SUIDManager.should_not be_root
+ end
+ end
+
+ describe "on Microsoft Windows", :if => Puppet.features.microsoft_windows? do
+ describe "2003 without UAC" do
+ it "should be root if user is a member of the Administrators group" do
+ Win32::Security.stubs(:elevated_security?).raises(Win32::Security::Error, "Incorrect function.")
+ Sys::Admin.stubs(:get_login).returns("Administrator")
+ Sys::Group.stubs(:members).returns(%w[Administrator])
+
+ Puppet::Util::SUIDManager.should be_root
+ end
+
+ it "should not be root if the process is running as Guest" do
+ Win32::Security.stubs(:elevated_security?).raises(Win32::Security::Error, "Incorrect function.")
+ Sys::Admin.stubs(:get_login).returns("Guest")
+ Sys::Group.stubs(:members).returns([])
+
+ Puppet::Util::SUIDManager.should_not be_root
+ end
+
+ it "should raise an exception if the process fails to open the process token" do
+ Win32::Security.stubs(:elevated_security?).raises(Win32::Security::Error, "Access denied.")
+ Sys::Admin.stubs(:get_login).returns("Administrator")
+ Sys::Group.expects(:members).never
+
+ lambda { Puppet::Util::SUIDManager.should raise_error(Win32::Security::Error, /Access denied./) }
+ end
+ end
+
+ describe "2008 with UAC" do
+ it "should be root if user is running with elevated privileges" do
+ Win32::Security.stubs(:elevated_security?).returns(true)
+ Sys::Admin.expects(:get_login).never
+
+ Puppet::Util::SUIDManager.should be_root
+ end
+
+ it "should not be root if user is not running with elevated privileges" do
+ Win32::Security.stubs(:elevated_security?).returns(false)
+ Sys::Admin.expects(:get_login).never
+
+ Puppet::Util::SUIDManager.should_not be_root
+ end
+
+ it "should raise an exception if the process fails to open the process token" do
+ Win32::Security.stubs(:elevated_security?).raises(Win32::Security::Error, "Access denied.")
+ Sys::Admin.expects(:get_login).never
+
+ lambda { Puppet::Util::SUIDManager.should raise_error(Win32::Security::Error, /Access denied./) }
+ end
+ end
+ end
+ end
end