#!/bin/bash

. /usr/share/preupgrade/common.sh

#END GENERATED SECTION




# Copy your config file from RHEL6 (in case of scenario RHEL6_7)
# to Temporary Directory
CONFIG_DIR="/etc/dovecot/"

# Exit if the configuration is invalid
validate ( ) {
read conf
err_msg=$(echo "$conf" | grep -o "\/.*[[:digit:]]")
if [ "$err_msg" != "" ];then
    log_high_risk "Error in $err_msg."
return 1
fi
}

doveconf 2>&1- | validate

if [ $? -eq 1 ];then
    log_high_risk "The Dovecot configuration is invalid. Fix it or remove the dovecot package before proceeding with the upgrade."
    exit $RESULT_FAIL
fi

#Get the values of first_valid_uid
uid_val=$(doveconf -a | awk -F' = ' '/^first_valid_uid/ { print $2}')
explicit_uid_val=$(doveconf -aN | awk -F' = ' '/^first_valid_uid/ { print $2}')

#Get the list of all possible places, where the first_valid_uid may be defined.
#List is compiled in line by line manner where the main configuration file
#continues to be read after each crawl into the included configuration directory.
declare -a included_files
while read line; do
    included_files=("${included_files[@]}" $(echo "$line" | awk '/^\!include(_try)?\>/ {print $2}' ))
    if echo "$line" | grep -q "^first_valid_uid" ;then
        included_files=( "${included_files[@]}" dovecot.conf )
    fi
done < /etc/dovecot/dovecot.conf
loaded_conf="$PWD/loaded.conf"

cat /dev/null > "$loaded_conf"

cp --parents -ar $CONFIG_DIR $VALUE_TMP_PREUPGRADE/dirtyconf

#workaround to openscap buggy missing PATH
export PATH=$PATH:/usr/bin

TMPF1=$(mktemp)
TMPF2=$(mktemp)

