def setup(config): siteuser = passwd.getpwnam(config.SITEUSER) siteowner = passwd.getpwnam(config.SITEOWNER) logroot = config.get("LOGROOT", "/var/log/lighttpd") fqdn = socket.get_fqdn() def _mkdir(path): if not os.path.isdir(path): os.mkdir(path, 0755) os.chown(path, siteowner.uid, siteowner.gid) for vhost in config.VHOSTS.keys(): vhostdir = config.SITEROOT + "/" + vhost vhostlogdir = logroot + "/" + vhost if not os.path.isdir(vhostlogdir): os.mkdir(vhostlogdir, 0755) os.chown(vhostlogdir, siteuser.uid, siteuser.gid) if not os.path.isdir(vhostdir): if fqdn == vhost: os.symlink(config.SITEROOT + "/localhost", vhostdir) else: _mkdir(vhostdir) _mkdir(vhostdir + "/htdocs") _mkdir(vhostdir + "/htdocs-secure") _mkdir(vhostdir + "/media") _mkdir(vhostdir + "/media/js") _mkdir(vhostdir + "/media/css") _mkdir(vhostdir + "/media/images")
def get_server(config): username = config.get("USERNAME") if username and os.getuid() == 0: pwent = passwd.getpwnam(username) else: pwent = None pm = ProcessManager(pwent) app = framework.FrameworkAdapter(config) if "MIDDLEWARE" in config: for mwtuple in config["MIDDLEWARE"]: mwobj = module.get_object(mwtuple[0]) args = mwtuple[1:] app = mwobj(app, *args) if config.DEBUG: logging.loglevel_debug() return FCGIServer(app, procmanager=pm, bindAddress=config.SOCKETPATH, errorhandler=None, umask=config.get("SOCKET_UMASK", 0), debug=config.DEBUG)
def add(self, argv): """add [--first_name=<firstname> --last_name=<lastname>] <username> Add a new user to the database.""" args, kwargs = CLI.breakout_args(argv[1:], self._environ) username = args[0] try: pwent = passwd.getpwnam(username) except KeyError: pass else: models.create_user(_session, pwent) return grp = _session.query(models.Group).filter(models.Group.name=="testers").one() kwargs["username"] = username kwargs["authservice"] = "local" kwargs.setdefault("is_staff", True) kwargs.setdefault("is_active", True) kwargs.setdefault("is_superuser", False) if "first_name" not in kwargs: kwargs["first_name"] = self._user_input("First Name? ") if "last_name" not in kwargs: kwargs["last_name"] = self._user_input("Last Name? ") user = models.create(models.User, **kwargs) user.groups = [grp] _session.add(user) _session.commit()
def get_or_create_User(username): try: user = _dbsession.query(models.User).filter(models.User.username==username).one() except models.NoResultFound: pwent = passwd.getpwnam(username) user = models.create_user(_dbsession, pwent) return user
def robots(config): from pycopia import passwd user = passwd.getpwnam(config.SITEOWNER) for vhost, scripts in config.VHOSTS.items(): rname = os.path.join(config.SITEROOT, vhost, "htdocs", "robots.txt") fo = open(rname, "w") fo.write(_get_robots_txt(scripts)) fo.close() os.chown(rname, user.uid, user.gid)
def pipe(self, cmd, user=None): """Run a subprocess, but connect by pipes rather than pty.""" logging.msg("pipe", cmd, "user=", str(user)) pm = proctools.get_procmanager() if type(user) is str: user = passwd.getpwnam(user) proc = pm.spawnpipe(cmd, pwent=user, callback=self._status_cb) text = proc.read() sts = proc.wait() proc.close() return sts, text
def run(self, cmd, user=None): """Run a subprocess, wait for completion and return status and stdout as text. """ logging.msg("run", cmd, "user=", str(user)) pm = proctools.get_procmanager() if type(user) is str: user = passwd.getpwnam(user) proc = pm.spawnpty(cmd, pwent=user) text = proc.read() sts = proc.wait() proc.close() return sts, text
def robots(config): user = passwd.getpwnam(config.SITEOWNER) for vhost, scripts in list(config.VHOSTS.items()): rname = os.path.join(config.SITEROOT, vhost, "htdocs", "robots.txt") if os.path.exists(rname): if config.FORCE: bakname = rname + ".bak" if os.path.exists(bakname): os.unlink(bakname) os.rename(rname, bakname) else: continue with open(rname, "w") as fo: fo.write(_get_robots_txt(scripts)) os.chown(rname, user.uid, user.gid)
def get_server(config): username = config.get("USERNAME") if username and os.getuid() == 0: pwent = passwd.getpwnam(username) else: pwent = None pm = ProcessManager(pwent) app = framework.WebApplication(config) if config.DEBUG: pass #from paste.evalexception.middleware import EvalException #app = EvalException(app) return FCGIServer(app, procmanager=pm, bindAddress=config.SOCKETPATH, umask=config.get("SOCKET_UMASK", 0), debug=config.DEBUG)
def get_server(config): username = config.get("USERNAME") middleware = config.get("MIDDLEWARE", []) if username and os.getuid() == 0: pwent = passwd.getpwnam(username) else: pwent = None app = module.get_object(config.APP_LOCATION) if config.DEBUG: logging.loglevel_debug() for mwtuple in middleware: mwobj = module.get_object(mwtuple[0]) args = mwtuple[1:] app = mwobj(app *args) return SCGIServer(app, config.SOCKETPATH, umask=config.get("SOCKET_UMASK", 0), pwent=pwent, debug=config.DEBUG)
def get_server(config): username = config.get("USERNAME") middleware = config.get("MIDDLEWARE", []) if username and os.getuid() == 0: pwent = passwd.getpwnam(username) else: pwent = None app = module.get_object(config.APP_LOCATION) if config.DEBUG: logging.loglevel_debug() for mwtuple in middleware: mwobj = module.get_object(mwtuple[0]) args = mwtuple[1:] app = mwobj(app * args) return SCGIServer(app, config.SOCKETPATH, umask=config.get("SOCKET_UMASK", 0), pwent=pwent, debug=config.DEBUG)
class PosixAgent(object): def __init__(self): self._files = {} self._status = {} # holds async process pids self._dirstack = [] def platform(self): return sys.platform def whatami(self): """Return agent implementation (class name).""" return self.__class__.__name__ # Since file objects are not pickle-able, a handle is returned. Use the # handle for subsequent file operations on f* methods. def fopen(self, fname, mode="r", bufsize=-1): "Opens a file object and returns a handle to it." fo = PosixFile(fname, mode, bufsize) handle = fo.fileno() self._files[handle] = fo return handle def fclose(self, handle): "Closes a file object given the handle." fo = self._files.get(handle, None) if fo: fo.close() del self._files[handle] def fread(self, handle, amt=-1): "Reads from the file object given the handle and amount to read." fo = self._files.get(handle, None) if fo: return fo.read(amt) else: return '' def fwrite(self, handle, data): "Writes to a file object given the handle." fo = self._files.get(handle, None) if fo: return fo.write(data) def fsync(self, handle): "fsync the file object." fo = self._files.get(handle, None) if fo: fo.flush() return os.fsync(fo.fileno()) def fseek(self, handle, pos, how=0): "Seek in the file object." fo = self._files.get(handle, None) if fo: return fo.seek(pos, how) def ftell(self, handle): "Tell where the seek pointer is in the file object." fo = self._files.get(handle, None) if fo: return fo.tell() def fflush(self, handle): """Flush the file object buffer.""" fo = self._files.get(handle, None) if fo: return fo.flush() def fileno(self, handle): "Return the file objects file descriptor." fo = self._files.get(handle, None) if fo: return fo.fileno() def flock(self, handle, length=0, start=0, whence=0, nonblocking=False): """Lock the file with the given range.""" fo = self._files.get(handle, None) if fo: return fo.lock_exclusive(length, start, whence, nonblocking) def funlock(self, handle, length, start=0, whence=0): fo = self._files.get(handle, None) if fo: fo.unlock(length, start, whence) def fstat(self, handle): fo = self._files.get(handle, None) if fo: return os.fstat(fo.fileno()) def fstatvfs(self, handle): fo = self._files.get(handle, None) if fo: return os.fstatvfs(fo.fileno()) def ftruncate(self, handle, length): fo = self._files.get(handle, None) if fo: return os.ftruncate(fo.fileno(), length) def flist(self): return self._files.keys() def get_handle_info(self, handle): fo = self._files.get(handle, None) if fo: return repr(fo) # XXX else: return None def unlink(self, path): "Unlink (delete) the given file." return os.unlink(path) def rename(self, src, dst): "Rename file from src to dst." return os.rename(src, dst) # directory methods def mkdir(self, path, mode=0777): "Make a directory." return os.mkdir(path, mode) def makedirs(self, path, mode=0777): "Make a full path." return os.makedirs(path, mode) def chdir(self, path): return os.chdir(path) def rmdir(self, path): "Delete a directory." return os.rmdir(path) def getcwd(self): return os.getcwd() def getcwdu(self): return os.getcwdu() def pushd(self, path=None): self._dirstack.append(os.getcwd()) if path: os.chdir(path) def popd(self): try: path = self._dirstack.pop() except IndexError: return None else: os.chdir(path) return path def get_pwent(self, name=None, uid=None): if uid is not None: return passwd.getpwuid(int(uid)) return passwd.getpwnam(name) def listdir(self, path): return os.listdir(path) def listfiles(self, path): isfile = os.path.isfile pjoin = os.path.join rv = [] for fname in os.listdir(path): if isfile(pjoin(path, fname)): rv.append(fname) return rv def chmod(self, path, mode): return os.chmod(path, mode) def chown(self, path, uid, gid): return os.chown(path, uid, gid) def stat(self, path): return os.stat(path) def statvfs(self, path): return os.statvfs(path) # fd ops ruturn the file descript as handle (of course) def open(self, fname, flags, mode=0777): fd = os.open(fname, mode) return fd def close(self, fd): return os.close(fd) def write(self, fd, data): return os.write(fd, data) def read(self, fd, n): return os.read(fd, n) # end fd ops # shutil interface def copyfile(self, src, dst): return shutil.copyfile(src, dst) def copymode(self, src, dst): return shutil.copymode(src, dst) def copystat(self, src, dst): return shutil.copystat(src, dst) def copy(self, src, dst): return shutil.copy(src, dst) def copy2(self, src, dst): return shutil.copy2(src, dst) def copytree(self, src, dst, symlinks=False): return shutil.copytree(src, dst, symlinks) def move(self, src, dst): return shutil.move(src, dst) def rmtree(self, path): self._rmtree_errors = [] shutil.rmtree(path, ignore_errors=True, onerror=self._rmtree_error_cb) return self._rmtree_errors def _rmtree_error_cb(self, func, arg, exc): self._rmtree_errors.append((str(arg), str(exc[1]))) # os.path delegates def exists(self, path): return os.path.exists(path) def isabs(self, path): return os.path.isabs(path) def isdir(self, path): return os.path.isdir(path) def isfile(self, path): return os.path.isfile(path) def islink(self, path): return os.path.islink(path) def ismount(self, path): return os.path.ismount(path) def system(self, cmd): return proctools.system("%s >/dev/null 2>&1" % cmd) def run(self, cmd, user=None): """Run a subprocess, wait for completion and return status and stdout as text. """ logging.msg("run", cmd, "user="******"""Run a subprocess, but connect by pipes rather than pty.""" logging.msg("pipe", cmd, "user="******"""Spawn a subprocess and return immediatly.""" pm = proctools.get_procmanager() if type(user) is str: user = passwd.getpwnam(user) proc = pm.spawnpty(cmd, callback=self._status_cb, pwent=user, async=async)
def switch_user(username): pwent = passwd.getpwnam(username) proctools.run_as(pwent)
def get_pwent(self, name=None, uid=None): if uid is not None: return passwd.getpwuid(int(uid)) return passwd.getpwnam(name)
def newuser(argv): """Create a new user newuser [-Mm] [<longopts>] <username> Options: -M Do NOT make home directory. -m Only make home directory for existing user with no home directory. Where long options are: --first_name=<firstname> --last_name=<lastname> --password=<newpass> --shell=<shell> --home=<home> You will be prompted for missing information. This function should be run as root user. """ makehome = True onlyhome = False try: opts, longopts, args = getopt.getopt(argv[1:], "h?Mm") except getopt.GetoptError: print(newuser.__doc__) return for opt, optarg in opts: if opt in ("-?", "-h"): print(newuser.__doc__) return elif opt == "-M": makehome = False elif opt == "-m": onlyhome = True try: username = args[0] except IndexError: username = cliutils.get_input("Account name? ") try: pwent = passwd.getpwnam(username) except KeyError: pass else: if onlyhome: make_homedir(pwent.home, pwent.uid, pwent.gid) return else: print("User already exists, exiting.", file=sys.stderr) return password = longopts.get("password") if not password: password = ask_password() if not password: print("Passwords do not match, exiting.", file=sys.stderr) return # Get maximum UID value from passwd and database, not including system ones. uidl = [pwe.uid for pwe in passwd.getpwall() if pwe.uid < 10000] dblist = [u.uid for u in models.dbsession.query(models.User).all()] uidl.extend(dblist) uid = max(uidl) + 1 first_name = longopts.get("first_name") if not first_name: first_name = cliutils.get_input("First Name? ") last_name = longopts.get("last_name") if not last_name: last_name = cliutils.get_input("Last Name? ") gecos = "{}, {}".format(last_name, first_name) shell = longopts.get("shell") if not shell: shell = cliutils.get_input("Shell? ", default="/bin/sh") home = longopts.get("home") if not home: home = cliutils.get_input("Homedir? ", default="/home/{}".format(username)) email = longopts.get("email") if not email: email = cliutils.get_input("Email? ") primary_grp = models.dbsession.query(models.Group).filter(models.Group.groupname == "users").one() glist = models.dbsession.query(models.Group).all() glist.remove(primary_grp) sup_groups = cliutils.choose_multiple(glist, prompt="Extra groups?") superuser = cliutils.yes_no("Is admin?") user = models.create( models.User, username=username, uid=uid, gid=primary_grp.gid, gecos=gecos, first_name=first_name, last_name=last_name, shell=shell, homedir=home, email=email, is_superuser=superuser, is_active=True, ) user.password = password models.dbsession.add(user) models.dbsession.commit() user.groups = sup_groups models.dbsession.commit() new_shadow(username, password) if makehome: make_homedir(home, user.uid, user.gid) return user