I want to start the following file called test.sh
as a specific user from superuser Ruby.
#!/bin/bash
echo "test.sh ok"
id
gid = 1001
uid = 1001
pid = fork do
exit 127 unless Process::GID.change_privilege(gid) == gid
exit 127 unless Process::UID.change_privilege(uid) == uid
begin
exec './test.sh'
rescue # Errno::ENOENT
exit 127
end
exit 127 #Something else
end
res = Process.waitpid(pid)
puts 'complete'
p $?
Execution result
$ sudo ruby a.rb
test.sh ok
uid=1001(****) gid=1001(****) groups=1001(****),0(root)
complete
#<Process::Status: pid 75202 exit 0>
--spawn
does not have a function to change the user, so fork
and then ʻexec. ――This is easy if everything is successful. I want to think about error handling in the case of failure. --Variables should not be shared because it is
fork and is a separate process. ʻIO.pipe
is also stupid
--ʻAbortThen, it is indistinguishable from the case where the application failed when exec succeeded. --Therefore, the exit code
127 (that is, ʻENOENT
) tells the failure. I can't tell if the application returns 127
when the exec is successful, but I'll leave it out.