/usr/sbin/rainbow-run is in rainbow 0.8.7-2.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | #!/usr/bin/python
import os
import sys
import pwd
import grp
from stat import S_ISREG, ST_MODE
from os.path import join, isdir
from optparse import OptionParser
from pprint import pformat
from rainbow.inject import inject
from rainbow.permissions import PermissionSet
from rainbow.util import make_reporter, enable_verbose_tracebacks
from rainbow.util import unshare, CLONE_NEWNS, read_envdir
enable_verbose_tracebacks()
def main():
parser = OptionParser(version='0.1')
parser.add_option('-v', '--verbose', default=0, action='count',
help='Verbosity. Repeat for more verbose output.')
parser.add_option('-q', '--quiet', default=False, action='store_true',
help='Quiet. Disable all output.')
parser.add_option('-s', '--spool', default=None,
help='Location of the rainbow spool.')
parser.add_option('-e', '--envdir', default=None,
help="Location of an envdir describing the desired environment.")
parser.add_option('-E', '--env', default=[], action='append',
help="Environment bindings to override.")
parser.add_option('-c', '--cwd', default=None,
help="Working directory.")
parser.add_option('-f', '--fd', default=[], action='append',
help="File descriptor number to leave open.")
parser.add_option('-i', '--id', default=[], action='append',
help="ID of shared-data group.")
parser.add_option('-o', '--option', default=[], action='append',
help="Options: video, audio, serial, constant-uid, x11, network.")
parser.add_option('-p', '--permissions', default=None,
help="Location of a permissions.info file.")
parser.add_option('-u', '--user', default=None,
help="Owning user.")
parser.add_option('-r', '--resume-user', default=None,
help="Resume <user>.")
parser.add_option('-a', '--assistant', default=None,
help="Task-specific assistant.")
parser.add_option('-G', '--group', default=[], action='append',
help="Extra groups.")
opts, args = parser.parse_args()
if len(args) == 0:
parser.print_help()
exit(1)
report = make_reporter(opts.verbose, opts.quiet, sys.stdout)
def check_spool(opts):
return opts.spool
def check_env(opts):
return read_envdir(opts.envdir, opts.env)
def check_argv(args):
return args
def check_cwd(opts):
return opts.cwd
def check_fds(opts):
return [int(s) for s in opts.fd]
def check_owner(opts):
p = pwd.getpwnam(opts.user)
return p.pw_uid, p.pw_gid
def check_groups(opts):
return [grp.getgrnam(g)[2] for g in opts.group]
def check_x11(opts):
return 'x11' in opts.option
def check_constant_uid(opts):
return 'constant-uid' in opts.option
def check_audio(opts):
return 'audio' in opts.option
def check_video(opts):
return 'video' in opts.option
def check_serial(opts):
return 'serial' in opts.option
def check_network(opts):
return 'network' in opts.option
def check_resume_user(opts):
uid = None
if opts.resume_user:
uid = pwd.getpwnam(opts.resume_user).pw_uid
assert 10000 <= uid and uid < 60000
return uid
def check_data_ids(opts):
return opts.id
def check_assistant(opts):
return opts.assistant
uid, gid = check_owner(opts)
spool = check_spool(opts)
# Use empty env? Use partial env? Fail unless perfect?
env = check_env(opts)
argv = check_argv(args)
cwd = check_cwd(opts)
safe_fds = check_fds(opts)
groups = check_groups(opts)
pset = PermissionSet(opts.permissions or [])
# Dirty hack -- pass 'constant-uid' and 'strace' in as permissions. <MS>
for perm in ('constant-uid', 'audio', 'video', 'serial', 'network'):
pset._permissions.setdefault(perm, locals()['check_'+perm.replace('-','_')](opts))
data_ids = check_data_ids(opts)
assistant = check_assistant(opts)
x11 = check_x11(opts)
resume_uid = check_resume_user(opts)
if resume_uid: report(1, "resuming uid (%d)", resume_uid)
args = (report, spool, env, argv, cwd, pset, safe_fds, uid, gid, resume_uid, groups, data_ids, assistant, x11)
report(1, 'rainbow:\n%s', pformat(args))
unshare(CLONE_NEWNS)
return inject(*args)
if __name__ == '__main__':
main()
# vim : et sw=4 ts=4 sts=4 :
|