1 """The su (switch user) module allows you to execute commands as root.
5 proxy_maker = SuProxyMaker('I need root access to change /etc/fstab')
6 yield proxy_maker.blocker
7 root = proxy_maker.get_root()
9 call = root.open('/etc/fstab')
19 See rox.suchild for a list of operations available on the 'root' object.
24 from rox
import master_proxy
, tasks
28 _my_dir
= os
.path
.abspath(os
.path
.dirname(__file__
))
29 _child_script
= os
.path
.join(_my_dir
, 'suchild.sh')
31 class SuProxyMaker(tasks
.Blocker
):
34 def __init__(self
, message
):
35 """Displays a box prompting the user for a password.
36 Creates a new master_proxy.MasterObject and starts the child
37 process. The user is prompted for the root
42 exec_term
= get_term_command()
47 to_child
.writeable
.close()
48 from_child
.readable
.close()
49 to_parent
= from_child
.writeable
50 from_parent
= to_child
.readable
51 fcntl
.fcntl(to_parent
, fcntl
.F_SETFD
, 0)
52 fcntl
.fcntl(from_parent
, fcntl
.F_SETFD
, 0)
62 from_child
.writeable
.close()
63 to_child
.readable
.close()
65 self
._root
= master_proxy
.MasterProxy(to_child
.writeable
,
66 from_child
.readable
).root
68 self
.blocker
= self
._root
.getuid()
71 """Raises UserAbort if the user cancels."""
73 uid
= self
.blocker
.result
74 except master_proxy
.LostConnection
:
75 raise rox
.UserAbort("Failed to become root (cancelled "
76 "at user's request?)")
81 def get_term_command():
82 def present_in_PATH(command
):
83 for x
in os
.environ
['PATH'].split(':'):
84 if os
.access(os
.path
.join(x
, command
), os
.X_OK
):
87 if present_in_PATH('xterm'):
89 raise Exception('No suitable terminal emulator could be found. Try installing "xterm"')
91 def _exec_xterm(message
, to_parent
, from_parent
, root_user
):
92 os
.execlp('xterm', 'xterm',
94 '-title', 'Enter password',
99 str(to_parent
.fileno()),
100 str(from_parent
.fileno()),
104 """Contains Python file objects for two pipe ends.
105 Wrapping the FDs in this way ensures that they will
106 be freed on error."""
113 self
.readable
= os
.fdopen(r
, 'r')
118 self
.writeable
= os
.fdopen(w
, 'w')