diff options
| author | Michael E Brown <michael_e_brown@dell.com> | 2007-10-18 14:56:58 -0500 |
|---|---|---|
| committer | Michael E Brown <michael_e_brown@dell.com> | 2007-10-18 14:56:58 -0500 |
| commit | 060fa0302eede2d5bb96d9c45d01492caa0c5f8a (patch) | |
| tree | 3678a0dc76c164c60f4070031344f57a53e8fc8e | |
| parent | 5b73769f58296bf218895037471d3b109d8170fa (diff) | |
| download | mock-060fa0302eede2d5bb96d9c45d01492caa0c5f8a.tar.gz mock-060fa0302eede2d5bb96d9c45d01492caa0c5f8a.tar.xz mock-060fa0302eede2d5bb96d9c45d01492caa0c5f8a.zip | |
change uidManager to push/pop so we can overlap regions. enforce naming convention on all class functions.
| -rwxr-xr-x | src/mock.py | 8 | ||||
| -rw-r--r-- | src/py-libs/backend.py | 64 | ||||
| -rw-r--r-- | src/py-libs/uid.py | 50 |
3 files changed, 77 insertions, 45 deletions
diff --git a/src/mock.py b/src/mock.py index 5046690..c04c029 100755 --- a/src/mock.py +++ b/src/mock.py @@ -187,7 +187,9 @@ def main(): try: # do whatever we're here to do - chroot = mock.backend.Root(config_opts, mock.uid.uidManager()) + # uidManager saves current real uid/gid which are unpriviledged (callers) + # due to suid helper, our current effective uid is 0 + chroot = mock.backend.Root(config_opts, mock.uid.uidManager(os.getuid(), os.getgid())) if config_opts['clean']: chroot.clean() @@ -203,7 +205,7 @@ def main(): chroot._mountall() try: cmd = ' '.join(args[1:]) - output = chroot.do_chroot(cmd, env="PS1='mock-chroot> '", interactive=1, raiseExc=0) + output = chroot.doChroot(cmd, env="PS1='mock-chroot> '", interactive=1, raiseExc=0) finally: chroot._umountall() @@ -211,7 +213,7 @@ def main(): chroot.init() chroot._mountall() try: - output = chroot.do_chroot("/bin/bash", env="PS1='mock-chroot> '", interactive=1, raiseExc=0) + output = chroot.doChroot("/bin/bash", env="PS1='mock-chroot> '", interactive=1, raiseExc=0) finally: chroot._umountall() diff --git a/src/py-libs/backend.py b/src/py-libs/backend.py index 31d966b..3b3c63e 100644 --- a/src/py-libs/backend.py +++ b/src/py-libs/backend.py @@ -130,7 +130,7 @@ class Root(object): # --> no /etc/yum.conf symlink (F7 and above) self.root_log.debug("elevating privs") - self.uidManager.elevatePrivs() + self.uidManager.becomeUser(0,0) # create our base directory heirarchy mock.util.mkdirIfAbsent(self.basedir) @@ -221,15 +221,15 @@ class Root(object): self._umountall() # create user - self._make_our_user() + self._makeBuildUser() # create rpmbuild dir - self._build_dir_setup() + self._buildDirSetup() # done with init @traceLog(moduleLog) - def do_chroot(self, command, env="", *args, **kargs): + def doChroot(self, command, env="", *args, **kargs): """execute given command in root""" cmd = "%s /usr/sbin/chroot %s %s" % (env, self.rootdir, command) return mock.util.do(cmd, *args, **kargs) @@ -248,7 +248,7 @@ class Root(object): arg_string = arg_string + " '%s'" % item finally: - self.uidManager.elevatePrivs() + self.uidManager.restorePrivs() # everything exists, okay, install them all. # pass build reqs (as strings) to installer @@ -261,6 +261,11 @@ class Root(object): self._yum('install %s' % arg_string) + # + # UNPRIVLEGED: + # Everything in this function runs as the build user + # -> except the pre/post hooks + # @traceLog(moduleLog) def build(self, srpm, timeout): """build an srpm into binary rpms, capture log""" @@ -268,16 +273,16 @@ class Root(object): # tell caching we are building self._callHooks('prebuild') - self.state("setup") - self.installSrpmDeps( [srpm,] ) # runs partially unprivileged - - self.state("build") - srpmChrootFilename = self._copySrpmIntoChroot(srpm) # runs unprivileged - srpmBasename = os.path.basename(srpmChrootFilename) - self._mountall() self.uidManager.becomeUser(self.chrootuid) try: + self.state("setup") + self.installSrpmDeps( [srpm,] ) # runs partially unprivileged + + self.state("build") + srpmChrootFilename = self._copySrpmIntoChroot(srpm) # runs unprivileged + srpmBasename = os.path.basename(srpmChrootFilename) + # install srpm # rebuild srpm @@ -285,7 +290,7 @@ class Root(object): cmd = "rpmbuild --rebuild --target %s --nodeps %s" % ( self.target_arch, srpmChrootFilename ) - self.do_chroot(cmd, env=env, logger=self.build_log, timeout=timeout, output=0) + self.doChroot(cmd, env=env, logger=self.build_log, timeout=timeout, output=0) bd_out = self.rootdir + self.builddir rpms = glob.glob(bd_out + '/RPMS/*.rpm') @@ -297,7 +302,7 @@ class Root(object): shutil.copy2(item, self.resultdir) finally: - self.uidManager.elevatePrivs() + self.uidManager.restorePrivs() self._umountall() # tell caching we are done building @@ -357,12 +362,12 @@ class Root(object): continue @traceLog(moduleLog) - def _ccache_build_hook(self): + def _ccacheBuildHook(self): mock.util.do("CCACHE_DIR=%s ccache -M %s" % (self.ccachePath, self.ccache_opts['max_cache_size'])) @traceLog(moduleLog) def _setupCcache(self): - self._addHook("prebuild", self._ccache_build_hook) + self._addHook("prebuild", self._ccacheBuildHook) self.ccachePath = os.path.join(self.cachedir, "ccache") mock.util.mkdirIfAbsent(os.path.join(self.rootdir, 'tmp/ccache')) mock.util.mkdirIfAbsent(self.ccachePath) @@ -371,9 +376,12 @@ class Root(object): os.environ['PATH'] = "/tmp/ccache:%s" % (os.environ['PATH']) os.environ['CCACHE_DIR'] = "/tmp/ccache" os.environ['CCACHE_UMASK'] = "002" - self._dumpToFile(os.path.join(self.ccachePath, "cc"), '#!/bin/sh\nexec ccache /usr/bin/cc "$@"\n', mode=0555) - self._dumpToFile(os.path.join(self.ccachePath, "gcc"), '#!/bin/sh\nexec ccache /usr/bin/gcc "$@"\n', mode=0555) - self._dumpToFile(os.path.join(self.ccachePath, "g++"), '#!/bin/sh\nexec ccache /usr/bin/g++ "$@"\n', mode=0555) + self._dumpToFile(os.path.join(self.ccachePath, "cc"), + '#!/bin/sh\nexec ccache /usr/bin/cc "$@"\n', mode=0555) + self._dumpToFile(os.path.join(self.ccachePath, "gcc"), + '#!/bin/sh\nexec ccache /usr/bin/gcc "$@"\n', mode=0555) + self._dumpToFile(os.path.join(self.ccachePath, "g++"), + '#!/bin/sh\nexec ccache /usr/bin/g++ "$@"\n', mode=0555) self._yum('install ccache') @traceLog(moduleLog) @@ -412,14 +420,14 @@ class Root(object): raise mock.exception.YumError, "Error performing yum command: %s" % cmd @traceLog(moduleLog) - def _make_our_user(self): + def _makeBuildUser(self): if not os.path.exists(os.path.join(self.rootdir, 'usr/sbin/useradd')): raise RootError, "Could not find useradd in chroot, maybe the install failed?" mock.util.rmtree(os.path.join(self.rootdir, self.homedir)) - self.do_chroot('/usr/sbin/userdel -r %s' % self.chrootuser, raiseExc=False) - self.do_chroot('/usr/sbin/groupdel %s' % self.chrootgroup, raiseExc=False) - self.do_chroot('/usr/sbin/useradd -m -u %s -d %s %s' % (self.chrootuid, self.homedir, self.chrootuser), raiseExc=True) + self.doChroot('/usr/sbin/userdel -r %s' % self.chrootuser, raiseExc=False) + self.doChroot('/usr/sbin/groupdel %s' % self.chrootgroup, raiseExc=False) + self.doChroot('/usr/sbin/useradd -m -u %s -d %s %s' % (self.chrootuid, self.homedir, self.chrootuser), raiseExc=True) # @@ -427,7 +435,7 @@ class Root(object): # Everything in this function runs as the build user # @traceLog(moduleLog) - def _build_dir_setup(self): + def _buildDirSetup(self): # create all dirs as the user who will be dropping things there. self.uidManager.becomeUser(self.chrootuid) try: @@ -450,8 +458,12 @@ class Root(object): rpmmacros.close() finally: - self.uidManager.elevatePrivs() + self.uidManager.restorePrivs() + # + # UNPRIVLEGED: + # Everything in this function runs as the build user + # @traceLog(moduleLog) def _copySrpmIntoChroot(self, srpm): self.uidManager.becomeUser(self.chrootuid) @@ -461,7 +473,7 @@ class Root(object): shutil.copy2(srpm, dest) origSrpmChrootFilename = os.path.join(self.builddir, 'originals', srpmFilename) finally: - self.uidManager.elevatePrivs() + self.uidManager.restorePrivs() return origSrpmChrootFilename diff --git a/src/py-libs/uid.py b/src/py-libs/uid.py index b706286..d5356af 100644 --- a/src/py-libs/uid.py +++ b/src/py-libs/uid.py @@ -31,26 +31,33 @@ log = logging.getLogger("mock.uid") # class class uidManager(object): @traceLog(log) - def __init__(self): - self.saveCurrentPrivs() + def __init__(self, unprivUid=-1, unprivGid=-1): + self.privStack = [] + self.unprivUid = unprivUid + self.unprivGid = unprivGid @traceLog(log) - def saveCurrentPrivs(self): - self.origruid = os.getuid() # 500 - self.origeuid = os.geteuid() # 0 - self.origrgid=os.getgid() # 500 - self.origegid=os.getegid() # 500 + def becomeUser(self, uid, gid=-1): + # save current ruid, euid, rgid, egid + self._push() + self._becomeUser(uid, gid) @traceLog(log) - def elevatePrivs(self): + def dropPrivsTemp(self): + # save current ruid, euid, rgid, egid + self._push() + self._becomeUser(self.unprivUid, self.unprivGid) + + @traceLog(log) + def restorePrivs(self): + # back to root first os.setreuid(0, 0) os.setregid(0, 0) - @traceLog(log) - def dropPrivsTemp(self): - self.elevatePrivs() - os.setregid(self.origrgid, self.origegid) - os.setreuid(0, self.origruid) + # then set saved + privs = self.privStack.pop() + os.setregid(privs[2], privs[3]) + os.setreuid(privs[0], privs[1]) @traceLog(log) def dropPrivsForever(self): @@ -59,9 +66,20 @@ class uidManager(object): os.setreuid(self.origruid, self.origruid) @traceLog(log) - def becomeUser(self, uid, gid=None): - self.elevatePrivs() - os.setreuid(0, uid) + def _push(self): + # save current ruid, euid, rgid, egid + self.privStack.append([ + os.getuid(), + os.geteuid(), + os.getgid(), + os.getegid(), + ]) + + @traceLog(log) + def _becomeUser(self, uid, gid=None): + os.setreuid(0, 0) + os.setregid(0, 0) if gid is not None: os.setregid(gid, gid) + os.setreuid(0, uid) |
