summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasu1105 <vasundhara.jagdale@msystechnologies.com>2020-01-27 04:17:05 -0800
committerVasu1105 <vasundhara.jagdale@msystechnologies.com>2020-02-23 23:09:55 -0800
commit5f03ec03b84cd0cb48aa06f65c7fdd26579378e0 (patch)
treef7fdb8a0cfbda9568f19607f77f9053a1da5a262
parent3d834aa124da411e62f5d6411f0257d4e93efc48 (diff)
downloadchef-5f03ec03b84cd0cb48aa06f65c7fdd26579378e0.tar.gz
MSYS-1230 Migrating windows_user_privilege resource from windows cookbook
Signed-off-by: Vasu1105 <vasundhara.jagdale@msystechnologies.com>
-rw-r--r--lib/chef/resource.rb2
-rw-r--r--lib/chef/resource/windows_user_privilege.rb147
-rw-r--r--lib/chef/resources.rb1
-rw-r--r--spec/functional/resource/windows_user_privilege_spec.rb129
4 files changed, 278 insertions, 1 deletions
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index ca1736aef9..19c6c2e59f 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -588,7 +588,7 @@ class Chef
begin
return if should_skip?(action)
- provider_for_action(action).run_action
+ provider_for_action(action).run_action(action)
rescue StandardError => e
if ignore_failure
logger.error("#{custom_exception_message(e)}; ignore_failure is set, continuing")
diff --git a/lib/chef/resource/windows_user_privilege.rb b/lib/chef/resource/windows_user_privilege.rb
new file mode 100644
index 0000000000..ca010210c6
--- /dev/null
+++ b/lib/chef/resource/windows_user_privilege.rb
@@ -0,0 +1,147 @@
+#
+# Author:: Jared Kauppila (<jared@kauppi.la>)
+# Author:: Vasundhara Jagdale(<vasundhara.jagdale@chef.io>)
+# Copyright 2008-2019, Chef Software, Inc.
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require_relative "../resource"
+
+class Chef
+ class Resource
+ class WindowsUserPrivilege < Chef::Resource
+ privilege_opts = %w{SeTrustedCredManAccessPrivilege
+ SeNetworkLogonRight
+ SeTcbPrivilege
+ SeMachineAccountPrivilege
+ SeIncreaseQuotaPrivilege
+ SeInteractiveLogonRight
+ SeRemoteInteractiveLogonRight
+ SeBackupPrivilege
+ SeChangeNotifyPrivilege
+ SeSystemtimePrivilege
+ SeTimeZonePrivilege
+ SeCreatePagefilePrivilege
+ SeCreateTokenPrivilege
+ SeCreateGlobalPrivilege
+ SeCreatePermanentPrivilege
+ SeCreateSymbolicLinkPrivilege
+ SeDebugPrivilege
+ SeDenyNetworkLogonRight
+ SeDenyBatchLogonRight
+ SeDenyServiceLogonRight
+ SeDenyInteractiveLogonRight
+ SeDenyRemoteInteractiveLogonRight
+ SeEnableDelegationPrivilege
+ SeRemoteShutdownPrivilege
+ SeAuditPrivilege
+ SeImpersonatePrivilege
+ SeIncreaseWorkingSetPrivilege
+ SeIncreaseBasePriorityPrivilege
+ SeLoadDriverPrivilege
+ SeLockMemoryPrivilege
+ SeBatchLogonRight
+ SeServiceLogonRight
+ SeSecurityPrivilege
+ SeRelabelPrivilege
+ SeSystemEnvironmentPrivilege
+ SeManageVolumePrivilege
+ SeProfileSingleProcessPrivilege
+ SeSystemProfilePrivilege
+ SeUndockPrivilege
+ SeAssignPrimaryTokenPrivilege
+ SeRestorePrivilege
+ SeShutdownPrivilege
+ SeSyncAgentPrivilege
+ SeTakeOwnershipPrivilege
+ }
+
+ resource_name :windows_user_privilege
+ description "The windows_user_privilege resource allows to add and set principal (User/Group) to the specified privilege. \n Ref: https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment"
+
+ property :principal, String,
+ description: "An optional property to add the user to the given privilege. Use only with add and remove action.",
+ name_property: true
+
+ property :users, Array,
+ description: "An optional property to set the privilege for given users. Use only with set action."
+
+ property :privilege, [Array, String],
+ description: "Privilege to set for users.",
+ required: true,
+ callbacks: {
+ "Option privilege must include any of the: #{privilege_opts}" => lambda {
+ |v| v.is_a?(Array) ? (privilege_opts & v).size == v.size : privilege_opts.include?(v)
+ },
+ }
+
+ property :sensitive, [true, false], default: true
+
+ load_current_value do |new_resource|
+ unless new_resource.principal.nil?
+ privilege Chef::ReservedNames::Win32::Security.get_account_right(new_resource.principal) unless new_resource.action.include?(:set)
+ end
+ end
+
+ action :add do
+ ([*new_resource.privilege] - [*current_resource.privilege]).each do |user_right|
+ converge_by("adding user privilege #{user_right}") do
+ Chef::ReservedNames::Win32::Security.add_account_right(new_resource.principal, user_right)
+ end
+ end
+ end
+
+ action :set do
+ uras = new_resource.privilege
+
+ if new_resource.users.nil? || new_resource.users.empty?
+ raise Chef::Exceptions::ValidationFailed, "Users are required property with set action."
+ end
+
+ if powershell_out!("Get-PackageSource -Name PSGallery").stdout.empty? || powershell_out!("(Get-Package -Name cSecurityOptions -WarningAction SilentlyContinue).name").stdout.empty?
+ raise "This resource needs Powershell module cSecurityOptions to be installed. \n Please install it and then re-run the recipe. \n https://www.powershellgallery.com/packages/cSecurityOptions/3.1.3"
+ end
+
+ uras.each do |ura|
+ dsc_resource "URA" do
+ module_name "cSecurityOptions"
+ resource :UserRightsAssignment
+ property :Ensure, "Present"
+ property :Privilege, ura
+ property :Identity, new_resource.users
+ sensitive new_resource.sensitive
+ end
+ end
+ end
+
+ action :remove do
+ curr_res_privilege = current_resource.privilege
+ new_res_privilege = new_resource.privilege
+
+ new_res_privilege = [] << new_res_privilege if new_resource.privilege.is_a?(String)
+ missing_res_privileges = (new_res_privilege - curr_res_privilege)
+
+ unless missing_res_privileges.empty?
+ Chef::Log.info("Privilege: #{missing_res_privileges.join(", ")} not present. Unable to delete")
+ end
+
+ (new_res_privilege - missing_res_privileges).each do |user_right|
+ converge_by("removing user privilege #{user_right}") do
+ Chef::ReservedNames::Win32::Security.remove_account_right(new_resource.principal, user_right)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 3681d9bd54..8bdd207e84 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -158,3 +158,4 @@ require_relative "resource/windows_task"
require_relative "resource/windows_uac"
require_relative "resource/windows_workgroup"
require_relative "resource/timezone"
+require_relative "resource/windows_user_privilege"
diff --git a/spec/functional/resource/windows_user_privilege_spec.rb b/spec/functional/resource/windows_user_privilege_spec.rb
new file mode 100644
index 0000000000..4f67032ff0
--- /dev/null
+++ b/spec/functional/resource/windows_user_privilege_spec.rb
@@ -0,0 +1,129 @@
+#
+# Author:: Vasundhara Jagdale (<vasundhara.jagdale@chef.io>)
+# Copyright 2008-2019, Chef Software, Inc.
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require_relative "../../spec_helper"
+require_relative "../../functional/resource/base"
+
+describe Chef::Resource::WindowsUserPrivilege, :windows_only do
+ include Chef::Mixin::PowershellOut
+
+ let(:principal) { nil }
+ let(:privilege) { nil }
+ let(:users) { nil }
+ let(:sensitive) { true }
+
+ let(:windows_test_run_context) do
+ node = Chef::Node.new
+ node.consume_external_attrs(OHAI_SYSTEM.data, {}) # node[:languages][:powershell][:version]
+ node.automatic["os"] = "windows"
+ node.automatic["platform"] = "windows"
+ node.automatic["platform_version"] = "6.1"
+ node.automatic["kernel"][:machine] = :x86_64 # Only 64-bit architecture is supported
+ empty_events = Chef::EventDispatch::Dispatcher.new
+ Chef::RunContext.new(node, {}, empty_events)
+ end
+
+ subject do
+ new_resource = Chef::Resource::WindowsUserPrivilege.new(principal, windows_test_run_context)
+ new_resource.privilege = privilege
+ new_resource.principal = principal
+ new_resource.users = users
+ new_resource
+ end
+
+ describe "#add privilege" do
+ after { subject.run_action(:remove) }
+
+ let(:principal) { "Administrator" }
+ let(:privilege) { "SeCreateSymbolicLinkPrivilege" }
+
+ it "adds user to privilege" do
+ subject.run_action(:add)
+ expect(subject).to be_updated_by_last_action
+ end
+
+ it "is idempotent" do
+ subject.run_action(:add)
+ subject.run_action(:add)
+ expect(subject).not_to be_updated_by_last_action
+ end
+ end
+
+ describe "#set privilege" do
+ before(:all) {
+ powershell_out!("Uninstall-Module -Name cSecurityOptions") unless powershell_out!("(Get-Package -Name cSecurityOptions -WarningAction SilentlyContinue).name").stdout.empty?
+ }
+
+ let(:principal) { "user_privilege" }
+ let(:users) { %w{Administrators Administrator} }
+ let(:privilege) { %w{SeCreateSymbolicLinkPrivilege} }
+
+ it "raises error if cSecurityOptions is not installed." do
+ subject.action(:set)
+ expect { subject.run_action(:set) }.to raise_error(RuntimeError)
+ end
+ end
+
+ describe "#set privilege" do
+ before(:all) {
+ powershell_out!("Install-Module -Name cSecurityOptions -Force") if powershell_out!("(Get-Package -Name cSecurityOptions -WarningAction SilentlyContinue).name").stdout.empty?
+ }
+
+ after { remove_user_privilege("Administrator", subject.privilege) }
+
+ let(:principal) { "user_privilege" }
+ let(:users) { %w{Administrators Administrator} }
+ let(:privilege) { %w{SeCreateSymbolicLinkPrivilege} }
+
+ it "sets user to privilege" do
+ subject.action(:set)
+ subject.run_action(:set)
+ expect(subject).to be_updated_by_last_action
+ end
+
+ it "is idempotent" do
+ subject.action(:set)
+ subject.run_action(:set)
+ subject.run_action(:set)
+ expect(subject).not_to be_updated_by_last_action
+ end
+
+ it "raise error if users not provided" do
+ subject.users = nil
+ subject.action(:set)
+ expect { subject.run_action(:set) }.to raise_error(Chef::Exceptions::ValidationFailed)
+ end
+ end
+
+ describe "#remove privilege" do
+ let(:principal) { "Administrator" }
+ let(:privilege) { "SeCreateSymbolicLinkPrivilege" }
+
+ it "remove user from privilege" do
+ subject.run_action(:add)
+ subject.run_action(:remove)
+ expect(subject).to be_updated_by_last_action
+ end
+ end
+
+ def remove_user_privilege(user, privilege)
+ subject.action(:remove)
+ subject.principal = user
+ subject.privilege = privilege
+ subject.run_action(:remove)
+ end
+end