# expected result after we filter-out safe options
cat >$TMPF2 <<EOF
passdb {
  driver = pam
userdb {
  driver = passwd
EOF
which doveconf >/dev/null 2>&1
RET=$?
set -o pipefail
[ $RET -eq 0 ] && doveconf -n | sed -e '/^#/d' -e '/ssl =/d' -e '/ssl_cert =/d' -e '/ssl_key =/d' -e '/auth_username_format =/d' -e '/mbox_write_locks =/d' -e '/mail_privileged_group =/d' -e '/mail_access_groups =/d' -e '/mail_location =/d' -e '/managesieve_notify_capability =/d' -e '/managesieve_sieve_capability =/d' -e '/ *sieve =/d' -e '/ *sieve_dir =/d' -e '/plugin {/d' -e '/^ *}/d' >$TMPF1
RET=$?

# auth_username_format default value has changed, so if it's not set explicitely, set it to original default value
if ! doveconf -n | grep -q auth_username_format
then
  AUTHCONF=$VALUE_TMP_PREUPGRADE/dirtyconf/etc/dovecot/conf.d/10-auth.conf
  if grep -q '#auth_username_format' $AUTHCONF
  then
    sed -i 's|^#auth_username_format *=.*$|auth_username_format =|' $AUTHCONF
  else
    echo 'auth_username_format =' >>$AUTHCONF
  fi
fi

if [ $RET -eq 0 ]
then
  cmp -s $TMPF1 $TMPF2
  RET=$?
  if [ "$RET" -eq 0 ]
  then
    rm -f $TMPF1 $TMPF2
  fi
else
  log_high_risk "The Dovecot configuration is invalid. Fix it or remove the dovecot package before proceeding with the upgrade."
  rm -f $TMPF1 $TMPF2
  exit $RESULT_FAIL
fi

log_info "The configuration files from $CONFIG_DIR will be fixed by the postupgrade script."
log_slight_risk "In some corner cases your configuration might not be migrated automatically."
echo "\
The doveconf tool should be able to migrate your configuration, but there is a slight risk
that you use some no longer supported options or plug-ins. In that case, update your configuration
file manually on the new system.
" > solution.txt

PREF=$POSTUPGRADE_DIR/dovecot
mkdir -p $PREF
sed '2,/^#!\//d' $0 >$PREF/dovecot_postupgrade.sh
chmod +x $PREF/dovecot_postupgrade.sh

rm -f $TMPF1 $TMPF2
cd /etc/dovecot/

#Get the the config, that actually provides the first_valid_uid directive
#As the configuration files are sourced in the manner explained above
#the folllowing code block ensures, the tracking of the actual
#configuration file providing the first_valid_uid directive.
if [[ "${included_files[@]}" != "" ]];then
    printf '%s\n' ${included_files[@]} | while IFS= read -r included_file 
    do
        if [ -e "$included_file" ];then
            if grep -q "^first_valid_uid" "$included_file" ;then
                echo "$included_file" > "$loaded_conf"
            fi

        fi
    done
fi
last_loaded=$(cat "$loaded_conf")
last_loaded="$VALUE_TMP_PREUPGRADE/dirtyconf${CONFIG_DIR}${last_loaded}"
export uid_val 
export last_loaded

if [[ "$explicit_uid_val" == "" ]];then
    #Change the explcitly stated default value on the target system to the default value on the source system
    perl -pi -e '$_ .= qq(first_valid_uid = $ENV{uid_val}\n) if eof ' "$VALUE_TMP_PREUPGRADE/dirtyconf/$CONFIG_DIR/dovecot.conf"
    log_medium_risk "You are using the first_valid_uid in the reserved range."
    log_info "The value of the first_valid_uid directive has been explicitly set to $uid_val in $VALUE_TMP_PREUPGRADE/dirtyconf/$CONFIG_DIR/dovecot.conf."
    echo "You are using the default first_valid_uid of $uid_val for Dovecot users, which is in the UID range reserved for the system users in Red Hat Enterprise Linux 7. The value of the first_valid_uid directive has been explicitly set to $uid_val in $VALUE_TMP_PREUPGRADE/dirtyconf/$CONFIG_DIR/dovecot.conf in order not to break the dovecot functionality on the target system. This is not a secure configuration. Migrate your regular users to UIDs 1000 and above, and increase the value of the first_valid_uid directive to 1000 or above in the target system." >> $SOLUTION_FILE
    exit_fail
elif [ "$explicit_uid_val" -lt 1000 ];then
    log_medium_risk "You are using the first_valid_uid in the reserved range."
    echo "You have configured the first_valid_uid of $explicit_uid_val for Dovecot users in $last_loaded, which is in the UID range reserved for the system users in Red Hat Enterprise Linux 7. This is not a secure configuration. Migrate your regular users to UIDs 1000 and above, and increase the value of the first_valid_uid directive to 1000 or above in the target system." >> $SOLUTION_FILE
    exit_fail

else
    log_info "The first_valid_uid directive in your Dovecot configuration is compatible with Red Hat Enterprise Linux 7." 
    exit_pass
fi

############################# postupgrade script ##########################################
#!/bin/bash

. /usr/share/preupgrade/common.sh

#END GENERATED SECTION

CONFIG_DIR="/etc/dovecot"
# This is simple postupgrade script.

# Source file was taken from source system and stored in preupgrade-assistant temporary directory

# In case that you have some tool for conversion from old configuration (on source system)
# to new configuration (on target system)
# Just call

# Make some modifications in $VALUE_TMP_PREUPGRADE/$CONFIG_DIR before conversion if needed

function checkconfig
{
  ret=1
  systemctl restart dovecot.service >/dev/null 2>&1
  systemctl is-active dovecot.service >/dev/null 2>&1 && ret=0
  systemctl stop dovecot.service >/dev/null 2>&1
  return $ret
}

mv $CONFIG_DIR $CONFIG_DIR.preup
cp -ar /root/preupgrade/dirtyconf/$CONFIG_DIR $CONFIG_DIR
restorecon -R $CONFIG_DIR


if checkconfig
then #original configuration works
  exit 0
fi

CONVLOG=$(mktemp --tmpdir preupgrade-dovecot-XXXXXX.log)
doveconf -n -c $CONFIG_DIR/dovecot.conf >/etc/dovecot.conf.preupnew 2>$CONVLOG
ret=$?
rm -rf $CONFIG_DIR
mkdir $CONFIG_DIR
mv /etc/dovecot.conf.preupnew $CONFIG_DIR/dovecot.conf
restorecon -R $CONFIG_DIR

if [ $ret -eq 0 ] && checkconfig
then #regenerated configuration works
  rm -f $CONVLOG
  exit 0
fi


rm -rf $CONFIG_DIR
cp -ar /root/preupgrade/dirtyconf/$CONFIG_DIR $CONFIG_DIR
#conversion failed, log should contain necessary information
cat $CONVLOG >&2
rm -f $CONVLOG
exit 1
