@ -2,6 +2,8 @@
# This file is part of Ansible
# This file is part of Ansible
#
#
# Copyright 2015, Phil Schwartz <schwartzmx@gmail.com>
# Copyright 2015, Phil Schwartz <schwartzmx@gmail.com>
# Copyright 2015, Trond Hindenes
# Copyright 2015, Hans-Joachim Kliemeck <git@kliemeck.de>
#
#
# Ansible is free software: you can redistribute it and/or modify
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# it under the terms of the GNU General Public License as published by
@ -25,141 +27,96 @@
#Functions
#Functions
Function UserSearch
Function UserSearch
{
{
Param ( [ string ] $ A ccountName)
Param ( [ string ] $ a ccountName)
#Check if there's a realm specified
#Check if there's a realm specified
if ( $AccountName . Split ( " \ " ) . count -gt 1 )
{
$searchDomain = $false
if ( $AccountName . Split ( " \ " ) [ 0 ] -eq $env:COMPUTERNAME )
$searchDomainUPN = $false
if ( $accountName . Split ( " \ " ) . count -gt 1 )
{
{
$IsLocalAccount = $true
if ( $accountName . Split ( " \ " ) [ 0 ] -ne $env:COMPUTERNAME )
}
Else
{
{
$ I sDomainAccount = $true
$searchDomain = $true
$ IsUpn = $false
$ accountName = $accountName . split ( " \ " ) [ 1 ]
}
}
}
}
Elseif ( $ AccountName -contains " @ " )
Elseif ( $ accountName. contains ( " @ " ) )
{
{
$ I sDomainAccount = $true
$ search Domain = $true
$ IsUpn = $true
$ searchDomainUPN = $true
}
}
Else
Else
{
{
#Default to local user account
#Default to local user account
$accountname = $env:COMPUTERNAME + " \ " + $AccountName
$accountName = $env:COMPUTERNAME + " \ " + $accountName
$IsLocalAccount = $true
}
}
if ( $searchDomain -eq $false )
if ( $IsLocalAccount -eq $true )
{
{
$localaccount = get-wmiobject -class " Win32_UserAccount " -namespace " root\CIMV2 " -filter " (LocalAccount = True) " | where { $_ . Caption -eq $AccountName }
# do not use Win32_UserAccount, because e.g. SYSTEM (BUILTIN\SYSTEM or COMPUUTERNAME\SYSTEM) will not be listed. on Win32_Account groups will be listed too
$localaccount = get-wmiobject -class " Win32_Account " -namespace " root\CIMV2 " -filter " (LocalAccount = True) " | where { $_ . Caption -eq $accountName }
if ( $localaccount )
if ( $localaccount )
{
{
return $localaccount . Caption
return $localaccount . SID
}
$LocalGroup = get-wmiobject -class " Win32_Group " -namespace " root\CIMV2 " -filter " LocalAccount = True " | where { $_ . Caption -eq $AccountName }
if ( $LocalGroup )
{
return $LocalGroup . Caption
}
}
}
}
Else If ( ( $IsDomainAccount -eq $true ) -and ( $IsUpn -eq $false ) )
Else
{
{
#Search by samaccountname
#Search by samaccountname
$Searcher = [ adsisearcher ] " "
$Searcher = [ adsisearcher ] " "
$Searcher . Filter = " sAMAccountName= $( $accountname . split ( " \ " ) [ 1 ] ) "
$result = $Searcher . FindOne ( )
If ( $searchDomainUPN -eq $false ) {
$Searcher . Filter = " sAMAccountName= $( $accountName ) "
}
Else {
$Searcher . Filter = " userPrincipalName= $( $accountName ) "
}
$result = $Searcher . FindOne ( )
if ( $result )
if ( $result )
{
{
return $accountname
$user = $result . GetDirectoryEntry ( )
# get binary SID from AD account
$binarySID = $user . ObjectSid . Value
# convert to string SID
return ( New-Object System . Security . Principal . SecurityIdentifier ( $binarySID , 0 ) ) . Value
}
}
}
}
}
}
$params = Parse-Args $args ;
$params = Parse-Args $args ;
$result = New-Object psobject @ {
$result = New-Object PSObject ;
win_acl = New-Object psobject
Set-Attr $result " changed " $false ;
changed = $false
}
If ( $params . path ) {
$path = Get-Attr $params " path " -failifempty $true
$path = $params . path . toString ( )
$user = Get-Attr $params " user " -failifempty $true
$rights = Get-Attr $params " rights " -failifempty $true
If ( -Not ( Test-Path -Path $path ) ) {
$type = Get-Attr $params " type " -failifempty $true -validateSet " allow " , " deny " -resultobj $result
Fail-Json $result " $path file or directory does not exist on the host "
$state = Get-Attr $params " state " " present " -validateSet " present " , " absent " -resultobj $result
}
}
Else {
Fail-Json $result " missing required argument: path "
}
If ( $params . user ) {
$inherit = Get-Attr $params " inherit " " "
$user = UserSearch -AccountName ( $Params . User )
$propagation = Get-Attr $params " propagation " " None " -validateSet " None " , " NoPropagateInherit " , " InheritOnly " -resultobj $result
# Test that the user/group is resolvable on the local machine
If ( -Not ( Test-Path -Path $path ) ) {
if ( ! $user )
Fail-Json $result " $path file or directory does not exist on the host "
{
Fail-Json $result " $( $Params . User ) is not a valid user or group on the host machine or domain "
}
}
Else {
Fail-Json $result " missing required argument: user. specify the user or group to apply permission changes. "
}
}
If ( $params . type -eq " allow " ) {
# Test that the user/group is resolvable on the local machine
$type = $true
$sid = UserSearch -AccountName ( $user )
}
if ( ! $sid )
ElseIf ( $params . type -eq " deny " ) {
{
$type = $false
Fail-Json $result " $user is not a valid user or group on the host machine or domain "
}
Else {
Fail-Json $result " missing required argument: type. specify whether to allow or deny the specified rights. "
}
}
If ( $params . inherit ) {
If ( Test-Path -Path $path -PathType Leaf ) {
# If it's a file then no flags can be set or an exception will be thrown
If ( Test-Path -Path $path -PathType Leaf ) {
$inherit = " None "
$inherit = " None "
}
Else {
$inherit = $params . inherit . toString ( )
}
}
}
Else {
ElseIf ( $inherit -eq " " ) {
# If it's a file then no flags can be set or an exception will be thrown
If ( Test-Path -Path $path -PathType Leaf ) {
$inherit = " None "
}
Else {
$inherit = " ContainerInherit, ObjectInherit "
$inherit = " ContainerInherit, ObjectInherit "
}
}
If ( $params . propagation ) {
$propagation = $params . propagation . toString ( )
}
Else {
$propagation = " None "
}
If ( $params . rights ) {
$rights = $params . rights . toString ( )
}
Else {
Fail-Json $result " missing required argument: rights "
}
If ( $params . state -eq " absent " ) {
$state = " remove "
}
Else {
$state = " add "
}
}
Try {
Try {
@ -167,41 +124,42 @@ Try {
$InheritanceFlag = [ System.Security.AccessControl.InheritanceFlags ] $inherit
$InheritanceFlag = [ System.Security.AccessControl.InheritanceFlags ] $inherit
$PropagationFlag = [ System.Security.AccessControl.PropagationFlags ] $propagation
$PropagationFlag = [ System.Security.AccessControl.PropagationFlags ] $propagation
If ( $type ) {
If ( $type -eq " allow " ) {
$objType = [ System.Security.AccessControl.AccessControlType ] :: Allow
$objType = [ System.Security.AccessControl.AccessControlType ] :: Allow
}
}
Else {
Else {
$objType = [ System.Security.AccessControl.AccessControlType ] :: Deny
$objType = [ System.Security.AccessControl.AccessControlType ] :: Deny
}
}
$objUser = New-Object System . Security . Principal . NTAccount( $user )
$objUser = New-Object System . Security . Principal . SecurityIdentifier( $sid )
$objACE = New-Object System . Security . AccessControl . FileSystemAccessRule ( $objUser , $colRights , $InheritanceFlag , $PropagationFlag , $objType )
$objACE = New-Object System . Security . AccessControl . FileSystemAccessRule ( $objUser , $colRights , $InheritanceFlag , $PropagationFlag , $objType )
$objACL = Get-ACL $path
$objACL = Get-ACL $path
# Check if the ACE exists already in the objects ACL list
# Check if the ACE exists already in the objects ACL list
$match = $false
$match = $false
ForEach ( $rule in $objACL . Access ) {
ForEach ( $rule in $objACL . Access ) {
If ( ( $rule . FileSystemRights -eq $objACE . FileSystemRights ) -And ( $rule . AccessControlType -eq $objACE . AccessControlType ) -And ( $rule . IdentityReference -eq $objACE . IdentityReference ) -And ( $rule . IsInherited -eq $objACE . IsInherited ) -And ( $rule . InheritanceFlags -eq $objACE . InheritanceFlags ) -And ( $rule . PropagationFlags -eq $objACE . PropagationFlags ) ) {
$ruleIdentity = $rule . IdentityReference . Translate ( [ System.Security.Principal.SecurityIdentifier ] )
If ( ( $rule . FileSystemRights -eq $objACE . FileSystemRights ) -And ( $rule . AccessControlType -eq $objACE . AccessControlType ) -And ( $ruleIdentity -eq $objACE . IdentityReference ) -And ( $rule . IsInherited -eq $objACE . IsInherited ) -And ( $rule . InheritanceFlags -eq $objACE . InheritanceFlags ) -And ( $rule . PropagationFlags -eq $objACE . PropagationFlags ) ) {
$match = $true
$match = $true
Break
Break
}
}
}
}
If ( $state -eq " add " -And $match -eq $false ) {
If ( $state -eq " present " -And $match -eq $false ) {
Try {
Try {
$objACL . AddAccessRule ( $objACE )
$objACL . AddAccessRule ( $objACE )
Set-ACL $path $objACL
Set-ACL $path $objACL
$result . changed = $true
Set-Attr $result " changed " $true ;
}
}
Catch {
Catch {
Fail-Json $result " an exception occured when adding the specified rule "
Fail-Json $result " an exception occured when adding the specified rule "
}
}
}
}
ElseIf ( $state -eq " remove " -And $match -eq $true ) {
ElseIf ( $state -eq " absent " -And $match -eq $true ) {
Try {
Try {
$objACL . RemoveAccessRule ( $objACE )
$objACL . RemoveAccessRule ( $objACE )
Set-ACL $path $objACL
Set-ACL $path $objACL
$result . changed = $true
Set-Attr $result " changed " $true ;
}
}
Catch {
Catch {
Fail-Json $result " an exception occured when removing the specified rule "
Fail-Json $result " an exception occured when removing the specified rule "