2015-01-15 05:25:22 +01:00
#!powershell
# This file is part of Ansible
#
2015-06-19 00:25:05 +02:00
# Copyright 2015, Phil Schwartz <schwartzmx@gmail.com>
2015-10-18 17:06:28 +02:00
# Copyright 2015, Trond Hindenes
# Copyright 2015, Hans-Joachim Kliemeck <git@kliemeck.de>
2015-01-15 05:25:22 +01:00
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
2015-07-15 01:35:28 +02:00
2015-01-15 05:25:22 +01:00
# WANT_JSON
# POWERSHELL_COMMON
2015-07-15 01:35:28 +02:00
2015-01-15 05:25:22 +01:00
# win_acl module (File/Resources Permission Additions/Removal)
2015-07-15 01:35:28 +02:00
#Functions
Function UserSearch
{
2016-01-12 09:52:08 +01:00
Param ( [ string ] $accountName )
2015-07-15 01:35:28 +02:00
#Check if there's a realm specified
2016-01-12 09:52:08 +01:00
$searchDomain = $false
$searchDomainUPN = $false
if ( $accountName . Split ( " \ " ) . count -gt 1 )
2015-07-15 01:35:28 +02:00
{
2016-01-12 09:52:08 +01:00
if ( $accountName . Split ( " \ " ) [ 0 ] -ne $env:COMPUTERNAME )
2015-07-15 01:35:28 +02:00
{
2016-01-12 09:52:08 +01:00
$searchDomain = $true
$accountName = $accountName . split ( " \ " ) [ 1 ]
2015-07-15 01:35:28 +02:00
}
}
2016-01-12 09:52:08 +01:00
Elseif ( $accountName . contains ( " @ " ) )
2015-07-15 01:35:28 +02:00
{
2016-01-12 09:52:08 +01:00
$searchDomain = $true
$searchDomainUPN = $true
2015-07-15 01:35:28 +02:00
}
Else
{
#Default to local user account
2016-01-12 09:52:08 +01:00
$accountName = $env:COMPUTERNAME + " \ " + $accountName
2015-07-15 01:35:28 +02:00
}
2015-10-17 23:05:51 +02:00
2016-01-12 09:52:08 +01:00
if ( $searchDomain -eq $false )
2015-07-15 01:35:28 +02:00
{
2015-10-15 12:01:11 +02:00
# 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
2016-01-12 09:52:08 +01:00
$localaccount = get-wmiobject -class " Win32_Account " -namespace " root\CIMV2 " -filter " (LocalAccount = True) " | where { $_ . Caption -eq $accountName }
2015-07-15 01:35:28 +02:00
if ( $localaccount )
{
2015-10-15 12:01:11 +02:00
return $localaccount . SID
2015-07-15 01:35:28 +02:00
}
}
2016-01-12 09:52:08 +01:00
Else
2015-07-15 01:35:28 +02:00
{
#Search by samaccountname
$Searcher = [ adsisearcher ] " "
2015-10-17 23:05:51 +02:00
2016-01-12 09:52:08 +01:00
If ( $searchDomainUPN -eq $false ) {
$Searcher . Filter = " sAMAccountName= $( $accountName ) "
2015-10-17 23:05:51 +02:00
}
Else {
2016-01-12 09:52:08 +01:00
$Searcher . Filter = " userPrincipalName= $( $accountName ) "
2015-10-17 23:05:51 +02:00
}
$result = $Searcher . FindOne ( )
2015-07-15 01:35:28 +02:00
if ( $result )
{
2015-10-15 12:01:11 +02:00
$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
2015-07-15 01:35:28 +02:00
}
}
}
2015-01-15 05:25:22 +01:00
$params = Parse-Args $args ;
2015-10-18 00:00:47 +02:00
$result = New-Object PSObject ;
Set-Attr $result " changed " $false ;
$path = Get-Attr $params " path " -failifempty $true
$user = Get-Attr $params " user " -failifempty $true
$rights = Get-Attr $params " rights " -failifempty $true
2015-11-17 15:36:52 +01:00
$type = Get-Attr $params " type " -failifempty $true -validateSet " allow " , " deny " -resultobj $result
2015-10-18 00:00:47 +02:00
$state = Get-Attr $params " state " " present " -validateSet " present " , " absent " -resultobj $result
$inherit = Get-Attr $params " inherit " " "
$propagation = Get-Attr $params " propagation " " None " -validateSet " None " , " NoPropagateInherit " , " InheritOnly " -resultobj $result
If ( -Not ( Test-Path -Path $path ) ) {
Fail-Json $result " $path file or directory does not exist on the host "
2015-01-15 05:25:22 +01:00
}
2015-10-18 00:00:47 +02:00
# Test that the user/group is resolvable on the local machine
$sid = UserSearch -AccountName ( $user )
if ( ! $sid )
{
Fail-Json $result " $user is not a valid user or group on the host machine or domain "
2015-01-15 05:25:22 +01:00
}
2015-10-18 00:00:47 +02:00
If ( Test-Path -Path $path -PathType Leaf ) {
$inherit = " None "
2015-01-15 05:25:22 +01:00
}
2015-10-18 00:00:47 +02:00
ElseIf ( $inherit -eq " " ) {
$inherit = " ContainerInherit, ObjectInherit "
2015-01-15 05:25:22 +01:00
}
2015-07-15 01:35:28 +02:00
2015-01-15 05:25:22 +01:00
Try {
$colRights = [ System.Security.AccessControl.FileSystemRights ] $rights
$InheritanceFlag = [ System.Security.AccessControl.InheritanceFlags ] $inherit
$PropagationFlag = [ System.Security.AccessControl.PropagationFlags ] $propagation
2015-07-15 01:35:28 +02:00
2015-10-18 00:00:47 +02:00
If ( $type -eq " allow " ) {
2015-01-15 05:25:22 +01:00
$objType = [ System.Security.AccessControl.AccessControlType ] :: Allow
}
Else {
$objType = [ System.Security.AccessControl.AccessControlType ] :: Deny
}
2015-07-15 01:35:28 +02:00
2015-10-15 12:01:11 +02:00
$objUser = New-Object System . Security . Principal . SecurityIdentifier ( $sid )
2015-01-15 05:25:22 +01:00
$objACE = New-Object System . Security . AccessControl . FileSystemAccessRule ( $objUser , $colRights , $InheritanceFlag , $PropagationFlag , $objType )
2015-07-15 18:42:27 +02:00
$objACL = Get-ACL $path
2015-07-15 01:35:28 +02:00
2015-06-19 00:25:05 +02:00
# Check if the ACE exists already in the objects ACL list
$match = $false
ForEach ( $rule in $objACL . Access ) {
2015-10-15 12:01:11 +02:00
$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 ) ) {
2015-06-19 00:25:05 +02:00
$match = $true
Break
}
}
2015-10-18 00:00:47 +02:00
If ( $state -eq " present " -And $match -eq $false ) {
2015-01-15 05:25:22 +01:00
Try {
$objACL . AddAccessRule ( $objACE )
2015-07-15 18:42:27 +02:00
Set-ACL $path $objACL
2015-10-18 00:00:47 +02:00
Set-Attr $result " changed " $true ;
2015-01-15 05:25:22 +01:00
}
Catch {
2015-06-19 00:25:05 +02:00
Fail-Json $result " an exception occured when adding the specified rule "
2015-01-15 05:25:22 +01:00
}
}
2015-10-18 00:00:47 +02:00
ElseIf ( $state -eq " absent " -And $match -eq $true ) {
2015-01-15 05:25:22 +01:00
Try {
$objACL . RemoveAccessRule ( $objACE )
2015-07-15 18:42:27 +02:00
Set-ACL $path $objACL
2015-10-18 00:00:47 +02:00
Set-Attr $result " changed " $true ;
2015-01-15 05:25:22 +01:00
}
Catch {
2015-06-19 00:25:05 +02:00
Fail-Json $result " an exception occured when removing the specified rule "
2015-01-15 05:25:22 +01:00
}
}
2015-06-19 00:25:05 +02:00
Else {
# A rule was attempting to be added but already exists
If ( $match -eq $true ) {
Exit-Json $result " the specified rule already exists "
}
# A rule didn't exist that was trying to be removed
Else {
Exit-Json $result " the specified rule does not exist "
}
}
2015-01-15 05:25:22 +01:00
}
Catch {
2015-10-18 00:00:47 +02:00
Fail-Json $result " an error occured when attempting to $state $rights permission(s) on $path for $user "
2015-01-15 05:25:22 +01:00
}
2015-07-15 01:35:28 +02:00
2015-10-17 23:05:51 +02:00
Exit-Json $result