From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 85CD61389E2 for ; Sun, 7 Dec 2014 09:01:35 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 64124E0919; Sun, 7 Dec 2014 09:01:31 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id D49D0E08AA for ; Sun, 7 Dec 2014 09:01:30 +0000 (UTC) Received: from pomiot.lan (mgorny-1-pt.tunnel.tserv28.waw1.ipv6.he.net [IPv6:2001:470:70:353::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: mgorny) by smtp.gentoo.org (Postfix) with ESMTPSA id 510EE33FFDF; Sun, 7 Dec 2014 09:01:29 +0000 (UTC) From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= To: gentoo-portage-dev@lists.gentoo.org Cc: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Subject: [gentoo-portage-dev] [PATCH] sync: allow overriding sync-user for the repository Date: Sun, 7 Dec 2014 10:01:23 +0100 Message-Id: <1417942883-22011-1-git-send-email-mgorny@gentoo.org> X-Mailer: git-send-email 2.2.0 In-Reply-To: <5483FB68.7070107@gentoo.org> References: <5483FB68.7070107@gentoo.org> Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-portage-dev@lists.gentoo.org Reply-to: gentoo-portage-dev@lists.gentoo.org X-Archives-Salt: 0bcb284c-c3d0-4d23-98af-61906587d4a9 X-Archives-Hash: 6bf9fd9a95d51f020e3719ab62fe0d5e --- 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