Comments (6)
@jborean93 I've implemented the reset functionality in my win_acl version. See additional improvements in my issue: #110
It still needs extensive testing, and the documentation part of the new state value.
Let me know how to contribute.
here is the win_acl.ps1 content:
#!powershell
# Copyright: (c) 2015, Phil Schwartz <[email protected]>
# Copyright: (c) 2015, Trond Hindenes
# Copyright: (c) 2015, Hans-Joachim Kliemeck <[email protected]>
# Revorked the logic to more exact handle of rights and proper return values,
# Added state='reset' option to reset the ACL to the inherited ACEs only.
# https://github.com/ansible-collections/ansible.windows/issues/18
# Added support of environment variables for Path
# https://github.com/ansible/ansible/issues/68597
# Laszlo Papp <[email protected]>
# 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"
# win_acl module (File/Resources Permission Additions/Removal)
#Functions
function Get-UserSID {
param(
[String]$AccountName
)
$userSID = $null
$searchAppPools = $false
if ($AccountName.Split("\").Count -gt 1) {
if ($AccountName.Split("\")[0] -eq "IIS APPPOOL") {
$searchAppPools = $true
$AccountName = $AccountName.Split("\")[1]
}
}
if ($searchAppPools) {
Import-Module -Name WebAdministration
$testIISPath = Test-Path -LiteralPath "IIS:"
if ($testIISPath) {
$appPoolObj = Get-ItemProperty -LiteralPath "IIS:\AppPools\$AccountName"
$userSID = $appPoolObj.applicationPoolSid
}
}
else {
$userSID = Convert-ToSID -account_name $AccountName
}
return $userSID
}
$params = Parse-Args $args
Function SetPrivilegeTokens() {
# Set privilege tokens only if admin.
# Admins would have these privs or be able to set these privs in the UI Anyway
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
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
$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
}
}
}
}
$result = @{
changed = $false
msg = ""
}
$path = (New-Object -ComObject Wscript.Shell).ExpandEnvironmentStrings(Get-AnsibleParam -obj $params -name "path" -type "str" -failifempty $true)
# We mount the HKCR, HKU, and HKCC registry hives so PS can access them.
# Network paths have no qualifiers so we use -EA SilentlyContinue to ignore that
$path_qualifier = Split-Path -Path $path -Qualifier -ErrorAction SilentlyContinue
if ($path_qualifier -eq "HKCR:" -and (-not (Test-Path -LiteralPath HKCR:\))) {
New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT > $null
}
if ($path_qualifier -eq "HKU:" -and (-not (Test-Path -LiteralPath HKU:\))) {
New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS > $null
}
if ($path_qualifier -eq "HKCC:" -and (-not (Test-Path -LiteralPath HKCC:\))) {
New-PSDrive -Name HKCC -PSProvider Registry -Root HKEY_CURRENT_CONFIG > $null
}
If (-Not (Test-Path -LiteralPath $path)) {
Fail-Json -obj $result -message "$path does not exist on the host"
}
$path_item = Get-Item -LiteralPath $path -Force
$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","present","reset"
if($state -eq 'reset'){
SetPrivilegeTokens
if(!(Get-Item $path).PSParentPath){
Fail-Json -obj $result -message "$path is a root folder! Cannot reset ACL!"
}
try
{
$objACL = Get-ACL -LiteralPath $path
if($objACL.AreAccessRulesProtected){
$result.changed=$true
$objacl.SetAccessRuleProtection($false,$false)
If ($path_item.PSProvider.Name -eq "Registry") {
Set-ACL -LiteralPath $path -AclObject $objACL
} else {
(Get-Item -LiteralPath $path).SetAccessControl($objACL)
}
$objACL = Get-ACL -LiteralPath $path
}
$changed=$false
$objACL.Access|?{!$_.isinherited}|%{
$result.changed=$true
$changed=$true
[void]$objACL.RemoveAccessRule($_)
}
if($changed){
If ($path_item.PSProvider.Name -eq "Registry") {
Set-ACL -LiteralPath $path -AclObject $objACL
} else {
(Get-Item -LiteralPath $path).SetAccessControl($objACL)
}
}
Exit-Json -obj $result
} catch {
Fail-Json -obj $result -message "an exception occurred when resetting the ACL - $($_.Exception.Message)"
}
}
$user = Get-AnsibleParam -obj $params -name "user" -type "str" -failifempty $true
$rights = Get-AnsibleParam -obj $params -name "rights" -type "str" -failifempty $true
$type = Get-AnsibleParam -obj $params -name "type" -type "str" -failifempty $true -validateset "allow","deny"
$inherit = Get-AnsibleParam -obj $params -name "inherit" -type "str"
$propagation = Get-AnsibleParam -obj $params -name "propagation" -type "str" -default "None" -validateset "InheritOnly","None","NoPropagateInherit"
# Reset:
# Test that the user/group is resolvable on the local machine
$sid = Get-UserSID -AccountName $user
if (!$sid) {
Fail-Json -obj $result -message "$user is not a valid user or group on the host machine or domain"
}
If (Test-Path -LiteralPath $path -PathType Leaf) {
$inherit = "None"
}
ElseIf ($null -eq $inherit) {
$inherit = "ContainerInherit, ObjectInherit"
}
# Bug in Set-Acl, Get-Acl where -LiteralPath only works for the Registry provider if the location is in that root
# qualifier. We also don't have a qualifier for a network path so only change if not null
if ($null -ne $path_qualifier) {
Push-Location -LiteralPath $path_qualifier
}
$myMessage=""
Try {
SetPrivilegeTokens
$PathType='FileSystem'
If ($path_item.PSProvider.Name -eq "Registry") {$PathType='Registry'}
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]$inherit
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]$propagation
If ($type -eq "deny") {
$objType =[System.Security.AccessControl.AccessControlType]::Deny
}
Else {
$objType =[System.Security.AccessControl.AccessControlType]::Allow
}
$objUser = New-Object System.Security.Principal.SecurityIdentifier($sid)
$objACE = New-Object System.Security.AccessControl."$($PathType)AccessRule" ($objUser, $Rights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = Get-ACL -LiteralPath $path
$objOldRules=$objACL.AccessToString
$objRights=$null
if($PathType -eq 'Registry'){
$objRights=[System.Security.AccessControl.RegistryRights]$rights
}else{
$objRights=[System.Security.AccessControl.FileSystemRights]$rights
}
Try {
$ar=$null
If ($state -eq "present"){
$objACL.AddAccessRule($objACE)
} else {
[void]$objACL.RemoveAccessRule($objACE)
$objACL.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier])|?{
($_.IdentityReference.Value -eq $sid) -and
(($_.PropagationFlags -band [System.Security.AccessControl.PropagationFlags]'InheritOnly') -ne
[System.Security.AccessControl.PropagationFlags]'InheritOnly') -and
($_.AccessControlType -eq $objType)
}|%{
if(!$ar){$ar=$_."$($PathType)Rights"}else{$ar=$ar -bor $_."$($PathType)Rights"}
}
}
$myMessage="Actual rights: "
$objACL.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier])|?{$_.IdentityReference.Value -eq $sid}|%{
$myMessage += "$($_.AccessControlType): $($_."$($PathType)Rights"): $(if($_.IsInherited){'Inherited,'}) $($_.InheritanceFlags); "
}
if($objOldRules -eq $objACL.AccessToString){
$result.changed = $false
$result.msg=$myMessage
} else {
If ($path_item.PSProvider.Name -eq "Registry") {
Set-ACL -LiteralPath $path -AclObject $objACL
} else {
(Get-Item -LiteralPath $path).SetAccessControl($objACL)
}
$result.changed = $true
$myMessage=$myMessage.Replace('Actual rights: ','New rights: ')
$result.msg=$myMessage
}
if(($ar) -and (([int]($ar -band $objRights).value__) -ne 0 ) -and ($state -ne "present")){
$result.stderr="$user still has $ar rights!"
$result.msg=$myMessage
Fail-Json -obj $result -message "$user still has $ar rights! $myMessage"
}
}
Catch {
Fail-Json -obj $result -message "an exception occurred when adding the specified rule - $($_.Exception.Message)"
}
}
Catch {
Fail-Json -obj $result -message "an error occurred when attempting to $state $rights permission(s) on $path for $user - $($_.Exception.Message)"
}
Finally {
# Make sure we revert the location stack to the original path just for cleanups sake
if ($null -ne $path_qualifier) {
Pop-Location
}
}
Exit-Json -obj $result
from ansible.windows.
From @dagwieers on Oct 05, 2018 13:20
needs_contributor
from ansible.windows.
Hello,
What exactly "reset" should mean?
- reset as remove all explicit rights and allow inheritance if not allowed,
- reset as revert to the state of install-time
from ansible.windows.
Based on the context of icacls it would be
Replaces ACLs with default inherited ACLs for all matching files.
So your first option.
from ansible.windows.
Well this may be dangerous when used on system folders like %SystemRoot% or %ProgramFiles% and so on...
Should the solution use the Linux mindset: "You're the root (Admin), you should know what you're doing", or the Microsoft one: "Let me protect from yourself" ?
from ansible.windows.
@placame the short answer is that you fork this repository in GitHub, make your changes, and submit a pull request.
For the longer answer and more details, see https://github.com/ansible-collections/ansible.windows#contributing-to-this-collection
from ansible.windows.
Related Issues (20)
- win_find cant find mapped drive nor networkshare HOT 9
- RFI: Does State:Searched and State:Installed work together HOT 1
- [Windows 11] CS1504 Failed to compile C# code HOT 11
- Error Installing Windows Server Updates with Ansible HOT 2
- Install Application with InstallAnywhere HOT 1
- win_get_url does not respect content-disposition HOT 1
- win_update failed since ansible 7.7.0 HOT 3
- win_update show different trigger in Event Viewer HOT 1
- ansible.windows.win_powershell misinterprets block scalar (string block) HOT 2
- win_package: support checksum verification HOT 2
- intermittent winrm connection failures with large hosts count HOT 8
- intermittent "unable to delete temporary file" errors HOT 9
- Win_updates fail with "Exception from HRESULT: 0x80072EE2" HOT 2
- Windows Update Module not installing any updates HOT 4
- Windows update failes due to update loop HOT 3
- win_environment : Maybe add an option to read variable content ? HOT 5
- Error during machine sid retrieval: An error (1788) occurred while enumerating the group membership. The member's SID could not be resolved. HOT 8
- Access denied after renaming windows host : Server not found in Kerberos database HOT 10
- Failed to create temporary directory when running win_template module against Windows Server 2019 HOT 10
- win_copy doesnt work when folder name has special character HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ansible.windows.