sys/vfs/hammer2: Fix multiple "radii" -> "radix"
[dragonfly.git] / tools / pw-update.sh
blob79b9cff49c850c1d33f55cead61cf72cf5da2483
1 #!/bin/sh
3 # Copyright (c) 2020 The DragonFly Project.
4 # All rights reserved.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in
14 # the documentation and/or other materials provided with the
15 # distribution.
16 # 3. Neither the name of The DragonFly Project nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific, prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 # COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 # SUCH DAMAGE.
34 # Exit if any untested command fails in non-interactive mode
35 set -e
36 # Exit when an undefined variable is referenced
37 set -u
39 # Usage: add_users <etcdir> <master.passwd> <group>
41 # Add new users and groups in <etcdir> according to the given <master.passwd>
42 # and <group> files.
44 # NOTE: Existing users and groups are not modified.
46 add_users() {
47 local etcdir="$1"
48 local fpasswd="$2"
49 local fgroup="$3"
50 local _name _pw _uid _gid _gids _group item
51 local _class _change _expire _gecos _home _shell _members
53 echo "===> Adding new users ..."
54 _gids=""
55 while IFS=':' read -r _name _pw _uid _gid _class \
56 _change _expire _gecos _home _shell; do
57 case ${_name} in
58 '' | \#*) continue ;;
59 esac
60 if pw -V ${etcdir} usershow ${_name} -q >/dev/null; then
61 continue
63 echo " * ${_name}: ${_uid}, ${_gid}, ${_gecos}, ${_home}, ${_shell}"
65 _group=${_gid}
66 if ! pw -V ${etcdir} groupshow ${_gid} -q >/dev/null; then
67 # Primary group doesn't exist yet, so first assign to
68 # the 'nogroup' group, and then adjust it after
69 # creating the group.
70 _group="nogroup"
71 _gids="${_gids} ${_name}:${_gid}"
74 # NOTE: The shell field can be empty (e.g., user 'toor') and
75 # would default to '/bin/sh'.
76 # NOTE: Use '-o' option to allow to create user of duplicate
77 # UID, which is required by the 'toor' user (same UID
78 # as 'root').
79 pw -V ${etcdir} useradd ${_name} \
80 -o \
81 -u ${_uid} \
82 -g ${_group} \
83 -d "${_home}" \
84 -s "${_shell}" \
85 -L "${_class}" \
86 -c "${_gecos}"
87 done < ${fpasswd}
89 echo "===> Adding new groups ..."
90 while IFS=':' read -r _name _pw _gid _members; do
91 case ${_name} in
92 '' | \#*) continue ;;
93 esac
94 if pw -V ${etcdir} groupshow ${_name} -q >/dev/null; then
95 continue
97 echo " * ${_name}: ${_gid}, ${_members}"
98 pw -V ${etcdir} groupadd ${_name} -g ${_gid} -M "${_members}"
99 done < ${fgroup}
101 echo "===> Adjusting the group of new users ..."
102 for item in ${_gids}; do
103 _name=${item%:*}
104 _gid=${item#*:}
105 echo " * ${_name}: ${_gid}"
106 pw -V ${etcdir} usermod ${_name} -g ${_gid}
107 done
110 # Usage: update_user <user> <etcdir> <master.passwd>
112 # Update an existing user in <etcdir> according to the given <master.passwd>.
114 update_user() {
115 local user="$1"
116 local etcdir="$2"
117 local fpasswd="$3"
118 local _line
119 local _name _pw _uid _gid _class _change _expire _gecos _home _shell
121 _line=$(grep "^${user}:" ${fpasswd}) || true
122 if [ -z "${_line}" ]; then
123 echo "ERROR: no such user '${user}'" >&2
124 exit 1
127 echo "${_line}" | {
128 IFS=':' read -r _name _pw _uid _gid _class \
129 _change _expire _gecos _home _shell
130 echo "===> Updating user ${user} ..."
131 echo " * ${_name}: ${_uid}, ${_gid}, ${_gecos}, ${_home}, ${_shell}"
132 pw -V ${etcdir} usermod ${user} \
133 -u ${_uid} \
134 -g ${_gid} \
135 -d ${_home} \
136 -s ${_shell} \
137 -L "${_class}" \
138 -c "${_gecos}"
142 # Usage: update_group <group> <etcdir> <group>
144 # Update an existing group in <etcdir> according to the given <group> file.
146 update_group() {
147 local group="$1"
148 local etcdir="$2"
149 local fgroup="$3"
150 local _line
151 local _name _pw _gid _members
153 _line=$(grep "^${group}:" ${fgroup}) || true
154 if [ -z "${_line}" ]; then
155 echo "ERROR: no such group '${group}'" >&2
156 exit 1
159 echo "${_line}" | {
160 IFS=':' read -r _name _pw _gid _members
161 echo "===> Updating group ${group} ..."
162 echo " * ${_name}: ${_gid}, ${_members}"
163 pw -V ${etcdir} groupmod ${group} -g ${_gid} -M "${_members}"
167 usage() {
168 cat > /dev/stderr << _EOF_
169 Add/update users and groups.
171 Usage: ${0##*/} -d <etc-dir> -g <group-file> -p <master.passwd-file>
172 [-G group] [-U user]
174 _EOF_
176 exit 1
179 ETC_DIR=
180 GROUP_FILE=
181 PASSWD_FILE=
182 UPDATE_GROUP=
183 UPDATE_USER=
185 while getopts :d:G:g:hp:U: opt; do
186 case ${opt} in
188 ETC_DIR=${OPTARG}
191 UPDATE_GROUP=${OPTARG}
194 GROUP_FILE=${OPTARG}
197 PASSWD_FILE=${OPTARG}
200 UPDATE_USER=${OPTARG}
202 h | \? | :)
203 usage
205 esac
206 done
208 shift $((OPTIND - 1))
209 [ $# -eq 0 ] || usage
210 [ -n "${ETC_DIR}" ] || usage
211 [ -n "${GROUP_FILE}" ] || usage
212 [ -n "${PASSWD_FILE}" ] || usage
214 if [ -z "${UPDATE_GROUP}" ] && [ -z "${UPDATE_USER}" ]; then
215 add_users "${ETC_DIR}" "${PASSWD_FILE}" "${GROUP_FILE}"
216 else
217 if [ -n "${UPDATE_GROUP}" ]; then
218 update_group "${UPDATE_GROUP}" "${ETC_DIR}" "${GROUP_FILE}"
220 if [ -n "${UPDATE_USER}" ]; then
221 update_user "${UPDATE_USER}" "${ETC_DIR}" "${PASSWD_FILE}"