#!/bin/sh # tool for managing the ACF passwords passwdfile=${ACFPASSWD:-/etc/acf/passwd} shadow=${SHADOW:-/etc/shadow} usage() { echo "usage: acfpasswd [-s] USER" echo "" exit 1 } die() { echo "$@" >&2 exit 1 } find_user_or_die() { local user="$1" grep -q "^${user}:" "$passwdfile" \ || die "user '$user' was not found in $passwdfile" } set_pw_hash() { local user="$1" local pwhash="$2" # use : as sed separator since its guaranteed to no be valid in shadow sed -i -e "s:^${user}\:[^\:]*\::${user}\:${pwhash}\::" "$passwdfile" } syncpasswd() { local user="$1" local pwhash=$(awk -F: -v user="$user" '$1 == user { print $2 }' \ $shadow) || exit find_user_or_die "$user" [ -z "$pwhash" ] && die "user '$user' was not found in $shadow" set_pw_hash "$user" "$pwhash" exit } sync_with_system= while getopts "hs" opt; do case "$opt" in h) usage;; s) sync_with_system=yes;; esac done shift $(($OPTIND - 1)) user="$1" [ -z "$user" ] && usage [ -n "$sync_with_system" ] && syncpasswd "$user" # set password for given user find_user_or_die "$user" tries=0 while true; do echo -n "Enter new ACF password for $user (will not echo): " hash=$(mkpasswd -m sha | tail -n1) salt=$(echo "$hash" | cut -d$ -f3) echo "" echo -n "Re-enter the ACF password (will not echo): " hash2=$(mkpasswd -S "$salt" -m sha | tail -n1) echo "" [ "$hash" = "$hash2" ] && break echo -n "The entered passwords does not match. " tries=$(( $tries + 1)) if [ $tries -gt 3 ]; then die "ACF password was NOT changed" else echo "Please try again." fi done set_pw_hash "$user" "$hash" && echo "ACF password for $user was changed."