From: Ezra Zygmuntowicz Date: 2009-01-29T02:14:47+09:00 Subject: Re: Super User Can't Change UID? On Jan 28, 2009, at 8:24 AM, James Gray wrote: > On Jan 27, 2009, at 11:18 PM, Daniel Berger wrote: > >> James Gray wrote: >>> Why would the super user not be able to switch UID's? >>> $ sudo ruby -r etc -e 'Process.uid = Etc.getpwnam("james").uid' >>> Password: >>> -e:1:in `uid=': Operation not permitted (Errno::EPERM) >>> from -e:1 >>> Tips of TFM I should go R are welcome. :) >> >> I seem to recall that setreuid() is busted on OS X, 10.4.x anyway. >> I think it's fixed in 10.5, but I can't confirm. > > I'm on Mac OS X 10.5.6. > >> I know this has come up before. Check the the ruby-core archives. > > I did a few searches, but didn't find a match. I did find old posts > about how Process.uid= can't handle negative UID's which is another > issue I'm fighting, but nothing about this issue. > > On Jan 28, 2009, at 8:01 AM, Daniel Berger wrote: > >> If I had to guess, I'd bet Apple replaced setreuid() with >> seteuid(), but that's a guess. > > If that were the case, would it maybe be possible to switch users > using Apple's alternate API? > > Unfortunately, this issue is a big snag that's preventing us from > shipping an application, so I've got to find some workaround. I've > considered trying to exec() my program adding su/sudo to switch the > user as a possible option. Would that work? I need to switch both > the user and group. > > James Edward Gray II Does something like this not work for you? def _change_privilege(user, group=user) uid, gid = Process.euid, Process.egid begin target_uid = Etc.getpwnam(user).uid rescue ArgumentError => e return false end begin target_gid = Etc.getgrnam(group).gid rescue ArgumentError => e return false end if (uid != target_uid) || (gid != target_gid) # Change process ownership Process.initgroups(user, target_gid) Process::GID.change_privilege(target_gid) Process::UID.change_privilege(target_uid) end true rescue Errno::EPERM => e false end Cheers- Ezra Zygmuntowicz ez@engineyard.com