davydany / sultan

Sultan: Command and Rule over your Shell
https://sultan.readthedocs.io/en/latest/
MIT License
680 stars 35 forks source link

question: context manager on a new bash or "su -" shell #43

Closed pdonorio closed 7 years ago

pdonorio commented 7 years ago

Hello there, thanks for this very cool project!

I didn't understand if it's possible to use the with Sultan.load block to emulate a new user (like the su - USER command) or eventually a new bash with new variables.

davydany commented 7 years ago

Try this: http://sultan.readthedocs.io/en/latest/sultan-examples.html#example-7-running-as-another-user

davydany commented 7 years ago

I'm closing this since there was no feedback. Also, checkout Sultan 0.6, just released today.

pdonorio commented 7 years ago

Oops, sorry! I forgot about this issue buried in a big pile of tasks :)

I created with Docker (I plan to work with sultan inside containers) a test which didn't work, if you get a chance you may try the same steps to reproduce it:

  1. Run latest python with the alpine small image:
docker run -it --rm python:3.6.2-alpine3.6 ash
# install sudo 
apk update && apk add sudo
# and the sultan package
pip3 install --upgrade ipython sultan
  1. Add two users, one will be able to become the other(s)
adduser -D master
adduser -D slave
# set password for master to test sudo
yes 'somepass' | passwd master
# add master to sudoers
visudo
# At 'User privilege specification' add: master ALL=(ALL) ALL
# SHIFT + zz to save and close
  1. Test with normal shell
# add a file into slave's home
su - slave -c 'touch empty'
# become the master and do things
su - master
# test the command
sudo su - slave -c 'ls -l'
# insert the password 'somepass'
# and it works

# prepare for python
ipython
  1. Test with sultan
from sultan.api import Sultan
user = 'slave'

with Sultan.load(sudo=True, user=user, cwd='/home/' + user) as s:
     s.ls('-lah', '.').run()

# error
# [sultan]: | sudo: su: command not found

Thank you

davydany commented 7 years ago

what does which sudo return for you?

davydany commented 7 years ago

I haven’t really worked with Alpine but when I ran it in the alpine image you gave the command which sudo, and it retuned with nothing which means that the command was not found. I suspect this is why it is not running for you.

davydany commented 7 years ago

Did some more digging.

Here is a workaround to get this working for you, for now. You will need to install sudo from apk, but by default, it isn't included in the image you used. To add it, do the following:

  1. Add http://dl-4.alpinelinux.org/alpine/edge/main/x86/ to /etc/apk/repositories (add to the end of the file)
  2. Run apk update
  3. Run apk add sudo

I'm still going to keep this ticket open because if the user is root, there is no need to run the command with sudo prepended to the command, which is the case when you login to a docker image. So, I'll add that fix, which (in the long term) will fix this issue for you without installing sudo on alpine.

davydany commented 7 years ago

I fixed it and pushed the change to https://github.com/aeroxis/sultan/tree/development-0.7. You can install it from this branch if you'd like to test it out and make sure it works like you intend it.

pdonorio commented 7 years ago

Sorry maybe you missed the apk update && apk add sudo line in the first block of my experiment, so that was not my issue.

Will run now a new test with the development version.

pdonorio commented 7 years ago

Ok tested by changing the pip command into:

apk add git
pip3 install --upgrade ipython git+https://github.com/aeroxis/sultan.git@development-0.7

The problem is still there with python + sultan:

sudo: su: command not found

which seems like the "su" command is not allowed or found for sudo.

Note that sultan tells me that the equivalent command executed is sudo su - slave -c 'cd /home/slave && ls -lah .;' which I can run perfectly outside of Python, so the issue seems to be related to python/sultan environment.

If you want I can test with a docker image based on ubuntu to restrict the circle of problems.

davydany commented 7 years ago

I can recreate this issue. I'll look into this later today after work, and get back to you. Thank you for your feedback!

pdonorio commented 7 years ago

Thank to you for dedicating your time to this. Please ask me anything to help.

davydany commented 7 years ago

I think I know what's going on now. Like you said, this was with the environment between python and sultan. I was setting the env to {} if no env was provided, but POpen expects None if env we don't want to pass a value, and it'll take the default value from the current process' environment.

More details here: https://docs.python.org/2/library/subprocess.html#popen-constructor

If env is not None, it must be a mapping that defines the environment variables for the new process; these are used instead of inheriting the current process’ environment, which is the default behavior.
davydany commented 7 years ago

Also, I changed the branch to development-0.6.4 since I want to release this as a bug fix ASAP. https://github.com/aeroxis/sultan/tree/development-0.6.4

Can you test it on your end and let me know if it works for you. I'll release this as 0.6.4 if it goes well on your end. Here is what I saw on my end:

In [1]: from sultan.api import Sultan
   ...:
   ...: user = 'slave'
   ...:
   ...: with Sultan.load(sudo=True, user=user, cwd='/home/' + user) as s:
   ...:      for line in s.ls('-lah', '.').run().stdout:
   ...:          print(line)
   ...:
[sultan]: sudo su - slave -c 'cd /home/slave && ls -lah .;'
total 8
drwxr-sr-x    2 slave    slave       4.0K Sep 12 04:12 .
drwxr-xr-x    1 root     root        4.0K Sep 12 04:12 ..
pdonorio commented 7 years ago

Testing now the development-0.6.4 branch with the same procedure and it works:

In [9]: res.stdout
Out[9]:
['total 8',
 'drwxr-sr-x    2 slave    slave       4.0K Sep 12 05:57 .',
 'drwxr-xr-x    1 root     root        4.0K Sep 12 05:57 ..',
 '-rw-r--r--    1 slave    slave          0 Sep 12 05:57 empty']

You can close this issue, at least for me. Thank you a lot!

davydany commented 7 years ago

👍 0.6.4 released.