public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/portage:master commit in: pym/portage/tests/emerge/, pym/portage/package/ebuild/, pym/portage/
@ 2014-10-22 23:19 Zac Medico
  0 siblings, 0 replies; only message in thread
From: Zac Medico @ 2014-10-22 23:19 UTC (permalink / raw
  To: gentoo-commits

commit:     1364fcd89384c9f60e6d72d7057dc00d8caba175
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon Sep 29 18:18:42 2014 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Wed Oct 22 23:11:58 2014 +0000
URL:        http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=1364fcd8

Support unprivileged mode for bug #433453.

This takes the existing unprivileged prefix support and enables it to
work when EPREFIX is empty. This "unprivileged" mode is automatically
enabled if the current user is not root, but has write access to the
EROOT directory (not due to the 0002 bit). For use in conditional logic
(for example, see doebuild.py diff), "unprivileged" is automatically
added to the FEATURES variable.

X-Gentoo-Bug: 433453
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=433453

---
 pym/portage/const.py                    |  1 +
 pym/portage/data.py                     | 95 ++++++++++++++++++++++-----------
 pym/portage/package/ebuild/config.py    | 21 +++++---
 pym/portage/package/ebuild/doebuild.py  |  4 +-
 pym/portage/tests/emerge/test_simple.py |  2 +-
 5 files changed, 83 insertions(+), 40 deletions(-)

diff --git a/pym/portage/const.py b/pym/portage/const.py
index acb90f9..d472075 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -189,6 +189,7 @@ SUPPORTED_FEATURES       = frozenset([
 	"unmerge-backup",
 	"unmerge-logs",
 	"unmerge-orphans",
+	"unprivileged",
 	"userfetch",
 	"userpriv",
 	"usersandbox",

diff --git a/pym/portage/data.py b/pym/portage/data.py
index 54e3a8d..3d91e48 100644
--- a/pym/portage/data.py
+++ b/pym/portage/data.py
@@ -59,6 +59,15 @@ def portage_group_warning():
 # If the "wheel" group does not exist then wheelgid falls back to 0.
 # If the "portage" group does not exist then portage_uid falls back to wheelgid.
 
+# If the current user is not root, but has write access to the
+# EROOT directory (not due to the 0002 bit), then use "unprivileged"
+# mode which sets secpass = 2 and uses the UID and GID of the EROOT
+# directory to generate default PORTAGE_INST_GID, PORTAGE_INST_UID,
+# PORTAGE_USERNAME, and PORTAGE_GRPNAME settings.
+def _unprivileged_mode(eroot, eroot_st):
+	return os.getuid() != 0 and os.access(eroot, os.W_OK) and \
+		not eroot_st.st_mode & 0o0002
+
 uid = os.getuid()
 wheelgid = 0
 try:
@@ -77,13 +86,33 @@ def _get_global(k):
 	if k in _initialized_globals:
 		return globals()[k]
 
-	if k in ('portage_gid', 'portage_uid', 'secpass'):
-		global portage_gid, portage_uid, secpass
-		secpass = 0
+	if k == 'secpass':
+
+		unprivileged = False
+		if hasattr(portage, 'settings'):
+			unprivileged = "unprivileged" in portage.settings.features
+		else:
+			# The config class has equivalent code, but we also need to
+			# do it here if _disable_legacy_globals() has been called.
+			eroot = os.path.join(os.environ.get('ROOT', os.sep),
+				portage.const.EPREFIX.lstrip(os.sep))
+			try:
+				eroot_st = os.stat(eroot)
+			except OSError:
+				pass
+			else:
+				unprivileged = _unprivileged_mode(eroot, eroot_st)
+
+		v = 0
 		if uid == 0:
-			secpass = 2
-		elif portage.const.EPREFIX:
-			secpass = 2
+			v = 2
+		elif unprivileged:
+			v = 2
+		elif portage_gid in os.getgroups():
+			v = 1
+
+	elif k in ('portage_gid', 'portage_uid'):
+
 		#Discover the uid and gid of the portage user/group
 		keyerror = False
 		try:
@@ -98,9 +127,6 @@ def _get_global(k):
 			keyerror = True
 			portage_gid = 0
 
-		if secpass < 1 and portage_gid in os.getgroups():
-			secpass = 1
-
 		# Suppress this error message if both PORTAGE_GRPNAME and
 		# PORTAGE_USERNAME are set to "root", for things like
 		# Android (see bug #454060).
@@ -118,16 +144,15 @@ def _get_global(k):
 				noiselevel=-1)
 			portage_group_warning()
 
+		globals()['portage_gid'] = portage_gid
 		_initialized_globals.add('portage_gid')
+		globals()['portage_uid'] = portage_uid
 		_initialized_globals.add('portage_uid')
-		_initialized_globals.add('secpass')
 
 		if k == 'portage_gid':
 			return portage_gid
 		elif k == 'portage_uid':
 			return portage_uid
-		elif k == 'secpass':
-			return secpass
 		else:
 			raise AssertionError('unknown name: %s' % k)
 
@@ -178,11 +203,9 @@ def _get_global(k):
 			v = os.environ[env_key]
 		elif hasattr(portage, 'settings'):
 			v = portage.settings.get(env_key)
-		elif portage.const.EPREFIX:
-			# For prefix environments, default to the UID and GID of
-			# the top-level EROOT directory. The config class has
-			# equivalent code, but we also need to do it here if
-			# _disable_legacy_globals() has been called.
+		else:
+			# The config class has equivalent code, but we also need to
+			# do it here if _disable_legacy_globals() has been called.
 			eroot = os.path.join(os.environ.get('ROOT', os.sep),
 				portage.const.EPREFIX.lstrip(os.sep))
 			try:
@@ -190,20 +213,21 @@ def _get_global(k):
 			except OSError:
 				pass
 			else:
-				if k == '_portage_grpname':
-					try:
-						grp_struct = grp.getgrgid(eroot_st.st_gid)
-					except KeyError:
-						pass
+				if _unprivileged_mode(eroot, eroot_st):
+					if k == '_portage_grpname':
+						try:
+							grp_struct = grp.getgrgid(eroot_st.st_gid)
+						except KeyError:
+							pass
+						else:
+							v = grp_struct.gr_name
 					else:
-						v = grp_struct.gr_name
-				else:
-					try:
-						pwd_struct = pwd.getpwuid(eroot_st.st_uid)
-					except KeyError:
-						pass
-					else:
-						v = pwd_struct.pw_name
+						try:
+							pwd_struct = pwd.getpwuid(eroot_st.st_uid)
+						except KeyError:
+							pass
+						else:
+							v = pwd_struct.pw_name
 
 		if v is None:
 			v = 'portage'
@@ -254,3 +278,14 @@ def _init(settings):
 			v = portage._native_string(v)
 		globals()['_portage_username'] = v
 		_initialized_globals.add('_portage_username')
+
+	if 'secpass' not in _initialized_globals:
+		v = 0
+		if uid == 0:
+			v = 2
+		elif "unprivileged" in settings.features:
+			v = 2
+		elif portage_gid in os.getgroups():
+			v = 1
+		globals()['secpass'] = v
+		_initialized_globals.add('secpass')

diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
index 264ed8e..1087443 100644
--- a/pym/portage/package/ebuild/config.py
+++ b/pym/portage/package/ebuild/config.py
@@ -834,14 +834,16 @@ class config(object):
 				"PORTAGE_INST_UID": "0",
 			}
 
-			if eprefix:
-				# For prefix environments, default to the UID and GID of
-				# the top-level EROOT directory.
-				try:
-					eroot_st = os.stat(eroot)
-				except OSError:
-					pass
-				else:
+			unprivileged = False
+			try:
+				eroot_st = os.stat(eroot)
+			except OSError:
+				pass
+			else:
+
+				if portage.data._unprivileged_mode(eroot, eroot_st):
+					unprivileged = True
+
 					default_inst_ids["PORTAGE_INST_GID"] = str(eroot_st.st_gid)
 					default_inst_ids["PORTAGE_INST_UID"] = str(eroot_st.st_uid)
 
@@ -880,6 +882,9 @@ class config(object):
 			# initialize self.features
 			self.regenerate()
 
+			if unprivileged:
+				self.features.add('unprivileged')
+
 			if bsd_chflags:
 				self.features.add('chflags')
 

diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
index d3e3f5a..9516173 100644
--- a/pym/portage/package/ebuild/doebuild.py
+++ b/pym/portage/package/ebuild/doebuild.py
@@ -200,7 +200,9 @@ def _doebuild_path(settings, eapi=None):
 	if "xattr" in settings.features:
 		path.append(os.path.join(portage_bin_path, "ebuild-helpers", "xattr"))
 
-	if eprefix and uid != 0 and "fakeroot" not in settings.features:
+	if uid != 0 and \
+		"unprivileged" in settings.features and \
+		"fakeroot" not in settings.features:
 		path.append(os.path.join(portage_bin_path,
 			"ebuild-helpers", "unprivileged"))
 

diff --git a/pym/portage/tests/emerge/test_simple.py b/pym/portage/tests/emerge/test_simple.py
index 6fc81ab..6c20a07 100644
--- a/pym/portage/tests/emerge/test_simple.py
+++ b/pym/portage/tests/emerge/test_simple.py
@@ -372,7 +372,7 @@ pkg_preinst() {
 				os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"]
 
 		updates_dir = os.path.join(test_repo_location, "profiles", "updates")
-		dirs = [cachedir, cachedir_pregen, distdir, fake_bin,
+		dirs = [cachedir, cachedir_pregen, cross_prefix, distdir, fake_bin,
 			portage_tmpdir, updates_dir,
 			user_config_dir, var_cache_edb]
 		etc_symlinks = ("dispatch-conf.conf", "etc-update.conf")


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2014-10-22 23:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-22 23:19 [gentoo-commits] proj/portage:master commit in: pym/portage/tests/emerge/, pym/portage/package/ebuild/, pym/portage/ Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox