From 2ae05a1413eea0e5b34e2d4eaf8bff046f692604 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Fri, 10 Apr 2020 13:25:28 -0500 Subject: [PATCH] add baker --- baker/bin/baker | 155 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 baker/bin/baker diff --git a/baker/bin/baker b/baker/bin/baker new file mode 100644 index 0000000..61999a8 --- /dev/null +++ b/baker/bin/baker @@ -0,0 +1,155 @@ +#!/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 + return "$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 "Need a user" + [ -z "$name" ] && die "Need a name" + [ -z "$keyfile" ] && die "Need a keyfile" + + log "Adding user $user" + adduser \ + --shell="$shell" \ + --gecos="$name" \ + --disabled-password "$user" && + ok + 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" + sudo --user="$user" \ + cp "$keyfile" "/home/$user/.ssh/authorized_keys2"; + } && 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%,}" && ok +} + +main() +{ # entry point + cmd="$1"; shift || die "Not enough arguments for \"$cmd\"" + case "$cmd" in + help|h) + (( $# == 0 )) && usage 0 + ;; + add|hire) + cmd=add ;; + remove|rm|fire) + cmd=remove ;; + promote) + cmd=promote ;; + demote) + cmd=demote ;; + esac + + "baker$cmd" "$@" +} + +main "$@"