... wherein I bloviate discursively

Brian Clapper,

Running a Ruby block as another user

| Comments

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

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 and end, 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 like getpwnam.
  • 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