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.

···

--
Iñaki Baz Castillo <ibc@aliax.net>

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.

···

On Sat, Dec 12, 2009 at 10:14 AM, Iñaki Baz Castillo <ibc@aliax.net> 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.

  ##
  # 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 Guterl

Hi,

···

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

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

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
*
Discover String#notempty? at <http://raa.ruby-lang.org/project/step&gt;\.

Thanks, I'll try it.

···

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

On Sat, Dec 12, 2009 at 10:14 AM, Iñaki Baz Castillo <ibc@aliax.net> 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

--
Iñaki Baz Castillo <ibc@aliax.net>

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 Sábado, 12 de Diciembre de 2009, Bertram Scharpf escribió:

Hi,

Am Sonntag, 13. Dez 2009, 00:14:03 +0900 schrieb Iñaki Baz Castillo:
> 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/classe
s/Kernel.src/M000100.html

--
Iñaki Baz Castillo <ibc@aliax.net>

> 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:

  > su "alice", "alice" do Dir.chdir("/home/ibc") ; end
  (irb):9:in `chdir': Permission denied - /home/ibc (Errno::EACCES)
        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).

kernel.rb:

···

El Sábado, 12 de Diciembre de 2009, Iñaki Baz Castillo escribió:
-------------
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.

--
Iñaki Baz Castillo <ibc@aliax.net>

- 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:

  > su "alice", "alice" do Dir.chdir("/home/ibc") ; end
  (irb):9:in `chdir': Permission denied - /home/ibc (Errno::EACCES)
        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:

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

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

···

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

--
Iñaki Baz Castillo <ibc@aliax.net>

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

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:

···

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

--
Alfred

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.

···

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?

--
Iñaki Baz Castillo <ibc@aliax.net>

I've re-checked:

In terminal shell:

···

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.

---------------
alice@ibc-laptop:/$ whoami
=> alice

alice@ibc-laptop:/$ pwd
=> /

alice@ibc-laptop:/$ cd /home/ibc

alice@ibc-laptop:/home/ibc$
---------------

In irb using "su":

--------------
root@ibc_laptop:/# whoami
=> root

root@ibc_laptop:/# su alice

alice@ibc-laptop:/$ pwd
=> /

alice@ibc-laptop:/$ irb -r "/tmp/kernel_su.rb"

require "fileutils"

=> true

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

(irb):2:in `chdir': Permission denied - /home/ibc (Errno::EACCES)
        from (irb):2:in `block in irb_binding'
        from /tmp/kernel.rb:11:in `block in su'
        from /tmp/kernel.rb:9:in `fork'
        from /tmp/kernel.rb:9:in `su'
        from (irb):1:in `irb_binding'

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

(irb):3:in `chdir': Permission denied - /home/ibc (Errno::EACCES)
        from (irb):3:in `block in irb_binding'
        from /tmp/kernel.rb:11:in `block in su'
        from /tmp/kernel.rb:9:in `fork'
        from /tmp/kernel.rb:9:in `su'
        from (irb):1:in `irb_binding'

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/

--
Iñaki Baz Castillo <ibc@aliax.net>