Add a new portage_util.apply_secpass_permissions() function that intelligently attemp...
authorZac Medico <zmedico@gentoo.org>
Mon, 13 Mar 2006 23:49:56 +0000 (23:49 -0000)
committerZac Medico <zmedico@gentoo.org>
Mon, 13 Mar 2006 23:49:56 +0000 (23:49 -0000)
svn path=/main/trunk/; revision=2868

pym/portage_util.py

index c8d55fcdda45a029f58f9574df04623e78d57e1f..782a10be1727e6bf813007f3d86fa14dd2615d90 100644 (file)
@@ -3,7 +3,7 @@
 # $Id: /var/cvsroot/gentoo-src/portage/pym/portage_util.py,v 1.11.2.6 2005/04/23 07:26:04 jstubbs Exp $
 
 
-import sys,string,shlex,os.path
+import sys,string,shlex,os
 try:
        import cPickle
 except ImportError:
@@ -475,6 +475,38 @@ def apply_stat_permissions(filename, newstat, stat_cached=None):
        apply_permissions(filename, uid=newstat.st_uid, gid=newstat.st_gid,
        mode=newstat.st_mode, stat_cached=stat_cached)
 
+def apply_secpass_permissions(filename, uid=-1, gid=-1, mode=0,
+       stat_cached=None):
+       """A wrapper around apply_permissions that uses secpass and simple
+       logic to apply as much of the permissions as possible without
+       generating an obviously avoidable permission exception. Despite
+       attempts to avoid an exception, it's possible that one will be raised
+       anyway, so be prepared.
+       Returns True if all permissions are applied and False if some are left
+       unapplied."""
+
+       if stat_cached is None:
+               stat_cached = os.stat(filename)
+
+       all_applied = True
+
+       import portage_data # not imported globally because of circular dep
+       if portage_data.secpass < 2:
+
+               if uid != -1 and \
+               uid != stat_cached.st_uid:
+                       all_applied = False
+                       uid = -1
+
+               if gid != -1 and \
+               gid != stat_cached.st_gid and \
+               gid not in os.getgroups():
+                       all_applied = False
+                       gid = -1
+
+       apply_permissions(filename, uid=uid, gid=gid, mode=mode, stat_cached=stat_cached)
+       return all_applied
+
 class atomic_ofstream(file):
        """Write a file atomically via os.rename().  Atomic replacement prevents
        interprocess interference and prevents corruption of the target