ansible-later/env_27/lib/python2.7/site-packages/ansible/modules/windows/win_audit_rule.ps1
2019-04-11 13:00:36 +02:00

194 lines
6.7 KiB
PowerShell

#!powershell
# Copyright: (c) 2017, Noah Sparks <nsparks@outlook.com>
# 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.SID
$params = Parse-Args -arguments $args -supports_check_mode $true
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
# module parameters
$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -aliases "destination","dest"
$user = Get-AnsibleParam -obj $params -name "user" -type "str" -failifempty $true
$rights = Get-AnsibleParam -obj $params -name "rights" -type "list"
$inheritance_flags = Get-AnsibleParam -obj $params -name "inheritance_flags" -type "list" -default 'ContainerInherit','ObjectInherit'
$propagation_flags = Get-AnsibleParam -obj $params -name "propagation_flags" -type "str" -default "none" -ValidateSet 'InheritOnly','None','NoPropagateInherit'
$audit_flags = Get-AnsibleParam -obj $params -name "audit_flags" -type "list" -default 'success'
$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset 'present','absent'
#Make sure target path is valid
If (-not (Test-Path -Path $path) )
{
Fail-Json -obj $result -message "defined path ($path) is not found/invalid"
}
#function get current audit rules and convert to hashtable
Function Get-CurrentAuditRules ($path) {
Try {
$ACL = Get-Acl $path -Audit
}
Catch {
Return "Unable to retrieve the ACL on $Path"
}
$HT = Foreach ($Obj in $ACL.Audit)
{
@{
user = $Obj.IdentityReference.ToString()
rights = ($Obj | Select-Object -expand "*rights").ToString()
audit_flags = $Obj.AuditFlags.ToString()
is_inherited = $Obj.IsInherited.ToString()
inheritance_flags = $Obj.InheritanceFlags.ToString()
propagation_flags = $Obj.PropagationFlags.ToString()
}
}
If (-Not $HT)
{
"No audit rules defined on $path"
}
Else {$HT}
}
$result = @{
changed = $false
current_audit_rules = Get-CurrentAuditRules $path
}
#Make sure identity is valid and can be looked up
Try {
$SID = Convert-ToSid $user
}
Catch {
Fail-Json -obj $result -message "Failed to lookup the identity ($user) - $($_.exception.message)"
}
#get the path type
$ItemType = (Get-Item $path).GetType()
switch ($ItemType)
{
([Microsoft.Win32.RegistryKey]) {$registry = $true; $result.path_type = 'registry'}
([System.IO.FileInfo]) {$file = $true; $result.path_type = 'file'}
([System.IO.DirectoryInfo]) {$result.path_type = 'directory'}
}
#Get current acl/audit rules on the target
Try {
$ACL = Get-Acl $path -Audit
}
Catch {
Fail-Json -obj $result -message "Unable to retrieve the ACL on $Path - $($_.Exception.Message)"
}
#configure acl object to remove the specified user
If ($state -eq 'absent')
{
#Try and find an identity on the object that matches user
#We skip inherited items since we can't remove those
$ToRemove = ($ACL.Audit | Where-Object {$_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) -eq $SID -and
$_.IsInherited -eq $false}).IdentityReference
#Exit with changed false if no identity is found
If (-Not $ToRemove)
{
$result.current_audit_rules = Get-CurrentAuditRules $path
Exit-Json -obj $result
}
#update the ACL object if identity found
Try
{
$ToRemove | ForEach-Object { $ACL.PurgeAuditRules($_) }
}
Catch
{
$result.current_audit_rules = Get-CurrentAuditRules $path
Fail-Json -obj $result -message "Failed to remove audit rule: $($_.Exception.Message)"
}
}
Else
{
If ($registry)
{
$PossibleRights = [System.Enum]::GetNames([System.Security.AccessControl.RegistryRights])
Foreach ($right in $rights)
{
if ($right -notin $PossibleRights)
{
Fail-Json -obj $result -message "$right does not seem to be a valid REGISTRY right"
}
}
$NewAccessRule = New-Object System.Security.AccessControl.RegistryAuditRule($user,$rights,$inheritance_flags,$propagation_flags,$audit_flags)
}
Else
{
$PossibleRights = [System.Enum]::GetNames([System.Security.AccessControl.FileSystemRights])
Foreach ($right in $rights)
{
if ($right -notin $PossibleRights)
{
Fail-Json -obj $result -message "$right does not seem to be a valid FILE SYSTEM right"
}
}
If ($file -and $inheritance_flags -ne 'none')
{
Fail-Json -obj $result -message "The target type is a file. inheritance_flags must be changed to 'none'"
}
$NewAccessRule = New-Object System.Security.AccessControl.FileSystemAuditRule($user,$rights,$inheritance_flags,$propagation_flags,$audit_flags)
}
#exit here if any existing rule matches defined rule since no change is needed
#if we need to ignore inherited rules in the future, this would be where to do it
#Just filter out inherited rules from $ACL.Audit
Foreach ($group in $ACL.Audit | Where-Object {$_.IsInherited -eq $false})
{
If (
($group | Select-Object -expand "*Rights") -eq ($NewAccessRule | Select-Object -expand "*Rights") -and
$group.AuditFlags -eq $NewAccessRule.AuditFlags -and
$group.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]) -eq $SID -and
$group.InheritanceFlags -eq $NewAccessRule.InheritanceFlags -and
$group.PropagationFlags -eq $NewAccessRule.PropagationFlags
)
{
$result.current_audit_rules = Get-CurrentAuditRules $path
Exit-Json -obj $result
}
}
#try and set the acl object. AddAuditRule allows for multiple entries to exist under the same
#identity...so if someone wanted success: write and failure: delete for example, that setup would be
#possible. The alternative is SetAuditRule which would instead modify an existing rule and not allow
#for setting the above example.
Try
{
$ACL.AddAuditRule($NewAccessRule)
}
Catch
{
Fail-Json -obj $result -message "Failed to set the audit rule: $($_.Exception.Message)"
}
}
#finally set the permissions
Try {
Set-Acl -Path $path -ACLObject $ACL -WhatIf:$check_mode
}
Catch {
$result.current_audit_rules = Get-CurrentAuditRules $path
Fail-Json -obj $result -message "Failed to apply audit change: $($_.Exception.Message)"
}
#exit here after a change is applied
$result.current_audit_rules = Get-CurrentAuditRules $path
$result.changed = $true
Exit-Json -obj $result