1d14afb2aSJulio Merino#!/bin/sh 2d14afb2aSJulio Merino# 3*179fa75eSJohn Baldwin# Copyright (c) 2010 Hudson River Trading LLC 4d14afb2aSJulio Merino# Written by: John H. Baldwin <jhb@FreeBSD.org> 5d14afb2aSJulio Merino# All rights reserved. 6d14afb2aSJulio Merino# 7d14afb2aSJulio Merino# Redistribution and use in source and binary forms, with or without 8d14afb2aSJulio Merino# modification, are permitted provided that the following conditions 9d14afb2aSJulio Merino# are met: 10d14afb2aSJulio Merino# 1. Redistributions of source code must retain the above copyright 11d14afb2aSJulio Merino# notice, this list of conditions and the following disclaimer. 12d14afb2aSJulio Merino# 2. Redistributions in binary form must reproduce the above copyright 13d14afb2aSJulio Merino# notice, this list of conditions and the following disclaimer in the 14d14afb2aSJulio Merino# documentation and/or other materials provided with the distribution. 15d14afb2aSJulio Merino# 16d14afb2aSJulio Merino# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17d14afb2aSJulio Merino# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18d14afb2aSJulio Merino# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19d14afb2aSJulio Merino# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20d14afb2aSJulio Merino# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21d14afb2aSJulio Merino# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22d14afb2aSJulio Merino# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23d14afb2aSJulio Merino# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24d14afb2aSJulio Merino# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25d14afb2aSJulio Merino# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26d14afb2aSJulio Merino# SUCH DAMAGE. 27d14afb2aSJulio Merino# 28d14afb2aSJulio Merino 29d14afb2aSJulio Merino# Various regression tests to run for the 'resolve' command. 30d14afb2aSJulio Merino 31d14afb2aSJulio MerinoFAILED=no 32d14afb2aSJulio MerinoWORKDIR=work 33d14afb2aSJulio Merino 34d14afb2aSJulio Merinousage() 35d14afb2aSJulio Merino{ 36d14afb2aSJulio Merino echo "Usage: conflicts.sh [-s script] [-w workdir]" 37d14afb2aSJulio Merino exit 1 38d14afb2aSJulio Merino} 39d14afb2aSJulio Merino 40d14afb2aSJulio Merino# Allow the user to specify an alternate work directory or script. 41d14afb2aSJulio MerinoCOMMAND=etcupdate 42d14afb2aSJulio Merinowhile getopts "s:w:" option; do 43d14afb2aSJulio Merino case $option in 44d14afb2aSJulio Merino s) 45d14afb2aSJulio Merino COMMAND="sh $OPTARG" 46d14afb2aSJulio Merino ;; 47d14afb2aSJulio Merino w) 48d14afb2aSJulio Merino WORKDIR=$OPTARG 49d14afb2aSJulio Merino ;; 50d14afb2aSJulio Merino *) 51d14afb2aSJulio Merino echo 52d14afb2aSJulio Merino usage 53d14afb2aSJulio Merino ;; 54d14afb2aSJulio Merino esac 55d14afb2aSJulio Merinodone 56d14afb2aSJulio Merinoshift $((OPTIND - 1)) 57d14afb2aSJulio Merinoif [ $# -ne 0 ]; then 58d14afb2aSJulio Merino usage 59d14afb2aSJulio Merinofi 60d14afb2aSJulio Merino 61d14afb2aSJulio MerinoCONFLICTS=$WORKDIR/conflicts 62d14afb2aSJulio MerinoOLD=$WORKDIR/old 63d14afb2aSJulio MerinoNEW=$WORKDIR/current 64d14afb2aSJulio MerinoTEST=$WORKDIR/test 65d14afb2aSJulio Merino 66d14afb2aSJulio Merino# These tests deal with conflicts to a single file. For each test, we 67d14afb2aSJulio Merino# generate a conflict in /etc/login.conf. Each resolve option is tested 68d14afb2aSJulio Merino# to ensure it DTRT. 69d14afb2aSJulio Merinobuild_login_conflict() 70d14afb2aSJulio Merino{ 71d14afb2aSJulio Merino 72d14afb2aSJulio Merino rm -rf $OLD $NEW $TEST $CONFLICTS 73d14afb2aSJulio Merino mkdir -p $OLD/etc $NEW/etc $TEST/etc 74d14afb2aSJulio Merino 75d14afb2aSJulio Merino # Generate a conflict in /etc/login.conf. 76d14afb2aSJulio Merino cat > $OLD/etc/login.conf <<EOF 77d14afb2aSJulio Merinodefault:\\ 78d14afb2aSJulio Merino :passwd_format=md5: 79d14afb2aSJulio MerinoEOF 80d14afb2aSJulio Merino cat > $NEW/etc/login.conf <<EOF 81d14afb2aSJulio Merinodefault:\\ 82d14afb2aSJulio Merino :passwd_format=md5:\\ 83d14afb2aSJulio Merino :copyright=/etc/COPYRIGHT 84d14afb2aSJulio MerinoEOF 85d14afb2aSJulio Merino cat > $TEST/etc/login.conf <<EOF 86d14afb2aSJulio Merinodefault:\\ 87d14afb2aSJulio Merino :passwd_format=md5:\\ 88d14afb2aSJulio Merino :welcome=/etc/motd: 89d14afb2aSJulio MerinoEOF 90d14afb2aSJulio Merino 91d14afb2aSJulio Merino $COMMAND -r -d $WORKDIR -D $TEST >/dev/null 92d14afb2aSJulio Merino} 93d14afb2aSJulio Merino 94d14afb2aSJulio Merino# This is used to verify special handling for /etc/mail/aliases and 95d14afb2aSJulio Merino# the newaliases warning. 96d14afb2aSJulio Merinobuild_aliases_conflict() 97d14afb2aSJulio Merino{ 98d14afb2aSJulio Merino 99d14afb2aSJulio Merino rm -rf $OLD $NEW $TEST $CONFLICTS 100d14afb2aSJulio Merino mkdir -p $OLD/etc/mail $NEW/etc/mail $TEST/etc/mail 101d14afb2aSJulio Merino 102d14afb2aSJulio Merino # Generate a conflict in /etc/mail/aliases 103d14afb2aSJulio Merino cat > $OLD/etc/mail/aliases <<EOF 104d14afb2aSJulio Merino# root: me@my.domain 105d14afb2aSJulio Merino 106d14afb2aSJulio Merino# Basic system aliases -- these MUST be present 107d14afb2aSJulio MerinoMAILER-DAEMON: postmaster 108d14afb2aSJulio Merinopostmaster: root 109d14afb2aSJulio MerinoEOF 110d14afb2aSJulio Merino cat > $NEW/etc/mail/aliases <<EOF 111d14afb2aSJulio Merino# root: me@my.domain 112d14afb2aSJulio Merino 113d14afb2aSJulio Merino# Basic system aliases -- these MUST be present 114d14afb2aSJulio MerinoMAILER-DAEMON: postmaster 115d14afb2aSJulio Merinopostmaster: root 116d14afb2aSJulio Merino 117d14afb2aSJulio Merino# General redirections for pseudo accounts 118d14afb2aSJulio Merino_dhcp: root 119d14afb2aSJulio Merino_pflogd: root 120d14afb2aSJulio MerinoEOF 121d14afb2aSJulio Merino cat > $TEST/etc/mail/aliases <<EOF 122d14afb2aSJulio Merinoroot: someone@example.com 123d14afb2aSJulio Merino 124d14afb2aSJulio Merino# Basic system aliases -- these MUST be present 125d14afb2aSJulio MerinoMAILER-DAEMON: postmaster 126d14afb2aSJulio Merinopostmaster: foo 127d14afb2aSJulio MerinoEOF 128d14afb2aSJulio Merino 129d14afb2aSJulio Merino $COMMAND -r -d $WORKDIR -D $TEST >/dev/null 130d14afb2aSJulio Merino} 131d14afb2aSJulio Merino 132d14afb2aSJulio Merino# $1 - relative path to file that should be missing from TEST 133d14afb2aSJulio Merinomissing() 134d14afb2aSJulio Merino{ 135d14afb2aSJulio Merino if [ -e $TEST/$1 -o -L $TEST/$1 ]; then 136d14afb2aSJulio Merino echo "File $1 should be missing" 137d14afb2aSJulio Merino FAILED=yes 138d14afb2aSJulio Merino fi 139d14afb2aSJulio Merino} 140d14afb2aSJulio Merino 141d14afb2aSJulio Merino# $1 - relative path to file that should be present in TEST 142d14afb2aSJulio Merinopresent() 143d14afb2aSJulio Merino{ 144d14afb2aSJulio Merino if ! [ -e $TEST/$1 -o -L $TEST/$1 ]; then 145d14afb2aSJulio Merino echo "File $1 should be present" 146d14afb2aSJulio Merino FAILED=yes 147d14afb2aSJulio Merino fi 148d14afb2aSJulio Merino} 149d14afb2aSJulio Merino 150d14afb2aSJulio Merino# $1 - relative path to regular file that should be present in TEST 151d14afb2aSJulio Merino# $2 - optional string that should match file contents 152d14afb2aSJulio Merino# $3 - optional MD5 of the flie contents, overrides $2 if present 153d14afb2aSJulio Merinofile() 154d14afb2aSJulio Merino{ 155d14afb2aSJulio Merino local contents sum 156d14afb2aSJulio Merino 157d14afb2aSJulio Merino if ! [ -f $TEST/$1 ]; then 158d14afb2aSJulio Merino echo "File $1 should be a regular file" 159d14afb2aSJulio Merino FAILED=yes 160d14afb2aSJulio Merino elif [ $# -eq 2 ]; then 161d14afb2aSJulio Merino contents=`cat $TEST/$1` 162d14afb2aSJulio Merino if [ "$contents" != "$2" ]; then 163d14afb2aSJulio Merino echo "File $1 has wrong contents" 164d14afb2aSJulio Merino FAILED=yes 165d14afb2aSJulio Merino fi 166d14afb2aSJulio Merino elif [ $# -eq 3 ]; then 167d14afb2aSJulio Merino sum=`md5 -q $TEST/$1` 168d14afb2aSJulio Merino if [ "$sum" != "$3" ]; then 169d14afb2aSJulio Merino echo "File $1 has wrong contents" 170d14afb2aSJulio Merino FAILED=yes 171d14afb2aSJulio Merino fi 172d14afb2aSJulio Merino fi 173d14afb2aSJulio Merino} 174d14afb2aSJulio Merino 175d14afb2aSJulio Merino# $1 - relative path to a regular file that should have a conflict 176d14afb2aSJulio Merino# $2 - optional MD5 of the conflict file contents 177d14afb2aSJulio Merinoconflict() 178d14afb2aSJulio Merino{ 179d14afb2aSJulio Merino local sum 180d14afb2aSJulio Merino 181d14afb2aSJulio Merino if ! [ -f $CONFLICTS/$1 ]; then 182d14afb2aSJulio Merino echo "File $1 missing conflict" 183d14afb2aSJulio Merino FAILED=yes 184d14afb2aSJulio Merino elif [ $# -gt 1 ]; then 185d14afb2aSJulio Merino sum=`md5 -q $CONFLICTS/$1` 186d14afb2aSJulio Merino if [ "$sum" != "$2" ]; then 187d14afb2aSJulio Merino echo "Conflict $1 has wrong contents" 188d14afb2aSJulio Merino FAILED=yes 189d14afb2aSJulio Merino fi 190d14afb2aSJulio Merino fi 191d14afb2aSJulio Merino} 192d14afb2aSJulio Merino 193d14afb2aSJulio Merino# $1 - relative path to a regular file that should no longer have a conflict 194d14afb2aSJulio Merinoresolved() 195d14afb2aSJulio Merino{ 196d14afb2aSJulio Merino if [ -f $CONFLICTS/$1 ]; then 197d14afb2aSJulio Merino echo "Conflict $1 should be resolved" 198d14afb2aSJulio Merino FAILED=yes 199d14afb2aSJulio Merino fi 200d14afb2aSJulio Merino} 201d14afb2aSJulio Merino 202d14afb2aSJulio Merinoif [ `id -u` -ne 0 ]; then 203d14afb2aSJulio Merino echo "must be root" 204d14afb2aSJulio Merino exit 0 205d14afb2aSJulio Merinofi 206d14afb2aSJulio Merino 207d14afb2aSJulio Merinoif [ -r /etc/etcupdate.conf ]; then 208d14afb2aSJulio Merino echo "WARNING: /etc/etcupdate.conf settings may break some tests." 209d14afb2aSJulio Merinofi 210d14afb2aSJulio Merino 211d14afb2aSJulio Merino# Test each of the following resolve options: 'p', 'mf', 'tf', 'r'. 212d14afb2aSJulio Merino 213d14afb2aSJulio Merinobuild_login_conflict 214d14afb2aSJulio Merino 215d14afb2aSJulio Merino# Verify that 'p' doesn't do anything. 216d14afb2aSJulio Merinoecho "Checking 'p':" 217d14afb2aSJulio Merinoecho 'p' | $COMMAND resolve -d $WORKDIR -D $TEST >/dev/null 218d14afb2aSJulio Merino 219d14afb2aSJulio Merinofile /etc/login.conf "" 95de92ea3f1bb1bf4f612a8b5908cddd 220d14afb2aSJulio Merinomissing /etc/login.conf.db 221d14afb2aSJulio Merinoconflict /etc/login.conf 222d14afb2aSJulio Merino 223d14afb2aSJulio Merino# Verify that 'mf' removes the conflict, but does nothing else. 224d14afb2aSJulio Merinoecho "Checking 'mf':" 225d14afb2aSJulio Merinoecho 'mf' | $COMMAND resolve -d $WORKDIR -D $TEST >/dev/null 226d14afb2aSJulio Merino 227d14afb2aSJulio Merinofile /etc/login.conf "" 95de92ea3f1bb1bf4f612a8b5908cddd 228d14afb2aSJulio Merinomissing /etc/login.conf.db 229d14afb2aSJulio Merinoresolved /etc/login.conf 230d14afb2aSJulio Merino 231d14afb2aSJulio Merinobuild_login_conflict 232d14afb2aSJulio Merino 233d14afb2aSJulio Merino# Verify that 'tf' installs the new version of the file. 234d14afb2aSJulio Merinoecho "Checking 'tf':" 235d14afb2aSJulio Merinoecho 'tf' | $COMMAND resolve -d $WORKDIR -D $TEST >/dev/null 236d14afb2aSJulio Merino 237d14afb2aSJulio Merinofile /etc/login.conf "" 7774a0f9a3a372c7c109c32fd31c4b6b 238d14afb2aSJulio Merinofile /etc/login.conf.db 239d14afb2aSJulio Merinoresolved /etc/login.conf 240d14afb2aSJulio Merino 241d14afb2aSJulio Merinobuild_login_conflict 242d14afb2aSJulio Merino 243d14afb2aSJulio Merino# Verify that 'r' installs the resolved version of the file. To 244d14afb2aSJulio Merino# simulate this, manually edit the merged file so that it doesn't 245d14afb2aSJulio Merino# contain conflict markers. 246d14afb2aSJulio Merinoecho "Checking 'r':" 247d14afb2aSJulio Merinocat > $CONFLICTS/etc/login.conf <<EOF 248d14afb2aSJulio Merinodefault:\\ 249d14afb2aSJulio Merino :passwd_format=md5:\\ 250d14afb2aSJulio Merino :copyright=/etc/COPYRIGHT\\ 251d14afb2aSJulio Merino :welcome=/etc/motd: 252d14afb2aSJulio MerinoEOF 253d14afb2aSJulio Merino 254d14afb2aSJulio Merinoecho 'r' | $COMMAND resolve -d $WORKDIR -D $TEST >/dev/null 255d14afb2aSJulio Merino 256d14afb2aSJulio Merinofile /etc/login.conf "" 966e25984b9b63da8eaac8479dcb0d4d 257d14afb2aSJulio Merinofile /etc/login.conf.db 258d14afb2aSJulio Merinoresolved /etc/login.conf 259d14afb2aSJulio Merino 260d14afb2aSJulio Merinobuild_aliases_conflict 261d14afb2aSJulio Merino 262d14afb2aSJulio Merino# Verify that 'p' and 'mf' do not generate the newaliases warning. 263d14afb2aSJulio Merinoecho "Checking newalias warning for 'p'": 264d14afb2aSJulio Merinoecho 'p' | $COMMAND resolve -d $WORKDIR -D $TEST | grep -q newalias 265d14afb2aSJulio Merinoif [ $? -eq 0 ]; then 266d14afb2aSJulio Merino echo "+ Extra warning" 267d14afb2aSJulio Merino FAILED=yes 268d14afb2aSJulio Merinofi 269d14afb2aSJulio Merinoecho "Checking newalias warning for 'mf'": 270d14afb2aSJulio Merinoecho 'mf' | $COMMAND resolve -d $WORKDIR -D $TEST | grep -q newalias 271d14afb2aSJulio Merinoif [ $? -eq 0 ]; then 272d14afb2aSJulio Merino echo "+ Extra warning" 273d14afb2aSJulio Merino FAILED=yes 274d14afb2aSJulio Merinofi 275d14afb2aSJulio Merino 276d14afb2aSJulio Merino# Verify that 'tf' and 'r' do generate the newaliases warning. 277d14afb2aSJulio Merinobuild_aliases_conflict 278d14afb2aSJulio Merinoecho "Checking newalias warning for 'tf'": 279d14afb2aSJulio Merinoecho 'tf' | $COMMAND resolve -d $WORKDIR -D $TEST | grep -q newalias 280d14afb2aSJulio Merinoif [ $? -ne 0 ]; then 281d14afb2aSJulio Merino echo "- Missing warning" 282d14afb2aSJulio Merino FAILED=yes 283d14afb2aSJulio Merinofi 284d14afb2aSJulio Merino 285d14afb2aSJulio Merinobuild_aliases_conflict 286d14afb2aSJulio Merinocp $TEST/etc/mail/aliases $CONFLICTS/etc/mail/aliases 287d14afb2aSJulio Merinoecho 'r' | $COMMAND resolve -d $WORKDIR -D $TEST | grep -q newalias 288d14afb2aSJulio Merinoif [ $? -ne 0 ]; then 289d14afb2aSJulio Merino echo "- Missing warning" 290d14afb2aSJulio Merino FAILED=yes 291d14afb2aSJulio Merinofi 292d14afb2aSJulio Merino 293d14afb2aSJulio Merino[ "${FAILED}" = no ] 294