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 |