175 lines
3.6 KiB
Bash
Executable File
175 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# baker: user administration for breadpunk.club
|
|
# by breadw
|
|
|
|
set -euo pipefail
|
|
|
|
usage()
|
|
{
|
|
case "$1" in
|
|
[0-9]*) ec="$1"; shift ;;
|
|
*) ec=0 ;;
|
|
esac
|
|
(( $# > 0 )) && printf '!! baker: %s\n' "$*"
|
|
sed -n '2s/^#* *//' "$0" >&2
|
|
echo >&2
|
|
cat <<-ENDUSAGE >&2
|
|
usage: baker COMMAND [OPTIONS] USER
|
|
|
|
COMMANDs:
|
|
add/hire add a new user
|
|
rm/fire remove a user
|
|
promote add to groups
|
|
demote remove from groups
|
|
help show help - use 'baker help COMMAND' for specifics
|
|
|
|
ENDUSAGE
|
|
exit "$ec"
|
|
}
|
|
|
|
die()
|
|
{
|
|
ec="$1"; shift
|
|
echo "!! ${FUNCNAME[1]}: $*" >&2
|
|
exit "$ec"
|
|
}
|
|
|
|
log() { printf '%s...' "$*" >&2; }
|
|
ok() { printf ' %s\n' "Done" >&2; }
|
|
|
|
bakeradd()
|
|
{
|
|
# add a baker
|
|
# baker add -u USER -n NAME -k KEYFILE [-G GROUPS] [-s SHELL]
|
|
# a wrapper around adduser
|
|
user=
|
|
name=
|
|
keyfile=
|
|
groups=bakers
|
|
shell=/bin/bash
|
|
|
|
while getopts s:n:G:k:u: opt; do
|
|
case "$opt" in
|
|
s) shell="$OPTARG" ;;
|
|
n) name="$OPTARG" ;;
|
|
G) groups="$groups${groups:+,}$OPTARG" ;;
|
|
k) keyfile="$OPTARG" ;;
|
|
u) user="$OPTARG" ;;
|
|
\?) die 1 ;;
|
|
*) die 1 "Unknown option -$opt" ;;
|
|
esac
|
|
done
|
|
|
|
[ -z "$user" ] && die 2 "Need a user"
|
|
[ -z "$name" ] && die 2 "Need a name"
|
|
[ -z "$keyfile" ] && die 2 "Need a keyfile"
|
|
|
|
log "Adding user $user"
|
|
adduser \
|
|
--shell="$shell" \
|
|
--gecos="$name" \
|
|
--disabled-password "$user" &&
|
|
ok || die 4 "Couldn't add user \"$user\""
|
|
log "Adding user $user to groups $groups"
|
|
usermod -a -G "$groups" "$user" && ok
|
|
|
|
log "Setting up ~/.ssh for $user"
|
|
{
|
|
sudo --user="$user" mkdir "/home/$user/.ssh"
|
|
cat "$keyfile" >> "/home/$user/.ssh/authorized_keys2"
|
|
chown "$user:$user" "/home/$user/.ssh/authorized_keys2"
|
|
chmod 700 "/home/$user/.ssh"
|
|
chmod 644 "/home/$user/.ssh/authorized_keys2"
|
|
} && ok
|
|
|
|
log "Adding gemini userdir for $user"
|
|
{
|
|
mkdir "/var/gemini/bakers/$user"
|
|
chown "$user:$user" "/var/gemini/bakers/$user"
|
|
chmod 755 "/var/gemini/bakers/$user"
|
|
sudo --user="$user" \
|
|
ln -s /var/gemini/bakers/$user /home/$user/public_gemini
|
|
} && ok
|
|
|
|
echo "$user added."
|
|
}
|
|
|
|
bakerremove()
|
|
{
|
|
# remove a baker
|
|
# baker rm USER
|
|
user="$1"
|
|
log "Locking $user's account"
|
|
passwd -l "$user" && ok
|
|
log "Killing $user's processes"
|
|
pkill -KILL -u "$user" && ok
|
|
log "Removing $user's crontab"
|
|
crontab -r -u "$user" && ok
|
|
log "Removing user $user"
|
|
# TODO: look into deluser.conf
|
|
deluser --remove-home "$user" --backup-to /bread/fired/ && ok
|
|
echo "$user removed."
|
|
}
|
|
|
|
bakerpromote()
|
|
{
|
|
# add a baker to groups
|
|
# baker promote USER GROUP...
|
|
user="$1"; shift
|
|
groups=
|
|
for group; do
|
|
groups="$groups${groups:+,}$group"
|
|
done
|
|
log "Adding $user to groups: $groups"
|
|
usermod -a -G "$groups" "$user" && ok
|
|
}
|
|
|
|
bakerdemote()
|
|
{
|
|
# remove a baker from groups
|
|
# baker demote USER GROUP...
|
|
user="$1"
|
|
_sed=( sed )
|
|
for group; do
|
|
if (groups "$user" | grep "$group"); then
|
|
log "Removing $user from $group"
|
|
_sed+=( -e "/$group/d" ) && ok
|
|
else
|
|
echo "$user is not a member of $group"
|
|
fi
|
|
done
|
|
groups="$(getent group|grep "$user"|cut -d: -f1|"${_sed[@]}"|tr '\n' ',')"
|
|
log "Applying changes"
|
|
usermod -G "${groups%,}" "$user" && ok
|
|
}
|
|
|
|
main()
|
|
{ # entry point
|
|
(( $# == 0 )) && usage 1
|
|
cmd="$1"; shift || die 2 "Not enough arguments for \"$cmd\""
|
|
case "$cmd" in
|
|
help|h|usage|-h|--help)
|
|
(( $# == 0 )) && usage 0
|
|
grep -q "baker$1" "$0" && {
|
|
echo "baker $1"
|
|
awk "BEGIN{FS=\"\\n\";RS=\"\";}/baker$1/{print}" "$0" |
|
|
sed -n 's/# //p'
|
|
exit
|
|
} || die 2 "No command \"$1\""
|
|
;;
|
|
add|hire)
|
|
cmd=add ;;
|
|
remove|rm|fire)
|
|
cmd=remove ;;
|
|
promote)
|
|
cmd=promote ;;
|
|
demote)
|
|
cmd=demote ;;
|
|
esac
|
|
|
|
(( $(id -u) == 0 )) || die 3 "Script must be run as root"
|
|
"baker$cmd" "$@"
|
|
}
|
|
|
|
main "$@"
|