From: James Gray Date: 2009-01-29T04:06:23+09:00 Subject: Re: Super User Can't Change UID? On Jan 28, 2009, at 11:14 AM, Ezra Zygmuntowicz wrote: > 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 This worked. Thanks so much Ezra. James Edward Gray II