change to shouldprocess, workaround set-acl issue on win7, use approved verb (#164)

PowerShell/Win32-OpenSSH#758
PowerShell/Win32-OpenSSH#749
PowerShell/Win32-OpenSSH#745
This commit is contained in:
Yanbing 2017-06-11 09:57:38 -07:00 committed by Manoj Ampalam
parent 91f9c71021
commit 5bea3a3759
4 changed files with 302 additions and 216 deletions

View File

@ -1,12 +1,14 @@
param ([switch]$Quiet)
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param ()
Set-StrictMode -Version 2.0
If (!(Test-Path variable:PSScriptRoot)) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition}
Import-Module $PSScriptRoot\OpenSSHUtils.psm1 -Force -DisableNameChecking
Import-Module $PSScriptRoot\OpenSSHUtils -Force
#check sshd config file
$sshdConfigPath = join-path $PSScriptRoot "sshd_config"
if(Test-Path $sshdConfigPath -PathType Leaf)
{
Fix-HostSSHDConfigPermissions -FilePath $sshdConfigPath @psBoundParameters
Repair-SshdConfigPermission -FilePath $sshdConfigPath @psBoundParameters
}
else
{
@ -14,16 +16,16 @@ else
}
#check host keys
<#$result = 'n'
if (-not $Quiet) {
Do
{
$input = Read-Host -Prompt "Did you register host private keys with ssh-agent? [Yes] Y; [No] N"
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
<#
$warning = @"
To keep the host private keys secure, it is recommended to register them with ssh-agent following
steps in link https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH.
If you choose not to register the keys with ssh-agent, please grant sshd read access to the private host keys after run this script.
"@
$prompt = "Did you register host private keys with ssh-agent?"
$description = "Grant sshd read access to the private host keys"
if($result.ToLower().Startswith('n'))
if($pscmdlet.ShouldProcess($description, $prompt, $warning))
{
$warning = @"
To keep the host private keys secure, it is recommended to register them with ssh-agent following
@ -35,7 +37,7 @@ If you choose not to register the keys with ssh-agent, please grant sshd read ac
}#>
Get-ChildItem $PSScriptRoot\ssh_host_*_key -ErrorAction SilentlyContinue | % {
Fix-HostKeyPermissions -FilePath $_.FullName @psBoundParameters
Repair-SshdHostKeyPermission -FilePath $_.FullName @psBoundParameters
}
@ -50,7 +52,7 @@ Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
$filePath = Join-Path $userProfilePath .ssh\authorized_keys
if(Test-Path $filePath -PathType Leaf)
{
Fix-AuthorizedKeyPermissions -FilePath $filePath @psBoundParameters
Repair-AuthorizedKeyPermission -FilePath $filePath @psBoundParameters
}
}

View File

@ -1,15 +1,17 @@
param ([switch]$Quiet)
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param ()
Set-StrictMode -Version 2.0
If (!(Test-Path variable:PSScriptRoot)) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition}
Import-Module $PSScriptRoot\OpenSSHUtils.psm1 -Force -DisableNameChecking
Import-Module $PSScriptRoot\OpenSSHUtils -Force
if(Test-Path ~\.ssh\config -PathType Leaf)
{
Fix-UserSSHConfigPermissions -FilePath ~\.ssh\config @psBoundParameters
Repair-UserSshConfigPermission -FilePath ~\.ssh\config @psBoundParameters
}
Get-ChildItem ~\.ssh\* -Include "id_rsa","id_dsa" -ErrorAction SilentlyContinue | % {
Fix-UserKeyPermissions -FilePath $_.FullName @psBoundParameters
Repair-UserKeyPermission -FilePath $_.FullName @psBoundParameters
}
Write-Host " Done."

View File

