111 lines
2.6 KiB
Plaintext
111 lines
2.6 KiB
Plaintext
--:Minify:--
|
|
local fs = require("fs")
|
|
|
|
local cmdArgs = {...}
|
|
local targetUser = "root"
|
|
local i = 1
|
|
|
|
if cmdArgs[i] == "-u" then
|
|
i = i + 1
|
|
local uarg = cmdArgs[i] or "root"
|
|
local numUid = tonumber(uarg)
|
|
if numUid then
|
|
local pwent = syscall.getpasswd(numUid)
|
|
targetUser = (pwent and pwent.username) or uarg
|
|
else
|
|
targetUser = uarg
|
|
end
|
|
i = i + 1
|
|
end
|
|
|
|
local cmd = cmdArgs[i]
|
|
if not cmd or cmd == "" then
|
|
print("usage: sudo [-u user] <command> [args...]")
|
|
syscall.exit(1)
|
|
return
|
|
end
|
|
|
|
local restArgs = {}
|
|
for j = i + 1, #cmdArgs do restArgs[#restArgs + 1] = cmdArgs[j] end
|
|
|
|
local currentUid = syscall.getuid()
|
|
local currentUser = syscall.getUsername(currentUid) or tostring(currentUid)
|
|
|
|
local targetUid = syscall.getuidbyname(targetUser)
|
|
if not targetUid then
|
|
print("sudo: user '" .. targetUser .. "' does not exist")
|
|
syscall.exit(1)
|
|
return
|
|
end
|
|
|
|
if currentUid ~= 0 then
|
|
printInline("[sudo] password for root: ")
|
|
local pw = ""
|
|
while true do
|
|
local ch = syscall.read(0)
|
|
if not ch or ch == "" then
|
|
elseif ch == "\n" then
|
|
syscall.write(1, "\n")
|
|
break
|
|
elseif ch == "\b" then
|
|
if #pw > 0 then pw = pw:sub(1, -2); syscall.write(1, "\b \b") end
|
|
else
|
|
pw = pw .. ch
|
|
syscall.write(1, "*")
|
|
end
|
|
end
|
|
|
|
local ok, err = syscall.login(0, pw)
|
|
if not ok then
|
|
sleep(1)
|
|
print("sudo: Authentication failure")
|
|
syscall.exit(1)
|
|
return
|
|
end
|
|
|
|
if targetUid ~= currentUid then
|
|
syscall.setuid(targetUid)
|
|
end
|
|
else
|
|
if targetUid ~= currentUid then
|
|
syscall.setuid(targetUid)
|
|
end
|
|
end
|
|
|
|
local cmdPath = ""
|
|
if cmd:find("/") then
|
|
if fs.exists(cmd) then cmdPath = cmd end
|
|
else
|
|
local paths = string.split(syscall.getEnviron("PATH") or "/bin/", ":")
|
|
for _, p in ipairs(paths) do
|
|
local full = p .. cmd
|
|
if fs.exists(full) then cmdPath = full; break end
|
|
end
|
|
end
|
|
|
|
if cmdPath == "" then
|
|
print("sudo: command not found: " .. cmd)
|
|
syscall.exit(1)
|
|
return
|
|
end
|
|
|
|
local text = fs.readAllText(cmdPath)
|
|
local program, loadErr = load(text, "@" .. cmdPath)
|
|
if not program then
|
|
print("sudo: cannot load " .. cmd .. ": " .. tostring(loadErr))
|
|
syscall.exit(1)
|
|
return
|
|
end
|
|
|
|
local pwent = syscall.getpasswd(targetUid)
|
|
if pwent and pwent.homedir then
|
|
syscall.setEnviron("HOME", pwent.homedir)
|
|
end
|
|
syscall.setEnviron("USER", targetUser)
|
|
|
|
local ok, err = xpcall(program, debug.traceback, table.unpack(restArgs))
|
|
if not ok then
|
|
print("sudo: " .. cmd .. ": " .. tostring(err))
|
|
syscall.exit(1)
|
|
end
|