Recently, on stackoverflow, someone asked:
Can you execute a block of Ruby code as a different OS user?
What I, ideally, want is something like this:
user("christoffer") do # do something end
My proposed solution, for Unix-like systems, turns out to be trivial and seems worth blogging about. It makes use of:
- Ruby’s block syntax, which allows a block of code (between
do
andend
, or between curly brackets) to be passed, as an object, to a function. - Ruby’s
etc
module which, on Unix-like systems, allows access to the password database via familiar functions likegetpwnam
. - Ruby’s
Process
module, for forking a child process.
The function to run a block of Ruby code as another user is trivial:
Using the function is also trivial:
Of course, the calling code has to be running as root (or setuid to root) to switch to another user. Running the above code on my Mac OS X laptop yields this output:
$ sudo ruby u.rb
Caller PID = 98003
Caller UID = 0
In child process. User=bmc, PID=98004, UID=501