@ -0,0 +1,44 @@
#
# Module manifest for module 'OpenSSHUtils'
#
# Generated on: 6/9/2017
#
@{
# Script module or binary module file associated with this manifest
ModuleToProcess = 'OpenSSHUtils.psm1'
# Version number of this module.
ModuleVersion = '1.0.0.1'
# ID used to uniquely identify this module
GUID = '08285dee-3d08-476b-8948-1a7e2562c079'
# Author of this module
Author = 'Yanbing Wang'
# Company or vendor of this module
CompanyName = ''
# Copyright statement for this module
Copyright = ''
# Description of the functionality provided by this module
Description = 'Configure OpenSSH for Windows related security settings like file owner and permissions.'
# Functions to export from this module
FunctionsToExport = '*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = '*'
# Aliases to export from this module
AliasesToExport = '*'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0'
}

View File

@ -1,4 +1,5 @@
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
Set-StrictMode -Version 2.0
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminsAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
$everyone = New-Object System.Security.Principal.NTAccount("EveryOne")
@ -6,78 +7,57 @@ $sshdAccount = New-Object System.Security.Principal.NTAccount("NT SERVICE","sshd
<#
.Synopsis
Fix-HostSSHDConfigPermissions
fix the file owner and permissions of sshd_config
Repair-SshdConfigPermission
Repair the file owner and Permission of sshd_config
#>
function Fix-HostSSHDConfigPermissions
function Repair-SshdConfigPermission
{
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
[string]$FilePath)
if ($PSVersionTable.CLRVersion.Major -gt 2)
{
Fix-FilePermissions -Owners $systemAccount,$adminsAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
}
else
{
Fix-FilePermissions -Owners $adminsAccount, $systemAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
}
Repair-FilePermission -Owners $systemAccount,$adminsAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
}
<#
.Synopsis
Fix-HostKeyPermissions
fix the file owner and permissions of host private and public key
Repair-SshdHostKeyPermission
Repair the file owner and Permission of host private and public key
-FilePath: The path of the private host key
#>
function Fix-HostKeyPermissions
function Repair-SshdHostKeyPermission
{
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
$parameters = $PSBoundParameters
if($parameters["FilePath"].EndsWith(".pub"))
{
$parameters["FilePath"] = $parameters["FilePath"].Replace(".pub", "")
}
if ($PSVersionTable.CLRVersion.Major -gt 2)
{
Fix-FilePermissions -Owners $systemAccount,$adminsAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
}
else
{
# issue in ps 2.0: system account is not allowed to set to a owner of the file
Fix-FilePermissions -Owners $adminsAccount, $systemAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
}
[string]$FilePath)
$parameters["FilePath"] += ".pub"
if ($PSVersionTable.CLRVersion.Major -gt 2)
if($PSBoundParameters["FilePath"].EndsWith(".pub"))
{
Fix-FilePermissions -Owners $systemAccount,$adminsAccount -ReadAccessOK $everyone -ReadAccessNeeded $sshdAccount @parameters
}
else
{
Fix-FilePermissions -Owners $adminsAccount,$systemAccount -ReadAccessOK $everyone -ReadAccessNeeded $sshdAccount @parameters
$PSBoundParameters["FilePath"] = $PSBoundParameters["FilePath"].Replace(".pub", "")
}
Repair-FilePermission -Owners $systemAccount,$adminsAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
$PSBoundParameters["FilePath"] += ".pub"
Repair-FilePermission -Owners $systemAccount,$adminsAccount -ReadAccessOK $everyone -ReadAccessNeeded $sshdAccount @psBoundParameters
}
<#
.Synopsis
Fix-AuthorizedKeyPermissions
fix the file owner and permissions of authorized_keys
Repair-AuthorizedKeyPermission
Repair the file owner and Permission of authorized_keys
#>
function Fix-AuthorizedKeyPermissions
function Repair-AuthorizedKeyPermission
{
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
[string]$FilePath)
if(-not (Test-Path $FilePath -PathType Leaf))
{
@ -101,7 +81,7 @@ function Fix-AuthorizedKeyPermissions
$account = Get-UserAccount -UserSid $userSid
if($account)
{
Fix-FilePermissions -Owners $account,$adminsAccount,$systemAccount -AnyAccessOK $account -ReadAccessNeeded $sshdAccount @psBoundParameters
Repair-FilePermission -Owners $account,$adminsAccount,$systemAccount -AnyAccessOK $account -ReadAccessNeeded $sshdAccount @psBoundParameters
}
else
{
@ -116,51 +96,53 @@ function Fix-AuthorizedKeyPermissions
<#
.Synopsis
Fix-UserKeyPermissions
fix the file owner and permissions of user config
Repair-UserKeyPermission
Repair the file owner and Permission of user config
-FilePath: The path of the private user key
-User: The user associated with this ssh config
#>
function Fix-UserKeyPermissions
function Repair-UserKeyPermission
{
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
[System.Security.Principal.NTAccount] $User = $currentUser)
$parameters = $PSBoundParameters
if($parameters["FilePath"].EndsWith(".pub"))
if($PSBoundParameters["FilePath"].EndsWith(".pub"))
{
$parameters["FilePath"] = $parameters["FilePath"].Replace(".pub", "")
$PSBoundParameters["FilePath"] = $PSBoundParameters["FilePath"].Replace(".pub", "")
}
Fix-FilePermissions -Owners $currentUser, $adminsAccount,$systemAccount -AnyAccessOK $currentUser @psBoundParameters
Repair-FilePermission -Owners $User, $adminsAccount,$systemAccount -AnyAccessOK $User @psBoundParameters
$parameters["FilePath"] += ".pub"
Fix-FilePermissions -Owners $currentUser, $adminsAccount,$systemAccount -AnyAccessOK $currentUser -ReadAccessOK $everyone @parameters
$PSBoundParameters["FilePath"] += ".pub"
Repair-FilePermission -Owners $User, $adminsAccount,$systemAccount -AnyAccessOK $User -ReadAccessOK $everyone @psBoundParameters
}
<#
.Synopsis
Fix-UserSSHConfigPermissions
fix the file owner and permissions of user config
Repair-UserSSHConfigPermission
Repair the file owner and Permission of user config
#>
function Fix-UserSSHConfigPermissions
function Repair-UserSshConfigPermission
{
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
Fix-FilePermissions -Owners $currentUser,$adminsAccount,$systemAccount -AnyAccessOK $currentUser @psBoundParameters
[string]$FilePath)
Repair-FilePermission -Owners $currentUser,$adminsAccount,$systemAccount -AnyAccessOK $currentUser @psBoundParameters
}
<#
.Synopsis
Fix-FilePermissionInternal
Repair-FilePermissionInternal
Only validate owner and ACEs of the file
#>
function Fix-FilePermissions
function Repair-FilePermission
{
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
@ -169,8 +151,7 @@ function Fix-FilePermissions
[System.Security.Principal.NTAccount[]] $Owners = $currentUser,
[System.Security.Principal.NTAccount[]] $AnyAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessNeeded,
[switch] $Quiet
[System.Security.Principal.NTAccount[]] $ReadAccessNeeded
)
if(-not (Test-Path $FilePath -PathType Leaf))
@ -180,20 +161,21 @@ function Fix-FilePermissions
}
Write-host " [*] $FilePath"
$return = Fix-FilePermissionInternal @PSBoundParameters
$return = Repair-FilePermissionInternal @PSBoundParameters
if($return -contains $true)
{
#Write-host "Re-check the health of file $FilePath"
Fix-FilePermissionInternal @PSBoundParameters
Repair-FilePermissionInternal @PSBoundParameters
}
}
<#
.Synopsis
Fix-FilePermissionInternal
Repair-FilePermissionInternal
#>
function Fix-FilePermissionInternal {
function Repair-FilePermissionInternal {
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
@ -202,45 +184,42 @@ function Fix-FilePermissionInternal {
[System.Security.Principal.NTAccount[]] $Owners = $currentUser,
[System.Security.Principal.NTAccount[]] $AnyAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessNeeded,
[switch] $Quiet
[System.Security.Principal.NTAccount[]] $ReadAccessNeeded
)
$acl = Get-Acl $FilePath
$needChange = $false
$health = $true
if ($Quiet)
{
$result = 'Y'
}
$paras = @{}
$PSBoundParameters.GetEnumerator() | % { if((-not $_.key.Contains("Owners")) -and (-not $_.key.Contains("Access"))) { $paras.Add($_.key,$_.Value) } }
$validOwner = $owners | ? { $_.equals([System.Security.Principal.NTAccount]$acl.owner)}
if($validOwner -eq $null)
{
if (-not $Quiet) {
$warning = "Current owner: '$($acl.Owner)'. '$($Owners[0])' should own $FilePath."
Do {
Write-Warning $warning
$input = Read-Host -Prompt "Shall I set the file owner? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
if($result.ToLower().Startswith('y'))
{
$needChange = $true
{
$caption = "Current owner: '$($acl.Owner)'. '$($Owners[0])' should own '$FilePath'."
$prompt = "Shall I set the file owner?"
$description = "Set '$($Owners[0])' as owner of '$FilePath'."
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
{
Enable-Privilege SeRestorePrivilege | out-null
$acl.SetOwner($Owners[0])
Write-Host "'$($Owners[0])' now owns $FilePath. " -ForegroundColor Green
Set-Acl -Path $FilePath -AclObject $acl -ErrorVariable e -Confirm:$false
if($e)
{
Write-Warning "Set owner failed with error: $($e[0].ToString())."
}
else
{
Write-Host "'$($Owners[0])' now owns '$FilePath'. " -ForegroundColor Green
}
}
else
{
$health = $false
Write-Host "The owner is still set to '$($acl.Owner)'." -ForegroundColor Yellow
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
{
Write-Host "The owner is still set to '$($acl.Owner)'." -ForegroundColor Yellow
}
}
}
@ -261,7 +240,7 @@ function Fix-FilePermissionInternal {
$specialIdRefs = "ALL APPLICATION PACKAGES","ALL RESTRICTED APPLICATION PACKAGES"
foreach($a in $acl.Access)
{
{
if($realAnyAccessOKList -and (($realAnyAccessOKList | ? { $_.equals($a.IdentityReference)}) -ne $null))
{
#ignore those accounts listed in the AnyAccessOK list.
@ -284,39 +263,28 @@ function Fix-FilePermissionInternal {
(-not (([System.UInt32]$a.FileSystemRights.value__) -band (-bnot $ReadAccessPerm))))
{
continue;
}
$warning = "'$($a.IdentityReference)' has the following access to $($FilePath): '$($a.FileSystemRights)'."
}
if($a.IsInherited)
{
if($needChange)
{
Set-Acl -Path $FilePath -AclObject $acl
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $acl -ErrorVariable e -Confirm:$false
if($e)
{
Write-Warning "Repair permission failed with error: $($e[0].ToString())."
}
}
$message = @"
$warning
Need to remove inheritance to fix it.
"@
return Remove-RuleProtection -FilePath $FilePath -Message $message -Quiet:$Quiet
}
if (-not $Quiet) {
Do {
Write-Warning $warning
$input = Read-Host -Prompt "Shall I make it Read only? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
return Remove-RuleProtection @paras
}
$caption = "'$($a.IdentityReference)' has the following access to '$FilePath': '$($a.FileSystemRights)'."
$prompt = "Shall I make it Read only?"
$description = "Set'$($a.IdentityReference)' Read access only to '$FilePath'. "
if($result.ToLower().Startswith('y'))
{
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
{
$needChange = $true
$idRefShortValue = ($a.IdentityReference.Value).split('\')[-1]
if ($specialIdRefs -icontains $idRefShortValue )
@ -329,7 +297,7 @@ Need to remove inheritance to fix it.
}
else
{
Write-Warning "can't translate '$idRefShortValue'. "
Write-Warning "Can't translate '$idRefShortValue'. "
continue
}
}
@ -339,45 +307,40 @@ Need to remove inheritance to fix it.
($a.IdentityReference, "Read", "None", "None", "Allow")
}
$acl.SetAccessRule($ace)
Write-Host "'$($a.IdentityReference)' now has Read access to $FilePath. " -ForegroundColor Green
Write-Host "'$($a.IdentityReference)' now has Read access to '$FilePath'. " -ForegroundColor Green
}
else
{
$health = $false
Write-Host "'$($a.IdentityReference)' still has these access to $($FilePath): '$($a.FileSystemRights)'." -ForegroundColor Yellow
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
{
Write-Host "'$($a.IdentityReference)' still has these access to '$FilePath': '$($a.FileSystemRights)'." -ForegroundColor Yellow
}
}
}
}
#other than AnyAccessOK and ReadAccessOK list, if any other account is allowed, they should be removed from the dacl
elseif($a.AccessControlType.Equals([System.Security.AccessControl.AccessControlType]::Allow))
{
$warning = "'$($a.IdentityReference)' should not have access to '$FilePath'. "
{
$caption = "'$($a.IdentityReference)' should not have access to '$FilePath'."
if($a.IsInherited)
{
if($needChange)
{
Set-Acl -Path $FilePath -AclObject $acl
}
$message = @"
$warning
Need to remove inheritance to fix it.
"@
return Remove-RuleProtection -FilePath $FilePath -Message $message -Quiet:$Quiet
}
if (-not $Quiet) {
Do {
Write-Warning $warning
$input = Read-Host -Prompt "Shall I remove this access? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $acl -ErrorVariable e -Confirm:$false
if($e)
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
Write-Warning "Repair permission failed with error: $($e[0].ToString())."
}
}
return Remove-RuleProtection @paras
}
if($result.ToLower().Startswith('y'))
{
$prompt = "Shall I remove this access?"
$description = "Remove access rule of '$($a.IdentityReference)' from '$FilePath'."
if($pscmdlet.ShouldProcess($description, $prompt, "$caption."))
{
$needChange = $true
$ace = $a
$idRefShortValue = ($a.IdentityReference.Value).split('\')[-1]
@ -398,19 +361,22 @@ Need to remove inheritance to fix it.
if(-not ($acl.RemoveAccessRule($ace)))
{
Write-Warning "failed to remove access of $($a.IdentityReference) rule to file $FilePath"
Write-Warning "Failed to remove access of '$($a.IdentityReference)' from '$FilePath'."
}
else
{
Write-Host "'$($a.IdentityReference)' has no more access to $FilePath." -ForegroundColor Green
Write-Host "'$($a.IdentityReference)' has no more access to '$FilePath'." -ForegroundColor Green
}
}
else
{
$health = $false
Write-Host "'$($a.IdentityReference)' still has access to $FilePath." -ForegroundColor Yellow
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
{
Write-Host "'$($a.IdentityReference)' still has access to '$FilePath'." -ForegroundColor Yellow
}
}
}
}
}
#This is the real account list we need to add read access to the file
@ -419,35 +385,29 @@ Need to remove inheritance to fix it.
$realReadAccessNeeded | % {
if((Get-UserSID -User $_) -eq $null)
{
Write-Warning "'$_' needs Read access to $FilePath', but it can't be translated on the machine."
Write-Warning "'$_' needs Read access to '$FilePath', but it can't be translated on the machine."
}
else
{
if (-not $Quiet) {
$warning = "'$_' needs Read access to $FilePath'."
Do {
Write-Warning $warning
$input = Read-Host -Prompt "Shall I make the above change? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
if($result.ToLower().Startswith('y'))
{
$caption = "'$_' needs Read access to '$FilePath'."
$prompt = "Shall I make the above change?"
$description = "Set '$_' Read only access to '$FilePath'. "
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
{
$needChange = $true
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($_, "Read", "None", "None", "Allow")
$acl.AddAccessRule($ace)
Write-Host "'$_' now has Read access to $FilePath. " -ForegroundColor Green
Write-Host "'$_' now has Read access to '$FilePath'." -ForegroundColor Green
}
else
{
$health = $false
Write-Host "'$_' does not have Read access to $FilePath." -ForegroundColor Yellow
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
{
Write-Host "'$_' does not have Read access to '$FilePath'." -ForegroundColor Yellow
}
}
}
}
@ -455,15 +415,20 @@ Need to remove inheritance to fix it.
if($needChange)
{
Set-Acl -Path $FilePath -AclObject $acl
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $acl -ErrorVariable e -Confirm:$false
if($e)
{
Write-Warning "Repair permission failed with error: $($e[0].ToString())."
}
}
if($health)
{
if ($needChange)
{
Write-Host " fixed permissions" -ForegroundColor Yellow
Write-Host " Repaired permissions" -ForegroundColor Yellow
}
else
else
{
Write-Host " looks good" -ForegroundColor Green
}
@ -477,36 +442,32 @@ Need to remove inheritance to fix it.
#>
function Remove-RuleProtection
{
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param (
[parameter(Mandatory=$true)]
[string]$FilePath,
[string]$Message,
[switch] $Quiet
[string]$FilePath
)
if (-not $Quiet) {
Do
{
Write-Warning $Message
$input = Read-Host -Prompt "Shall I remove the inheritace? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
$message = "Need to remove the inheritance before repair the rules."
$prompt = "Shall I remove the inheritace?"
$description = "Remove inheritance of '$FilePath'."
if($result.ToLower().Startswith('y'))
{
$acl = Get-ACL $FilePath
if($pscmdlet.ShouldProcess($description, $prompt, $message))
{
$acl = Get-acl -Path $FilePath
$acl.SetAccessRuleProtection($True, $True)
Set-Acl -Path $FilePath -AclObject $acl
Write-Host "inheritance is removed from $FilePath. " -ForegroundColor Green
Enable-Privilege SeRestorePrivilege | out-null
Set-Acl -Path $FilePath -AclObject $acl -ErrorVariable e -Confirm:$false
if($e)
{
Write-Warning "Remove-RuleProtection failed with error: $($e[0].ToString())."
}
Write-Host "Inheritance is removed from '$FilePath'." -ForegroundColor Green
return $true
}
else
elseif(-not $PSBoundParameters.ContainsKey("WhatIf"))
{
Write-Host "inheritance is not removed from $FilePath. Skip Checking FilePath." -ForegroundColor Yellow
Write-Host "inheritance is not removed from '$FilePath'. Skip Checking FilePath." -ForegroundColor Yellow
return $false
}
}
@ -545,5 +506,82 @@ function Get-UserSID
}
}
function Enable-Privilege {
param(
## The privilege to adjust. This set is taken from
## http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
[ValidateSet(
"SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",
"SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",
"SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
"SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
"SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",
"SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
"SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",
"SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
"SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
"SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege",
"SeUndockPrivilege", "SeUnsolicitedInputPrivilege")]
$Privilege,
## Switch to disable the privilege, rather than enable it.
[Switch] $Disable
)
Export-ModuleMember -Function Fix-FilePermissions, Fix-HostSSHDConfigPermissions, Fix-HostKeyPermissions, Fix-AuthorizedKeyPermissions, Fix-UserKeyPermissions, Fix-UserSSHConfigPermissions
## Taken from P/Invoke.NET with minor adjustments.
$definition = @'
using System;
using System.Runtime.InteropServices;
public class AdjPriv
{
[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, SetLastError = 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_ENABLED = 0x00000002;
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public static bool EnablePrivilege(string privilege, bool disable)
{
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;
if(disable)
{
tp.Attr = SE_PRIVILEGE_DISABLED;
}
else
{
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;
}
}
'@
$type = Add-Type $definition -PassThru
$type[0]::EnablePrivilege($Privilege, $Disable)
}
Export-ModuleMember -Function Repair-FilePermission, Repair-SshdConfigPermission, Repair-SshdHostKeyPermission, Repair-AuthorizedKeyPermission, Repair-UserKeyPermission, Repair-UserSshConfigPermission