Question

I'm trying to run a python script as other user (not root) which is also a system user with no shell. I understand that I can't set suid flag directly on the script so I wrote a C++ wrapper.

wrapper.cpp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>

int main(void)
{
    std::cout << geteuid() << std::endl;

    setgid(getgid());
    setuid(getuid());

    execl("/usr/bin/python2.6", "/usr/bin/python2.6", "test.py", NULL);
}

And set following permissions

sudo chown NoShellUser:NoShellGroup /path/to/wrapper
sudo chmod 7755 /path/to/wrapper

Finally, to try it out I have a python script

import sys
import getpass
import os
import pwd
print "VERSION:", sys.version
print "USER:", getpass.getuser(), pwd.getpwuid(os.getuid())
print "EUSER:", pwd.getpwuid(os.geteuid())

With following permissions if that matters at all

sudo chown NoShellUser:NoShellGroup /path/to/test.py
sudo chmod 7755 /path/to/test.py

Now when I run this whole thing as user "test" I see this:

255                                                    # UID of NoShellUser
VERSION: 2.6.8 (unknown, Apr 12 2012, 20:59:36)        # Don't know where that comes from
[GCC 4.1.2 20080704 (Red Hat 4.1.2-52)]                # Don't know where that comes from
USER: test pwd.struct_passwd(pw_name='test', pw_passwd='hash', pw_uid=20804, pw_gid=604, pw_gecos='Name Surname', pw_dir='/home/test', pw_shell='/bin/bash')
EUSER: pwd.struct_passwd(pw_name='test', pw_passwd='hash', pw_uid=20804, pw_gid=604, pw_gecos='Name Surname', pw_dir='/home/test', pw_shell='/bin/bash')

As you can see the effective user is still "test". Can somebody please point to me what am I doing wrong, because I looked at few examples already and they all seems to be showing exact same thing more or less?

Was it helpful?

Solution

Your wrapper is slightly wrong - try this instead

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>

int main(void)
{
  std::cout << "Real user " << getuid() << std::endl;
  std::cout << "Effective user " << geteuid() << std::endl;

  setregid(getegid(), getegid());
  setreuid(geteuid(), geteuid());

  std::cout << "Real user " << getuid() << std::endl;
  std::cout << "Effective user " << geteuid() << std::endl;

  execl("/usr/bin/python2.6", "/usr/bin/python2.6", "test.py", NULL);
}

It sets the real and effective user/group ids to the effective group id before execing the python script.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top