Last active
November 15, 2019 03:32
-
-
Save lukesampson/9130445 to your computer and use it in GitHub Desktop.
Debug script for sudo.ps1 (psutils)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# to debug sudo problems. | |
# to download: | |
# (new-object net.webclient).downloadfile('https://gist.githubusercontent.com/lukesampson/9130445/raw/sudo_debug.ps1', "$pwd/sudo_debug.ps1") | |
# to test: | |
# ./sudo_debug.ps1 echo hi | |
if(!$args) { "usage: sudo <cmd...>"; exit 1 } | |
function is_admin { | |
write-host "DEBUG: is_admin" | |
$id = [security.principal.windowsidentity]::getcurrent() | |
write-host "DEBUG: is_admin: identity: $($id.name)" | |
$name = $id.name -replace '^[^\\]*\\', '' | |
$admin_group = (gwmi win32_group -filter "LocalAccount=True AND SID='S-1-5-32-544'").name # be language-agnostic | |
write-host "DEBUG: is_admin: admin group: $admin_group" | |
$res = gwmi win32_groupuser | ? { $_.groupcomponent -match "name=`"$admin_group`"" -and $_.partcomponent -match "name=`"$name`"" } | |
write-host "DEBUG: is_admin: gwmi result: $res" | |
if($res) { $true } | |
} | |
function sudo_do($parent_pid, $dir, $cmd) { | |
write-host "DEBUG: sudo_do" | |
$src = 'using System.Runtime.InteropServices; | |
public class Kernel { | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern bool AttachConsole(uint dwProcessId); | |
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] | |
public static extern bool FreeConsole(); | |
}' | |
write-host "DEBUG: sudo_do: adding Kernel functions" | |
$kernel = add-type $src -passthru | |
write-host "DEBUG: sudo_do: Kernel functions were added" | |
write-host "DEBUG: freeing console" | |
$kernel::freeconsole() | |
write-host "DEBUG: sudo_do: console freed" | |
write-host "DEBUG: sudo_do: attaching to parent: pid = $parent_pid" | |
$kernel::attachconsole($parent_pid) | |
$p = new-object diagnostics.process; $start = $p.startinfo | |
$start.filename = "powershell.exe" | |
$start.arguments = "-noprofile $cmd`nexit `$lastexitcode" | |
write-host "DEBUG: sudo_do: powershell arguments: '$($start.arguments)'" | |
$start.useshellexecute = $false | |
$start.workingdirectory = $dir | |
write-host "DEBUG: sudo_do: starting process" | |
$p.start() | |
write-host "DEBUG: sudo_do: waiting for process to exit" | |
$p.waitforexit() | |
write-host "DEBUG: sudo_do: process exited (exit code = $($p.exitcode)" | |
return $p.exitcode | |
} | |
function serialize($a, $escape) { | |
if($a -is [string] -and $a -match '\s') { return "'$a'" } | |
if($a -is [array]) { | |
return $a | % { (serialize $_ $escape) -join ', ' } | |
} | |
if($escape) { return $a -replace '[>&]', '`$0' } | |
return $a | |
} | |
if($args[0] -eq '-do') { | |
write-host "DEBUG: child process" | |
$null, $dir, $parent_pid, $cmd = $args | |
$exit_code = sudo_do $parent_pid $dir (serialize $cmd) | |
write-host "DEBUG: child process: exit code: $exit_code" | |
exit $exit_code | |
} | |
if(!(is_admin)) { | |
[console]::error.writeline("sudo: you must be an administrator to run sudo") | |
exit 1 | |
} | |
$a = serialize $args $true | |
write-host "DEBUG: args: $a" | |
$savetitle = $host.ui.rawui.windowtitle | |
$p = new-object diagnostics.process; $start = $p.startinfo | |
$start.filename = "powershell.exe" | |
$wd = convert-path $pwd # convert in case pwd is a PSDrive | |
$start.arguments = "-noprofile & '$pscommandpath' -do $wd $pid $a`nexit `$lastexitcode" | |
$start.verb = 'runas' | |
# don't hide window for debug | |
# $start.windowstyle = 'hidden' | |
try { | |
write-host "DEBUG: starting powershell process" | |
$null = $p.start() | |
write-host "DEBUG: successfully started powershell process" | |
} catch { exit 1 } # user didn't provide consent | |
write-host "DEBUG: waiting for powershell process to exit" | |
$p.waitforexit() | |
write-host "DEBUG: powershell process exited. exit code $($p.exitcode)" | |
$host.ui.rawui.windowtitle = $savetitle | |
exit $p.exitcode |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment