public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Michał Górny" <mgorny@gentoo.org>
To: gentoo-portage-dev@lists.gentoo.org
Cc: "Michał Górny" <mgorny@gentoo.org>
Subject: [gentoo-portage-dev] [PATCH] sync: allow overriding sync-user for the repository
Date: Sun,  7 Dec 2014 10:01:23 +0100	[thread overview]
Message-ID: <1417942883-22011-1-git-send-email-mgorny@gentoo.org> (raw)
In-Reply-To: <5483FB68.7070107@gentoo.org>

---
Changes:
* manpage entry
* perform username lookup before UID lookup (POSIX agrees)
* support specifying ':group' only
* fix ValueError on errors

 man/portage.5                    | 12 ++++++++++
 pym/portage/repository/config.py | 13 +++++++---
 pym/portage/sync/controller.py   | 51 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/man/portage.5 b/man/portage.5
index 8c3d389..4a02c64 100644
--- a/man/portage.5
+++ b/man/portage.5
@@ -934,6 +934,18 @@ ssh://ssh\-user@192.168.0.1:22/\\${HOME}/portage\-storage
 .TP
 Note: For the ssh:// scheme, key\-based authentication might be of interest.
 .RE
+.TP
+.B sync\-user
+Specifies the credentials used to perform the synchronization.
+.br
+Syntax: [user][:group]
+.br
+If only user is provided, the primary group of the user will be used.
+If only group is provided, the current user will be preserved and only
+group id will be changed.
+.br
+This key takes precedence over FEATURES=userpriv. If user or group id
+is provided, Portage no longer uses owner of the directory.
 .RE
 
 .I Example:
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py
index 678cc68..f45684b 100644
--- a/pym/portage/repository/config.py
+++ b/pym/portage/repository/config.py
@@ -85,7 +85,7 @@ class RepoConfig(object):
 		'main_repo', 'manifest_hashes', 'masters', 'missing_repo_name',
 		'name', 'portage1_profiles', 'portage1_profiles_compat', 'priority',
 		'profile_formats', 'sign_commit', 'sign_manifest', 'sync_cvs_repo',
-		'sync_type', 'sync_umask', 'sync_uri', 'thin_manifest',
+		'sync_type', 'sync_umask', 'sync_uri', 'sync_user', 'thin_manifest',
 		'update_changelog', 'user_location', '_eapis_banned',
 		'_eapis_deprecated', '_masters_orig')
 
@@ -165,6 +165,11 @@ class RepoConfig(object):
 			sync_uri = sync_uri.strip()
 		self.sync_uri = sync_uri or None
 
+		sync_user = repo_opts.get('sync-user')
+		if sync_user is not None:
+			sync_user = sync_user.strip()
+		self.sync_user = sync_user or None
+
 		auto_sync = repo_opts.get('auto-sync')
 		if auto_sync is not None:
 			auto_sync = auto_sync.strip().lower()
@@ -385,6 +390,8 @@ class RepoConfig(object):
 			repo_msg.append(indent + "sync-umask: " + self.sync_umask)
 		if self.sync_uri:
 			repo_msg.append(indent + "sync-uri: " + self.sync_uri)
+		if self.sync_user:
+			repo_msg.append(indent + "sync-user: " + self.sync_user)
 		if self.masters:
 			repo_msg.append(indent + "masters: " + " ".join(master.name for master in self.masters))
 		if self.priority is not None:
@@ -472,7 +479,7 @@ class RepoConfigLoader(object):
 						# repos.conf is allowed to override.
 						for k in ('aliases', 'auto_sync', 'eclass_overrides',
 							'force', 'masters', 'priority', 'sync_cvs_repo',
-							'sync_type', 'sync_umask', 'sync_uri',
+							'sync_type', 'sync_umask', 'sync_uri', 'sync_user',
 							):
 							v = getattr(repos_conf_opts, k, None)
 							if v is not None:
@@ -923,7 +930,7 @@ class RepoConfigLoader(object):
 	def config_string(self):
 		str_or_int_keys = ("auto_sync", "format", "location",
 			"main_repo", "priority", "sync_cvs_repo",
-			"sync_type", "sync_umask", "sync_uri")
+			"sync_type", "sync_umask", "sync_uri", 'sync_user')
 		str_tuple_keys = ("aliases", "eclass_overrides", "force")
 		repo_config_tuple_keys = ("masters",)
 		keys = str_or_int_keys + str_tuple_keys + repo_config_tuple_keys
diff --git a/pym/portage/sync/controller.py b/pym/portage/sync/controller.py
index 1c8c756..de803b7 100644
--- a/pym/portage/sync/controller.py
+++ b/pym/portage/sync/controller.py
@@ -6,6 +6,7 @@ from __future__ import print_function
 
 import sys
 import logging
+import grp
 import pwd
 
 import portage
@@ -201,7 +202,55 @@ class SyncManager(object):
 		self.usersync_uid = None
 		spawn_kwargs = {}
 		spawn_kwargs["env"] = self.settings.environ()
-		if ('usersync' in self.settings.features and
+		if repo.sync_user is not None:
+			def get_sync_user_data(sync_user):
+				user = None
+				group = None
+				home = None
+
+				spl = sync_user.split(':', 1)
+				if spl[0]:
+					username = spl[0]
+					try:
+						try:
+							pw = pwd.getpwnam(username)
+						except KeyError:
+							pw = pwd.getpwuid(int(username))
+					except (ValueError, KeyError):
+						writemsg("!!! User '%s' invalid or does not exist\n"
+								% username, noiselevel=-1)
+						return (user, group, home)
+					user = pw.pw_uid
+					group = pw.pw_gid
+					home = pw.pw_dir
+
+				if len(spl) > 1:
+					groupname = spl[1]
+					try:
+						try:
+							gp = grp.getgrnam(groupname)
+						except KeyError:
+							pw = grp.getgrgid(int(groupname))
+					except (ValueError, KeyError):
+						writemsg("!!! Group '%s' invalid or does not exist\n"
+								% groupname, noiselevel=-1)
+						return (user, group, home)
+
+					group = gp.gr_gid
+
+				return (user, group, home)
+
+			# user or user:group
+			(uid, gid, home) = get_sync_user_data(repo.sync_user)
+			if uid is not None
+				spawn_kwargs["uid"] = uid
+				self.usersync_uid = uid
+			if gid is not None:
+				spawn_kwargs["gid"] = gid
+				spawn_kwargs["groups"] = [gid]
+			if home is not None:
+				spawn_kwargs["env"]["HOME"] = home
+		elif ('usersync' in self.settings.features and
 			portage.data.secpass >= 2 and
 			(st.st_uid != os.getuid() and st.st_mode & 0o700 or
 			st.st_gid != os.getgid() and st.st_mode & 0o070)):
-- 
2.2.0



  reply	other threads:[~2014-12-07  9:01 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-06  0:03 [gentoo-portage-dev] [PATCH 0/4] sync: sync-umask and sync-user support Michał Górny
2014-12-06  0:03 ` [gentoo-portage-dev] [PATCH 1/4] sync: allow overriding sync-umask for the repository Michał Górny
2014-12-07  6:46   ` Zac Medico
2014-12-07  9:00     ` [gentoo-portage-dev] [PATCH] " Michał Górny
2014-12-06  0:03 ` [gentoo-portage-dev] [PATCH 2/4] sync: allow overriding sync-user " Michał Górny
2014-12-07  7:02   ` Zac Medico
2014-12-07  9:01     ` Michał Górny [this message]
2014-12-07  9:07       ` [gentoo-portage-dev] [PATCH] " Michał Górny
2014-12-07 18:32         ` Zac Medico
2014-12-08  6:53       ` Arfrever Frehtes Taifersar Arahesis
2014-12-06  0:03 ` [gentoo-portage-dev] [PATCH 3/4] sync: ensure sync_{umask,user} is respected when creating repo Michał Górny
2014-12-07  7:10   ` Zac Medico
2014-12-06  0:03 ` [gentoo-portage-dev] [PATCH 4/4] sync: Add backwards compat with SYNC_{UMASK,USER} variables Michał Górny
2014-12-07  7:15   ` Zac Medico
2014-12-07  8:22     ` Michał Górny
2014-12-07  9:04       ` Zac Medico
2014-12-07  9:06         ` Michał Górny
2014-12-07 18:33           ` Zac Medico
2014-12-07 18:39             ` Michał Górny

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1417942883-22011-1-git-send-email-mgorny@gentoo.org \
    --to=mgorny@gentoo.org \
    --cc=gentoo-portage-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox