diff options
author | Jordan Borean <jborean93@gmail.com> | 2018-07-31 07:48:54 +1000 |
---|---|---|
committer | Matt Davis <nitzmahone@users.noreply.github.com> | 2018-07-30 14:48:54 -0700 |
commit | 9259f31fee03e75a99a23b9fde5106b43f0cc437 (patch) | |
tree | 56c10a1eab499632f2059b0f7b3a177ecaba38f0 /lib/ansible/modules/windows | |
parent | d79027b77fb30d45cd322a54f151c559b11bc1ad (diff) | |
download | ansible-9259f31fee03e75a99a23b9fde5106b43f0cc437.tar.gz |
Add Ansible.ModuleUtils.PrivilegeUtil and converted code to use it (#43179)
* Add Ansible.ModuleUtils.PrivilegeUtil and converted code to use it
* Changed namespace and class to be a better standard and fixed some typos
* Changes from review
* changes to avoid out of bound mem of server 2008
* changes to detect failure when setting a privileged not allowed
Diffstat (limited to 'lib/ansible/modules/windows')
-rw-r--r-- | lib/ansible/modules/windows/win_acl.ps1 | 110 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_file.ps1 | 3 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_find.ps1 | 3 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_get_url.ps1 | 3 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_regedit.ps1 | 104 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_region.ps1 | 3 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_scheduled_task.ps1 | 3 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_scheduled_task_stat.ps1 | 3 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_user.ps1 | 3 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_user_right.ps1 | 3 | ||||
-rw-r--r-- | lib/ansible/modules/windows/win_whoami.ps1 | 3 |
11 files changed, 27 insertions, 214 deletions
diff --git a/lib/ansible/modules/windows/win_acl.ps1 b/lib/ansible/modules/windows/win_acl.ps1 index 4db0ba718b..75bd1393ab 100644 --- a/lib/ansible/modules/windows/win_acl.ps1 +++ b/lib/ansible/modules/windows/win_acl.ps1 @@ -6,6 +6,7 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) #Requires -Module Ansible.ModuleUtils.Legacy +#Requires -Module Ansible.ModuleUtils.PrivilegeUtil #Requires -Module Ansible.ModuleUtils.SID $ErrorActionPreference = "Stop" @@ -43,96 +44,7 @@ function Get-UserSID { return $userSID } -# Need to adjust token privs when executing Set-ACL in certain cases. -# e.g. d:\testdir is owned by group in which current user is not a member and no perms are inherited from d:\ -# This also sets us up for setting the owner as a feature. -$AdjustTokenPrivileges = @" -using System; -using System.Runtime.InteropServices; - -namespace Ansible { - public class TokenManipulator { - - [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] - internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, - ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); - - [DllImport("kernel32.dll", ExactSpelling = true)] - internal static extern IntPtr GetCurrentProcess(); - - [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] - internal static extern bool OpenProcessToken(IntPtr h, int acc, - ref IntPtr phtok); - - [DllImport("advapi32.dll", SetLastError = true)] - internal static extern bool LookupPrivilegeValue(string host, string name, - ref long pluid); - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct TokPriv1Luid - { - public int Count; - public long Luid; - public int Attr; - } - - internal const int SE_PRIVILEGE_DISABLED = 0x00000000; - internal const int SE_PRIVILEGE_ENABLED = 0x00000002; - internal const int TOKEN_QUERY = 0x00000008; - internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; - - public static bool AddPrivilege(string privilege) { - try { - bool retVal; - TokPriv1Luid tp; - IntPtr hproc = GetCurrentProcess(); - IntPtr htok = IntPtr.Zero; - retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); - tp.Count = 1; - tp.Luid = 0; - tp.Attr = SE_PRIVILEGE_ENABLED; - retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); - retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); - return retVal; - } - catch (Exception ex) { - throw ex; - } - } - - public static bool RemovePrivilege(string privilege) { - try { - bool retVal; - TokPriv1Luid tp; - IntPtr hproc = GetCurrentProcess(); - IntPtr htok = IntPtr.Zero; - retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); - tp.Count = 1; - tp.Luid = 0; - tp.Attr = SE_PRIVILEGE_DISABLED; - retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); - retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); - return retVal; - } - - catch (Exception ex) { - throw ex; - } - } - } -} -"@ - $params = Parse-Args $args -$_remote_tmp = Get-AnsibleParam $params "_ansible_remote_tmp" -type "path" -default $env:TMP - -$original_tmp = $env:TMP -$original_temp = $env:TEMP -$env:TMP = $_remote_tmp -$env:TEMP = $_remote_tmp -add-type $AdjustTokenPrivileges -$env:TMP = $original_tmp -$env:TEMP = $original_temp Function SetPrivilegeTokens() { # Set privilege tokens only if admin. @@ -144,13 +56,23 @@ Function SetPrivilegeTokens() { if ($myWindowsPrincipal.IsInRole($adminRole)) { - + # Need to adjust token privs when executing Set-ACL in certain cases. + # e.g. d:\testdir is owned by group in which current user is not a member and no perms are inherited from d:\ + # This also sets us up for setting the owner as a feature. # See the following for details of each privilege # https://msdn.microsoft.com/en-us/library/windows/desktop/bb530716(v=vs.85).aspx - - [void][Ansible.TokenManipulator]::AddPrivilege("SeRestorePrivilege") #Grants all write access control to any file, regardless of ACL. - [void][Ansible.TokenManipulator]::AddPrivilege("SeBackupPrivilege") #Grants all read access control to any file, regardless of ACL. - [void][Ansible.TokenManipulator]::AddPrivilege("SeTakeOwnershipPrivilege") #Grants ability to take owernship of an object w/out being granted discretionary access + Import-PrivilegeUtil + $privileges = @( + "SeRestorePrivilege", # Grants all write access control to any file, regardless of ACL. + "SeBackupPrivilege", # Grants all read access control to any file, regardless of ACL. + "SeTakeOwnershipPrivilege" # Grants ability to take owernship of an object w/out being granted discretionary access + ) + foreach ($privilege in $privileges) { + $state = Get-AnsiblePrivilege -Name $privilege + if ($state -eq $false) { + Set-AnsiblePrivilege -Name $privilege -Value $true + } + } } } diff --git a/lib/ansible/modules/windows/win_file.ps1 b/lib/ansible/modules/windows/win_file.ps1 index 60cf3762e4..06f03494fa 100644 --- a/lib/ansible/modules/windows/win_file.ps1 +++ b/lib/ansible/modules/windows/win_file.ps1 @@ -52,12 +52,9 @@ namespace Ansible.Command { } "@ $original_tmp = $env:TMP -$original_temp = $env:TEMP $env:TMP = $_remote_tmp -$env:TEMP = $_remote_tmp Add-Type -TypeDefinition $symlink_util $env:TMP = $original_tmp -$env:TEMP = $original_temp # Used to delete directories and files with logic on handling symbolic links function Remove-File($file, $checkmode) { diff --git a/lib/ansible/modules/windows/win_find.ps1 b/lib/ansible/modules/windows/win_find.ps1 index fc8c1dc925..f2095e09bf 100644 --- a/lib/ansible/modules/windows/win_find.ps1 +++ b/lib/ansible/modules/windows/win_find.ps1 @@ -71,12 +71,9 @@ namespace Ansible.Command { } "@ $original_tmp = $env:TMP -$original_temp = $env:TEMP $env:TMP = $_remote_tmp -$env:TEMP = $_remote_tmp Add-Type -TypeDefinition $symlink_util $env:TMP = $original_tmp -$env:TEMP = $original_temp Function Assert-Age($info) { $valid_match = $true diff --git a/lib/ansible/modules/windows/win_get_url.ps1 b/lib/ansible/modules/windows/win_get_url.ps1 index c105915974..26aa1107c8 100644 --- a/lib/ansible/modules/windows/win_get_url.ps1 +++ b/lib/ansible/modules/windows/win_get_url.ps1 @@ -30,12 +30,9 @@ $webclient_util = @" } "@ $original_tmp = $env:TMP -$original_temp = $env:TEMP $env:TMP = $_remote_tmp -$env:TEMP = $_remote_tmp Add-Type -TypeDefinition $webclient_util $env:TMP = $original_tmp -$env:TEMP = $original_temp Function CheckModified-File($url, $dest, $headers, $credentials, $timeout, $use_proxy, $proxy) { diff --git a/lib/ansible/modules/windows/win_regedit.ps1 b/lib/ansible/modules/windows/win_regedit.ps1 index abeed87366..9fd0c072d5 100644 --- a/lib/ansible/modules/windows/win_regedit.ps1 +++ b/lib/ansible/modules/windows/win_regedit.ps1 @@ -6,6 +6,7 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) #Requires -Module Ansible.ModuleUtils.Legacy +#Requires -Module Ansible.ModuleUtils.PrivilegeUtil $ErrorActionPreference = "Stop" @@ -39,23 +40,8 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; -namespace Ansible +namespace Ansible.RegEdit { - [StructLayout(LayoutKind.Sequential)] - public struct LUID - { - public UInt32 LowPart; - public Int32 HighPart; - } - - [StructLayout(LayoutKind.Sequential)] - public struct TOKEN_PRIVILEGES - { - public UInt32 PrivilegeCount; - public LUID Luid; - public UInt32 Attributes; - } - public enum HKEY : uint { LOCAL_MACHINE = 0x80000002, @@ -74,41 +60,8 @@ namespace Ansible public static explicit operator Win32Exception(string message) { return new Win32Exception(message); } } - public class RegistryUtil + public class Hive { - - public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; - public const int TOKEN_QUERY = 0x00000008; - public const int SE_PRIVILEGE_ENABLED = 0x00000002; - - [DllImport("kernel32.dll", CharSet = CharSet.Auto)] - private static extern IntPtr GetCurrentProcess(); - - [DllImport("kernel32.dll", CharSet = CharSet.Auto)] - private static extern bool CloseHandle( - IntPtr hObject); - - [DllImport("advapi32.dll", CharSet = CharSet.Auto)] - private static extern bool OpenProcessToken( - IntPtr ProcessHandle, - UInt32 DesiredAccess, - out IntPtr TokenHandle); - - [DllImport("advapi32.dll", CharSet = CharSet.Auto)] - private static extern bool LookupPrivilegeValue( - string lpSystemName, - string lpName, - [MarshalAs(UnmanagedType.Struct)] out LUID lpLuid); - - [DllImport("advapi32.dll", CharSet = CharSet.Auto)] - private static extern bool AdjustTokenPrivileges( - IntPtr TokenHandle, - [MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges, - ref TOKEN_PRIVILEGES NewState, - UInt32 BufferLength, - IntPtr PreviousState, - IntPtr ReturnLength); - [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int RegLoadKey( HKEY hKey, @@ -120,41 +73,6 @@ namespace Ansible HKEY hKey, string lpSubKey); - public static void EnablePrivileges() - { - List<String> privileges = new List<String>() - { - "SeRestorePrivilege", - "SeBackupPrivilege" - }; - foreach (string privilege in privileges) - { - IntPtr hToken; - LUID luid; - TOKEN_PRIVILEGES tkpPrivileges; - - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken)) - throw new Win32Exception("OpenProcessToken() failed"); - - try - { - if (!LookupPrivilegeValue(null, privilege, out luid)) - throw new Win32Exception("LookupPrivilegeValue() failed"); - - tkpPrivileges.PrivilegeCount = 1; - tkpPrivileges.Luid = luid; - tkpPrivileges.Attributes = SE_PRIVILEGE_ENABLED; - - if (!AdjustTokenPrivileges(hToken, false, ref tkpPrivileges, 0, IntPtr.Zero, IntPtr.Zero)) - throw new Win32Exception(String.Format("AdjustTokenPrivileges() failed to adjust privilege {0}", privilege)); - } - finally - { - CloseHandle(hToken); - } - } - } - public static void LoadHive(string lpSubKey, string lpFile) { int ret; @@ -373,29 +291,29 @@ if ($hive) { } $original_tmp = $env:TMP - $original_temp = $env:TEMP $env:TMP = $_remote_tmp - $env:TEMP = $_remote_tmp Add-Type -TypeDefinition $registry_util $env:TMP = $original_tmp - $env:TEMP = $original_temp + + Import-PrivilegeUtil try { - [Ansible.RegistryUtil]::EnablePrivileges() + Set-AnsiblePrivilege -Name SeBackupPrivilege -Value $true + Set-AnsiblePrivilege -Name SeRestorePrivilege -Value $true } catch [System.ComponentModel.Win32Exception] { - Fail-Json -obj $result -message "failed to enable SeRestorePrivilege and SeRestorePrivilege for the current process: $($_.Exception.Message)" + Fail-Json -obj $result -message "failed to enable SeBackupPrivilege and SeRestorePrivilege for the current process: $($_.Exception.Message)" } if (Test-Path -Path HKLM:\ANSIBLE) { Add-Warning -obj $result -message "hive already loaded at HKLM:\ANSIBLE, had to unload hive for win_regedit to continue" try { - [Ansible.RegistryUtil]::UnloadHive("ANSIBLE") + [Ansible.RegEdit.Hive]::UnloadHive("ANSIBLE") } catch [System.ComponentModel.Win32Exception] { Fail-Json -obj $result -message "failed to unload registry hive HKLM:\ANSIBLE from $($hive): $($_.Exception.Message)" } } try { - [Ansible.RegistryUtil]::LoadHive("ANSIBLE", $hive) + [Ansible.RegEdit.Hive]::LoadHive("ANSIBLE", $hive) } catch [System.ComponentModel.Win32Exception] { Fail-Json -obj $result -message "failed to load registry hive from '$hive' to HKLM:\ANSIBLE: $($_.Exception.Message)" } @@ -566,7 +484,7 @@ $key_prefix[$path] [GC]::Collect() [GC]::WaitForPendingFinalizers() try { - [Ansible.RegistryUtil]::UnloadHive("ANSIBLE") + [Ansible.RegEdit.Hive]::UnloadHive("ANSIBLE") } catch [System.ComponentModel.Win32Exception] { Fail-Json -obj $result -message "failed to unload registry hive HKLM:\ANSIBLE from $($hive): $($_.Exception.Message)" } diff --git a/lib/ansible/modules/windows/win_region.ps1 b/lib/ansible/modules/windows/win_region.ps1 index df2059da5d..6dc06cda64 100644 --- a/lib/ansible/modules/windows/win_region.ps1 +++ b/lib/ansible/modules/windows/win_region.ps1 @@ -88,12 +88,9 @@ Function Set-CultureLegacy($culture) { $reg_key = 'HKCU:\Control Panel\International' $original_tmp = $env:TMP - $original_temp = $env:TEMP $env:TMP = $_remote_tmp - $env:TEMP = $_remote_tmp Add-Type -TypeDefinition $lctype_util $env:TMP = $original_tmp - $env:TEMP = $original_temp $lookup = New-Object Ansible.LocaleHelper($culture) # hex values are from http://www.pinvoke.net/default.aspx/kernel32/GetLocaleInfoEx.html diff --git a/lib/ansible/modules/windows/win_scheduled_task.ps1 b/lib/ansible/modules/windows/win_scheduled_task.ps1 index 8dd9323712..92e918ac02 100644 --- a/lib/ansible/modules/windows/win_scheduled_task.ps1 +++ b/lib/ansible/modules/windows/win_scheduled_task.ps1 @@ -125,12 +125,9 @@ public enum TASK_TRIGGER_TYPE2 // https://msdn.microsoft.com/en-us/library/windo "@ $original_tmp = $env:TMP -$original_temp = $env:TEMP $env:TMP = $_remote_tmp -$env:TEMP = $_remote_tmp Add-Type -TypeDefinition $task_enums $env:TMP = $original_tmp -$env:TEMP = $original_temp ######################## ### HELPER FUNCTIONS ### diff --git a/lib/ansible/modules/windows/win_scheduled_task_stat.ps1 b/lib/ansible/modules/windows/win_scheduled_task_stat.ps1 index 328c15dae5..71cbe7ebfe 100644 --- a/lib/ansible/modules/windows/win_scheduled_task_stat.ps1 +++ b/lib/ansible/modules/windows/win_scheduled_task_stat.ps1 @@ -70,12 +70,9 @@ public enum TASK_TRIGGER_TYPE2 "@ $original_tmp = $env:TMP -$original_temp = $env:TEMP $env:TMP = $_remote_tmp -$env:TEMP = $_remote_tmp Add-Type -TypeDefinition $task_enums $env:TMP = $original_tmp -$env:TEMP = $original_temp Function Get-PropertyValue($task_property, $com, $property) { $raw_value = $com.$property diff --git a/lib/ansible/modules/windows/win_user.ps1 b/lib/ansible/modules/windows/win_user.ps1 index 1c3964506a..715861e923 100644 --- a/lib/ansible/modules/windows/win_user.ps1 +++ b/lib/ansible/modules/windows/win_user.ps1 @@ -70,12 +70,9 @@ namespace Ansible '@ $original_tmp = $env:TMP - $original_temp = $env:TEMP $env:TMP = $_remote_tmp - $env:TEMP = $_remote_tmp Add-Type -TypeDefinition $platform_util $env:TMP = $original_tmp - $env:TEMP = $original_temp $handle = [IntPtr]::Zero $logon_res = [Ansible.WinUserPInvoke]::LogonUser($Username, $null, $Password, diff --git a/lib/ansible/modules/windows/win_user_right.ps1 b/lib/ansible/modules/windows/win_user_right.ps1 index 01d328025b..e896326e84 100644 --- a/lib/ansible/modules/windows/win_user_right.ps1 +++ b/lib/ansible/modules/windows/win_user_right.ps1 @@ -267,12 +267,9 @@ namespace Ansible "@ $original_tmp = $env:TMP -$original_temp = $env:TEMP $env:TMP = $_remote_tmp -$env:TEMP = $_remote_tmp Add-Type -TypeDefinition $sec_helper_util $env:TMP = $original_tmp -$env:TEMP = $original_temp Function Compare-UserList($existing_users, $new_users) { $added_users = [String[]]@() diff --git a/lib/ansible/modules/windows/win_whoami.ps1 b/lib/ansible/modules/windows/win_whoami.ps1 index 16988208a9..6c9965af7e 100644 --- a/lib/ansible/modules/windows/win_whoami.ps1 +++ b/lib/ansible/modules/windows/win_whoami.ps1 @@ -783,12 +783,9 @@ namespace Ansible '@ $original_tmp = $env:TMP -$original_temp = $env:TEMP $env:TMP = $_remote_tmp -$env:TEMP = $_remote_tmp Add-Type -TypeDefinition $session_util $env:TMP = $original_tmp -$env:TEMP = $original_temp $session_info = [Ansible.SessionUtil]::GetSessionInfo() |