1 |
--- |
2 |
eclass/sys-group.eclass | 105 ++++++++++++++++++++ |
3 |
eclass/sys-user.eclass | 206 ++++++++++++++++++++++++++++++++++++++++ |
4 |
2 files changed, 311 insertions(+) |
5 |
create mode 100644 eclass/sys-group.eclass |
6 |
create mode 100644 eclass/sys-user.eclass |
7 |
|
8 |
diff --git a/eclass/sys-group.eclass b/eclass/sys-group.eclass |
9 |
new file mode 100644 |
10 |
index 000000000000..3960db16b5d6 |
11 |
--- /dev/null |
12 |
+++ b/eclass/sys-group.eclass |
13 |
@@ -0,0 +1,105 @@ |
14 |
+# Copyright 2019 Gentoo Authors |
15 |
+# Distributed under the terms of the GNU General Public License v2 |
16 |
+ |
17 |
+# @ECLASS: sys-group.eclass |
18 |
+# @MAINTAINER: |
19 |
+# Michał Górny <mgorny@g.o> |
20 |
+# @AUTHOR: |
21 |
+# Michael Orlitzky <mjo@g.o> |
22 |
+# Michał Górny <mgorny@g.o> |
23 |
+# @BLURB: Eclass used to create and maintain a single group entry |
24 |
+# @DESCRIPTION: |
25 |
+# This eclass represents and creates a single group entry. The name |
26 |
+# of the group is derived from ${PN}, while (preferred) GID needs to |
27 |
+# be specified via SYS_GROUP_ID. Packages (and users) needing the group |
28 |
+# in question should depend on the package providing it. |
29 |
+# |
30 |
+# Example: |
31 |
+# If your package needs group 'foo', you create 'group/foo' package |
32 |
+# and add an ebuild with the following contents: |
33 |
+# |
34 |
+# @CODE |
35 |
+# EAPI=7 |
36 |
+# inherit sys-group |
37 |
+# SYS_GROUP_ID=200 |
38 |
+# @CODE |
39 |
+# |
40 |
+# Then you add appropriate dependency to your package. The dependency |
41 |
+# type(s) should be: |
42 |
+# - DEPEND (+ RDEPEND) if the group is already needed at build time, |
43 |
+# - RDEPEND if it is needed at install time (e.g. you 'fowners' files |
44 |
+# in pkg_preinst), |
45 |
+# - PDEPEND if it is only needed at runtime. |
46 |
+ |
47 |
+ |
48 |
+if [[ -z ${_SYS_GROUP_ECLASS} ]]; then |
49 |
+_SYS_GROUP_ECLASS=1 |
50 |
+ |
51 |
+case ${EAPI:-0} in |
52 |
+ 7) ;; |
53 |
+ *) die "EAPI=${EAPI} not supported";; |
54 |
+esac |
55 |
+ |
56 |
+inherit user |
57 |
+ |
58 |
+ |
59 |
+# << Eclass variables >> |
60 |
+ |
61 |
+# @ECLASS-VARIABLE: SYS_GROUP_ID |
62 |
+# @REQUIRED |
63 |
+# @DESCRIPTION: |
64 |
+# Preferred GID for the new group. This variable is obligatory, and its |
65 |
+# value must be unique across all group packages. |
66 |
+ |
67 |
+# @ECLASS-VARIABLE: SYS_GROUP_ENFORCE_ID |
68 |
+# @DESCRIPTION: |
69 |
+# If set to a non-null value, the eclass will require the group to have |
70 |
+# specified GID. If the group already exists with another GID, or |
71 |
+# the GID is taken by another group, the install will fail. |
72 |
+: ${SYS_GROUP_ENFORCE_ID:=} |
73 |
+ |
74 |
+ |
75 |
+# << Boilerplate ebuild variables >> |
76 |
+: ${DESCRIPTION:="System group: ${PN}"} |
77 |
+: ${HOMEPAGE:=https://www.gentoo.org/} |
78 |
+: ${SLOT:=0} |
79 |
+: ${KEYWORDS:=alpha amd64 arm arm64 hppa ia64 m68k ~mips ppc ppc64 ~riscv s390 sh sparc x86 ~ppc-aix ~x64-cygwin ~amd64-fbsd ~x86-fbsd ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~m68k-mint ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris} |
80 |
+S=${WORKDIR} |
81 |
+ |
82 |
+ |
83 |
+# << Phase functions >> |
84 |
+EXPORT_FUNCTIONS pkg_pretend pkg_preinst |
85 |
+ |
86 |
+# @FUNCTION: sys-group_pkg_pretend |
87 |
+# @DESCRIPTION: |
88 |
+# Performs sanity checks for correct eclass usage, and early-checks |
89 |
+# whether requested GID can be enforced. |
90 |
+sys-group_pkg_pretend() { |
91 |
+ debug-print-function ${FUNCNAME} "${@}" |
92 |
+ |
93 |
+ # verify SYS_GROUP_ID |
94 |
+ [[ -n ${SYS_GROUP_ID} ]] || die "Ebuild error: SYS_GROUP_ID must be set!" |
95 |
+ [[ ${SYS_GROUP_ID} -ge 0 ]] || die "Ebuild errors: SYS_GROUP_ID=${SYS_GROUP_ID} invalid!" |
96 |
+ |
97 |
+ # check for SYS_GROUP_ID collisions early |
98 |
+ if [[ -n ${SYS_GROUP_ENFORCE_ID} ]]; then |
99 |
+ local grp=$(egetent group "${SYS_GROUP_ID}") |
100 |
+ if [[ -n ${grp} ]]; then |
101 |
+ eerror "The required GID is already taken by another group." |
102 |
+ eerror " GID: ${SYS_GROUP_ID} (needed for ${PN})" |
103 |
+ eerror " current group: ${grp}" |
104 |
+ die "GID ${SYS_GROUP_ID} taken already" |
105 |
+ fi |
106 |
+ fi |
107 |
+} |
108 |
+ |
109 |
+# @FUNCTION: sys-group_pkg_preinst |
110 |
+# @DESCRIPTION: |
111 |
+# Creates the group if it does not exist yet. |
112 |
+sys-group_pkg_preinst() { |
113 |
+ debug-print-function ${FUNCNAME} "${@}" |
114 |
+ |
115 |
+ enewgroup -F "${PN}" "${SYS_GROUP_ID}" |
116 |
+} |
117 |
+ |
118 |
+fi |
119 |
diff --git a/eclass/sys-user.eclass b/eclass/sys-user.eclass |
120 |
new file mode 100644 |
121 |
index 000000000000..de59af99a843 |
122 |
--- /dev/null |
123 |
+++ b/eclass/sys-user.eclass |
124 |
@@ -0,0 +1,206 @@ |
125 |
+# Copyright 2019 Gentoo Authors |
126 |
+# Distributed under the terms of the GNU General Public License v2 |
127 |
+ |
128 |
+# @ECLASS: sys-user.eclass |
129 |
+# @MAINTAINER: |
130 |
+# Michał Górny <mgorny@g.o> |
131 |
+# @AUTHOR: |
132 |
+# Michael Orlitzky <mjo@g.o> |
133 |
+# Michał Górny <mgorny@g.o> |
134 |
+# @BLURB: Eclass used to create and maintain a single user entry |
135 |
+# @DESCRIPTION: |
136 |
+# This eclass represents and creates a single user entry. The name |
137 |
+# of the user is derived from ${PN}, while (preferred) UID needs to |
138 |
+# be specified via SYS_USER_ID. Additional variables are provided |
139 |
+# to override the default home directory, shell and add group |
140 |
+# membership. Packages needing the user in question should depend |
141 |
+# on the package providing it. |
142 |
+# |
143 |
+# Example: |
144 |
+# If your package needs user 'foo' belonging to same-named group, you |
145 |
+# create 'user/foo' package and add an ebuild with the following |
146 |
+# contents: |
147 |
+# |
148 |
+# @CODE |
149 |
+# EAPI=7 |
150 |
+# inherit sys-user |
151 |
+# SYS_USER_ID=200 |
152 |
+# SYS_USER_GROUPS=( foo ) |
153 |
+# sys-user_add_deps |
154 |
+# @CODE |
155 |
+# |
156 |
+# Then you add appropriate dependency to your package. The dependency |
157 |
+# type(s) should be: |
158 |
+# - DEPEND (+ RDEPEND) if the user is already needed at build time, |
159 |
+# - RDEPEND if it is needed at install time (e.g. you 'fowners' files |
160 |
+# in pkg_preinst), |
161 |
+# - PDEPEND if it is only needed at runtime. |
162 |
+ |
163 |
+if [[ -z ${_SYS_USER_ECLASS} ]]; then |
164 |
+_SYS_USER_ECLASS=1 |
165 |
+ |
166 |
+case ${EAPI:-0} in |
167 |
+ 7) ;; |
168 |
+ *) die "EAPI=${EAPI} not supported";; |
169 |
+esac |
170 |
+ |
171 |
+inherit user |
172 |
+ |
173 |
+ |
174 |
+# << Eclass variables >> |
175 |
+ |
176 |
+# @ECLASS-VARIABLE: SYS_USER_ID |
177 |
+# @REQUIRED |
178 |
+# @DESCRIPTION: |
179 |
+# Preferred UID for the new user. This variable is obligatory, and its |
180 |
+# value must be unique across all user packages. |
181 |
+ |
182 |
+# @ECLASS-VARIABLE: SYS_USER_ENFORCE_ID |
183 |
+# @DESCRIPTION: |
184 |
+# If set to a non-null value, the eclass will require the user to have |
185 |
+# specified UID. If the user already exists with another UID, or |
186 |
+# the UID is taken by another user, the install will fail. |
187 |
+: ${SYS_USER_ENFORCE_ID:=} |
188 |
+ |
189 |
+# @ECLASS-VARIABLE: SYS_USER_SHELL |
190 |
+# @DESCRIPTION: |
191 |
+# The shell to use for the new user. If not specified, a 'nologin' |
192 |
+# variant for the system is used. This affects only new user accounts. |
193 |
+: ${SYS_USER_SHELL:=-1} |
194 |
+ |
195 |
+# @ECLASS-VARIABLE: SYS_USER_HOME |
196 |
+# @DESCRIPTION: |
197 |
+# The home directory for the new user. If not specified, /dev/null |
198 |
+# is used. This affects only new user accounts. The directory will |
199 |
+# be created with appropriate permissions if it does not exist. |
200 |
+: ${SYS_USER_HOME:=/dev/null} |
201 |
+ |
202 |
+# @ECLASS-VARIABLE: SYS_USER_GROUPS |
203 |
+# @DEFAULT_UNSET |
204 |
+# @DESCRIPTION: |
205 |
+# List of groups the user should belong to. This must be a bash |
206 |
+# array. If not specified, the user is not added to any groups. |
207 |
+# This affects only new user accounts. |
208 |
+# |
209 |
+# If SYS_USER_GROUPS is specified, the ebuild needs to call |
210 |
+# sys-user_add_deps in global scope to add appropriate dependencies. |
211 |
+ |
212 |
+ |
213 |
+# << Boilerplate ebuild variables >> |
214 |
+: ${DESCRIPTION:="System user: ${PN}"} |
215 |
+: ${HOMEPAGE:=https://www.gentoo.org/} |
216 |
+: ${SLOT:=0} |
217 |
+: ${KEYWORDS:=alpha amd64 arm arm64 hppa ia64 m68k ~mips ppc ppc64 ~riscv s390 sh sparc x86 ~ppc-aix ~x64-cygwin ~amd64-fbsd ~x86-fbsd ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~m68k-mint ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris} |
218 |
+S=${WORKDIR} |
219 |
+ |
220 |
+ |
221 |
+# << API functions >> |
222 |
+ |
223 |
+# @FUNCTION: sys-user_add_deps |
224 |
+# @DESCRIPTION: |
225 |
+# Generate appropriate RDEPEND from SYS_USER_GROUPS. This must be |
226 |
+# called if SYS_USER_GROUPS are set. |
227 |
+sys-user_add_deps() { |
228 |
+ debug-print-function ${FUNCNAME} "${@}" |
229 |
+ |
230 |
+ # SYS_USER_GROUPS sanity check |
231 |
+ if ! declare -p SYS_USER_GROUPS &>/dev/null; then |
232 |
+ return |
233 |
+ elif [[ $(declare -p SYS_USER_GROUPS) != "declare -a"* ]]; then |
234 |
+ die 'SYS_USER_GROUPS must be an array.' |
235 |
+ fi |
236 |
+ |
237 |
+ local g |
238 |
+ for g in "${SYS_USER_GROUPS[@]}"; do |
239 |
+ RDEPEND+=" group/${g}" |
240 |
+ done |
241 |
+ |
242 |
+ _SYS_USER_ADD_DEPS_CALLED=1 |
243 |
+} |
244 |
+ |
245 |
+ |
246 |
+# << Phase functions >> |
247 |
+EXPORT_FUNCTIONS pkg_pretend src_install pkg_preinst pkg_prerm |
248 |
+ |
249 |
+# @FUNCTION: sys-user_pkg_pretend |
250 |
+# @DESCRIPTION: |
251 |
+# Performs sanity checks for correct eclass usage, and early-checks |
252 |
+# whether requested UID can be enforced. |
253 |
+sys-user_pkg_pretend() { |
254 |
+ debug-print-function ${FUNCNAME} "${@}" |
255 |
+ |
256 |
+ # verify that sys-user_add_deps() has been called |
257 |
+ # (it verifies SYS_USER_GROUPS itself) |
258 |
+ if [[ -z ${_SYS_USER_ADD_DEPS_CALLED} ]]; then |
259 |
+ if declare -p SYS_USER_GROUPS &>/dev/null; then |
260 |
+ die "Ebuild error: sys-user_add_deps must have been called in global scope!" |
261 |
+ fi |
262 |
+ fi |
263 |
+ |
264 |
+ # verify SYS_USER_ID |
265 |
+ [[ -n ${SYS_USER_ID} ]] || die "Ebuild error: SYS_USER_ID must be set!" |
266 |
+ [[ ${SYS_USER_ID} -ge 0 ]] || die "Ebuild errors: SYS_USER_ID=${SYS_USER_ID} invalid!" |
267 |
+ |
268 |
+ # check for SYS_USER_ID collisions early |
269 |
+ if [[ -n ${SYS_USER_ENFORCE_ID} ]]; then |
270 |
+ local pwd=$(egetent passwd "${SYS_USER_ID}") |
271 |
+ if [[ -n ${pwd} ]]; then |
272 |
+ eerror "The required UID is already taken by another user." |
273 |
+ eerror " UID: ${SYS_USER_ID} (needed for ${PN})" |
274 |
+ eerror " current user: ${pwd}" |
275 |
+ die "UID ${SYS_USER_ID} taken already" |
276 |
+ fi |
277 |
+ fi |
278 |
+} |
279 |
+ |
280 |
+# @FUNCTION: sys-user_src_install |
281 |
+# @DESCRIPTION: |
282 |
+# Installs a keep-file into the user's home directory to ensure it is |
283 |
+# owned by the package. |
284 |
+sys-user_src_install() { |
285 |
+ debug-print-function ${FUNCNAME} "${@}" |
286 |
+ |
287 |
+ if [[ ${SYS_USER_HOME} != /dev/null ]]; then |
288 |
+ # note: we can't set permissions here since the user isn't |
289 |
+ # created yet |
290 |
+ keepdir "${SYS_USER_HOME}" |
291 |
+ fi |
292 |
+} |
293 |
+ |
294 |
+# @FUNCTION: sys-user_pkg_preinst |
295 |
+# @DESCRIPTION: |
296 |
+# Creates the user if it does not exist yet. Sets permissions |
297 |
+# of the home directory in install image. |
298 |
+sys-user_pkg_preinst() { |
299 |
+ debug-print-function ${FUNCNAME} "${@}" |
300 |
+ |
301 |
+ local groups=${SYS_USER_GROUPS[*]} |
302 |
+ enewuser -F -M "${PN}" "${SYS_USER_ID}" "${SYS_USER_SHELL}" \ |
303 |
+ "${SYS_USER_HOME}" "${groups// /,}" |
304 |
+ |
305 |
+ if [[ ${SYS_USER_HOME} != /dev/null ]]; then |
306 |
+ # set ownership of homedir to user:primary-group |
307 |
+ fowners "${SYS_USER_ID}" "${SYS_USER_HOME}" |
308 |
+ if [[ -n ${SYS_USER_GROUPS[0]} ]]; then |
309 |
+ fowners ":${SYS_USER_GROUPS[0]}" "${SYS_USER_HOME}" |
310 |
+ fi |
311 |
+ # TODO: should we fperms it too? To 0700 or is 0755 better |
312 |
+ # for service users? |
313 |
+ fi |
314 |
+} |
315 |
+ |
316 |
+# @FUNCTION: sys-user_pkg_prerm |
317 |
+# @DESCRIPTION: |
318 |
+# Ensures that the user account is locked out when it is removed. |
319 |
+sys-user_pkg_prerm() { |
320 |
+ debug-print-function ${FUNCNAME} "${@}" |
321 |
+ |
322 |
+ if [[ -z ${REPLACED_BY_VERSION} ]]; then |
323 |
+ : |
324 |
+ # TODO: what should we do here, exactly? we shouldn't touch |
325 |
+ # shell, and it should be nologin anyway. we could reset |
326 |
+ # the password but it should not be set anyway. |
327 |
+ fi |
328 |
+} |
329 |
+ |
330 |
+fi |
331 |
-- |
332 |
2.22.0.rc1 |