summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Borean <jborean93@gmail.com>2018-11-20 09:21:28 +1000
committerSviatoslav Sydorenko <wk@sydorenko.org.ua>2018-11-20 17:52:21 +0100
commit40e7bdf16b503b3b8895c03edd1e33c6177d4503 (patch)
tree0d374d13501aa2ca3b12f9ae6a149be7cdf7bd27
parentb20520f500ad6878750bd2e2e8be46f756e4eaa5 (diff)
downloadansible-backport-9b0dd52-stable-2.3.tar.gz
[stable-2.3] win_security_policy - add warning when using this module ot edit rights (#48850).backport-9b0dd52-stable-2.3
(cherry picked from commit 9b0dd5224be225be1981065e209ea6221ee4948f) Co-authored-by: Jordan Borean <jborean93@gmail.com>
-rw-r--r--changelogs/fragments/win_security_policy-rights.yaml2
-rw-r--r--lib/ansible/modules/windows/win_security_policy.ps1197
-rw-r--r--lib/ansible/modules/windows/win_security_policy.py121
3 files changed, 320 insertions, 0 deletions
diff --git a/changelogs/fragments/win_security_policy-rights.yaml b/changelogs/fragments/win_security_policy-rights.yaml
new file mode 100644
index 0000000000..986004c3e4
--- /dev/null
+++ b/changelogs/fragments/win_security_policy-rights.yaml
@@ -0,0 +1,2 @@
+minor_changes:
+- win_security_policy - warn users to use win_user_right instead when editing ``Privilege Rights``
diff --git a/lib/ansible/modules/windows/win_security_policy.ps1 b/lib/ansible/modules/windows/win_security_policy.ps1
new file mode 100644
index 0000000000..45734c15b7
--- /dev/null
+++ b/lib/ansible/modules/windows/win_security_policy.ps1
@@ -0,0 +1,197 @@
+#!powershell
+
+# Copyright: (c) 2017, Jordan Borean <jborean93@gmail.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#Requires -Module Ansible.ModuleUtils.Legacy
+
+$ErrorActionPreference = 'Stop'
+
+$params = Parse-Args $args -supports_check_mode $true
+$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
+$diff_mode = Get-AnsibleParam -obj $Params -name "_ansible_diff" -type "bool" -default $false
+
+$section = Get-AnsibleParam -obj $params -name "section" -type "str" -failifempty $true
+$key = Get-AnsibleParam -obj $params -name "key" -type "str" -failifempty $true
+$value = Get-AnsibleParam -obj $params -name "value" -failifempty $true
+
+$result = @{
+ changed = $false
+ section = $section
+ key = $key
+ value = $value
+}
+
+if ($diff_mode) {
+ $result.diff = @{}
+}
+
+Function Run-SecEdit($arguments) {
+ $rc = $null
+ $stdout = $null
+ $stderr = $null
+ $log_path = [IO.Path]::GetTempFileName()
+ $arguments = $arguments + @("/log", $log_path)
+
+ try {
+ $stdout = &SecEdit.exe $arguments | Out-String
+ } catch {
+ $stderr = $_.Exception.Message
+ }
+ $log = Get-Content -Path $log_path
+ Remove-Item -Path $log_path -Force
+
+ $return = @{
+ log = ($log -join "`n").Trim()
+ stdout = $stdout
+ stderr = $stderr
+ rc = $LASTEXITCODE
+ }
+
+ return $return
+}
+
+Function Export-SecEdit() {
+ $secedit_ini_path = [IO.Path]::GetTempFileName()
+ # while this will technically make a change to the system in check mode by
+ # creating a new file, we need these values to be able to do anything
+ # substantial in check mode
+ $export_result = Run-SecEdit -arguments @("/export", "/cfg", $secedit_ini_path, "/quiet")
+
+ # check the return code and if the file has been populated, otherwise error out
+ if (($export_result.rc -ne 0) -or ((Get-Item -Path $secedit_ini_path).Length -eq 0)) {
+ Remove-Item -Path $secedit_ini_path -Force
+ $result.rc = $export_result.rc
+ $result.stdout = $export_result.stdout
+ $result.stderr = $export_result.stderr
+ Fail-Json $result "Failed to export secedit.ini file to $($secedit_ini_path)"
+ }
+ $secedit_ini = ConvertFrom-Ini -file_path $secedit_ini_path
+
+ return $secedit_ini
+}
+
+Function Import-SecEdit($ini) {
+ $secedit_ini_path = [IO.Path]::GetTempFileName()
+ $secedit_db_path = [IO.Path]::GetTempFileName()
+ Remove-Item -Path $secedit_db_path -Force # needs to be deleted for SecEdit.exe /import to work
+
+ $ini_contents = ConvertTo-Ini -ini $ini
+ Set-Content -Path $secedit_ini_path -Value $ini_contents
+ $result.changed = $true
+
+ $import_result = Run-SecEdit -arguments @("/configure", "/db", $secedit_db_path, "/cfg", $secedit_ini_path, "/quiet")
+ $result.import_log = $import_result.log
+ Remove-Item -Path $secedit_ini_path -Force
+ if ($import_result.rc -ne 0) {
+ $result.rc = $import_result.rc
+ $result.stdout = $import_result.stdout
+ $result.stderr = $import_result.stderr
+ Fail-Json $result "Failed to import secedit.ini file from $($secedit_ini_path)"
+ }
+}
+
+Function ConvertTo-Ini($ini) {
+ $content = @()
+ foreach ($key in $ini.GetEnumerator()) {
+ $section = $key.Name
+ $values = $key.Value
+
+ $content += "[$section]"
+ foreach ($value in $values.GetEnumerator()) {
+ $value_key = $value.Name
+ $value_value = $value.Value
+
+ if ($value_value -ne $null) {
+ $content += "$value_key = $value_value"
+ }
+ }
+ }
+
+ return $content -join "`r`n"
+}
+
+Function ConvertFrom-Ini($file_path) {
+ $ini = @{}
+ switch -Regex -File $file_path {
+ "^\[(.+)\]" {
+ $section = $matches[1]
+ $ini.$section = @{}
+ }
+ "(.+?)\s*=(.*)" {
+ $name = $matches[1].Trim()
+ $value = $matches[2].Trim()
+ if ($value -match "^\d+$") {
+ $value = [int]$value
+ } elseif ($value.StartsWith('"') -and $value.EndsWith('"')) {
+ $value = $value.Substring(1, $value.Length - 2)
+ }
+
+ $ini.$section.$name = $value
+ }
+ }
+
+ return $ini
+}
+
+if ($section -eq "Privilege Rights") {
+ Add-Warning -obj $result -message "Using this module to edit rights and privileges is error-prone, use the win_user_right module instead"
+}
+
+$will_change = $false
+$secedit_ini = Export-SecEdit
+if (-not ($secedit_ini.ContainsKey($section))) {
+ Fail-Json $result "The section '$section' does not exist in SecEdit.exe output ini"
+}
+
+if ($secedit_ini.$section.ContainsKey($key)) {
+ $current_value = $secedit_ini.$section.$key
+
+ if ($current_value -cne $value) {
+ if ($diff_mode) {
+ $result.diff.prepared = @"
+[$section]
+-$key = $current_value
++$key = $value
+"@
+ }
+
+ $secedit_ini.$section.$key = $value
+ $will_change = $true
+ }
+} elseif ([string]$value -eq "") {
+ # Value is requested to be removed, and has already been removed, do nothing
+} else {
+ if ($diff_mode) {
+ $result.diff.prepared = @"
+[$section]
++$key = $value
+"@
+ }
+ $secedit_ini.$section.$key = $value
+ $will_change = $true
+}
+
+if ($will_change -eq $true) {
+ $result.changed = $true
+ if (-not $check_mode) {
+ Import-SecEdit -ini $secedit_ini
+
+ # secedit doesn't error out on improper entries, re-export and verify
+ # the changes occurred
+ $verification_ini = Export-SecEdit
+ $new_section_values = $verification_ini.$section
+ if ($new_section_values.ContainsKey($key)) {
+ $new_value = $new_section_values.$key
+ if ($new_value -cne $value) {
+ Fail-Json $result "Failed to change the value for key '$key' in section '$section', the value is still $new_value"
+ }
+ } elseif ([string]$value -eq "") {
+ # Value was empty, so OK if no longer in the result
+ } else {
+ Fail-Json $result "The key '$key' in section '$section' is not a valid key, cannot set this value"
+ }
+ }
+}
+
+Exit-Json $result
diff --git a/lib/ansible/modules/windows/win_security_policy.py b/lib/ansible/modules/windows/win_security_policy.py
new file mode 100644
index 0000000000..6282ac54e2
--- /dev/null
+++ b/lib/ansible/modules/windows/win_security_policy.py
@@ -0,0 +1,121 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# this is a windows documentation stub, actual code lives in the .ps1
+# file of the same name
+
+ANSIBLE_METADATA = {'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'community'}
+
+DOCUMENTATION = r'''
+---
+module: win_security_policy
+version_added: '2.4'
+short_description: Change local security policy settings
+description:
+- Allows you to set the local security policies that are configured by
+ SecEdit.exe.
+notes:
+- This module uses the SecEdit.exe tool to configure the values, more details
+ of the areas and keys that can be configured can be found here
+ U(https://msdn.microsoft.com/en-us/library/bb742512.aspx).
+- If you are in a domain environment these policies may be set by a GPO policy,
+ this module can temporarily change these values but the GPO will override
+ it if the value differs.
+- You can also run C(SecEdit.exe /export /cfg C:\temp\output.ini) to view the
+ current policies set on your system.
+- When assigning user rights, use the M(win_user_right) module instead.
+options:
+ section:
+ description:
+ - The ini section the key exists in.
+ - If the section does not exist then the module will return an error.
+ - Example sections to use are 'Account Policies', 'Local Policies',
+ 'Event Log', 'Restricted Groups', 'System Services', 'Registry' and
+ 'File System'
+ - If wanting to edit the C(Privilege Rights) section, use the
+ M(win_user_right) module instead.
+ required: yes
+ key:
+ description:
+ - The ini key of the section or policy name to modify.
+ - The module will return an error if this key is invalid.
+ required: yes
+ value:
+ description:
+ - The value for the ini key or policy name.
+ - If the key takes in a boolean value then 0 = False and 1 = True.
+ required: yes
+author:
+- Jordan Borean (@jborean93)
+'''
+
+EXAMPLES = r'''
+- name: change the guest account name
+ win_security_policy:
+ section: System Access
+ key: NewGuestName
+ value: Guest Account
+
+- name: set the maximum password age
+ win_security_policy:
+ section: System Access
+ key: MaximumPasswordAge
+ value: 15
+
+- name: do not store passwords using reversible encryption
+ win_security_policy:
+ section: System Access
+ key: ClearTextPassword
+ value: 0
+
+- name: enable system events
+ win_security_policy:
+ section: Event Audit
+ key: AuditSystemEvents
+ value: 1
+'''
+
+RETURN = r'''
+rc:
+ description: The return code after a failure when running SecEdit.exe.
+ returned: failure with secedit calls
+ type: int
+ sample: -1
+stdout:
+ description: The output of the STDOUT buffer after a failure when running
+ SecEdit.exe.
+ returned: failure with secedit calls
+ type: string
+ sample: check log for error details
+stderr:
+ description: The output of the STDERR buffer after a failure when running
+ SecEdit.exe.
+ returned: failure with secedit calls
+ type: string
+ sample: failed to import security policy
+import_log:
+ description: The log of the SecEdit.exe /configure job that configured the
+ local policies. This is used for debugging purposes on failures.
+ returned: secedit.exe /import run and change occurred
+ type: string
+ sample: Completed 6 percent (0/15) \tProcess Privilege Rights area.
+key:
+ description: The key in the section passed to the module to modify.
+ returned: success
+ type: string
+ sample: NewGuestName
+section:
+ description: The section passed to the module to modify.
+ returned: success
+ type: string
+ sample: System Access
+value:
+ description: The value passed to the module to modify to.
+ returned: success
+ type: string
+ sample: Guest Account
+'''