1 |
--- |
2 |
eclass/acct-group.eclass | 105 +++++++++++++++++++ |
3 |
eclass/acct-user.eclass | 217 +++++++++++++++++++++++++++++++++++++++ |
4 |
2 files changed, 322 insertions(+) |
5 |
create mode 100644 eclass/acct-group.eclass |
6 |
create mode 100644 eclass/acct-user.eclass |
7 |
|
8 |
diff --git a/eclass/acct-group.eclass b/eclass/acct-group.eclass |
9 |
new file mode 100644 |
10 |
index 000000000000..8b3b2202aa35 |
11 |
--- /dev/null |
12 |
+++ b/eclass/acct-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: acct-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 ACCT_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 'acct-group/foo' package |
32 |
+# and add an ebuild with the following contents: |
33 |
+# |
34 |
+# @CODE |
35 |
+# EAPI=7 |
36 |
+# inherit acct-group |
37 |
+# ACCT_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 ${_ACCT_GROUP_ECLASS} ]]; then |
49 |
+_ACCT_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: ACCT_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: ACCT_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 |
+: ${ACCT_GROUP_ENFORCE_ID:=} |
73 |
+ |
74 |
+ |
75 |
+# << Boilerplate ebuild variables >> |
76 |
+: ${DESCRIPTION:="Service 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: acct-group_pkg_pretend |
87 |
+# @DESCRIPTION: |
88 |
+# Performs sanity checks for correct eclass usage, and early-checks |
89 |
+# whether requested GID can be enforced. |
90 |
+acct-group_pkg_pretend() { |
91 |
+ debug-print-function ${FUNCNAME} "${@}" |
92 |
+ |
93 |
+ # verify ACCT_GROUP_ID |
94 |
+ [[ -n ${ACCT_GROUP_ID} ]] || die "Ebuild error: ACCT_GROUP_ID must be set!" |
95 |
+ [[ ${ACCT_GROUP_ID} -ge 0 ]] || die "Ebuild errors: ACCT_GROUP_ID=${ACCT_GROUP_ID} invalid!" |
96 |
+ |
97 |
+ # check for ACCT_GROUP_ID collisions early |
98 |
+ if [[ -n ${ACCT_GROUP_ENFORCE_ID} ]]; then |
99 |
+ local grp=$(egetent group "${ACCT_GROUP_ID}") |
100 |
+ if [[ -n ${grp} ]]; then |
101 |
+ eerror "The required GID is already taken by another group." |
102 |
+ eerror " GID: ${ACCT_GROUP_ID} (needed for ${PN})" |
103 |
+ eerror " current group: ${grp}" |
104 |
+ die "GID ${ACCT_GROUP_ID} taken already" |
105 |
+ fi |
106 |
+ fi |
107 |
+} |
108 |
+ |
109 |
+# @FUNCTION: acct-group_pkg_preinst |
110 |
+# @DESCRIPTION: |
111 |
+# Creates the group if it does not exist yet. |
112 |
+acct-group_pkg_preinst() { |
113 |
+ debug-print-function ${FUNCNAME} "${@}" |
114 |
+ |
115 |
+ enewgroup -F "${PN}" "${ACCT_GROUP_ID}" |
116 |
+} |
117 |
+ |
118 |
+fi |
119 |
diff --git a/eclass/acct-user.eclass b/eclass/acct-user.eclass |
120 |
new file mode 100644 |
121 |
index 000000000000..12bc3652f333 |
122 |
--- /dev/null |
123 |
+++ b/eclass/acct-user.eclass |
124 |
@@ -0,0 +1,217 @@ |
125 |
+# Copyright 2019 Gentoo Authors |
126 |
+# Distributed under the terms of the GNU General Public License v2 |
127 |
+ |
128 |
+# @ECLASS: acct-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 ACCT_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 'acct-user/foo' package and add an ebuild with the following |
146 |
+# contents: |
147 |
+# |
148 |
+# @CODE |
149 |
+# EAPI=7 |
150 |
+# inherit acct-user |
151 |
+# ACCT_USER_ID=200 |
152 |
+# ACCT_USER_GROUPS=( foo ) |
153 |
+# acct-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 ${_ACCT_USER_ECLASS} ]]; then |
164 |
+_ACCT_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: ACCT_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: ACCT_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 |
+: ${ACCT_USER_ENFORCE_ID:=} |
188 |
+ |
189 |
+# @ECLASS-VARIABLE: ACCT_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 |
+: ${ACCT_USER_SHELL:=-1} |
194 |
+ |
195 |
+# @ECLASS-VARIABLE: ACCT_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 |
+: ${ACCT_USER_HOME:=/dev/null} |
201 |
+ |
202 |
+# @ECLASS-VARIABLE: ACCT_USER_HOME_OWNER |
203 |
+# @DEFAULT_UNSET |
204 |
+# @DESCRIPTION: |
205 |
+# The ownership to use for the home directory, in chown ([user][:group]) |
206 |
+# syntax. Defaults to the newly created user, and its primary group |
207 |
+# (if any; :root otherwise). |
208 |
+ |
209 |
+# @ECLASS-VARIABLE: ACCT_USER_HOME_PERMS |
210 |
+# @DESCRIPTION: |
211 |
+# The permissions to use for the home directory, in chmod (octal |
212 |
+# or verbose) form. |
213 |
+: ${ACCT_USER_HOME_PERMS:=0755} |
214 |
+ |
215 |
+# @ECLASS-VARIABLE: ACCT_USER_GROUPS |
216 |
+# @DEFAULT_UNSET |
217 |
+# @DESCRIPTION: |
218 |
+# List of groups the user should belong to. This must be a bash |
219 |
+# array. If not specified, the user is not added to any groups. |
220 |
+# This affects only new user accounts. |
221 |
+# |
222 |
+# If ACCT_USER_GROUPS is specified, the ebuild needs to call |
223 |
+# acct-user_add_deps in global scope to add appropriate dependencies. |
224 |
+ |
225 |
+ |
226 |
+# << Boilerplate ebuild variables >> |
227 |
+: ${DESCRIPTION:="Service user: ${PN}"} |
228 |
+: ${HOMEPAGE:=https://www.gentoo.org/} |
229 |
+: ${SLOT:=0} |
230 |
+: ${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} |
231 |
+S=${WORKDIR} |
232 |
+ |
233 |
+ |
234 |
+# << API functions >> |
235 |
+ |
236 |
+# @FUNCTION: acct-user_add_deps |
237 |
+# @DESCRIPTION: |
238 |
+# Generate appropriate RDEPEND from ACCT_USER_GROUPS. This must be |
239 |
+# called if ACCT_USER_GROUPS are set. |
240 |
+acct-user_add_deps() { |
241 |
+ debug-print-function ${FUNCNAME} "${@}" |
242 |
+ |
243 |
+ # ACCT_USER_GROUPS sanity check |
244 |
+ if ! declare -p ACCT_USER_GROUPS &>/dev/null; then |
245 |
+ return |
246 |
+ elif [[ $(declare -p ACCT_USER_GROUPS) != "declare -a"* ]]; then |
247 |
+ die 'ACCT_USER_GROUPS must be an array.' |
248 |
+ fi |
249 |
+ |
250 |
+ RDEPEND+=${ACCT_USER_GROUPS[*]/#/ acct-group/} |
251 |
+ _ACCT_USER_ADD_DEPS_CALLED=1 |
252 |
+} |
253 |
+ |
254 |
+ |
255 |
+# << Phase functions >> |
256 |
+EXPORT_FUNCTIONS pkg_pretend src_install pkg_preinst pkg_prerm |
257 |
+ |
258 |
+# @FUNCTION: acct-user_pkg_pretend |
259 |
+# @DESCRIPTION: |
260 |
+# Performs sanity checks for correct eclass usage, and early-checks |
261 |
+# whether requested UID can be enforced. |
262 |
+acct-user_pkg_pretend() { |
263 |
+ debug-print-function ${FUNCNAME} "${@}" |
264 |
+ |
265 |
+ # verify that acct-user_add_deps() has been called |
266 |
+ # (it verifies ACCT_USER_GROUPS itself) |
267 |
+ if [[ -z ${_ACCT_USER_ADD_DEPS_CALLED} ]]; then |
268 |
+ if declare -p ACCT_USER_GROUPS &>/dev/null; then |
269 |
+ die "Ebuild error: acct-user_add_deps must have been called in global scope!" |
270 |
+ fi |
271 |
+ fi |
272 |
+ |
273 |
+ # verify ACCT_USER_ID |
274 |
+ [[ -n ${ACCT_USER_ID} ]] || die "Ebuild error: ACCT_USER_ID must be set!" |
275 |
+ [[ ${ACCT_USER_ID} -ge 0 ]] || die "Ebuild errors: ACCT_USER_ID=${ACCT_USER_ID} invalid!" |
276 |
+ |
277 |
+ # check for ACCT_USER_ID collisions early |
278 |
+ if [[ -n ${ACCT_USER_ENFORCE_ID} ]]; then |
279 |
+ local pwd=$(egetent passwd "${ACCT_USER_ID}") |
280 |
+ if [[ -n ${pwd} ]]; then |
281 |
+ eerror "The required UID is already taken by another user." |
282 |
+ eerror " UID: ${ACCT_USER_ID} (needed for ${PN})" |
283 |
+ eerror " current user: ${pwd}" |
284 |
+ die "UID ${ACCT_USER_ID} taken already" |
285 |
+ fi |
286 |
+ fi |
287 |
+} |
288 |
+ |
289 |
+# @FUNCTION: acct-user_src_install |
290 |
+# @DESCRIPTION: |
291 |
+# Installs a keep-file into the user's home directory to ensure it is |
292 |
+# owned by the package. |
293 |
+acct-user_src_install() { |
294 |
+ debug-print-function ${FUNCNAME} "${@}" |
295 |
+ |
296 |
+ if [[ ${ACCT_USER_HOME} != /dev/null ]]; then |
297 |
+ # note: we can't set permissions here since the user isn't |
298 |
+ # created yet |
299 |
+ keepdir "${ACCT_USER_HOME}" |
300 |
+ fi |
301 |
+} |
302 |
+ |
303 |
+# @FUNCTION: acct-user_pkg_preinst |
304 |
+# @DESCRIPTION: |
305 |
+# Creates the user if it does not exist yet. Sets permissions |
306 |
+# of the home directory in install image. |
307 |
+acct-user_pkg_preinst() { |
308 |
+ debug-print-function ${FUNCNAME} "${@}" |
309 |
+ |
310 |
+ local groups=${ACCT_USER_GROUPS[*]} |
311 |
+ enewuser -F -M "${PN}" "${ACCT_USER_ID}" "${ACCT_USER_SHELL}" \ |
312 |
+ "${ACCT_USER_HOME}" "${groups// /,}" |
313 |
+ |
314 |
+ if [[ ${ACCT_USER_HOME} != /dev/null ]]; then |
315 |
+ # default ownership to user:group |
316 |
+ if [[ -z ${ACCT_USER_HOME_OWNER} ]]; then |
317 |
+ ACCT_USER_HOME_OWNER=${PN} |
318 |
+ if [[ -n ${ACCT_USER_GROUPS[0]} ]]; then |
319 |
+ ACCT_USER_HOME_OWNER+=:${ACCT_USER_GROUPS[0]} |
320 |
+ fi |
321 |
+ fi |
322 |
+ fowners "${ACCT_USER_HOME_OWNER}" "${ACCT_USER_HOME}" |
323 |
+ fperms "${ACCT_USER_HOME_PERMS}" "${ACCT_USER_HOME}" |
324 |
+ fi |
325 |
+} |
326 |
+ |
327 |
+# @FUNCTION: acct-user_pkg_prerm |
328 |
+# @DESCRIPTION: |
329 |
+# Ensures that the user account is locked out when it is removed. |
330 |
+acct-user_pkg_prerm() { |
331 |
+ debug-print-function ${FUNCNAME} "${@}" |
332 |
+ |
333 |
+ if [[ -z ${REPLACED_BY_VERSION} ]]; then |
334 |
+ : |
335 |
+ # TODO: what should we do here, exactly? we shouldn't touch |
336 |
+ # shell, and it should be nologin anyway. we could reset |
337 |
+ # the password but it should not be set anyway. |
338 |
+ fi |
339 |
+} |
340 |
+ |
341 |
+fi |
342 |
-- |
343 |
2.22.0.rc3 |