#!/usr/bin/python # Run a command as another user. import sys, os, pwd, grp, signal, optparse def main(): parser = optparse.OptionParser(usage="usage: %prog USER COMMAND ...") parser.disable_interspersed_args() parser.add_option("--home", help="Home directory to create and pass in $HOME", metavar="DIR") (options, args) = parser.parse_args() if len(args) < 2: parser.error("too few arguments") username = args[0] command = args[1:] passwd = pwd.getpwnam(username) groups = [group.gr_gid for group in grp.getgrall() if username in group.gr_mem] if options.home: home = options.home try: os.makedirs(home) except OSError: pass os.chown(home, passwd.pw_uid, passwd.pw_gid) os.chmod(home, 0755) else: home = passwd.pw_dir os.setgid(passwd.pw_gid) os.setgroups(groups) os.setuid(passwd.pw_uid) os.putenv("LOGNAME", username) os.putenv("HOME", home) # Python ignores SIGPIPE by default, which will confuse many child # processes. signal.signal(signal.SIGPIPE, signal.SIG_DFL) os.execvp(command[0], command) if __name__ == "__main__": main()