diff --git a/drop_database_user.sh b/drop_database_user.sh new file mode 100755 index 0000000..04aaa9a --- /dev/null +++ b/drop_database_user.sh @@ -0,0 +1,607 @@ +#!/usr/bin/env bash + +working_dir="$(dirname $(realpath $0))" +log_dir="${working_dir}/log" + +conf_file="${working_dir}/conf/mysql_credetials.conf" + +tmp_log_file="$(mktemp)" + +# ------------- +# - Variable settings +# ------------- + +MYSQL_CREDENTIALS_GIVEN=false + +# DATABASE_NAME="" +DATABASE_USER="" +# DATABASE_NAME_NEEDED=true +DATABASE_USER_NEEDED=true +# DO_NOT_DELTE_USER=false +QUIET_MODE=false +NON_INTERACTIVE_MODE=false + + +# ------------- +# --- Some functions +# ------------- + +usage() { + echo + [ -n "$1" ] && echo -e "Error: $1\n" + + cat< + The name of the database user who will be granted full access to the given + database. If not set, script looks for a file 'databases/'. If + found, script reads database settings (user/password) from that file. If not + running in quiet mode, you will be asked to confirm or set the db-user. + +EOF +clean_up 1 +} + + +clean_up() { + + # Perform program exit housekeeping + rm -f $tmp_log_file + exit $1 +} + +fatal(){ + echo "" + if $terminal ; then + if [[ -n "$*" ]] ; then + echo -e " [ \033[31m\033[1mFatal\033[m ]: $*" + else + echo " \033[31m\033[1mFatal error\033[m:" + fi + echo "" + echo -e " \033[31m\033[1mScript will be interrupted.\033[m\033[m" + else + if [[ -n "$*" ]] ; then + echo " [ Fatal ]: $*" + else + echo " Fatal error:" + fi + echo "" + echo " Script was terminated...." + fi + echo "" + clean_up 1 +} + +echononl(){ + if $terminal && ! $QUIET_MODE ; then + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo -e -n "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ + fi +} + +error(){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mError\033[m ]: $*" + else + echo "Error: $*" + fi + echo "" +} + +warn (){ + if $terminal && ! $QUIET_MODE ; then + echo "" + echo -e " [ \033[33m\033[1mWarning\033[m ]: $*" + echo "" + fi +} + +info (){ + if $terminal && ! $QUIET_MODE ; then + echo "" + echo -e " [ \033[32m\033[1mInfo\033[m ]: $*" + echo "" + fi +} + +echo_ok() { + if $terminal && ! $QUIET_MODE ; then + echo -e "\033[80G[ \033[32mok\033[m ]" + fi +} +echo_failed(){ + if $terminal && ! $QUIET_MODE ; then + echo -e "\033[80G[ \033[1;31mfailed\033[m ]" + fi +} +echo_skipped() { + if $terminal && ! $QUIET_MODE ; then + echo -e "\033[80G[ \033[37mskipped\033[m ]" + fi +} + +is_number() { + + return $(test ! -z "${1##*[!0-9]*}" > /dev/null 2>&1); + + # - also possible + # - + #[[ ! -z "${1##*[!0-9]*}" ]] && return 0 || return 1 + #return $([[ ! -z "${1##*[!0-9]*}" ]]) +} + +detect_mysql_version () { + + _MYSQLD_VERSION="$(mysqld -V 2>/dev/null)" + + if [[ -z "$_MYSQLD_VERSION" ]]; then + fatal "No installed MySQL server or distribution found!" + elif [[ -d "/usr/local/mysql" ]] && [[ "$(basename "$(realpath "/usr/local/mysql")")" =~ percona- ]]; then + MYSQL_CUR_DISTRIBUTION="Percona" + elif [[ "$_MYSQLD_VERSION" =~ MariaDB ]]; then + MYSQL_CUR_DISTRIBUTION="MariaDB" + elif [[ "$_MYSQLD_VERSION" =~ MySQL ]]; then + MYSQL_CUR_DISTRIBUTION="MySQL" + elif [[ -d "/usr/local/mysql" ]] && [[ "$(basename "$(realpath "/usr/local/mysql")")" =~ mysql- ]]; then + MYSQL_CUR_DISTRIBUTION="MySQL" + elif [[ -d "/usr/local/mysql" ]] && [[ "$(basename "$(realpath "/usr/local/mysql")")" =~ mariadb- ]]; then + MYSQL_CUR_DISTRIBUTION="MariaDB" + else + error "MySQL Instalation found, but cannot determin the distribution!" + + MYSQL_CUR_DISTRIBUTION= + echo "" + echo " Select the MySQL distribution to install." + echo "" + echo " [1] MySQL (the original community edition)" + echo " [2] Percona Server for MySQL" + echo " [3] MariaDB" + echo "" + echononl " Eingabe [1/2/3]: " + + while [ "$MYSQL_CUR_DISTRIBUTION" != "MySQL" -a "$MYSQL_CUR_DISTRIBUTION" != "MariaDB" -a "$MYSQL_CUR_DISTRIBUTION" != "Percona" ];do + read OPTION + case $OPTION in + 1) MYSQL_CUR_DISTRIBUTION="MySQL" + ;; + 2) MYSQL_CUR_DISTRIBUTION="Percona" + ;; + 3) MYSQL_CUR_DISTRIBUTION="MariaDB" + ;; + *) echo "" + echo -e "\tFalsche Eingabe ! [ 1 = MySQL ; 2 = Percona ; 3 = MariaDB ]" + echo "" + echononl " Eingabe:" + ;; + esac + done + fi + + MYSQL_VERSION="$(echo $_MYSQLD_VERSION | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?" | head -n 1)" + MYSQL_MAJOR_VERSION="$(echo $MYSQL_VERSION | cut -d '.' -f1)" + MYSQL_MINOR_VERSION="$(echo $MYSQL_VERSION | cut -d '.' -f2)" + MYSQL_PATCH_LEVEL="$(echo $MYSQL_VERSION | cut -d '.' -f3)" + MYSQL_MAIN_VERSION="$(echo $MYSQL_VERSION | cut -d '.' -f1,2)" + +} + + +trap clean_up SIGHUP SIGINT SIGTERM + + + + +# ------------- +# - Read Commandline Parameters +# ------------- + +while getopts hIqu: opt ; do + case $opt in + I) NON_INTERACTIVE_MODE=true + ;; + q) QUIET_MODE=true + NON_INTERACTIVE_MODE=true + ;; + u) DATABASE_USER="$OPTARG" + DATABASE_USER_NEEDED=false + ;; + h) usage + ;; + *) usage + esac +done + +shift $(expr $OPTIND - 1) +[[ "$#" -gt 0 ]] && usage "Wrong number of arguments given!" + +# - If not running in a terminal, be silent and non-interactive +# - +if [[ -t 1 ]] ; then + terminal=true +else + terminal=false + QUIET_MODE=true + NON_INTERACTIVE_MODE=true +fi + +if [[ -z "$DATABASE_NAME" ]] ; then + DATABASE_USER_NEEDED=true + DATABASE_PASSWD_NEEDED=true +fi + +if $NON_INTERACTIVE_MODE && [[ -z "$DATABASE_NAME" ]]; then + fatal "In quiet mode at least the database name must ibe given on th command line!" +fi + + +if [[ -n "$DATABASE_NAME" ]] ; then + if [[ -z "$DATABASE_USER" || -z "$DATABASE_PASSWD" ]] ; then + read_file="" + if [[ -f "${working_dir}/databases/$DATABASE_NAME" ]]; then + read_file="${working_dir}/databases/$DATABASE_NAME" + elif [[ -f "${working_dir}/databases/DELETED/$DATABASE_NAME" ]]; then + read_file="${working_dir}/databases/DELETED/$DATABASE_NAME" + fi + + if [[ -n "$read_file" ]]; then + while read -r _db_name _db_user _db_pass ; do + + # - if var '_db_name' begins with '#', that means the readed line + # - is a comment line, then empty this variable + # - + # - + _db_name="$(echo $_db_name | grep -vE "^\s*#")" + + # - Do not consider empty lines or commented lines + # - + [[ -z "$_db_name" ]] && continue + + if [[ "$_db_name" = "$DATABASE_NAME" ]]; then + [[ -z "$DATABASE_USER" ]] && DATABASE_USER="$_db_user" + [[ -z "$DATABASE_PASSWD" ]] && DATABASE_PASSWD="$_db_pass" + break + fi + + done < "$read_file" + fi + fi +fi + + +if $NON_INTERACTIVE_MODE ; then + if [[ -z "$DATABASE_USER" ]]; then + fatal "Database user not given. Maybe missing or wrong file '${working_dir}/databases/$DATABASE_NAME'." + fi + if [[ -z "$DATABASE_PASSWD" ]]; then + fatal "Database user's password nit given. Maybe missing or wrong file '${working_dir}/databases/$DATABASE_NAME'." + fi + +fi + + +# - Clear Screen +# - +clear + + +# ------------- +# - Load Settings from configuration file mysql_credetials.conf +# ------------- + +if ! $QUIET_MODE ; then + echo "" +fi +echononl " Loading configuration settings from $(basename ${conf_file}).." +if [[ -f "$conf_file" ]]; then + source "$conf_file" > $tmp_log_file 2>&1 + if [[ $? -eq 0 ]]; then + echo_ok + else + echo_failed + fatal "$(cat $tmp_log_file)" + fi +else + echo_skipped + warn "No Configuration File found. Loading defaults.." +fi + +if [[ -n "$mysql_credential_args" ]]; then + MYSQL_CREDENTIAL_ARGS="$mysql_credential_args" + MYSQL_CREDENTIALS_GIVEN=true +fi + + +if ! $NON_INTERACTIVE_MODE ; then + + declare -i index_arr=0 + + # - Get MySQL Version + # - + if [[ ${#mysql_credential_args_arr[@]} -gt 0 ]] ; then + + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Which Installation should be used for dropping database user?" + echo "" + echo "" + + declare -a _tmp_arr=() + #for _val in ${mysql_credential_args_arr[@]} ; do + while [[ $index_arr -lt ${#mysql_credential_args_arr[@]} ]] ; do + + #IFS=':' read -a _val_arr <<< "${_val}" + IFS=':' read -a _val_arr <<< "${mysql_credential_args_arr[$index_arr]}" + + mysql_version="${_val_arr[0]}" + mysql_credential_args="${_val_arr[1]}" + mysql_dist_string="$(mysql $mysql_credential_args -N -s -e "SELECT VERSION()" 2> /dev/null)" + if [[ "$mysql_dist_string" =~ MariaDB ]]; then + mysql_dist="MariaDB $mysql_version" + else + mysql_dist="MySQL/Percona $mysql_version" + fi + echo " [$index_arr] $mysql_dist" + _temp_arr[${index_arr}]="$mysql_credential_args" + #_temp_arr+=("$mysql_credential_args") + (( index_arr++ )) + done + + _OK=false + echo "" + echononl "Eingabe: " + while ! $_OK ; do + read _IN + if is_number "$_IN" && [[ -n ${_temp_arr[$_IN]} ]]; then + + MYSQL_CREDENTIAL_ARGS="${_temp_arr[$_IN]}" + _OK=true + else + echo "" + echo -e "\tFalsche Eingabe !" + echo "" + echononl "Eingabe: " + fi + done + + MYSQL_CREDENTIALS_GIVEN=true + + fi + + + if $DATABASE_USER_NEEDED ; then + echo "" + echo -e "\033[32m--\033[m" + echo "" + echo "Insert Database user which should be deleted'.." + echo "" + echo "" + if [ -z "$DATABASE_USER" ]; then + echononl "Remove Database user: " + read DATABASE_USER + while [ "X$DATABASE_USER" = "X" ] ; do + echo -e "\n\t\033[33m\033[1mEingabe erforderlich.\033[m\n" + echononl "Remove Database user': " + read DATABASE_USER + done + else + _DATABASE_USER="$DATABASE_USER" + echononl "Remove Database user' [${_DATABASE_USER}]: " + read DATABASE_USER + if [[ "X$DATABASE_USER" = "X" ]]; then + DATABASE_USER=$_DATABASE_USER + fi + fi + fi + +fi + + +if $MYSQL_CREDENTIALS_GIVEN ; then + + # - Get MySQL Version + # - + echo "" + echo -e "\033[32m--\033[m" + echo "" + echononl " Get MySQL Version" + _version="$(mysql $MYSQL_CREDENTIAL_ARGS -N -s -e "SELECT VERSION()" 2> $tmp_log_file)" + if [[ $? -ne 0 ]] ; then + echo_failed + fatal "$(cat $tmp_log_file)" + else + echo_ok + fi + + IFS='.' read -r -a version_arr <<< "$_version" + declare -i MAJOR_VERSION="${version_arr[0]}" + declare -i MINOR_VERSION="${version_arr[1]}" + _path_level="${version_arr[2]}" + declare -i PATCH_LEVEL="${_path_level%%-*}" + + ## - Get current MySQL Distribution + ## - + echononl " Get current MySQL distribution .." + if [[ -z "$_version" ]]; then + echo_failed + fatal "No installed MySQL server or distribution found!" + elif [[ "$_version" =~ MariaDB ]]; then + MYSQL_CUR_DISTRIBUTION="MariaDB" + else + MYSQL_CUR_DISTRIBUTION="MySQL" + fi + echo_ok + echo "" + echo -e "\033[32m--\033[m" + echo "" + +else + + detect_mysql_version + + MAJOR_VERSION="$MYSQL_MAJOR_VERSION" + MINOR_VERSION="$MYSQL_MINOR_VERSION" + PATCH_LEVEL="$MYSQL_PATCH_LEVEL" + + if [[ "$MYSQL_CUR_DISTRIBUTION" = "MariaDB" ]] && ([[ $MAJOR_VERSION -gt 10 ]] \ + || ( [[ $MAJOR_VERSION -eq 10 ]] && [[ $MINOR_VERSION -gt 3 ]] )) ; then + if [[ -S "/tmp/mysql.sock" ]]; then + MYSQL_CREDENTIAL_ARGS="-u root -S /tmp/mysql.sock" + elif [[ -S "/var/run/mysqld/mysqld.sock" ]]; then + MYSQL_CREDENTIAL_ARGS="-u root -S /var/run/mysqld/mysqld.sock" + else + fatal "Parameter 'MYSQL_CREDENTIAL_ARGS' cannot be determined automated. + + Use configuration file "$conf_file" to set + parameter manually." + fi + else + if $(mysql --login-path=local -e ";" > /dev/null 2>&1) ; then + MYSQL_CREDENTIAL_ARGS="--login-path=local" + elif [[ -f "/usr/local/mysql/sys-maint.cnf" ]] ; then + MYSQL_CREDENTIAL_ARGS="--defaults-file=/usr/local/mysql/sys-maint.cnf" + elif [[ -f "/etc/mysql/debian.cnf" ]] ; then + MYSQL_CREDENTIAL_ARGS="--defaults-file=/etc/mysql/debian.cnf" + else + fatal "Parameter 'MYSQL_CREDENTIAL_ARGS' cannot be determined automated. + + Use configuration file "$conf_file" to set + parameter manually." + fi + fi +fi + + +if ! $QUIET_MODE ; then + echo "" + echo "" + echo -e "\033[32m\033[1m====================\033[m" + echo "Drop MySQL Database settings" + echo -e "\033[32m\033[1m====================\033[m" + echo "" + echo " MySQL Distribution...........: $MYSQL_CUR_DISTRIBUTION" + echo " MySQL Version................: ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_LEVEL}" + echo " MySQL Credentials............: $MYSQL_CREDENTIAL_ARGS" + echo "" + echo -e " Drop Database user...........: \033[33m$DATABASE_USER\033[m" + echo "" + echo "" +fi + +if ! $NON_INTERACTIVE_MODE ; then + + info "To Continue dropping database user \033[1m$DATABASE_USER\033[m type uppercase 'YES'" + echo -e -n "\033[1mContinue:\033[m " + read OK + + if [[ "$OK" != "YES" ]] ; then + fatal "Abort by user request - Answer as not 'YES'" + fi + +fi + + +if ! $QUIET_MODE ; then + echo "" + echo "" + echo -e " Processing database \033[1m$DATABASE_NAME\033[m" + echo "" +fi + +# - Check if User already exists +# - +echononl " Check if user '$DATABASE_USER' exists .." +if [[ "$(mysql $MYSQL_CREDENTIAL_ARGS -se "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '${DATABASE_USER}')")" = "1" ]]; then + user_exists=true +else + user_exists=false + +fi +echo_ok + + +# - Test given user is associated with a database +# - +echononl " Check if db user '$DATABASE_USER' is associated with a database" +_count_user="$(mysql $MYSQL_CREDENTIAL_ARGS mysql -N -s -e \ + "SELECT count(User) FROM db WHERE User = '$DATABASE_USER'" 2> $tmp_log_file)" +if [[ -z "$_count_user" ]]; then + echo_failed + error $(cat "$tmp_log_file") +else + echo_ok +fi + + +if ! $QUIET_MODE ; then + echo "" +fi + + +echononl " Delete username '$DATABASE_USER' from table mysql.db" +if [[ $_count_user -gt 0 ]]; then + mysql $MYSQL_CREDENTIAL_ARGS mysql -N -s -e \ + "DELETE FROM db WHERE User = '$DATABASE_USER'" > $tmp_log_file 2>&1 + if [[ $? -ne 0 ]] ; then + echo_failed + fatal "$(cat $tmp_log_file)" + else + echo_ok + fi +else + echo_skipped +fi + +echononl " Delete username '$DATABASE_USER' from table mysql.user" +if $user_exists ; then + mysql $MYSQL_CREDENTIAL_ARGS mysql -N -s -e \ + "DELETE FROM user WHERE User = '$DATABASE_USER'" > $tmp_log_file 2>&1 + if [[ $? -ne 0 ]] ; then + echo_failed + fatal "$(cat $tmp_log_file)" + else + echo_ok + fi + +else + echo_skipped + warn "No Database User named '$DATABASE_USER' found in table mysql.user." +fi + +echononl " Flush Privileges.." +mysql $MYSQL_CREDENTIAL_ARGS -N -s -e "FLUSH PRIVILEGES" > $tmp_log_file 2>&1 +if [[ $? -ne 0 ]] ; then + echo_failed + error "$(cat $tmp_log_file)" +else + echo_ok +fi + +if ! $QUIET_MODE ; then + echo "" +fi + +clean_up 0