Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] portage.data: add build user (bug 600804)
Date: Mon, 25 Jun 2018 00:55:21
Message-Id: 20180625005151.9979-1-zmedico@gentoo.org
1 Add attributes and override variables for a separate build
2 user, with defaults corresponding to the status quo. This
3 reuses the existing PORTAGE_BUILD_USER and PORTAGE_BUILD_GROUP
4 variables that were already exported to the ebuild environment.
5
6 When PORTAGE_BUILD_USER and PORTAGE_BUILD_GROUP are unset,
7 the build user can still be overridden by the existing
8 PORTAGE_USERNAME and PORTAGE_GRPNAME variables.
9
10 This sets the stage for migration of internal code to use
11 a separate build user, as required to solve bug 600804 in a
12 manner that complies with PMS.
13
14 Bug: https://bugs.gentoo.org/600804
15 ---
16 pym/portage/data.py | 54 +++++++++++++++++++++++++++++-----
17 pym/portage/package/ebuild/doebuild.py | 12 ++++----
18 2 files changed, 52 insertions(+), 14 deletions(-)
19
20 diff --git a/pym/portage/data.py b/pym/portage/data.py
21 index 28d6eb79db..7b2db21c6b 100644
22 --- a/pym/portage/data.py
23 +++ b/pym/portage/data.py
24 @@ -105,6 +105,15 @@ try:
25 except KeyError:
26 pass
27
28 +_attr_env_vars = {
29 + # TODO: Migrate all internals to use the build user/group
30 + # instead of the "portage" user/group where appropriate.
31 + '_build_group': 'PORTAGE_BUILD_GROUP',
32 + '_build_user': 'PORTAGE_BUILD_USER',
33 + '_portage_grpname': 'PORTAGE_GRPNAME',
34 + '_portage_username': 'PORTAGE_USERNAME',
35 +}
36 +
37 # The portage_uid and portage_gid global constants, and others that
38 # depend on them are initialized lazily, in order to allow configuration
39 # via make.conf. Eventually, these constants may be deprecated in favor
40 @@ -142,6 +151,32 @@ def _get_global(k):
41 elif _get_global('portage_gid') in os.getgroups():
42 v = 1
43
44 + elif k in ('_build_gid', '_build_uid'):
45 + keyerror = False
46 + try:
47 + build_uid = pwd.getpwnam(_get_global('_build_user')).pw_uid
48 + except KeyError:
49 + writemsg('!!! PORTAGE_BUILD_USER refers to non-existant user "%s"\n'
50 + % _get_global('_build_user'), noiselevel=-1)
51 + build_uid = 0
52 +
53 + try:
54 + build_gid = grp.getgrnam(_get_global('_build_group')).gr_gid
55 + except KeyError:
56 + writemsg('!!! PORTAGE_BUILD_GROUP refers to non-existant user "%s"\n'
57 + % _get_global('_build_group'), noiselevel=-1)
58 + build_gid = 0
59 +
60 + globals()['_build_gid'] = build_gid
61 + _initialized_globals.add('_build_gid')
62 + globals()['_build_uid'] = build_uid
63 + _initialized_globals.add('_build_uid')
64 +
65 + if k == '_build_gid':
66 + return build_gid
67 + else:
68 + return build_uid
69 +
70 elif k in ('portage_gid', 'portage_uid'):
71
72 #Discover the uid and gid of the portage user/group
73 @@ -193,7 +228,7 @@ def _get_global(k):
74 # Get a list of group IDs for the portage user. Do not use
75 # grp.getgrall() since it is known to trigger spurious
76 # SIGPIPE problems with nss_ldap.
77 - cmd = ["id", "-G", _portage_username]
78 + cmd = ["id", "-G", _get_global('_build_user')]
79
80 if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000:
81 # Python 3.1 _execvp throws TypeError for non-absolute executable
82 @@ -223,12 +258,9 @@ def _get_global(k):
83
84 # Avoid instantiating portage.settings when the desired
85 # variable is set in os.environ.
86 - elif k in ('_portage_grpname', '_portage_username'):
87 + elif k in _attr_env_vars:
88 v = None
89 - if k == '_portage_grpname':
90 - env_key = 'PORTAGE_GRPNAME'
91 - else:
92 - env_key = 'PORTAGE_USERNAME'
93 + env_key = _attr_env_vars[k]
94
95 if env_key in os.environ:
96 v = os.environ[env_key]
97 @@ -245,7 +277,7 @@ def _get_global(k):
98 pass
99 else:
100 if _unprivileged_mode(eroot_or_parent, eroot_st):
101 - if k == '_portage_grpname':
102 + if k in ('_build_group', '_portage_grpname'):
103 try:
104 grp_struct = grp.getgrgid(eroot_st.st_gid)
105 except KeyError:
106 @@ -261,7 +293,12 @@ def _get_global(k):
107 v = pwd_struct.pw_name
108
109 if v is None:
110 - v = 'portage'
111 + if k == '_build_group':
112 + v = _get_global('_portage_grpname')
113 + elif k == '_build_user':
114 + v = _get_global('_portage_username')
115 + else:
116 + v = 'portage'
117 else:
118 raise AssertionError('unknown name: %s' % k)
119
120 @@ -281,6 +318,7 @@ class _GlobalProxy(portage.proxy.objectproxy.ObjectProxy):
121 return _get_global(object.__getattribute__(self, '_name'))
122
123 for k in ('portage_gid', 'portage_uid', 'secpass', 'userpriv_groups',
124 + '_build_gid', '_build_group', '_build_uid', '_build_user',
125 '_portage_grpname', '_portage_username'):
126 globals()[k] = _GlobalProxy(k)
127 del k
128 diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
129 index 97a9199a31..3981a7d7ae 100644
130 --- a/pym/portage/package/ebuild/doebuild.py
131 +++ b/pym/portage/package/ebuild/doebuild.py
132 @@ -1592,8 +1592,8 @@ def spawn(mystring, mysettings, debug=False, free=False, droppriv=False,
133 if "userpriv" in features and "userpriv" not in mysettings["PORTAGE_RESTRICT"].split() and secpass >= 2:
134 # Since Python 3.4, getpwuid and getgrgid
135 # require int type (no proxies).
136 - portage_build_uid = int(portage_uid)
137 - portage_build_gid = int(portage_gid)
138 + portage_build_uid = int(portage.data._build_uid)
139 + portage_build_gid = int(portage.data._build_gid)
140
141 if "PORTAGE_BUILD_USER" not in mysettings:
142 user = None
143 @@ -1602,8 +1602,8 @@ def spawn(mystring, mysettings, debug=False, free=False, droppriv=False,
144 except KeyError:
145 if portage_build_uid == 0:
146 user = "root"
147 - elif portage_build_uid == portage_uid:
148 - user = portage.data._portage_username
149 + elif portage_build_uid == portage.data._build_uid:
150 + user = portage.data._build_user
151 if user is not None:
152 mysettings["PORTAGE_BUILD_USER"] = user
153
154 @@ -1614,8 +1614,8 @@ def spawn(mystring, mysettings, debug=False, free=False, droppriv=False,
155 except KeyError:
156 if portage_build_gid == 0:
157 group = "root"
158 - elif portage_build_gid == portage_gid:
159 - group = portage.data._portage_grpname
160 + elif portage_build_gid == portage.data._build_gid:
161 + group = portage.data._build_group
162 if group is not None:
163 mysettings["PORTAGE_BUILD_GROUP"] = group
164
165 --
166 2.13.6