Skip to content

Instantly share code, notes, and snippets.

@rjmholt
Last active July 17, 2018 22:46
Show Gist options
  • Save rjmholt/4d00bc7bb07a8c2be49184ac84fb993b to your computer and use it in GitHub Desktop.
Save rjmholt/4d00bc7bb07a8c2be49184ac84fb993b to your computer and use it in GitHub Desktop.
Script for ACL-ing things to the current user in PowerShell
param(
[ValidateNotNullOrEmpty()]
[string]$KeyFileName,
[ValidateNotNullOrEmpty()]
[string]$KeyFileDir = $null
)
# Test if the given Windows Identity is the Built-in Administrator
function Test-IsAdministrator
{
param([System.Security.Principal.WindowsIdentity]$Identity)
$principal = [System.Security.Principal.WindowsPrincipal]::new($Identity)
return $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}
# Remove all ACL access rules on a given file system security object
function Remove-AllAccessRules
{
param([System.Security.AccessControl.FileSystemSecurity]$FSSecurityObj)
$FSSecurityObj.SetAccessRuleProtection($true, $false)
foreach ($rule in $FSSecurityObj.Access)
{
$FSSecurityObj.RemoveAccessRuleAll($rule)
}
}
# Check if a file/directory can be accessed by anyone other than the user with the given SID
function Test-ItemCanBeAccessedByOthers
{
param(
[System.Security.AccessControl.FileSystemSecurity]$FSSecurityObj,
[System.Security.Principal.IdentityReference]$UserSid
)
foreach ($accessRule in $itemSecurityObj.Access)
{
if ($accessRule.IdentityReference -ne $UserSid)
{
if ($accessRule.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow)
{
return $true
}
}
}
}
# Set Read/Write (inlcuding delete) only permissions only to the current user
function Set-ThisUserOnlyRWPermissions
{
param(
[string]$Path
)
# *nix is just a case of chmodding the file
if ($IsLinux -or $IsMacOS)
{
chown -R $(whoami) $Path
chmod -R 700 $Path
return
}
# Get the current user
$currUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
# If the current user is in the Administrator role, we need to ACL to Administrator
$idToAclTo = if (Test-IsAdministrator $currUser) {
[System.Security.Principal.SecurityIdentifier]::new([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $null)
} else {
$currUser.User
}
# Get the current ACL on the file
$fileSecurityObj = Get-Acl -Path $Path
# If the file is already ACL'd properly, there's nothing to do
if (-not (Test-ItemCanBeAccessedByOthers -FSSecurityObj $fileSecurityObj -User $idToAclTo))
{
# TODO: Possibly test to see if the current user has the neccessary rw permissions
return
}
# Set the access rights here
$rw = [System.Security.AccessControl.FileSystemRights]::Read -bor
[System.Security.AccessControl.FileSystemRights]::Write -bor
[System.Security.AccessControl.FileSystemRights]::Modify -bor
[System.Security.AccessControl.FileSystemRights]::Delete -bor
[System.Security.AccessControl.FileSystemRights]::DeleteSubdirectoriesAndFiles
# Set recursive rights inheritance
$recursive = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor
[System.Security.AccessControl.InheritanceFlags]::ObjectInherit
# Set no propagation flags
$noPropagation = [System.Security.AccessControl.PropagationFlags]::None
# Make this an allow ACL
$allow = [System.Security.AccessControl.AccessControlType]::Allow
# Construct the access rule
$thisUserRWOnlyAccess = [System.Security.AccessControl.FileSystemAccessRule]::new(
$idToAclTo,
$rw,
$recursive,
$noPropagation,
$allow
)
# Remove all existing ACLs
Remove-AllAccessRules -FSSecurityObj $fileSecurityObj
# Set the one we want
$fileSecurityObj.AddAccessRule($thisUserRWOnlyAccess)
# Set the ACL
Set-Acl -Path $Path -AclObject $fileSecurityObj
}
# Create a new strong-cryptographically-random byte array of the given size
function New-CryptoKey
{
[OutputType([byte[]])]
param(
# Default is 64 bytes = 512 bits
[int]$KeyByteSize = 64
)
$keyBytes = [byte[]]::new($KeyByteSize)
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
$rng.GetBytes($keyBytes)
$rng.Dispose()
return $keyBytes
}
# Default name of KeyFileDir is "keys"
if (-not $KeyFileDir)
{
$KeyFileDir = Join-Path -Path $PSScriptRoot -ChildPath 'keys'
}
# Get the full path of the key file
$KeyFilePath = Join-Path -Path $KeyFileDir -ChildPath $KeyFileName
# Ensure the path is absolute, relative meaning relative to this script
if (-not [System.IO.Path]::IsPathRooted($KeyFilePath))
{
$KeyFilePath = Join-Path -Path $PSScriptRoot -ChildPath $KeyFilePath
}
# Make sure the key file doesn't already exist
if (Test-Path $KeyFilePath)
{
throw "Key file already exists at '$KeyFilePath'"
}
# Create the key directory if it doesn't already exist as a directory
if (-not (Test-Path $KeyFileDir -PathType Container))
{
if (Test-Path $KeyFileDir)
{
throw "Cannot create key file directory at '$KeyFileDir': it already exists as a file"
}
New-Item -Path $KeyFileDir -ItemType Directory
}
# Create the empty key file
New-Item -Path $KeyFilePath -ItemType File
# Set the relevant permissions on the directory
Set-ThisUserOnlyRWPermissions -Path $KeyFileDir
# Now add the secret to the file
[IO.File]::WriteAllBytes($KeyFilePath, (New-CryptoKey))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment