How to make a ruby program tu run unser other user:group different than root

Hi, many daemons allow an argument “-u uid” which makes the program to
run
under that user. Of course this can be done just by root or privileged
users.

It’s commonly used in init scripts. These are started by init process
running
as root and start services running under other user.

However it seems that ruby binary doesn’t implement such option. Is
there any
way to get it?
If not I should use “su” command and so.

Thanks.

On Sat, Dec 12, 2009 at 10:14 AM, Iñaki Baz C. [email protected]
wrote:

Hi, many daemons allow an argument “-u uid” which makes the program to run
under that user. Of course this can be done just by root or privileged users.

It’s commonly used in init scripts. These are started by init process running
as root and start services running under other user.

However it seems that ruby binary doesn’t implement such option. Is there any
way to get it?
If not I should use “su” command and so.

Here’s a snippet from our unicorn config that changes the user for
workers from root to deploy. You can probably use something from it.

Unicorn master is started as root, which is fine, but let’s

drop the workers to deploy:deploy

uid, gid = Process.euid, Process.egid
user, group = 'deploy', 'deploy'
target_uid = Etc.getpwnam(user).uid
target_gid = Etc.getgrnam(group).gid
worker.tmp.chown(target_uid, target_gid)
if uid != target_uid || gid != target_gid
  Process.initgroups(user, target_gid)
  Process::GID.change_privilege(target_gid)
  Process::UID.change_privilege(target_uid)
end

Best regards,
Michael G.

El Sábado, 12 de Diciembre de 2009, Michael G. escribió:

If not I should use “su” command and so.
target_uid = Etc.getpwnam(user).uid
target_gid = Etc.getgrnam(group).gid
worker.tmp.chown(target_uid, target_gid)
if uid != target_uid || gid != target_gid
Process.initgroups(user, target_gid)
Process::GID.change_privilege(target_gid)
Process::UID.change_privilege(target_uid)
end

Thanks, I’ll try it.

Hi,

Am Sonntag, 13. Dez 2009, 00:14:03 +0900 schrieb Iñaki Baz C.:

Hi, many daemons allow an argument “-u uid” which makes the program to run
under that user. Of course this can be done just by root or privileged users.

It’s commonly used in init scripts. These are started by init process running
as root and start services running under other user.

However it seems that ruby binary doesn’t implement such option. Is there any
way to get it?
If not I should use “su” command and so.

Maybe you like to copy that:

http://bertram-scharpf.homelinux.com:8808/doc_root/bs-ruby-3.0/rdoc/classes/Kernel.src/M000100.html

Bertram

El Sábado, 12 de Diciembre de 2009, Iñaki Baz C.
escribió:

Maybe you like to copy that:

http://bertram-scharpf.homelinux.com:8808/doc_root/bs-ruby-3.0/rdoc/class
e s/Kernel.src/M000100.html

Really annoying. however I’ve found an issue with group permissions when
doing Kernel#su. I must to investigate it a bit more.

Let me explain it:

  • My home “/home/ibc” has these owner/group and permissions:

    drwxr-x— ibc ibc_grp /home/ibc/

  • Other user “alice” belongs to group “ibc_grp” group so “alice” user
    can read
    into /home/ibc:

    ~# whoami
    alice
    ~# cd /home/ibc
    ~# echo $?
    0

  • Now I start a irb session with root user, load “fileutils” and your
    “kernel#su” Ruby file.

  • I do “su” to become “alice:alice” and try to enter in /home/ibc, but
    it
    fails:

    irb> su “alice”, “alice” do Dir.chdir("/home/ibc") ; end
    (irb):9:in chdir': Permission denied - /home/ibc (Errno::EACCES) from (irb):9:inblock in irb_binding’
    from /PATH_TO/kernel.rb:7:in `block in su’

  • It also doesn’t work even setting “root” as group (same error).

kernel.rb:

module Kernel

def su u, g = nil
if block_given? then
pid = fork {
su u, g
yield <— line 7
}
_, status = Process.waitpid2 pid
return status
end
uid = case u
when Fixnum then
[…]

Is it an issue in your code or in fileutils gem?

Thanks a lot.

El Sábado, 12 de Diciembre de 2009, Iñaki Baz C.
escribió:> ~# echo $?

    from (irb):9:in `block in irb_binding'
    from /PATH_TO/kernel.rb:7:in `block in su'
  • It also doesn’t work even setting “root” as group (same error).

But does work if I do:

irb> su “alice”, “ibc_grp” do Dir.chdir("/home/ibc") ; end

Strange? It doesn’t behave as when running a shell.

kernel.rb:

module Kernel

def su u, g = nil
^^
if block_given? then
pid = fork {
su u, g
^^
It looks like a recursion to me. You do not get infinite
recursion just because you do not supply a block in line 6.

Can you tell what is your Kernel#su supposed to do?

Alfred

El Sábado, 12 de Diciembre de 2009, Bertram S.
escribió:> > However it seems that ruby binary doesn’t implement such option. Is there

any way to get it?
If not I should use “su” command and so.

Maybe you like to copy that:

http://bertram-scharpf.homelinux.com:8808/doc_root/bs-ruby-3.0/rdoc/classe
s/Kernel.src/M000100.html

Really annoying. however I’ve found an issue with group permissions when
doing
Kernel#su. I must to investigate it a bit more.

Thanks a lot.

El Lunes, 14 de Diciembre de 2009, aalfred
escribió:> Forget about my previous answer. I’ve copied the original code nd it

is okay ;-). I’ve tested it on my machine on Fedora 11 and ruby 1.8.6
(2009-08-04 patchlevel 383) and I get right results in all different
scenarios I tested.

What about permission on /home directory?

No issues there as using shell and logging as “alice” I can go into
/home/ibc
because alice’s group belongs to ibc’s group.

Forget about my previous answer. I’ve copied the original code nd it
is okay ;-). I’ve tested it on my machine on Fedora 11 and ruby 1.8.6
(2009-08-04 patchlevel 383) and I get right results in all different
scenarios I tested.

What about permission on /home directory?

It is almost certainly a permission issue. Check it again.
I’ve tested and it works fine.
Only when directory was unreadable I got same result (error) as you
had.

Just a notice: there is a slight difference in your tests:

El Lunes, 14 de Diciembre de 2009, aalfred
escribió:> It is almost certainly a permission issue. Check it again.

I’ve tested and it works fine.
Only when directory was unreadable I got same result (error) as you
had.

I’ve re-checked:

In terminal shell:


[email protected]:/$ whoami
=> alice

[email protected]:/$ pwd
=> /

[email protected]:/$ cd /home/ibc

[email protected]:/home/ibc$

In irb using “su”:


[email protected]_laptop:/# whoami
=> root

[email protected]_laptop:/# su alice

[email protected]:/$ pwd
=> /

[email protected]:/$ irb -r “/tmp/kernel_su.rb”

irb> require “fileutils”
=> true

irb> su(“alice”, “alice”) do Dir.chdir("/home/ibc") ; end
(irb):2:in chdir': Permission denied - /home/ibc (Errno::EACCES) from (irb):2:inblock in irb_binding’
from /tmp/kernel.rb:11:in block in su' from /tmp/kernel.rb:9:infork’
from /tmp/kernel.rb:9:in su' from (irb):1:inirb_binding’

irb> su(“alice”) do Dir.chdir("/home/ibc") ; end
(irb):3:in chdir': Permission denied - /home/ibc (Errno::EACCES) from (irb):3:inblock in irb_binding’
from /tmp/kernel.rb:11:in block in su' from /tmp/kernel.rb:9:infork’
from /tmp/kernel.rb:9:in su' from (irb):1:inirb_binding’

irb> su(“openxdms”, “ibc_grp”) do Dir.chdir("/home/ibc") ; end
=> #<Process::Status: pid 10824 exit 0>

Just a notice: there is a slight difference in your tests:

Yes, I cannot access to /home/ibc directory doing:

su “alice”, “alice” do Dir.chdir("/home/ibc") ; end

but I can access doing:

su “alice”, “ibc_grp” do Dir.chdir("/home/ibc") ; end

Note that “alice” has “alice” has primary group but also belongs to
“ibc_grp”
group:

~# id alice
uid=1003(alice) gid=1003(alice) grupos=1003(alice),1004(ibc_priv)

~# ll -d /home/ibc
drwxr-x— 77 ibc ibc_grp 4,0K 2009-12-14 09:50 /home/ibc/