diff options
author | Tim Smith <tsmith@chef.io> | 2019-03-18 17:01:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-18 17:01:42 -0700 |
commit | 89daf43c4efb03d2adea1670d677bb14f73aa254 (patch) | |
tree | 2a2f11d631e7bc908256604a18854c9028ae5881 | |
parent | a671180029968689fc395dc78594ef33fa148b21 (diff) | |
parent | 78d135def8632ea0ff74e00b66b4c2a20c97bb23 (diff) | |
download | chef-89daf43c4efb03d2adea1670d677bb14f73aa254.tar.gz |
Merge pull request #8303 from jasonwbarnett/backport-windows_service-fix
Backport fix for #8080
-rw-r--r-- | lib/chef/provider/service/windows.rb | 34 | ||||
-rw-r--r-- | spec/unit/provider/service/windows_spec.rb | 26 |
2 files changed, 44 insertions, 16 deletions
diff --git a/lib/chef/provider/service/windows.rb b/lib/chef/provider/service/windows.rb index 28988fdb3d..710cdd67c6 100644 --- a/lib/chef/provider/service/windows.rb +++ b/lib/chef/provider/service/windows.rb @@ -83,22 +83,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service def start_service if Win32::Service.exists?(@new_resource.service_name) - # reconfiguration is idempotent, so just do it. - new_config = { - service_name: @new_resource.service_name, - service_start_name: @new_resource.run_as_user, - password: @new_resource.run_as_password, - }.reject { |k, v| v.nil? || v.length == 0 } - - Win32::Service.configure(new_config) - logger.info "#{@new_resource} configured." - - # LocalSystem is the default runas user, which is a special service account that should ultimately have the rights of BUILTIN\Administrators, but we wouldn't see that from get_account_right - if new_config.key?(:service_start_name) && new_config[:service_start_name].casecmp("localsystem") != 0 - unless Chef::ReservedNames::Win32::Security.get_account_right(canonicalize_username(new_config[:service_start_name])).include?(SERVICE_RIGHT) - grant_service_logon(new_config[:service_start_name]) - end - end + configure_service_run_as_properties state = current_state if state == RUNNING @@ -281,6 +266,21 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service private + def configure_service_run_as_properties + return unless new_resource.property_is_set?(:run_as_user) + + new_config = { + service_name: new_resource.service_name, + service_start_name: new_resource.run_as_user, + password: new_resource.run_as_password, + }.reject { |k, v| v.nil? || v.length == 0 } + + Win32::Service.configure(new_config) + logger.info "#{new_resource} configured." + + grant_service_logon(new_resource.run_as_user) if new_resource.run_as_user.casecmp("localsystem") != 0 + end + def current_delayed_start if service = Win32::Service.services.find { |x| x.service_name == new_resource.service_name } service.delayed_start == 0 ? false : true @@ -290,6 +290,8 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service end def grant_service_logon(username) + return if Chef::ReservedNames::Win32::Security.get_account_right(canonicalize_username(username)).include?(SERVICE_RIGHT) + begin Chef::ReservedNames::Win32::Security.add_account_right(canonicalize_username(username), SERVICE_RIGHT) rescue Chef::Exceptions::Win32APIError => err diff --git a/spec/unit/provider/service/windows_spec.rb b/spec/unit/provider/service/windows_spec.rb index 6432df145d..3e40291aea 100644 --- a/spec/unit/provider/service/windows_spec.rb +++ b/spec/unit/provider/service/windows_spec.rb @@ -96,6 +96,7 @@ describe Chef::Provider::Service::Windows, "load_current_resource", :windows_onl Win32::Service::DEMAND_START = 0x00000003 Win32::Service::DISABLED = 0x00000004 + allow(Win32::Service).to receive(:start).with(any_args).and_return(Win32::Service) allow(Win32::Service).to receive(:status).with(new_resource.service_name).and_return( double("StatusStruct", current_state: "running")) allow(Win32::Service).to receive(:config_info).with(new_resource.service_name) @@ -505,6 +506,31 @@ describe Chef::Provider::Service::Windows, "load_current_resource", :windows_onl double("StatusStruct", current_state: "running")) end + context "run_as_user user is specified" do + let(:run_as_user) { provider.new_resource.class.properties[:run_as_user].default } + + before do + provider.new_resource.run_as_user run_as_user + end + + it "configures service run_as_user and run_as_password" do + expect(provider).to receive(:configure_service_run_as_properties).and_call_original + expect(Win32::Service).to receive(:configure) + provider.start_service + end + end + + context "run_as_user user is not specified" do + before do + expect(provider.new_resource.property_is_set?(:run_as_user)).to be false + end + + it "does not configure service run_as_user and run_as_password" do + expect(Win32::Service).not_to receive(:configure) + provider.start_service + end + end + it "calls the start command if one is specified" do new_resource.start_command "sc start #{chef_service_name}" expect(provider).to receive(:shell_out!).with((new_resource.start_command).to_s).and_return("Starting custom service") |