#!/usr/bin/bash

set -u

CHECK_TGT_TICKET=$(klist 2>/dev/null)
CHECK_CACHE_TICKET=$(klist 2>/dev/null | grep '01.01.1970 03:00:00')
CURRENT_LOGNAME=$(echo $USER | awk -F '@' '{print $1}')
TIMESTAMP=$(date +%d-%m-%Y_%H:%M:%S)
LOG_FOLDER="$HOME/.cache/change-domain-pwd"
LOG_FILE="$LOG_FOLDER/change-domain-pwd.log"
DOMAIN='hq.corp.mos.ru'
LDAP_BASE='dc=hq,dc=corp,dc=mos,dc=ru'
LDAP_PORT='3268'
LDAP_MAIN_SRV='eskhq-kor02p.hq.corp.mos.ru'
badpwd_count=0

if [[ ! -d "$LOG_FOLDER" ]]; then
	mkdir -p "$LOG_FOLDER"
fi

check_adm_logon() {
if [[ $CURRENT_LOGNAME =~ ^.*-adm$ ]]; then
	USER_LOGNAME=$(echo $CURRENT_LOGNAME | cut -d '-' -f 1)
	ADM_LOGNAME=$CURRENT_LOGNAME
else
	USER_LOGNAME=$CURRENT_LOGNAME
	ADM_LOGNAME="$CURRENT_LOGNAME-adm"
fi
}

