diff options
author | Nick McSpadden <nmcspadden@gmail.com> | 2018-05-14 23:33:45 -0700 |
---|---|---|
committer | Nick McSpadden <nmcspadden@gmail.com> | 2018-05-14 23:33:45 -0700 |
commit | c935ce85f591e53f2f200e55cb252185e1801387 (patch) | |
tree | dfeee6151c50d805138a3d10761a531c2ffbf984 /spec/functional/win32 | |
parent | c48fd22a51deb74a3d4bc3abca308043689b494a (diff) | |
parent | c0609e449135fae43d436136a4f0fd3889a9b8f1 (diff) | |
download | chef-c935ce85f591e53f2f200e55cb252185e1801387.tar.gz |
Merge branch 'master' into mac_uid
Diffstat (limited to 'spec/functional/win32')
-rw-r--r-- | spec/functional/win32/crypto_spec.rb | 2 | ||||
-rw-r--r-- | spec/functional/win32/registry_spec.rb | 1 | ||||
-rw-r--r-- | spec/functional/win32/security_spec.rb | 118 | ||||
-rw-r--r-- | spec/functional/win32/versions_spec.rb | 16 |
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+. |