summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornimisha <nimisha.sharad@msystechnologies.com>2017-12-21 15:52:32 +0530
committernimisha <nimisha.sharad@msystechnologies.com>2018-01-24 15:00:40 +0530
commit7381679100ca96c63751cadff8b54722aefed5f4 (patch)
tree33de58126b040053a750260fe6c6156905446da2
parent85e0c15d15425978de490bdce7fa7692690e6dc4 (diff)
downloadchef-7381679100ca96c63751cadff8b54722aefed5f4.tar.gz
Fixed/added specs for LogonSession changes
Signed-off-by: nimisha <nimisha.sharad@msystechnologies.com>
-rw-r--r--lib/chef/mixin/user_context.rb8
-rw-r--r--lib/chef/provider/remote_file/network_file.rb2
-rw-r--r--lib/chef/resource/remote_file.rb2
-rw-r--r--lib/chef/util/windows/logon_session.rb10
-rw-r--r--spec/functional/win32/security_spec.rb1
-rw-r--r--spec/unit/util/windows/logon_session_spec.rb4
-rw-r--r--spec/unit/win32/security_spec.rb36
7 files changed, 52 insertions, 11 deletions
diff --git a/lib/chef/mixin/user_context.rb b/lib/chef/mixin/user_context.rb
index 0807bd5a95..f5c2da1389 100644
--- a/lib/chef/mixin/user_context.rb
+++ b/lib/chef/mixin/user_context.rb
@@ -22,8 +22,10 @@ class Chef
module Mixin
module UserContext
- # valid logon_type values => :remote, :local
- def with_user_context(user, password, domain = nil, logon_type = :remote, &block)
+ # valid values for authentication => :remote, :local
+ # When authentication = :local, we use the credentials to create a logon session against the local system, and then try to access the files.
+ # When authentication = :remote, we continue with the current user but pass the provided credentials to the remote system.
+ def with_user_context(user, password, domain = nil, authentication = :remote, &block)
unless Chef::Platform.windows?
raise Exceptions::UnsupportedPlatform, "User context impersonation is supported only on the Windows platform"
end
@@ -36,7 +38,7 @@ class Chef
begin
if user
- logon_session = Chef::Util::Windows::LogonSession.new(user, password, domain, logon_type)
+ logon_session = Chef::Util::Windows::LogonSession.new(user, password, domain, authentication)
logon_session.open
logon_session.set_user_context
end
diff --git a/lib/chef/provider/remote_file/network_file.rb b/lib/chef/provider/remote_file/network_file.rb
index a7ba0207bd..f9dc7b0e7b 100644
--- a/lib/chef/provider/remote_file/network_file.rb
+++ b/lib/chef/provider/remote_file/network_file.rb
@@ -43,7 +43,7 @@ class Chef
tempfile = Chef::FileContentManagement::Tempfile.new(new_resource).tempfile
Chef::Log.debug("#{new_resource} staging #{@source} to #{tempfile.path}")
- with_user_context(new_resource.remote_user, new_resource.remote_password, new_resource.remote_domain, :remote) do
+ with_user_context(new_resource.remote_user, new_resource.remote_password, new_resource.remote_domain, new_resource.authentication) do
::File.open(@source, "rb") do |remote_file|
while data = remote_file.read(TRANSFER_CHUNK_SIZE)
tempfile.write(data)
diff --git a/lib/chef/resource/remote_file.rb b/lib/chef/resource/remote_file.rb
index 4db055a20d..d2c2622524 100644
--- a/lib/chef/resource/remote_file.rb
+++ b/lib/chef/resource/remote_file.rb
@@ -139,6 +139,8 @@ class Chef
property :remote_password, String, sensitive: true
+ property :authentication, equal_to: [:remote, :local], default: :remote
+
def after_created
validate_identity_platform(remote_user, remote_password, remote_domain)
identity = qualify_user(remote_user, remote_password, remote_domain)
diff --git a/lib/chef/util/windows/logon_session.rb b/lib/chef/util/windows/logon_session.rb
index 20c49cfd27..912a603865 100644
--- a/lib/chef/util/windows/logon_session.rb
+++ b/lib/chef/util/windows/logon_session.rb
@@ -25,7 +25,7 @@ class Chef
class LogonSession
include Chef::Mixin::WideString
- def initialize(username, password, domain = nil, logon_type = :remote)
+ def initialize(username, password, domain = nil, authentication = :remote)
if username.nil? || password.nil?
raise ArgumentError, "The logon session must be initialize with non-nil user name and password parameters"
end
@@ -33,7 +33,7 @@ class Chef
@original_username = username
@original_password = password
@original_domain = domain
- @logon_type = logon_type
+ @authentication = authentication
@token = FFI::Buffer.new(:pointer)
@session_opened = false
@impersonating = false
@@ -48,9 +48,9 @@ class Chef
password = wstring(original_password)
domain = wstring(original_domain)
- if logon_type == :remote
+ if authentication == :remote
status = Chef::ReservedNames::Win32::API::Security.LogonUserW(username, domain, password, Chef::ReservedNames::Win32::API::Security::LOGON32_LOGON_NEW_CREDENTIALS, Chef::ReservedNames::Win32::API::Security::LOGON32_PROVIDER_DEFAULT, token)
- elsif logon_type == :local
+ elsif authentication == :local
status = Chef::ReservedNames::Win32::API::Security.LogonUserW(username, domain, password, Chef::ReservedNames::Win32::API::Security::LOGON32_LOGON_NETWORK, Chef::ReservedNames::Win32::API::Security::LOGON32_PROVIDER_DEFAULT, token)
end
@@ -115,7 +115,7 @@ class Chef
attr_reader :original_username
attr_reader :original_password
attr_reader :original_domain
- attr_reader :logon_type
+ attr_reader :authentication
attr_reader :token
attr_reader :session_opened
diff --git a/spec/functional/win32/security_spec.rb b/spec/functional/win32/security_spec.rb
index d35f6dea0b..6c24cbec08 100644
--- a/spec/functional/win32/security_spec.rb
+++ b/spec/functional/win32/security_spec.rb
@@ -39,6 +39,7 @@ describe "Chef::Win32::Security", :windows_only do
whoami.error!
whoami.stdout.split("\\")[0]
end
+
before do
allow_any_instance_of(Chef::Mixin::UserContext).to receive(:node).and_return({ "platform_family" => "windows" })
allow(Chef::Platform).to receive(:windows_server_2003?).and_return(false)
diff --git a/spec/unit/util/windows/logon_session_spec.rb b/spec/unit/util/windows/logon_session_spec.rb
index 77915c2ae1..8a94802bf6 100644
--- a/spec/unit/util/windows/logon_session_spec.rb
+++ b/spec/unit/util/windows/logon_session_spec.rb
@@ -27,8 +27,8 @@ describe ::Chef::Util::Windows::LogonSession do
stub_const("Chef::ReservedNames::Win32::API::System", Class.new )
end
- let(:session) { ::Chef::Util::Windows::LogonSession.new(session_user, password, session_domain, logon_type) }
- let(:logon_type) { :remote }
+ let(:session) { ::Chef::Util::Windows::LogonSession.new(session_user, password, session_domain, authentication) }
+ let(:authentication) { :remote }
shared_examples_for "it received syntactically invalid credentials" do
it "does not raisees an exception when it is initialized" do
diff --git a/spec/unit/win32/security_spec.rb b/spec/unit/win32/security_spec.rb
index 4e22668a93..6e4441a482 100644
--- a/spec/unit/win32/security_spec.rb
+++ b/spec/unit/win32/security_spec.rb
@@ -64,6 +64,42 @@ describe "Chef::Win32::Security", :windows_only do
end
end
+ describe "self.has_admin_privileges?" do
+ it "returns true for windows server 2003" do
+ allow(Chef::Platform).to receive(:windows_server_2003?).and_return(true)
+ expect(Chef::ReservedNames::Win32::Security.has_admin_privileges?).to be true
+ end
+
+ context "when the user doesn't have admin privileges" do
+ it "returns false" do
+ allow(Chef::Platform).to receive(:windows_server_2003?).and_return(false)
+ allow(Chef::ReservedNames::Win32::Security).to receive(:open_current_process_token).and_raise("Access is denied.")
+ expect(Chef::ReservedNames::Win32::Security.has_admin_privileges?).to be false
+ end
+ end
+
+ context "when open_current_process_token fails with some other error than `Access is Denied`" do
+ it "raises error" do
+ allow(Chef::Platform).to receive(:windows_server_2003?).and_return(false)
+ allow(Chef::ReservedNames::Win32::Security).to receive(:open_current_process_token).and_raise("boom")
+ expect { Chef::ReservedNames::Win32::Security.has_admin_privileges? }.to raise_error(Chef::Exceptions::Win32APIError)
+ end
+ end
+
+ context "when the user has admin privileges" do
+ it "returns true" do
+ allow(Chef::Platform).to receive(:windows_server_2003?).and_return(false)
+ allow(Chef::ReservedNames::Win32::Security).to receive(:open_current_process_token)
+ token = Chef::ReservedNames::Win32::Security.open_current_process_token
+ allow(token).to receive_message_chain(:handle, :handle)
+ allow(Chef::ReservedNames::Win32::Security).to receive(:get_token_information_elevation_type)
+ allow(Chef::ReservedNames::Win32::Security).to receive(:GetTokenInformation).and_return(true)
+ allow_any_instance_of(FFI::Buffer).to receive(:read_ulong).and_return(1)
+ expect(Chef::ReservedNames::Win32::Security.has_admin_privileges?).to be true
+ end
+ end
+ end
+
describe "self.get_token_information_elevation_type" do
let(:token_rights) { Chef::ReservedNames::Win32::Security::TOKEN_READ }