694 lines
26 KiB
PowerShell
694 lines
26 KiB
PowerShell
Set-StrictMode -Version 2.0
|
|
|
|
<#
|
|
.Synopsis
|
|
Get-UserSID
|
|
#>
|
|
function Get-UserSID
|
|
{
|
|
[CmdletBinding(DefaultParameterSetName='User')]
|
|
param
|
|
( [parameter(Mandatory=$true, ParameterSetName="User")]
|
|
[ValidateNotNull()]
|
|
[System.Security.Principal.NTAccount]$User,
|
|
[parameter(Mandatory=$true, ParameterSetName="WellKnownSidType")]
|
|
[ValidateNotNull()]
|
|
[System.Security.Principal.WellKnownSidType]$WellKnownSidType
|
|
)
|
|
try
|
|
{
|
|
if($PSBoundParameters.ContainsKey("User"))
|
|
{
|
|
$sid = $User.Translate([System.Security.Principal.SecurityIdentifier])
|
|
}
|
|
elseif($PSBoundParameters.ContainsKey("WellKnownSidType"))
|
|
{
|
|
$sid = New-Object System.Security.Principal.SecurityIdentifier($WellKnownSidType, $null)
|
|
}
|
|
$sid
|
|
}
|
|
catch {
|
|
return $null
|
|
}
|
|
}
|
|
|
|
# get the local System user
|
|
$systemSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::LocalSystemSid)
|
|
|
|
# get the Administrators group
|
|
$adminsSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid)
|
|
|
|
# get the everyone
|
|
$everyoneSid = Get-UserSID -WellKnownSidType ([System.Security.Principal.WellKnownSidType]::WorldSid)
|
|
|
|
$currentUserSid = Get-UserSID -User "$($env:USERDOMAIN)\$($env:USERNAME)"
|
|
|
|
#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 -ErrorAction SilentlyContinue
|
|
|
|
<#
|
|
.Synopsis
|
|
Repair-SshdConfigPermission
|
|
Repair the file owner and Permission of sshd_config
|
|
#>
|
|
function Repair-SshdConfigPermission
|
|
{
|
|
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
|
|
param (
|
|
[parameter(Mandatory=$true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$FilePath)
|
|
|
|
Repair-FilePermission -Owners $systemSid,$adminsSid -FullAccessNeeded $systemSid @psBoundParameters
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Repair-SshdHostKeyPermission
|
|
Repair the file owner and Permission of host private and public key
|
|
-FilePath: The path of the private host key
|
|
#>
|
|
function Repair-SshdHostKeyPermission
|
|
{
|
|
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
|
|
param (
|
|
[parameter(Mandatory=$true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$FilePath)
|
|
|
|
if($PSBoundParameters["FilePath"].EndsWith(".pub"))
|
|
{
|
|
$PSBoundParameters["FilePath"] = $PSBoundParameters["FilePath"].Replace(".pub", "")
|
|
}
|
|
|
|
Repair-FilePermission -Owners $systemSid,$adminsSid @psBoundParameters
|
|
|
|
$PSBoundParameters["FilePath"] += ".pub"
|
|
Repair-FilePermission -Owners $systemSid,$adminsSid -ReadAccessOK $everyoneSid @psBoundParameters
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Repair-AuthorizedKeyPermission
|
|
Repair the file owner and Permission of authorized_keys
|
|
#>
|
|
function Repair-AuthorizedKeyPermission
|
|
{
|
|
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
|
|
param (
|
|
[parameter(Mandatory=$true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$FilePath)
|
|
|
|
if(-not (Test-Path $FilePath -PathType Leaf))
|
|
{
|
|
Write-host "$FilePath not found" -ForegroundColor Yellow
|
|
return
|
|
}
|
|
$fullPath = (Resolve-Path $FilePath).Path
|
|
$profileListPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
|
|
$profileItem = Get-ChildItem $profileListPath -ErrorAction SilentlyContinue | ? {
|
|
$properties = Get-ItemProperty $_.pspath -ErrorAction SilentlyContinue
|
|
$userProfilePath = $null
|
|
if($properties)
|
|
{
|
|
$userProfilePath = $properties.ProfileImagePath
|
|
}
|
|
$userProfilePath = $userProfilePath.Replace("\", "\\")
|
|
if ( $properties.PSChildName -notmatch '\.bak$') {
|
|
$fullPath -match "^$userProfilePath\\[\\|\W|\w]+authorized_keys$"
|
|
}
|
|
}
|
|
if($profileItem)
|
|
{
|
|
$userSid = $profileItem.PSChildName
|
|
Repair-FilePermission -Owners $userSid,$adminsSid,$systemSid -AnyAccessOK $userSid -FullAccessNeeded $systemSid @psBoundParameters
|
|
|
|
}
|
|
else
|
|
{
|
|
Write-host "$fullPath is not in the profile folder of any user. Skip checking..." -ForegroundColor Yellow
|
|
}
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
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 Repair-UserKeyPermission
|
|
{
|
|
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
|
|
param (
|
|
[parameter(Mandatory=$true, Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$FilePath,
|
|
[System.Security.Principal.SecurityIdentifier] $UserSid = $currentUserSid)
|
|
|
|
if($PSBoundParameters["FilePath"].EndsWith(".pub"))
|
|
{
|
|
$PSBoundParameters["FilePath"] = $PSBoundParameters["FilePath"].Replace(".pub", "")
|
|
}
|
|
Repair-FilePermission -Owners $UserSid, $adminsSid,$systemSid -AnyAccessOK $UserSid @psBoundParameters
|
|
|
|
$PSBoundParameters["FilePath"] += ".pub"
|
|
Repair-FilePermission -Owners $UserSid, $adminsSid,$systemSid -AnyAccessOK $UserSid -ReadAccessOK $everyoneSid @psBoundParameters
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Repair-UserSSHConfigPermission
|
|
Repair the file owner and Permission of user config
|
|
#>
|
|
function Repair-UserSshConfigPermission
|
|
{
|
|
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
|
|
param (
|
|
[parameter(Mandatory=$true)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$FilePath,
|
|
[System.Security.Principal.SecurityIdentifier] $UserSid = $currentUserSid)
|
|
Repair-FilePermission -Owners $UserSid,$adminsSid,$systemSid -AnyAccessOK $UserSid @psBoundParameters
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Repair-FilePermissionInternal
|
|
Only validate owner and ACEs of the file
|
|
#>
|
|
function Repair-FilePermission
|
|
{
|
|
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
|
|
param (
|
|
[parameter(Mandatory=$true, Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$FilePath,
|
|
[ValidateNotNull()]
|
|
[System.Security.Principal.SecurityIdentifier[]] $Owners = $currentUserSid,
|
|
[System.Security.Principal.SecurityIdentifier[]] $AnyAccessOK = $null,
|
|
[System.Security.Principal.SecurityIdentifier[]] $FullAccessNeeded = $null,
|
|
[System.Security.Principal.SecurityIdentifier[]] $ReadAccessOK = $null,
|
|
[System.Security.Principal.SecurityIdentifier[]] $ReadAccessNeeded = $null
|
|
)
|
|
|
|
if(-not (Test-Path $FilePath -PathType Leaf))
|
|
{
|
|
Write-host "$FilePath not found" -ForegroundColor Yellow
|
|
return
|
|
}
|
|
|
|
Write-host " [*] $FilePath"
|
|
$return = Repair-FilePermissionInternal @PSBoundParameters
|
|
|
|
if($return -contains $true)
|
|
{
|
|
#Write-host "Re-check the health of file $FilePath"
|
|
Repair-FilePermissionInternal @PSBoundParameters
|
|
}
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Repair-FilePermissionInternal
|
|
#>
|
|
function Repair-FilePermissionInternal {
|
|
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
|
|
param (
|
|
[parameter(Mandatory=$true, Position = 0)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[string]$FilePath,
|
|
[ValidateNotNull()]
|
|
[System.Security.Principal.SecurityIdentifier[]] $Owners = $currentUserSid,
|
|
[System.Security.Principal.SecurityIdentifier[]] $AnyAccessOK = $null,
|
|
[System.Security.Principal.SecurityIdentifier[]] $FullAccessNeeded = $null,
|
|
[System.Security.Principal.SecurityIdentifier[]] $ReadAccessOK = $null,
|
|
[System.Security.Principal.SecurityIdentifier[]] $ReadAccessNeeded = $null
|
|
)
|
|
|
|
$acl = Get-Acl $FilePath
|
|
$needChange = $false
|
|
$health = $true
|
|
$paras = @{}
|
|
$PSBoundParameters.GetEnumerator() | % { if((-not $_.key.Contains("Owners")) -and (-not $_.key.Contains("Access"))) { $paras.Add($_.key,$_.Value) } }
|
|
|
|
$currentOwnerSid = Get-UserSid -User $acl.owner
|
|
if($owners -notcontains $currentOwnerSid)
|
|
{
|
|
$newOwner = Get-UserAccount -User $Owners[0]
|
|
$caption = "Current owner: '$($acl.Owner)'. '$newOwner' should own '$FilePath'."
|
|
$prompt = "Shall I set the file owner?"
|
|
$description = "Set '$newOwner' as owner of '$FilePath'."
|
|
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
|
|
{
|
|
Enable-Privilege SeRestorePrivilege | out-null
|
|
$acl.SetOwner($newOwner)
|
|
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
|
|
}
|
|
else
|
|
{
|
|
$health = $false
|
|
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
|
|
{
|
|
Write-Host "The owner is still set to '$($acl.Owner)'." -ForegroundColor Yellow
|
|
}
|
|
}
|
|
}
|
|
|
|
$ReadAccessPerm = ([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Read.value__) -bor `
|
|
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Synchronize.value__)
|
|
$FullControlPerm = [System.UInt32] [System.Security.AccessControl.FileSystemRights]::FullControl.value__
|
|
|
|
#system and admin groups can have any access to the file; plus the account in the AnyAccessOK list
|
|
$realAnyAccessOKList = @($systemSid, $adminsSid)
|
|
if($AnyAccessOK)
|
|
{
|
|
$realAnyAccessOKList += $AnyAccessOK
|
|
}
|
|
|
|
$realFullAccessNeeded = $FullAccessNeeded
|
|
$realReadAccessNeeded = $ReadAccessNeeded
|
|
if($realFullAccessNeeded -contains $everyoneSid)
|
|
{
|
|
$realFullAccessNeeded = @($everyoneSid)
|
|
$realReadAccessNeeded = $null
|
|
}
|
|
|
|
if($realReadAccessNeeded -contains $everyoneSid)
|
|
{
|
|
$realReadAccessNeeded = @($everyoneSid)
|
|
}
|
|
#this is original list requested by the user, the account will be removed from the list if they already part of the dacl
|
|
if($realReadAccessNeeded)
|
|
{
|
|
$realReadAccessNeeded = $realReadAccessNeeded | ? { ($_ -ne $null) -and ($realFullAccessNeeded -notcontains $_) }
|
|
}
|
|
|
|
#if accounts in the ReadAccessNeeded or $realFullAccessNeeded already part of dacl, they are okay;
|
|
#need to make sure they have read access only
|
|
$realReadAcessOKList = $ReadAccessOK + $realReadAccessNeeded
|
|
|
|
foreach($a in $acl.Access)
|
|
{
|
|
if ($a.IdentityReference -is [System.Security.Principal.SecurityIdentifier])
|
|
{
|
|
$IdentityReferenceSid = $a.IdentityReference
|
|
}
|
|
Else
|
|
{
|
|
$IdentityReferenceSid = Get-UserSid -User $a.IdentityReference
|
|
}
|
|
if($IdentityReferenceSid -eq $null)
|
|
{
|
|
$idRefShortValue = ($a.IdentityReference.Value).split('\')[-1]
|
|
$IdentityReferenceSid = Get-UserSID -User $idRefShortValue
|
|
if($IdentityReferenceSid -eq $null)
|
|
{
|
|
Write-Warning "Can't translate '$idRefShortValue'. "
|
|
continue
|
|
}
|
|
}
|
|
|
|
if($realFullAccessNeeded -contains ($IdentityReferenceSid))
|
|
{
|
|
$realFullAccessNeeded = $realFullAccessNeeded | ? { ($_ -ne $null) -and (-not $_.Equals($IdentityReferenceSid)) }
|
|
if($realReadAccessNeeded)
|
|
{
|
|
$realReadAccessNeeded = $realReadAccessNeeded | ? { ($_ -ne $null) -and (-not $_.Equals($IdentityReferenceSid)) }
|
|
}
|
|
if (($a.AccessControlType.Equals([System.Security.AccessControl.AccessControlType]::Allow)) -and `
|
|
((([System.UInt32]$a.FileSystemRights.value__) -band $FullControlPerm) -eq $FullControlPerm))
|
|
{
|
|
continue;
|
|
}
|
|
#update the account to full control
|
|
if($a.IsInherited)
|
|
{
|
|
if($needChange)
|
|
{
|
|
Enable-Privilege SeRestorePrivilege | out-null
|
|
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
|
|
}
|
|
|
|
return Remove-RuleProtection @paras
|
|
}
|
|
$caption = "'$($a.IdentityReference)' has the following access to '$FilePath': '$($a.AccessControlType)'-'$($a.FileSystemRights)'."
|
|
$prompt = "Shall I make it Allow FullControl?"
|
|
$description = "Grant '$($a.IdentityReference)' FullControl access to '$FilePath'. "
|
|
|
|
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
|
|
{
|
|
$needChange = $true
|
|
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
|
|
($IdentityReferenceSid, "FullControl", "None", "None", "Allow")
|
|
|
|
$acl.SetAccessRule($ace)
|
|
Write-Host "'$($a.IdentityReference)' now has FullControl access to '$FilePath'. " -ForegroundColor Green
|
|
}
|
|
else
|
|
{
|
|
$health = $false
|
|
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
|
|
{
|
|
Write-Host "'$($a.IdentityReference)' still has these access to '$FilePath': '$($a.AccessControlType)'-'$($a.FileSystemRights)'." -ForegroundColor Yellow
|
|
}
|
|
}
|
|
}
|
|
elseif(($realAnyAccessOKList -contains $everyoneSid) -or ($realAnyAccessOKList -contains $IdentityReferenceSid))
|
|
{
|
|
#ignore those accounts listed in the AnyAccessOK list.
|
|
continue;
|
|
}
|
|
#If everyone is in the ReadAccessOK list, any user can have read access;
|
|
# below block make sure they are granted Read access only
|
|
elseif(($realReadAcessOKList -contains $everyoneSid) -or ($realReadAcessOKList -contains $IdentityReferenceSid))
|
|
{
|
|
if($realReadAccessNeeded -and ($IdentityReferenceSid.Equals($everyoneSid)))
|
|
{
|
|
$realReadAccessNeeded= $null
|
|
}
|
|
elseif($realReadAccessNeeded)
|
|
{
|
|
$realReadAccessNeeded = $realReadAccessNeeded | ? { ($_ -ne $null ) -and (-not $_.Equals($IdentityReferenceSid)) }
|
|
}
|
|
|
|
if (-not ($a.AccessControlType.Equals([System.Security.AccessControl.AccessControlType]::Allow)) -or `
|
|
(-not (([System.UInt32]$a.FileSystemRights.value__) -band (-bnot $ReadAccessPerm))))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if($a.IsInherited)
|
|
{
|
|
if($needChange)
|
|
{
|
|
Enable-Privilege SeRestorePrivilege | out-null
|
|
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
|
|
}
|
|
|
|
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($pscmdlet.ShouldProcess($description, $prompt, $caption))
|
|
{
|
|
$needChange = $true
|
|
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
|
|
($IdentityReferenceSid, "Read", "None", "None", "Allow")
|
|
|
|
$acl.SetAccessRule($ace)
|
|
Write-Host "'$($a.IdentityReference)' now has Read access to '$FilePath'. " -ForegroundColor Green
|
|
}
|
|
else
|
|
{
|
|
$health = $false
|
|
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))
|
|
{
|
|
$caption = "'$($a.IdentityReference)' should not have access to '$FilePath'."
|
|
if($a.IsInherited)
|
|
{
|
|
if($needChange)
|
|
{
|
|
Enable-Privilege SeRestorePrivilege | out-null
|
|
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
|
|
}
|
|
return Remove-RuleProtection @paras
|
|
}
|
|
|
|
$prompt = "Shall I remove this access?"
|
|
$description = "Remove access rule of '$($a.IdentityReference)' from '$FilePath'."
|
|
|
|
if($pscmdlet.ShouldProcess($description, $prompt, "$caption."))
|
|
{
|
|
$needChange = $true
|
|
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
|
|
($IdentityReferenceSid, $a.FileSystemRights, $a.InheritanceFlags, $a.PropagationFlags, $a.AccessControlType)
|
|
|
|
if(-not ($acl.RemoveAccessRule($ace)))
|
|
{
|
|
Write-Warning "Failed to remove access of '$($a.IdentityReference)' from '$FilePath'."
|
|
}
|
|
else
|
|
{
|
|
Write-Host "'$($a.IdentityReference)' has no more access to '$FilePath'." -ForegroundColor Green
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$health = $false
|
|
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
|
|
{
|
|
Write-Host "'$($a.IdentityReference)' still has access to '$FilePath'." -ForegroundColor Yellow
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if($realFullAccessNeeded)
|
|
{
|
|
$realFullAccessNeeded | % {
|
|
$account = Get-UserAccount -UserSid $_
|
|
if($account -eq $null)
|
|
{
|
|
Write-Warning "'$_' needs FullControl access to '$FilePath', but it can't be translated on the machine."
|
|
}
|
|
else
|
|
{
|
|
$caption = "'$account' needs FullControl access to '$FilePath'."
|
|
$prompt = "Shall I make the above change?"
|
|
$description = "Set '$account' FullControl access to '$FilePath'. "
|
|
|
|
if($pscmdlet.ShouldProcess($description, $prompt, $caption))
|
|
{
|
|
$needChange = $true
|
|
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
|
|
($_, "FullControl", "None", "None", "Allow")
|
|
$acl.AddAccessRule($ace)
|
|
Write-Host "'$account' now has FullControl to '$FilePath'." -ForegroundColor Green
|
|
}
|
|
else
|
|
{
|
|
$health = $false
|
|
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
|
|
{
|
|
Write-Host "'$account' does not have FullControl to '$FilePath'." -ForegroundColor Yellow
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#This is the real account list we need to add read access to the file
|
|
if($realReadAccessNeeded)
|
|
{
|
|
$realReadAccessNeeded | % {
|
|
$account = Get-UserAccount -UserSid $_
|
|
if($account -eq $null)
|
|
{
|
|
Write-Warning "'$_' needs Read access to '$FilePath', but it can't be translated on the machine."
|
|
}
|
|
else
|
|
{
|
|
$caption = "'$account' needs Read access to '$FilePath'."
|
|
$prompt = "Shall I make the above change?"
|
|
$description = "Set '$account' 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 "'$account' now has Read access to '$FilePath'." -ForegroundColor Green
|
|
}
|
|
else
|
|
{
|
|
$health = $false
|
|
if(-not $PSBoundParameters.ContainsKey("WhatIf"))
|
|
{
|
|
Write-Host "'$account' does not have Read access to '$FilePath'." -ForegroundColor Yellow
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if($needChange)
|
|
{
|
|
Enable-Privilege SeRestorePrivilege | out-null
|
|
Set-Acl -Path $FilePath -AclObject $acl -Confirm:$false
|
|
}
|
|
if($health)
|
|
{
|
|
if ($needChange)
|
|
{
|
|
Write-Host " Repaired permissions" -ForegroundColor Yellow
|
|
}
|
|
else
|
|
{
|
|
Write-Host " looks good" -ForegroundColor Green
|
|
}
|
|
}
|
|
Write-host " "
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Remove-RuleProtection
|
|
#>
|
|
function Remove-RuleProtection
|
|
{
|
|
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
|
|
param (
|
|
[parameter(Mandatory=$true)]
|
|
[string]$FilePath
|
|
)
|
|
$message = "Need to remove the inheritance before repair the rules."
|
|
$prompt = "Shall I remove the inheritace?"
|
|
$description = "Remove inheritance of '$FilePath'."
|
|
|
|
if($pscmdlet.ShouldProcess($description, $prompt, $message))
|
|
{
|
|
$acl = Get-acl -Path $FilePath
|
|
$acl.SetAccessRuleProtection($True, $True)
|
|
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
|
|
}
|
|
elseif(-not $PSBoundParameters.ContainsKey("WhatIf"))
|
|
{
|
|
Write-Host "inheritance is not removed from '$FilePath'. Skip Checking FilePath." -ForegroundColor Yellow
|
|
return $false
|
|
}
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Get-UserAccount
|
|
#>
|
|
function Get-UserAccount
|
|
{
|
|
[CmdletBinding(DefaultParameterSetName='Sid')]
|
|
param
|
|
( [parameter(Mandatory=$true, ParameterSetName="Sid")]
|
|
[ValidateNotNull()]
|
|
[System.Security.Principal.SecurityIdentifier]$UserSid,
|
|
[parameter(Mandatory=$true, ParameterSetName="WellKnownSidType")]
|
|
[ValidateNotNull()]
|
|
[System.Security.Principal.WellKnownSidType]$WellKnownSidType
|
|
)
|
|
try
|
|
{
|
|
if($PSBoundParameters.ContainsKey("UserSid"))
|
|
{
|
|
$objUser = $UserSid.Translate([System.Security.Principal.NTAccount])
|
|
}
|
|
elseif($PSBoundParameters.ContainsKey("WellKnownSidType"))
|
|
{
|
|
$objSID = New-Object System.Security.Principal.SecurityIdentifier($WellKnownSidType, $null)
|
|
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
|
|
}
|
|
$objUser
|
|
}
|
|
catch {
|
|
return $null
|
|
}
|
|
}
|
|
|
|
<#
|
|
.Synopsis
|
|
Enable-Privilege
|
|
#>
|
|
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
|
|
)
|
|
|
|
$type[0]::EnablePrivilege($Privilege, $Disable)
|
|
}
|
|
|
|
Export-ModuleMember -Function Repair-FilePermission, Repair-SshdConfigPermission, Repair-SshdHostKeyPermission, Repair-AuthorizedKeyPermission, Repair-UserKeyPermission, Repair-UserSshConfigPermission, Enable-Privilege, Get-UserAccount, Get-UserSID
|