0

My script needs to execute as root, and for some tasks as someuser, I also need to get someuser $HOME path, and thats where comes the problem.

For that job (find user home) I'm using os.path.expanduser.

As mentioned the script needs to change his user with su and run the code to get user home:

test_home.py

from os.path import expanduser

def user_home():
    home = expanduser("~")
    return home

print user_home()

The main script calls the test_home.py with su:

# su someuser -c /tmp/test_home.py
/home/someuser

Perfectly fine. But for AIX and Solaris the script doesn't get someuser $HOME, instead, it gets the root $HOME.

AIX: Executing as root

su someuser -c /tmp/test_home.py
/

Solaris: Executing as root

su someuser -c /tmp/test_home.py
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
/root

I've tested this code on several distros:

  1. RedHat
  2. SLES
  3. HP-UX
  4. AIX
  5. Solaris
  6. Debian

The problem it's only on AIX and Solaris. Does anyone knows why?

UPDATE

Using login with with - or -l works, but I can't use su - on my script. Any thoughts on how to overcome this?

I was trying to not use a shell approach like the above but I'm getting out of options

cat /etc/passwd | grep someuser | cut -d: -f 6

Bernardo Vale
  • 3,224
  • 4
  • 21
  • 34
  • I'm surprised it worked on the other systems. To get an environment as though you logged in you want `su -l someuser -c /tmp/test_home.py`. Does that work for you? – tdelaney Mar 06 '16 at 00:11
  • Hi @tdelaney, no, even when you use `-l` to login it doesn't work – Bernardo Vale Mar 06 '16 at 00:15
  • 1
    Looking at the [aix docs](https://www-01.ibm.com/support/knowledgecenter/ssw_aix_72/com.ibm.aix.cmds5/su.htm), it says just a dash (`-`) instead of `-l`. Linux takes both. Other than that, I've no idea what to do. – tdelaney Mar 06 '16 at 00:18
  • @tdelaney, it works with `-` but unfortunetly, I can't use this option on my main script, because it's ansible who does the privilege escalation and it doesn't support login as far as a know – Bernardo Vale Mar 06 '16 at 00:31
  • What 'login' do you mean? Instead of this: `su projects -c 'echo $HOME'` use this: `su - projects -c 'echo $HOME'` – Zsigmond Lőrinczy Mar 06 '16 at 11:14
  • Or simply: `echo ~someuser` – Zsigmond Lőrinczy Mar 06 '16 at 11:49
  • 1
    It's not clear though why python is mixed into the question. What is your real problem? http://www.catb.org/esr/faqs/smart-questions.html#idm46469134009424 – Zsigmond Lőrinczy Mar 06 '16 at 11:53
  • Why *can't* you use `su - user -c /tmp/test_home.py`? – Andrew Henle Mar 06 '16 at 15:32
  • @AndrewHenle, the code it's called by Ansible using privilege escalation, it doesn't support "su - " – Bernardo Vale Mar 08 '16 at 00:54
  • What `become_method` are you using? – Mark Plotnick Mar 08 '16 at 01:10
  • @BernardoVale *The main script calls the test_home.py with `su`* So call **something else** with Ansible using privilege escalation that then calls `su - user -c /tmp/test_home.py`. You might want to call it something like `shellScriptThatCallsMyPythonScriptWithTheFullEnvironmentOfTheUser.sh`. And put this inside: `su - user -c /tmp/test_home.py` – Andrew Henle Mar 08 '16 at 02:19
  • @MarkPlotnick I'm using `become_method: su` – Bernardo Vale Mar 08 '16 at 02:22
  • @AndrewHenle, this will work but it's not the best solution for my problem, because it requires me send `test_home.py` to all servers before I can execute `shellScriptThatCallsMyPythonScriptWithTheFullEnvironmentOfTheUser.sh` – Bernardo Vale Mar 08 '16 at 02:25
  • @OP I think you had a question regarding this "ansible", but instead of asking it, you asked something remotely related, and misled everyone. It's rather annoying, I should say. – Lorinczy Zsigmond Mar 08 '16 at 05:27
  • 1
    There are a couple answers in http://stackoverflow.com/questions/2668909/how-to-find-the-real-user-home-directory-using-python that may help. In a noninteractive setting, environment variables may be wrong or missing, so rather than calling expanduser with a lone `~`; call it with `~user` or use `pwd.getpwuid(os.getuid()).pw_dir`. Or possibly (I haven't tested this) use `become_method: sudo` and ensure that sudoers has `always_set_home`. – Mark Plotnick Mar 08 '16 at 09:19
  • @BernardoVale *this will work but it's not the best solution for my problem, because it requires me send `test_home.py` to all servers* You have to send that file to the servers you want to execute it on no matter how you invoke it. – Andrew Henle Mar 08 '16 at 10:51
  • It won't help your portability, but on Solaris you can use profiles (https://docs.oracle.com/cd/E23824_01/html/821-1456/rbacref-26.html) and pfexec. – Paul Floyd Jul 13 '17 at 12:53

2 Answers2

0

I faced same issue, after using sudo or su , It was giving root home directory, I fixed with below way:

akjha-mn2:~ akjha$ python test1
/Users/akjha
akjha-mn2:~ akjha$ sudo python test1
Password:
/Users/akjha
akjha-mn2:~ akjha$ cat test1
#!/bin/env python
import os
user1=os.getlogin()
home=os.path.expanduser("~{0}".format(user1))
print home
akjha-mn2:~ akjha$
Aashutosh jha
  • 552
  • 6
  • 8
0
import socket
import os
import time
import sys
import pwd


###############################################################################
# Set uid and gid
###############################################################################

def set_uid_gid( uid, gid ):
    os.setgid(gid)
    os.setuid(uid)
###############################################################################
# Set effective uid and gid
###############################################################################
def set_effective_uid_gid( uid, gid ):
    os.setegid(gid)
    os.seteuid(uid)

###############################################################################
# Get uid and gid
###############################################################################

def get_uid_gid():
    uid = os.getuid()
    gid = os.getgid()
    return( uid, gid )
###############################################################################
def get_euid_egid():
    uid = os.geteuid()
    gid = os.getegid()
    return( uid, gid )

###############################################################################
def get_uid_gid_for_user( username):
    pwd_obj = pwd.getpwnam(username)
    uid = pwd_obj.pw_uid
    gid = pwd_obj.pw_gid
    return( uid, gid)

#Switch to <SOMEUSER>
def switch_user():
    (original_uid , original_gid) = get_uid_gid()
    (analyst_uid , analyst_gid) = get_uid_gid_for_user("<SOMEUSER>")
    set_effective_uid_gid(analyst_uid ,analyst_gid)
    os.system('python run_this_script,py')
    #Switch back to root/original
    set_uid_gid(original_uid , original_gid)
Ajay2588
  • 527
  • 3
  • 6