Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: "Michał Górny" <mgorny@g.o>
Subject: [gentoo-dev] [PATCH v4 16/19] acct-user.eclass: Supporting locking & unlocking accounts
Date: Tue, 11 Jun 2019 16:29:30
Message-Id: 20190611162347.2989-17-mgorny@gentoo.org
In Reply to: [gentoo-dev] [PATCH v4 00/19] User/group packages by "Michał Górny"
1 Signed-off-by: Michał Górny <mgorny@g.o>
2 ---
3 eclass/acct-user.eclass | 127 ++++++++++++++++++++++++++++++++++++++++
4 1 file changed, 127 insertions(+)
5
6 diff --git a/eclass/acct-user.eclass b/eclass/acct-user.eclass
7 index 4a37bf3e1d95..1b8a0bf94a62 100644
8 --- a/eclass/acct-user.eclass
9 +++ b/eclass/acct-user.eclass
10 @@ -136,6 +136,131 @@ acct-user_add_deps() {
11 }
12
13
14 +# << Helper functions >>
15 +
16 +# @FUNCTION: eislocked
17 +# @INTERNAL
18 +# @USAGE: <user>
19 +# @DESCRIPTION:
20 +# Check whether the specified user account is currently locked.
21 +# Returns 0 if it is locked, 1 if it is not, 2 if the platform
22 +# does not support determining it.
23 +eislocked() {
24 + [[ $# -eq 1 ]] || die "usage: ${FUNCNAME} <user>"
25 +
26 + if [[ ${EUID} != 0 ]] ; then
27 + einfo "Insufficient privileges to execute ${FUNCNAME[0]}"
28 + return 0
29 + fi
30 +
31 + case ${CHOST} in
32 + *-freebsd*|*-dragonfly*|*-netbsd*)
33 + [[ $(egetent "$1" | cut -d: -f2) == '*LOCKED*'* ]]
34 + ;;
35 +
36 + *-openbsd*)
37 + return 2
38 + ;;
39 +
40 + *)
41 + # NB: 'no password' and 'locked' are indistinguishable
42 + # but we also expire the account which is more clear
43 + [[ $(getent shadow ftp | cut -d: -f2) == '!'* ]] &&
44 + [[ $(getent shadow ftp | cut -d: -f8) == 1 ]]
45 + ;;
46 + esac
47 +}
48 +
49 +# @FUNCTION: elockuser
50 +# @INTERNAL
51 +# @USAGE: <user>
52 +# @DESCRIPTION:
53 +# Lock the specified user account, using the available platform-specific
54 +# functions. This should prevent any login to the account.
55 +#
56 +# Established lock can be reverted using eunlockuser.
57 +#
58 +# This function returns 0 if locking succeeded, 2 if it is not supported
59 +# by the platform code or dies if it fails.
60 +elockuser() {
61 + [[ $# -eq 1 ]] || die "usage: ${FUNCNAME} <user>"
62 +
63 + if [[ ${EUID} != 0 ]] ; then
64 + einfo "Insufficient privileges to execute ${FUNCNAME[0]}"
65 + return 0
66 + fi
67 +
68 + eislocked "$1"
69 + [[ $? -eq 0 ]] && return 0
70 +
71 + case ${CHOST} in
72 + *-freebsd*|*-dragonfly*)
73 + pw lock "$1" || die "Locking account $1 failed"
74 + pw user mod "$1" -e 1 || die "Expiring account $1 failed"
75 + ;;
76 +
77 + *-netbsd*)
78 + usermod -e 1 -C yes "$1" || die "Locking account $1 failed"
79 + ;;
80 +
81 + *-openbsd*)
82 + return 2
83 + ;;
84 +
85 + *)
86 + usermod -e 1 -L "$1" || die "Locking account $1 failed"
87 + ;;
88 + esac
89 +
90 + elog "User account $1 locked"
91 + return 0
92 +}
93 +
94 +# @FUNCTION: eunlockuser
95 +# @INTERNAL
96 +# @USAGE: <user>
97 +# @DESCRIPTION:
98 +# Unlock the specified user account, using the available platform-
99 +# specific functions.
100 +#
101 +# This function returns 0 if unlocking succeeded, 1 if it is not
102 +# supported by the platform code or dies if it fails.
103 +eunlockuser() {
104 + [[ $# -eq 1 ]] || die "usage: ${FUNCNAME} <user>"
105 +
106 + if [[ ${EUID} != 0 ]] ; then
107 + einfo "Insufficient privileges to execute ${FUNCNAME[0]}"
108 + return 0
109 + fi
110 +
111 + eislocked "$1"
112 + [[ $? -eq 1 ]] && return 0
113 +
114 + case ${CHOST} in
115 + *-freebsd*|*-dragonfly*)
116 + pw user mod "$1" -e 0 || die "Unexpiring account $1 failed"
117 + pw unlock "$1" || die "Unlocking account $1 failed"
118 + ;;
119 +
120 + *-netbsd*)
121 + usermod -e 0 -C no "$1" || die "Unlocking account $1 failed"
122 + ;;
123 +
124 + *-openbsd*)
125 + return 1
126 + ;;
127 +
128 + *)
129 + # silence warning if account does not have a password
130 + usermod -e "" -U "$1" 2>/dev/null || die "Unlocking account $1 failed"
131 + ;;
132 + esac
133 +
134 + ewarn "User account $1 unlocked after reinstating."
135 + return 0
136 +}
137 +
138 +
139 # << Phase functions >>
140 EXPORT_FUNCTIONS pkg_pretend src_install pkg_preinst pkg_postinst \
141 pkg_prerm
142 @@ -228,6 +353,7 @@ acct-user_pkg_postinst() {
143 esetgroups "${ACCT_USER_NAME}" "${groups// /,}"
144 # comment field can not contain colons
145 esetcomment "${ACCT_USER_NAME}" "${DESCRIPTION//[:,=]/;}"
146 + eunlockuser "${ACCT_USER_NAME}"
147 }
148
149 # @FUNCTION: acct-user_pkg_prerm
150 @@ -240,6 +366,7 @@ acct-user_pkg_prerm() {
151 esetshell "${ACCT_USER_NAME}" -1
152 esetcomment "${ACCT_USER_NAME}" \
153 "$(egetcomment "${ACCT_USER_NAME}"); user account removed @ $(date +%Y-%m-%d)"
154 + elockuser "${ACCT_USER_NAME}"
155 fi
156 }
157
158 --
159 2.22.0