summaryrefslogtreecommitdiff
path: root/spec/functional/win32
diff options
context:
space:
mode:
authorNick McSpadden <nmcspadden@gmail.com>2018-05-14 23:33:45 -0700
committerNick McSpadden <nmcspadden@gmail.com>2018-05-14 23:33:45 -0700
commitc935ce85f591e53f2f200e55cb252185e1801387 (patch)
treedfeee6151c50d805138a3d10761a531c2ffbf984 /spec/functional/win32
parentc48fd22a51deb74a3d4bc3abca308043689b494a (diff)
parentc0609e449135fae43d436136a4f0fd3889a9b8f1 (diff)
downloadchef-c935ce85f591e53f2f200e55cb252185e1801387.tar.gz
Merge branch 'master' into mac_uid
Diffstat (limited to 'spec/functional/win32')
-rw-r--r--spec/functional/win32/crypto_spec.rb2
-rw-r--r--spec/functional/win32/registry_spec.rb1
-rw-r--r--spec/functional/win32/security_spec.rb118
-rw-r--r--spec/functional/win32/versions_spec.rb16
4 files changed, 112 insertions, 25 deletions
diff --git a/spec/functional/win32/crypto_spec.rb b/spec/functional/win32/crypto_spec.rb
index 75a8bfbd24..145c9881b9 100644
--- a/spec/functional/win32/crypto_spec.rb
+++ b/spec/functional/win32/crypto_spec.rb
@@ -22,7 +22,7 @@ if Chef::Platform.windows?
end
describe "Chef::ReservedNames::Win32::Crypto", :windows_only do
- describe '#encrypt' do
+ describe "#encrypt" do
before(:all) do
new_node = Chef::Node.new
new_node.consume_external_attrs(OHAI_SYSTEM.data, {})
diff --git a/spec/functional/win32/registry_spec.rb b/spec/functional/win32/registry_spec.rb
index 4a6157a6d5..bcfa0ffd48 100644
--- a/spec/functional/win32/registry_spec.rb
+++ b/spec/functional/win32/registry_spec.rb
@@ -26,6 +26,7 @@ describe "Chef::Win32::Registry", :windows_only do
#Create a registry item
::Win32::Registry::HKEY_CURRENT_USER.create "Software\\Root"
::Win32::Registry::HKEY_CURRENT_USER.create "Software\\Root\\Branch"
+ ::Win32::Registry::HKEY_CURRENT_USER.create "Software\\Root\\BĀ®anch"
::Win32::Registry::HKEY_CURRENT_USER.create "Software\\Root\\Branch\\Flower"
::Win32::Registry::HKEY_CURRENT_USER.open('Software\\Root', Win32::Registry::KEY_ALL_ACCESS) do |reg|
reg["RootType1", Win32::Registry::REG_SZ] = "fibrous"
diff --git a/spec/functional/win32/security_spec.rb b/spec/functional/win32/security_spec.rb
index c4951f375c..f88cde0204 100644
--- a/spec/functional/win32/security_spec.rb
+++ b/spec/functional/win32/security_spec.rb
@@ -17,6 +17,8 @@
#
require "spec_helper"
+require "mixlib/shellout"
+require "chef/mixin/user_context"
if Chef::Platform.windows?
require "chef/win32/security"
end
@@ -26,13 +28,37 @@ describe "Chef::Win32::Security", :windows_only do
expect(Chef::ReservedNames::Win32::Security.has_admin_privileges?).to eq(true)
end
- # We've done some investigation adding a negative test and it turned
- # out to be a lot of work since mixlib-shellout doesn't have user
- # support for windows.
- #
- # TODO - Add negative tests once mixlib-shellout has user support
- it "has_admin_privileges? returns false when running as non-admin" do
- skip "requires user support in mixlib-shellout"
+ describe "running as non admin user" do
+ include Chef::Mixin::UserContext
+ let(:user) { "security_user" }
+ let(:password) { "Security@123" }
+
+ let(:domain) do
+ whoami = Mixlib::ShellOut.new("whoami")
+ whoami.run_command
+ whoami.error!
+ whoami.stdout.split("\\")[0]
+ end
+
+ before do
+ allow_any_instance_of(Chef::Mixin::UserContext).to receive(:node).and_return({ "platform_family" => "windows" })
+ add_user = Mixlib::ShellOut.new("net user #{user} #{password} /ADD")
+ add_user.run_command
+ add_user.error!
+ end
+
+ after do
+ delete_user = Mixlib::ShellOut.new("net user #{user} /delete")
+ delete_user.run_command
+ delete_user.error!
+ end
+
+ it "has_admin_privileges? returns false" do
+ has_admin_privileges = with_user_context(user, password, domain, :local) do
+ Chef::ReservedNames::Win32::Security.has_admin_privileges?
+ end
+ expect(has_admin_privileges).to eq(false)
+ end
end
describe "get_file_security" do
@@ -45,27 +71,27 @@ describe "Chef::Win32::Security", :windows_only do
end
describe "access_check" do
- let(:security_descriptor) {
+ let(:security_descriptor) do
Chef::ReservedNames::Win32::Security.get_file_security(
"C:\\Program Files")
- }
+ end
let(:token_rights) { Chef::ReservedNames::Win32::Security::TOKEN_ALL_ACCESS }
- let(:token) {
+ let(:token) do
Chef::ReservedNames::Win32::Security.open_process_token(
Chef::ReservedNames::Win32::Process.get_current_process,
token_rights).duplicate_token(:SecurityImpersonation)
- }
+ end
- let(:mapping) {
+ let(:mapping) do
mapping = Chef::ReservedNames::Win32::Security::GENERIC_MAPPING.new
mapping[:GenericRead] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_READ
mapping[:GenericWrite] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_WRITE
mapping[:GenericExecute] = Chef::ReservedNames::Win32::Security::FILE_GENERIC_EXECUTE
mapping[:GenericAll] = Chef::ReservedNames::Win32::Security::FILE_ALL_ACCESS
mapping
- }
+ end
let(:desired_access) { Chef::ReservedNames::Win32::Security::FILE_GENERIC_READ }
@@ -76,11 +102,11 @@ describe "Chef::Win32::Security", :windows_only do
end
describe "Chef::Win32::Security::Token" do
- let(:token) {
+ let(:token) do
Chef::ReservedNames::Win32::Security.open_process_token(
Chef::ReservedNames::Win32::Process.get_current_process,
token_rights)
- }
+ end
context "with all rights" do
let(:token_rights) { Chef::ReservedNames::Win32::Security::TOKEN_ALL_ACCESS }
@@ -97,4 +123,66 @@ describe "Chef::Win32::Security", :windows_only do
end
end
end
+
+ describe ".get_token_information_elevation_type" do
+ let(:token_rights) { Chef::ReservedNames::Win32::Security::TOKEN_READ }
+
+ let(:token) do
+ Chef::ReservedNames::Win32::Security.open_process_token(
+ Chef::ReservedNames::Win32::Process.get_current_process,
+ token_rights)
+ end
+
+ context "when the token is valid" do
+ let(:token_elevation_type) { [:TokenElevationTypeDefault, :TokenElevationTypeFull, :TokenElevationTypeLimited] }
+
+ it "returns the token elevation type" do
+ elevation_type = Chef::ReservedNames::Win32::Security.get_token_information_elevation_type(token)
+ expect(token_elevation_type).to include(elevation_type)
+ end
+ end
+
+ context "when the token is invalid" do
+ it "raises `handle invalid` error" do
+ # If `OpenProcessToken` is stubbed, `open_process_token` returns an invalid token
+ allow(Chef::ReservedNames::Win32::Security).to receive(:OpenProcessToken).and_return(true)
+ expect { Chef::ReservedNames::Win32::Security.get_token_information_elevation_type(token) }.to raise_error(Chef::Exceptions::Win32APIError)
+ end
+ end
+ end
+
+ describe ".get_account_right" do
+ let(:username) { ENV["USERNAME"] }
+
+ context "when given a valid username" do
+ it "returns an array of account right constants" do
+ Chef::ReservedNames::Win32::Security.add_account_right(username, "SeBatchLogonRight")
+ expect(Chef::ReservedNames::Win32::Security.get_account_right(username)).to include("SeBatchLogonRight")
+ end
+
+ it "passes an FFI::Pointer to LsaFreeMemory" do
+ Chef::ReservedNames::Win32::Security.add_account_right(username, "SeBatchLogonRight") # otherwise we return an empty array before LsaFreeMemory
+ expect(Chef::ReservedNames::Win32::Security).to receive(:LsaFreeMemory).with(instance_of(FFI::Pointer)).and_return(0) # not FFI::MemoryPointer
+ Chef::ReservedNames::Win32::Security.get_account_right(username)
+ end
+ end
+
+ context "when given an invalid username" do
+ let(:username) { "noooooooooope" }
+
+ it "raises an exception" do
+ expect { Chef::ReservedNames::Win32::Security.get_account_right(username) }.to raise_error(Chef::Exceptions::Win32APIError)
+ end
+ end
+ end
+
+ describe ".test_and_raise_lsa_nt_status" do
+ # NTSTATUS code: 0xC0000001 / STATUS_UNSUCCESSFUL
+ # Windows Error: ERROR_GEN_FAILURE / 31 / 0x1F / A device attached to the system is not functioning.
+ let(:status_unsuccessful) { 0xC0000001 }
+
+ it "raises an exception with the Win Error if the win32 result is not 0" do
+ expect { Chef::ReservedNames::Win32::Security.test_and_raise_lsa_nt_status(status_unsuccessful) }.to raise_error(Chef::Exceptions::Win32APIError)
+ end
+ end
end
diff --git a/spec/functional/win32/versions_spec.rb b/spec/functional/win32/versions_spec.rb
index d6e840ed7f..19bd0e3875 100644
--- a/spec/functional/win32/versions_spec.rb
+++ b/spec/functional/win32/versions_spec.rb
@@ -21,7 +21,7 @@ if Chef::Platform.windows?
require "chef/win32/version"
end
-describe "Chef::ReservedNames::Win32::Version", :windows_only, :not_supported_on_win2k3 do
+describe "Chef::ReservedNames::Win32::Version", :windows_only do
before do
wmi = WmiLite::Wmi.new
@@ -31,14 +31,12 @@ describe "Chef::ReservedNames::Win32::Version", :windows_only, :not_supported_on
# On Win2k8R2 and later, we can dynamically obtain marketing
# names for comparison from WMI so the test should not
# need to be modified when new Windows releases arise.
- # For Win2k3 and Win2k8, we use static names in this test
- # based on the version number information from WMI. The names
- # from WMI contain extended characters such as registered
- # trademark on Win2k8 and Win2k3 that we're not using in our
- # library, so we have to set the expectation statically.
- if Chef::Platform.windows_server_2003?
- @current_os_version = "Windows Server 2003 R2"
- elsif is_windows_server_2008?(host)
+ # For Win2k8 we use static names in this test based on the
+ # version number information from WMI. The names from WMI
+ # contain extended characters such as registered trademark
+ # on Win2k8 that we're not using in our library, so we have
+ # to set the expectation statically.
+ if is_windows_server_2008?(host)
@current_os_version = "Windows Server 2008"
else
# The name from WMI is actually what we want in Win2k8R2+.