[Ruby] Execute an external command as another user

Premise

I want to start the following file called test.sh as a specific user from superuser Ruby.

#!/bin/bash
echo "test.sh ok"
id

Implementation

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>

important point

--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 code127 (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.

Recommended Posts

[Ruby] Execute an external command as another user
Execute external command in python
'pip' is not recognized as an internal or external command, operable program or batch file.