179 lines
3.8 KiB
Bash
Executable File
179 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# -*- mode: shell-script; indent-tabs-mode: true; tab-width: 4; -*-
|
|
|
|
# Creates system users and groups, based on files in the format described
|
|
# in sysusers.d(5). Replacement for systemd-sysusers(8) for the use of RPM
|
|
#
|
|
# USAGE:
|
|
#
|
|
# sysusers.sh [--root ROOTDIR] [--replace CONFIGFILE] [CONFIGFILE...]
|
|
#
|
|
# SEE ALSO systemd-sysusers(8)
|
|
#
|
|
# Based on sysusers.generate-pre.sh from the Fedora systemd package
|
|
|
|
SYSTEMDIR=/usr/lib/sysusers.d
|
|
RUNTIMEDIR=/run/sysusers.d
|
|
SYSTEMCONFDIR=/etc/sysusers.d
|
|
|
|
ROOT=/
|
|
REPLACE=#
|
|
|
|
while test $# -gt 0 ; do
|
|
case "${1}" in
|
|
--root )
|
|
shift
|
|
ROOT=${1}
|
|
shift
|
|
;;
|
|
--replace )
|
|
shift
|
|
REPLACE=${1}
|
|
shift
|
|
;;
|
|
--help )
|
|
cat <<EOF
|
|
|
|
sysusers.sh - Creates system users and groups, based on files in the
|
|
format described in sysusers.d(5). Replacement for systemd-sysusers(8)
|
|
for the use of RPM.
|
|
|
|
USAGE:
|
|
|
|
sysusers.sh [--root ROOTDIR] [--replace CONFIGFILE] [CONFIGFILE...]
|
|
|
|
SEE ALSO systemd-sysusers(8)
|
|
|
|
EOF
|
|
shift
|
|
;;
|
|
* )
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
|
|
hasuser() {
|
|
grep "^${1}:" "$ROOT"/etc/passwd >/dev/null
|
|
}
|
|
|
|
hasuid() {
|
|
cut -d: -f3 "$ROOT"/etc/passwd | grep "${1}" >/dev/null
|
|
}
|
|
|
|
hasgroup() {
|
|
grep "^${1}:" "$ROOT"/etc/group >/dev/null
|
|
}
|
|
|
|
user() {
|
|
local user="$1"
|
|
local uid="$2"
|
|
local desc="$3"
|
|
local group="$4"
|
|
local home="$5"
|
|
local shell="$6"
|
|
|
|
[ "$desc" = '-' ] && desc=
|
|
{ [ "$home" = '-' ] || [ "$home" = '' ]; } && home=/
|
|
{ [ "$shell" = '-' ] || [ "$shell" = '' ]; } && shell=/sbin/nologin
|
|
|
|
if [ "$uid" = '-' ] || [ "$uid" = '' ]; then
|
|
if ! hasuser "$user" ; then
|
|
useradd -R "$ROOT" -r -g "${group}" -d "${home}" -s "${shell}" -c "${desc}" "${user}" || :
|
|
fi
|
|
else
|
|
if ! hasuser "${user}" ; then
|
|
if ! hasuid "${uid}" ; then
|
|
useradd -R "$ROOT" -r -u "${uid}" -g "${group}" -d "${home}" -s "${shell}" -c "${desc}" "${user}" || :
|
|
else
|
|
useradd -R "$ROOT" -r -g "${group}" -d "${home}" -s "${shell}" -c "${desc}" "${user}" || :
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
group() {
|
|
local group="$1"
|
|
local gid="$2"
|
|
|
|
if [ "$gid" = '-' ]; then
|
|
hasgroup "${group}" || groupadd -R "$ROOT" -f -r "${group}" || :
|
|
else
|
|
hasgroup "${group}" || groupadd -R "$ROOT" -f -g "${gid}" -r "${group}" || :
|
|
fi
|
|
}
|
|
|
|
usermod() {
|
|
local user="$1"
|
|
local group="$2"
|
|
|
|
if hasgroup "${group}" ; then
|
|
usermod -R "$ROOT" -a -G "${group}" "$user" || :
|
|
fi
|
|
}
|
|
|
|
parse() {
|
|
local line arr
|
|
|
|
while read -r line || [ -n "$line" ] ; do
|
|
{ [ "${line:0:1}" = '#' ] || [ "${line:0:1}" = ';' ]; } && continue
|
|
line="${line## *}"
|
|
[ -z "$line" ] && continue
|
|
mapfile -t arr < <(xargs -n1 <<<"$line")
|
|
|
|
case "${arr[0]}" in
|
|
('u')
|
|
if [[ "${arr[2]}" == *":"* ]]; then
|
|
user "${arr[1]}" "${arr[2]%:*}" "${arr[3]}" "${arr[2]#*:}" "${arr[4]}" "${arr[5]}"
|
|
else
|
|
group "${arr[1]}" "${arr[2]}"
|
|
user "${arr[1]}" "${arr[2]}" "${arr[3]}" "${arr[1]}" "${arr[4]}" "${arr[5]}"
|
|
fi
|
|
;;
|
|
('g')
|
|
group "${arr[1]}" "${arr[2]}"
|
|
;;
|
|
('m')
|
|
group "${arr[2]}" "-"
|
|
user "${arr[1]}" "-" "" "${arr[1]}" "" ""
|
|
usermod "${arr[1]}" "${arr[2]}"
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
|
|
# Make sure etc and the user/group files exist
|
|
mkdir -p "$ROOT"/etc/
|
|
[ -e "$ROOT"/etc/passwd ] || touch "$ROOT"/etc/passwd
|
|
[ -e "$ROOT"/etc/shadow ] || touch "$ROOT"/etc/shadow
|
|
[ -e "$ROOT"/etc/group ] || touch "$ROOT"/etc/group
|
|
|
|
# read files from command line
|
|
for fn in "$@"; do
|
|
# check if file is replaced by one with higher priority
|
|
REPLACEDIR=$(dirname "$REPLACE")
|
|
REPLACENAME=$(basename "$REPLACE")
|
|
if [[ "$REPLACEDIR" == "${SYSTEMDIR}" ]] ; then
|
|
if [ -f "${ROOT}${RUNTIMEDIR}/${REPLACENAME}" ] ; then
|
|
continue
|
|
fi
|
|
if [ -f "${ROOT}${SYSTEMCONFDIR}/${REPLACENAME}" ] ; then
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
if [[ "$REPLACEDIR" == "$RUNTIMEDIR" ]] ; then
|
|
if [ -f "${ROOT}${SYSTEMCONFDIR}/${REPLACENAME}" ] ; then
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
if [ "-" = "$fn" ]; then
|
|
parse <&0
|
|
else
|
|
[ -r "$fn" ] || continue
|
|
parse <"$fn"
|
|
fi
|
|
done
|