check_domain_entry() {
CHECK_DOM_PING=$(ping -c 2 $DOMAIN 2>/dev/null)
if [[ ! $CHECK_TGT_TICKET ]]; then
	kdialog --error 'Вход в систему не является доменным! Пароль не может быть изменен!\nНеобходимо перезайти в систему под доменной учетной записью!' --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Вход в систему не является доменным! Пароль не может быть изменен." >> "$LOG_FILE"
	exit 1;
elif [[ $CHECK_CACHE_TICKET ]]; then
	kdialog --error 'Автономный вход в систему! Пароль не может быть изменен!\nПодключитесь к корпоративной сети или VPN NGate\nи выполните повторный вход в систему!' --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Автономный вход в систему! Пароль не может быть изменен." >> "$LOG_FILE"
	exit 1;
elif [[ ! $CHECK_DOM_PING ]]; then
	kdialog --error "Домен $DOMAIN недоступен! Пароль не может быть изменен!\nПроверьте подключение к корпоративной сети или VPN NGate!" --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Домен $DOMAIN недоступен! Пароль не может быть изменен." >> "$LOG_FILE"
	exit 1;
fi
LDAP_TEST=$(ldapsearch -LLL -H ldap://$LDAP_MAIN_SRV:$LDAP_PORT -b $LDAP_BASE "(sAMAccountName=$USER_LOGNAME)")
if [[ ! $LDAP_TEST ]]; then
	kdialog --error "Проблема с подключением к домену по LDAP! Пароль не может быть изменен!" --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Проблема с подключением к домену по LDAP! Пароль не может быть изменен." >> "$LOG_FILE"
	exit 1;
fi
}

change_pwd_MAIN() {
get_pwdset_time=$(ldapsearch -LLL -H ldap://$LDAP_MAIN_SRV:$LDAP_PORT -b $LDAP_BASE "(|(sAMAccountName=$USER_LOGNAME)(userPrincipalName=$USER_LOGNAME@$DOMAIN))" msDS-UserPasswordExpiryTimeComputed | grep -i msDS-UserPasswordExpiryTimeComputed | awk '{print $2}')
if [[ -n $get_pwdset_time ]]; then
	set_to_UNIXepoche=$((($get_pwdset_time / 10000000) - 11644473600))
	calculate_days=$(date -d @$set_to_UNIXepoche +"%F")
	days_to_lock=$((($(date -d "$calculate_days" +%s) - $(date -d "$(date +%F)" +%s))/86400))
	kdialog --passivepopup "Осталось дней до смены пароля: $days_to_lock" 5 --title 'Смена пароля' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $USER_LOGNAME: осталось дней до смены пароля: $days_to_lock" >> "$LOG_FILE"
else
	kdialog --msgbox 'Пароль еще не был установлен!' --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $USER_LOGNAME: пароль еще не был установлен!" >> "$LOG_FILE"
	exit 0;
fi

if [[ $badpwd_count -eq 5 ]]; then
	kdialog --error '5 неверных попыток ввода пароля!\nПопробуйте повторить позже.' --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $USER_LOGNAME: 5 неверных попыток ввода пароля!" >> "$LOG_FILE"
	exit 1;
fi

OLD_PASSWD=$(kdialog --password 'Введите ТЕКУЩИЙ пароль:' --title 'Смена пароля' --icon 'change-domain-pwd-gui')
if [[ $? -ne 0 ]]; then
	kdialog --passivepopup 'Отмена смены пароля!' 5 --title 'Смена пароля' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $USER_LOGNAME: отмена смены пароля!" >> "$LOG_FILE"
	exit 0;
elif [[ -z $OLD_PASSWD ]]; then
	kdialog --error 'Пароль не может быть пустым!' --title 'Смена пароля' --ok-label 'Повторный ввод' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $USER_LOGNAME: пароль не может быть пустым!" >> "$LOG_FILE"
	change_pwd_MAIN;
fi

NEW_PASSWD=$(kdialog --newpassword 'Введите НОВЫЙ пароль.\n\nТребования к паролю:\n▪️ 8 и более символов\n▪️ Буквы в ВЕРХНЕМ регистре\n▪️ Буквы в нижнем регистре\n▪️ цифры\n▪️ спецсимволы\n▪️ отсутствие кириллицы' --title 'Смена пароля' --icon 'change-domain-pwd-gui')
if [[ $? -ne 0 ]]; then
	kdialog --passivepopup 'Отмена смены пароля!' 5 --title 'Смена пароля' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $USER_LOGNAME: отмена смены пароля!" >> "$LOG_FILE"
	exit 0;
elif [[ -z $NEW_PASSWD ]]; then
	kdialog --error 'Пароль не может быть пустым!' --title 'Смена пароля' --ok-label 'Повторный ввод' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $USER_LOGNAME: пароль не может быть пустым!" >> "$LOG_FILE"
	change_pwd_MAIN;
elif ! echo "$NEW_PASSWD" | grep -qP '^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[-#!$@%^&*_+~=:;?\/]).{8,}$'; then
	kdialog --error 'Пароль не соответствует требованиям безопасности!' --title 'Смена пароля' --ok-label 'Повторный ввод' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $USER_LOGNAME: пароль не соответствует требованиям безопасности!" >> "$LOG_FILE"
	change_pwd_MAIN;
else echo -e "$OLD_PASSWD\n$NEW_PASSWD\n$NEW_PASSWD" | kpasswd "$USER_LOGNAME"
	if [[ $? -ne 0 ]]; then
		kdialog --error 'Ошибка смены пароля, попробуйте еще раз!\n\nВероятные причины:\n1. Текущий пароль введен не верно.\n2. Новый пароль не удовлетворяет парольным политикам\n(документ: https://cloud.dit.mos.ru/s/370B3wdHyaprcH6).\n3. Пароль уже менялся ближайшие 24 ч.\n\nВ остальных случаях, просьба обратиться в техподдержку ДИТ, контакты:\nТел.:  75555 (внутренний), +7 (495) 989-8025 (городской)\nПортал ITSM:  https://moscow.itsm.mos.ru/self-service' --title 'Смена пароля' --ok-label 'Повторный ввод' --icon 'change-domain-pwd-gui';
		echo "$TIMESTAMP - Пользователь $USER_LOGNAME: ошибка смены пароля!" >> "$LOG_FILE"
		unset OLD_PASSWD;
		unset NEW_PASSWD; (( badpwd_count++ )) || true;
		change_pwd_MAIN;
	else
		kdialog --msgbox 'Пароль был изменен!\nНеобходимо перезайти в систему с новым паролем!' --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
		echo "$TIMESTAMP - Пользователь $USER_LOGNAME: пароль был изменен!" >> "$LOG_FILE"
		unset OLD_PASSWD;
		unset NEW_PASSWD;
		exit 0;
	fi
fi
}

change_pwd_ADM() {
get_pwdset_time=$(ldapsearch -LLL -H ldap://$LDAP_MAIN_SRV:$LDAP_PORT -b $LDAP_BASE "(|(sAMAccountName=$ADM_LOGNAME)(userPrincipalName=$ADM_LOGNAME@$DOMAIN))" msDS-UserPasswordExpiryTimeComputed | grep -i msDS-UserPasswordExpiryTimeComputed | awk '{print $2}')
if [[ -n $get_pwdset_time ]]; then
	set_to_UNIXepoche=$((($get_pwdset_time / 10000000) - 11644473600))
	calculate_days=$(date -d @$set_to_UNIXepoche +"%F")
	days_to_lock=$((($(date -d "$calculate_days" +%s) - $(date -d "$(date +%F)" +%s))/86400))
	kdialog --passivepopup "Осталось дней до смены пароля: $days_to_lock" 5 --title 'Смена пароля' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $ADM_LOGNAME: осталось дней до смены пароля: $days_to_lock" >> "$LOG_FILE"
else
	kdialog --msgbox 'Пароль еще не был установлен!' --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
	exit 0;
fi

if [[ $badpwd_count -eq 3 ]]; then
	kdialog --error '3 неверных попытки ввода пароля!\nПопробуйте повторить позже.' --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $ADM_LOGNAME: 3 неверных попытки ввода пароля!" >> "$LOG_FILE"
	exit 1;
fi

OLD_PASSWD=$(kdialog --password 'Введите ТЕКУЩИЙ пароль' --title 'Смена пароля' --icon 'change-domain-pwd-gui')
if [[ $? -ne 0 ]]; then
	kdialog --passivepopup 'Отмена смены пароля!' 5 --title 'Смена пароля' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $ADM_LOGNAME: отмена смены пароля!" >> "$LOG_FILE"
	exit 0;
elif [[ -z $OLD_PASSWD ]]; then
	kdialog --error 'Пароль не может быть пустым!' --title 'Смена пароля' --ok-label 'Повторный ввод' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $ADM_LOGNAME: пароль не может быть пустым!" >> "$LOG_FILE"
	change_pwd_ADM;
fi

NEW_PASSWD=$(kdialog --newpassword 'Введите НОВЫЙ пароль.\n\nТребования к паролю:\n▪️ 12 и более символов\n▪️ Буквы в ВЕРХНЕМ регистре\n▪️ Буквы в нижнем регистре\n▪️ цифры\n▪️ спецсимволы\n▪️ отсутствие кириллицы' --title 'Смена пароля' --icon 'change-domain-pwd-gui')
if [[ $? -ne 0 ]]; then
	kdialog --passivepopup 'Отмена смены пароля!' 5 --title 'Смена пароля' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $ADM_LOGNAME: отмена смены пароля!" >> "$LOG_FILE"
	exit 0;
elif [[ -z $NEW_PASSWD ]]; then
	kdialog --error 'Пароль не может быть пустым!' --title 'Смена пароля' --ok-label 'Повторный ввод' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $ADM_LOGNAME: пароль не может быть пустым!" >> "$LOG_FILE"
	change_pwd_ADM;
elif ! echo "$NEW_PASSWD" | grep -qP '^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[-#!$@%^&*_+~=:;?\/]).{12,}$'; then
	kdialog --error 'Пароль не соответствует требованиям безопасности!' --title 'Смена пароля' --ok-label 'Повторный ввод' --icon 'change-domain-pwd-gui';
	echo "$TIMESTAMP - Пользователь $ADM_LOGNAME: пароль не соответствует требованиям безопасности!" >> "$LOG_FILE"
	change_pwd_ADM;
else echo -e "$OLD_PASSWD\n$NEW_PASSWD\n$NEW_PASSWD" | kpasswd "$ADM_LOGNAME"
	if [[ $? -ne 0 ]]; then
		kdialog --error 'Ошибка смены пароля, попробуйте еще раз!\n\nВероятные причины:\n1. Текущий пароль введен не верно.\n2. Новый пароль не удовлетворяет парольным политикам\n(документ: https://cloud.dit.mos.ru/s/370B3wdHyaprcH6).\n3. Пароль уже менялся ближайшие 48 ч.\n\nВ остальных случаях, просьба обратиться в техподдержку ДИТ, контакты:\nТел.:  75555 (внутренний), +7 (495) 989-8025 (городской)\nПортал ITSM:  https://moscow.itsm.mos.ru/self-service' --title 'Смена пароля' --ok-label 'Повторный ввод' --icon 'change-domain-pwd-gui';
		echo "$TIMESTAMP - Пользователь $ADM_LOGNAME: ошибка смены пароля!" >> "$LOG_FILE"
		unset OLD_PASSWD;
		unset NEW_PASSWD; (( badpwd_count++ )) || true;
		change_pwd_ADM;
	else
		kdialog --msgbox 'Пароль был изменен!\nНеобходимо перезайти в систему с новым паролем!' --title 'Смена пароля' --ok-label 'Выход' --icon 'change-domain-pwd-gui';
		echo "$TIMESTAMP - Пользователь $ADM_LOGNAME: пароль был изменен!" >> "$LOG_FILE"
		unset OLD_PASSWD;
		unset NEW_PASSWD;
		exit 0;
	fi
fi
}

check_adm_account() {
get_adm_account=$(ldapsearch -LLL -H ldap://$LDAP_MAIN_SRV:$LDAP_PORT -b $LDAP_BASE "(|(sAMAccountName=$ADM_LOGNAME)(userPrincipalName=$ADM_LOGNAME@$DOMAIN))" sAMAccountName | grep -i sAMAccountName | awk '{print $2}')
if [[ -n $get_adm_account ]]; then
		select_account=$(kdialog --radiolist "Найдено несколько учетных записей,\nвыберите, для какой необходимо сменить пароль:" 1 "$USER_LOGNAME" on 2 "$ADM_LOGNAME" off --title 'Смена пароля' --icon 'change-domain-pwd-gui');
		if [[ $select_account -eq 1 ]]; then
			change_pwd_MAIN;
		elif [[ $select_account -eq 2 ]]; then
			change_pwd_ADM;
		else
			kdialog --passivepopup 'Отмена смены пароля!' 5 --title 'Смена пароля' --icon 'change-domain-pwd-gui';
			exit 0;
		fi
else
	change_pwd_MAIN
fi
}

kdialog --yesno 'Запуск программы смены пароля доменной учетной записи' --title 'Смена пароля' --yes-label 'Продолжить' --no-label 'Отмена' --icon 'change-domain-pwd-gui'
if [[ $? -ne 0 ]]; then
	kdialog --passivepopup 'Отмена смены пароля!' 5 --title 'Смена пароля' --icon 'change-domain-pwd-gui';
	exit 0;
else
	check_adm_logon
	check_domain_entry
	check_adm_account
fi
