#!/bin/sh #---------------------------------------------------------------------------------- # /var/install/bin/mail-dovecot-onverttatus-tool - show dovecot status information # # Copyright (c) 2020-2025 The Eisfair Team, team(at)eisfair(dot)org # # Creation: 2020-06-01 jed # Last Update: $Id$ # # Information: It has been decided to not convert any email archive folders # outside of the default home directory of a user yet. These # folders need to be converted manually, if desired. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. #---------------------------------------------------------------------------------- # read eislib . /var/install/include/eislib . /var/install/include/jedlib # activate debug output #debug=true if ${debug:-false} then exec 2> /tmp/$(basename ${0})-trace$$.log set -x ask_debug=true export ask_debug fi #---------------------------------------------------------------------------------------- # check IPv4 address # # input : ip address # return: 0 - ip address valid # 1 - ip address invalid #---------------------------------------------------------------------------------------- check_ipv4_address() { local _c4a_address=$1 local _c4a_ret=1 local _c4a_invalid=0 if expr "${_c4a_address}" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null then _c4a_invalid=0 _c4a_oldifs=${IFS} IFS='.' set ${_c4a_address} IFS=${_c4a_oldifs} for QUAD in 1 2 3 4 do if eval [ \$${QUAD} -gt 255 ] then # fail _c4a_invalid=1 break fi done if [ ${_c4a_invalid} -eq 0 ] then # success _c4a_ret=0 fi fi return ${_c4a_ret} } #---------------------------------------------------------------------------------------- # print main menu # # $sel_values contains space separated list of menu options #---------------------------------------------------------------------------------------- print_main_menu() { local _pmm_output clrhome mecho --info "Show Dovecot specific information" echo _pmm_output=`${varlib_path}/mail status dovecot | sed '2,4s/^.*$/ &/g'` echo "Status: ${_pmm_output}" echo echo "1 - Show logged in users" echo "2 - Test user login" echo "3 - Resynchronize a mailbox of a user" echo "4 - Terminate all sessions of a user" if [ -z "${sel_values}" ] then sel_values="1 2 3 4" else sel_values="${sel_values} 1 2 3 4" fi echo } #---------------------------------------------------------------------------------------- # check if valid menu selection # # input: $1 - value to check # $2 - string of available menu values # # return: 0 - valid value, entry found # 1 - invalid value, entry not found #---------------------------------------------------------------------------------------- is_valid_menu_selection() { local _ivms_sval=$1 # value to check local _ivms_ret if [ -z "${_ivms_sval}" ] then # empty string - invalid value _ivms_ret=1 else shift _ivms_sel_values=" $* " # string of available menu values echo "${_ivms_sel_values}" | grep -q " ${_ivms_sval} " _ivms_ret=$? fi return ${_ivms_ret} } #---------------------------------------------------------------------------------------- # show logged in users #---------------------------------------------------------------------------------------- show_logged_in_users() { clrhome mecho --info "List of logged in users" echo techo --begin 20 7 10 23 techo --row --info "user name" --info "count" --info "program" --info "ip address" ${doveadm_bin} who | awk 'NR==2 || !/^username/' | tr ')(' '|' | tr -s ' ' | \ while read LINE do # echo "LINE: $LINE" user=`echo "${LINE}" | cut -d' ' -f1` conn=`echo "${LINE}" | cut -d' ' -f2` prog=`echo "${LINE}" | cut -d' ' -f3` ip=` echo "${LINE}" | cut -d'|' -f4` techo --row "${user}" "${conn}" "${prog}" "${ip}" done techo --end echo } #---------------------------------------------------------------------------------------- # test user login #---------------------------------------------------------------------------------------- test_user_login() { local _tul_user local _tul_service='imap' local _tul_address='' local _tul_rc clrhome mecho --info "Test login of a user" echo ${ask_bin} "Name of user whos login should be tested, (q)uit" 'q' '+' > ${ask_tmpfile} rc=$? read _tul_user < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${_tul_user} in q|Q ) echo break ;; * ) if [ -n "${_tul_user}" ] then if getent passwd ${_tul_user} >/dev/null 2>&1 then ${ask_bin} "Do you want to test the (i)map or (p)op3 access" 'q' '+' > ${ask_tmpfile} rc=$? read _tul_service < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${_tul_service} in q|Q ) _tul_service='' break ;; i|I|imap ) _tul_service='imap' ;; p|P|pop3 ) _tul_service='pop3' ;; * ) _tul_service='' ;; esac if [ -n "${_tul_service}" ] then ${ask_bin} "Enter an ip address to simulate a remote access or press ENTER" '' '*' > ${ask_tmpfile} rc=$? read _tul_address < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${_tul_address} in q|Q ) echo break ;; * ) if [ -n "${_tul_address}" ] then if check_ipv4_address "${_tul_address}" then echo "testing ${_tul_service}-login of user '${_tul_user}' from address ${_tul_address} ..." _tul_address="-x rip=${_tul_address}" else mecho --error "Invalid ip address '${_tul_address} given!" _tul_address='' return 1 fi else echo "testing ${_tul_service}-login of user '${_tul_user}' ..." fi echo # testing access ${doveadm_bin} -v auth test -x service=${_tul_service} ${_tul_address} ${_tul_user} _tul_rc=$? if [ ${_tul_rc} -eq 0 ] then echo "Done." else mecho --warn "The program reported an error (${_tul_rc}). Please check the log file!" fi ;; esac fi else mecho -error "The user '${_tul_user}' doesn't exist!" fi else mecho -error "Invalid input!" fi echo ;; esac } #---------------------------------------------------------------------------------------- # force a resynchronization of a mailbox #---------------------------------------------------------------------------------------- force_resync_of_mailbox() { local _from_user local _from_yesno local _from_rc clrhome mecho --info "Force a resync of a mailbox" echo ${ask_bin} "Name of user whos mailbox should be resynced, (a)ll, (q)uit" 'q' '+' > ${ask_tmpfile} rc=$? read _from_user < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${_from_user} in q|Q ) echo break ;; * ) if [ -n "${_from_user}" ] then _from_yesno='no' if [ "${_from_user}" = 'a' -o "${_from_user}" = 'A' -o "${_from_user}" = 'all' ] then _from_user='all' ${ask_bin} "Please confirm that the mailbox of 'all' users should be resynced" 'no' > ${ask_tmpfile} rc=$? read _from_yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi else if getent passwd ${_from_user} >/dev/null 2>&1 then ${ask_bin} "Please confirm that the mailbox of '${_from_user}' should be resynced" 'no' > ${ask_tmpfile} rc=$? read _from_yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi else mecho -error "The user '${_from_user}' doesn't exist!" fi fi case ${_from_yesno} in y|Y|yes ) echo # '*' - resync all mail folders if [ "${_from_user}" = 'all' ] then # resynchronize the mailboxes of 'all' users echo "resynchronizing mailboxex of all users ..." ${doveadm_bin} -v force-resync -A '*' _from_rc=$? else echo "resynchronizing mailbox of user '${_from_user}' ..." ${doveadm_bin} -v force-resync -u ${_from_user} '*' _from_rc=$? fi if [ ${_from_rc} -eq 0 ] then echo "Done." else mecho --warn "The program reported an error (${_from_rc}). Please check the log file!" fi ;; * ) ;; esac else mecho -error "Invalid input!" fi echo ;; esac } #---------------------------------------------------------------------------------------- # disconnect a user by name #---------------------------------------------------------------------------------------- terminate_user_sessions() { local _tus_user local _tus_yesno local _tus_rc clrhome mecho --info "Terminate all sessions of a user" echo ${ask_bin} "Name of user whos sessions should be terminated, (q)uit" 'q' '+' > ${ask_tmpfile} rc=$? read _tus_user < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${_tus_user} in q|Q ) echo break ;; * ) if [ -n "${_tus_user}" ] then if getent passwd ${_tus_user} >/dev/null 2>&1 then ${ask_bin} "Please confirm that all sesssions of user '${_tus_user}' should be terminated" 'no' > ${ask_tmpfile} rc=$? read _tus_yesno < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${_tus_yesno} in y|Y|yes ) echo echo "terminating all sessions of user ''${_tus_user}' ..." ${doveadm_bin} -v kick ${_tus_user} _tus_rc=$? if [ ${_tus_rc} -eq 0 ] then echo "Done." else mecho --warn "The program reported an error (${_tus_rc}). Please check the log file!" fi ;; * ) ;; esac else mecho -error "The user '${_tus_user}' doesn't exist!" fi else mecho -error "Invalid input!" fi echo ;; esac } #======================================================================================== # main #======================================================================================== pgmname=`basename $0` ask_bin=/var/install/bin/ask ask_tmpfile=/tmp/${pgmname}-ask.$$ doveadm_bin=/usr/bin/doveadm varlib_path=/var/lib/mail # extract only required parameters to keep environment slim tmp_file=/var/tmp/${pgmname}.$$ if is_root "`whoami`" then # interactive mode endflag=0 until [ ${endflag} -eq 1 ] do sel_values='' print_main_menu ${ask_bin} "Please select (`echo "${sel_values}" | sed 's/ /,/g'`), (q)uit?" 'q' '+' > ${ask_tmpfile} rc=$? read choice < ${ask_tmpfile} rm -f ${ask_tmpfile} if [ ${rc} = 255 ] then exit 1 fi case ${choice} in [qQ] ) # quit endflag=1 ;; [1-7] ) # check input and run command if is_valid_menu_selection ${choice} ${sel_values} then echo # other possible commands: # - doveadm pw ... # - doveadm deduplicate ... # - doveadm penalty ... # - doveadm quota get -u user : requires quota to be configured # - doveadm quota recalc -u user : requires quota to be configured case ${choice} in 1 ) # show logged in users show_logged_in_users ;; 2 ) # test login of a user test_user_login ;; 3 ) # force the resynchronization of a users mailbox force_resync_of_mailbox ;; 4 ) # terminate all sessions of a user terminate_user_sessions ;; * ) # error mecho --error "Error: input not in range, try again!" ;; esac else # error mecho --error "Error: input not in range, try again!" fi anykey ;; * ) # error mecho --error "Error: input not in range, try again!" anykey ;; esac done else mecho --error "You need root equivalent rights to use this script!" fi #========================================================================================= # end #========================================================================================= exit 0