Skip to content

Commit

Permalink
* Experimental support for setting UID.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomekwojcik committed Mar 26, 2013
1 parent 296894d commit 5011bde
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion sh.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
from functools import partial
import inspect
import time as _time
import pwd

from locale import getpreferredencoding
DEFAULT_ENCODING = getpreferredencoding() or "utf-8"
Expand Down Expand Up @@ -472,6 +473,10 @@ class Command(object):
# the output is being T'd to both the redirected destination and our
# internal buffers
"tee": None,

# UID to set after forking. Requires root privileges. Not supported on
# Windows.
"uid": None,
}

# these are arguments that cannot be called together, because they wouldn't
Expand Down Expand Up @@ -746,6 +751,18 @@ def __init__(self, cmd, stdin, stdout, stderr, call_args,

self.call_args = call_args

if self.call_args['uid'] is not None:
if os.getuid() != 0:
raise RuntimeError('UID setting requires root privileges')

self.call_args["tty_in"] = False
self.call_args["tty_out"] = False

target_uid = self.call_args['uid']

pwrec = pwd.getpwuid(self.call_args['uid'])
target_gid = pwrec.pw_gid

self._single_tty = self.call_args["tty_in"] and self.call_args["tty_out"]

# this logic is a little convoluted, but basically this top-level
Expand Down Expand Up @@ -781,7 +798,7 @@ def __init__(self, cmd, stdin, stdout, stderr, call_args,
# by the time the process exits, and the data will be lost.
# i've only seen this on OSX.
if stderr is not STDOUT:
self._stderr_fd, self._slave_stderr_fd = os.pipe()
self._stderr_fd, self._slave_stderr_fd = os.pipe()

gc_enabled = gc.isenabled()
if gc_enabled: gc.disable()
Expand All @@ -797,6 +814,10 @@ def __init__(self, cmd, stdin, stdout, stderr, call_args,
if IS_OSX and IS_PY3: _time.sleep(0.01)

os.setsid()

if call_args['uid'] is not None:
os.setgid(target_gid)
os.setuid(target_uid)

if self.call_args["tty_out"]:
# set raw mode, so there isn't any weird translation of newlines
Expand Down

0 comments on commit 5011bde

Please sign in to comment.