blob: 75f031c695a7c6ded326ee9f902080cadde97432 [file] [log] [blame] [edit]
#!/bin/sh
###############################################################################
# BRLTTY - A background process providing access to the console screen (when in
# text mode) for a blind person using a refreshable braille display.
#
# Copyright (C) 1995-2023 by The BRLTTY Developers.
#
# BRLTTY comes with ABSOLUTELY NO WARRANTY.
#
# This is free software, placed under the terms of the
# GNU Lesser General Public License, as published by the Free Software
# Foundation; either version 2.1 of the License, or (at your option) any
# later version. Please see the file LICENSE-LGPL for details.
#
# Web Page: http://brltty.app/
#
# This software is maintained by Dave Mielke <dave@mielke.cc>.
###############################################################################
set -e
. "`dirname "${0}"`/brltty-prologue.sh"
. "${programDirectory}/brltty-config.sh"
showProgramUsagePurpose() {
cat <<END_OF_PROGRAM_USAGE_PURPOSE
Simplify the job of Creating and making changes to BRLTTY's unprivileged user.
END_OF_PROGRAM_USAGE_PURPOSE
}
declare -A privilegeParameters
parseParameterString privilegeParameters "${BRLTTY_PRIVILEGE_PARAMETERS}" lx
readonly defaultUserName="${privilegeParameters["USER"]}"
readonly defaultUserInformation="Braille Device Daemon"
readonly defaultHomeDirectory="${BRLTTY_UPDATABLE_DIRECTORY}"
readonly defaultLoginShell="/sbin/nologin"
showProgramUsageNotes() {
cat <<END_OF_PROGRAM_USAGE_NOTES
When creating a new user, these options have the following defaults:
-d ${defaultHomeDirectory:-the home directory isn't defined}
-g a new group with the same name as the user
-i ${defaultUserInformation}
-l ${defaultLoginShell}
These defaults don't apply when making changes to an existing user.
END_OF_PROGRAM_USAGE_NOTES
}
executeCommand() {
"${useSudo}" && set -- sudo -- "${@}"
if "${testMode}"
then
echo "${*}"
else
"${@}"
fi
}
groupList=()
addGroups() {
while [ "${#}" -gt 0 ]
do
local group="${1}"
shift 1
[ -n "${group}" ] || continue
[ "${group#*/}" = "${group}" ] || {
group="$(stat -c "%G" "${group}")" || :
[ -n "${group}" ] || continue
}
local g
for g in "${groupList[@]}"
do
[ "${g}" = "${group}" ] && {
group=""
break
}
done
[ -n "${group}" ] && groupList[${#groupList[*]}]="${group}"
done
return 0
}
addProgramOption a flag noALSA "don't allow playing sound via the ALSA framework"
addProgramOption b flag noBrlapi "don't allow reading BrlAPI's authorization key file"
addProgramOption c flag noConsoles "don't allow access to the virtual consoles"
addProgramOption d string.path homeDirectory "set/change the home (login) directory"
addProgramOption g string.group primaryGroup "set/change the primary (login) group"
addProgramOption i string.text userInformation "set/change the user information (gecos) text"
addProgramOption k flag noKeyboards "don't allow keyboard monitoring"
addProgramOption l string.path loginShell "set/change the login shell"
addProgramOption p flag noPulse "don't allow playing sound via the Pulse Audio server"
addProgramOption s flag noSerial "don't allow access to serial devices"
addProgramOption u flag noUSB "don't allow access to USB devices"
addProgramOption E flag allowChanges "allow changes to an existing user"
addProgramOption G flag noGroups "don't set/change the supplementary group list"
addProgramOption N flag allowCreate "allow creating a new user"
addProgramOption S flag useSudo "use sudo to execute the commands as root"
addProgramOption T flag testMode "test mode - show the commands that would be executed"
addProgramOption U string.user userName "the user to be created/changed" "${defaultUserName}"
parseProgramArguments "${@}"
[ -n "${userName}" ] || userName="${defaultUserName}"
[ -n "${userName}" ] || syntaxError "unprivileged user not configured - use -U (user) to specify"
if id -u "${userName}" >/dev/null 2>&1
then
"${allowChanges}" || semanticError "user already exists: ${userName} - use -E (existing) to allow"
command=(usermod)
else
"${allowCreate}" || semanticError "user doesn't exist: ${userName} - use -N (new) to allow"
command=(useradd --system)
[ -n "${primaryGroup}" ] || command+=(--user-group)
[ -n "${userInformation}" ] || userInformation="${defaultUserInformation}"
[ -n "${homeDirectory}" ] || homeDirectory="${defaultHomeDirectory}"
[ -n "${loginShell}" ] || loginShell="${defaultLoginShell}"
if [ -n "${homeDirectory}" ]
then
command+=(--create-home)
else
command+=(--no-create-home)
fi
fi
[ -n "${homeDirectory}" ] && command+=(--home "${homeDirectory}")
[ -n "${primaryGroup}" ] && command+=(--gid "${primaryGroup}")
[ -n "${userInformation}" ] && command+=(--comment "${userInformation}")
[ -n "${loginShell}" ] && command+=(--shell "${loginShell}")
"${noGroups}" || {
"${noALSA}" || addGroups audio
"${noBrlapi}" || addGroups "${BRLAPI_KEY_FILE}"
"${noConsoles}" || addGroups tty /dev/vcs1 /dev/tty1
"${noKeyboards}" || addGroups input
"${noPulse}" || addGroups pulse-access
"${noSerial}" || addGroups /dev/ttyS0
"${noUSB}" || addGroups /dev/bus/usb
groupsOperand="${groupList[*]}"
groupsOperand="${groupsOperand// /,}"
command+=(--groups "${groupsOperand}")
}
"${testMode}" || {
if "${useSudo}"
then
sudo -v
elif [ "$(id -u)" -ne 0 ]
then
semanticError "not executing as root"
fi
}
command+=(-- "${userName}")
executeCommand "${command[@]}"
exit 0