Index: usr.sbin/etcupdate/etcupdate.sh =================================================================== --- usr.sbin/etcupdate/etcupdate.sh +++ usr.sbin/etcupdate/etcupdate.sh @@ -871,6 +871,76 @@ egrep -q '^(<{7}|\|{7}|={7}|>{7}) ' $CONFLICTS/$1 } +# We create a "database" of passwords for users. We don't save actual +# hashes to any variable to not leek them through process list. +# +# $1 - pathname to the file from which database should be created +create_user_database() +{ + awk ' + BEGIN { + FS = ":" + } + { + if ($1 ~ "^#" || NF < 10) + next + printf("%s:", $1) + if ($2 ~ "^[a-zA-Z0-9*/$.]+$") + printf("yes\n") + else + printf("no\n") + } + ' $1 +} + +# Check if user mistakenly didn't remove the password +# +# $1 - filename of current analyzed file +# $2 - directory from which take a new version of file +check_passwd() +{ + local filename newdir junk + local newdb olddb + local username newpass + local olduser oldcount oldpass + + filename="$1" + newdir="$2" + + if [ "${filename}" != "/etc/master.passwd" ]; then + return 0 + fi + + newdb=`create_user_database "${newdir}${filename}"` + olddb=`create_user_database "${DESTDIR}${filename}"` + + for user in $newdb; do + username=`echo "${user}" | cut -d":" -f1` + newpass=`echo "${user}" | cut -d":" -f2` + + olduser=`echo "${olddb}" | grep "^${username}:"` + oldcount=`echo "${olduser}" | wc -l` + if [ "${oldcount}" -eq 0 ]; then + # User doesn't exists in old db. Skipping. + continue + elif [ "${oldcount}" -ne 1 ]; then + panic "Unable to check file ${filename}." \ + "Multiple records for user ${username}" + fi + + oldpass=`echo "${olduser}" | cut -d":" -f2` + if [ "${oldpass}" != "${newpass}" -a "${newpass}" = "no" ]; then + echo "After merge, '${username}' has no password," \ + "do you want to continue? (y/n) " + read junk + if [ "${junk}" != "y" ]; then + return 1 + fi + fi + done + return 0 +} + # Attempt to resolve a conflict. The user is prompted to choose an # action for each conflict. If the user edits the file, they are # prompted again for an action. The process is very similar to @@ -935,6 +1005,10 @@ fi fi + if ! check_passwd $1 ${CONFLICTS}; then + continue + fi + if ! install_resolved $1; then panic "Unable to install merged" \ "version of $1" @@ -946,6 +1020,11 @@ # For theirs-full, install the new # version of the file over top of the # existing file. + + if ! check_passwd $1 ${NEWTREE}; then + continue + fi + if ! install_new $1; then panic "Unable to install new" \ "version of $1"