This commit is contained in:
tuend-work
2025-11-13 07:41:56 +07:00
parent 7f357f3a30
commit 4478491d73
1729 changed files with 193578 additions and 20 deletions

View File

@@ -0,0 +1,181 @@
#!/bin/sh
#VERSION=0.1
# This script is written by Martynas Bendorius and DirectAdmin
# It is used to move database and it's user from one reseller to another
# Official DirectAdmin webpage: http://www.directadmin.com
# Usage:
# ./rename_database_with_user.sh <olddatabase> <newdatabase>
MYUID=`/usr/bin/id -u`
if [ "$MYUID" != 0 ]; then
echo "You require Root Access to run this script";
exit 0;
fi
if [ $# != 2 ]; then
echo "Usage:";
echo "$0 <olddatabase> <newdatabase>";
echo "you gave #$#: $0 $1 $2";
exit 0;
fi
OLDUSER_DATABASE="$1"
NEWUSER_DATABASE="$2"
OLDUSER_ESCAPED_DATABASE="`echo ${OLDUSER_DATABASE} | perl -p0 -e 's|_|\\\_|'`"
NEWUSER_ESCAPED_DATABASE="`echo ${NEWUSER_DATABASE} | perl -p0 -e 's|_|\\\_|'`"
OLDUSER_ESCAPED_DATABASE_MT="`echo ${OLDUSER_DATABASE} | perl -p0 -e 's|_|\\\\\\\_|'`"
NEWUSER_ESCAPED_DATABASE_MT="`echo ${NEWUSER_DATABASE} | perl -p0 -e 's|_|\\\\\\\_|'`"
MYSQLDUMP=/usr/local/mysql/bin/mysqldump
if [ ! -e ${MYSQLDUMP} ]; then
MYSQLDUMP=/usr/local/bin/mysqldump
fi
if [ ! -e ${MYSQLDUMP} ]; then
MYSQLDUMP=/usr/bin/mysqldump
fi
if [ ! -e ${MYSQLDUMP} ]; then
echo "Cannot find ${MYSQLDUMP}"
exit 1
fi
MYSQL=/usr/local/mysql/bin/mysql
if [ ! -e ${MYSQL} ]; then
MYSQL=/usr/local/bin/mysql
fi
if [ ! -e ${MYSQL} ]; then
MYSQL=/usr/bin/mysql
fi
if [ ! -e ${MYSQL} ]; then
echo "Cannot find ${MYSQL}"
exit 1
fi
DEFM=--defaults-extra-file=/usr/local/directadmin/conf/my.cnf
# If MySQL new database does not exist, create it and copy all the data from the old database, then drop the old database
if ! ${MYSQL} ${DEFM} --skip-column-names -e "SHOW DATABASES LIKE '${NEWUSER_DATABASE}';" -s | grep -m1 -q "${NEWUSER_DATABASE}"; then
if ! ${MYSQL} ${DEFM} --skip-column-names -e "SHOW DATABASES LIKE '${OLDUSER_DATABASE}';" -s | grep -m1 -q "${OLDUSER_DATABASE}"; then
echo "Specified database name does not exist: ${OLDUSER_DATABASE}"
exit 1
fi
#Count the number of tables in current database
OLD_TABLES_COUNT="`${MYSQL} ${DEFM} -D \"${OLDUSER_DATABASE}\" --skip-column-names -e 'SHOW TABLES;' | wc -l`"
#Create an empty new database, \` is needed for databases having "-" in it's name, so that no math would be done by sql :)
${MYSQL} ${DEFM} -e "CREATE DATABASE \`${NEWUSER_DATABASE}\`;"
echo "Dumping+restoring ${OLDUSER_DATABASE} -> ${NEWUSER_DATABASE}..."
#Dump+restore to the new database on the fly
${MYSQLDUMP} ${DEFM} --routines "${OLDUSER_DATABASE}" | ${MYSQL} ${DEFM} -D "${NEWUSER_DATABASE}"
#Count the number of tables in new database
NEW_TABLES_COUNT="`${MYSQL} ${DEFM} -D \"${NEWUSER_DATABASE}\" --skip-column-names -e 'SHOW TABLES;' | wc -l`"
if echo "${OLD_TABLES_COUNT}" | grep -qE ^\-?[0-9]+$; then
COUNT1_IS_NUMERIC=true
else
COUNT1_IS_NUMERIC=false
fi
if echo "${NEW_TABLES_COUNT}" | grep -qE ^\-?[0-9]+$; then
COUNT2_IS_NUMERIC=true
else
COUNT2_IS_NUMERIC=false
fi
#Drop the old database if the count of tables matches
if [ ${OLD_TABLES_COUNT} -eq ${NEW_TABLES_COUNT} ] && ${COUNT1_IS_NUMERIC} && ${COUNT2_IS_NUMERIC}; then
${MYSQL} ${DEFM} -e "DROP DATABASE \`${OLDUSER_DATABASE}\`;"
echo "Database has been renamed successfully: ${OLDUSER_DATABASE} -> ${NEWUSER_DATABASE}"
#User management part
OLD_USER=`echo ${OLDUSER_DATABASE} | egrep -o '^[^_]*'`
NEW_USER=`echo ${NEWUSER_DATABASE} | egrep -o '^[^_]*'`
#default user
if [ ${OLD_USER} = ${NEW_USER} ]; then
echo "Raname in same user - no need to check base user"
else
echo "Moving to a new user, granting new user/revoking old user permissions"
if [ `${MYSQL} ${DEFM} -e "SELECT COUNT(*) FROM mysql.user WHERE User='${NEW_USER}'" -sss` -lt 1 ]; then
echo "Base new user '${NEW_USER}' does not exist, skipping base user grant management"
else
OLD_USER_HOSTS=`${MYSQL} ${DEFM} -s -r -e "SELECT Host FROM mysql.user WHERE User='${OLD_USER}'" -sss`
for OLD_USER_HOST in ${OLD_USER_HOSTS}
do
BASE_USER_GRANTS=`${MYSQL} ${DEFM} -s -r -e "SHOW GRANTS FOR '${OLD_USER}'@'${OLD_USER_HOST}'" 2>/dev/null | egrep "\\\`${OLDUSER_DATABASE}\\\`|\\\`${OLDUSER_ESCAPED_DATABASE_MT}\\\`"`
echo "${BASE_USER_GRANTS}" | while read -r GRANT
do
DO_GRANT=`echo ${GRANT} | sed "s/'${OLD_USER}'/'${NEW_USER}'/"`
DO_GRANT=`echo ${DO_GRANT} | sed "s/\\\`${OLDUSER_DATABASE}\\\`/\\\`${NEWUSER_DATABASE}\\\`/"`
DO_GRANT=`echo ${DO_GRANT} | sed "s/\\\`${OLDUSER_ESCAPED_DATABASE_MT}\\\`/\\\`${NEWUSER_DATABASE}\\\`/"`
DO_REVOKE=`echo ${GRANT} | sed "s/^GRANT /REVOKE /"`
DO_REVOKE=`echo ${DO_REVOKE} | sed "s/ TO / FROM /"`
${MYSQL} ${DEFM} -e "${DO_GRANT}"
${MYSQL} ${DEFM} -e "${DO_REVOKE}"
done
done
fi
fi
#other users
OTHER_USERS=`${MYSQL} ${DEFM} -s -e "SELECT User,Host FROM (SELECT User,Db,Host FROM mysql.db UNION SELECT User,Db,Host FROM mysql.tables_priv UNION SELECT User,Db,Host FROM mysql.columns_priv UNION SELECT User,Db,Host FROM mysql.procs_priv) tb WHERE User like '${OLD_USER}_%' AND (Db='${OLDUSER_ESCAPED_DATABASE}' OR Db='${OLDUSER_DATABASE}')"`
echo "$OTHER_USERS" | while read OTHER
do
OUSER=`echo "$OTHER" | awk '{print $1}'`
OHOST=`echo "$OTHER" | awk '{print $2}'`
NUSER=`echo "$OUSER" | sed "s/${OLD_USER}_/${NEW_USER}_/"`
OTHER_USER_GRANTS=`${MYSQL} ${DEFM} -s -r -e "SHOW GRANTS FOR '${OUSER}'@'${OHOST}'" 2>/dev/null | egrep "\\\`${OLDUSER_DATABASE}\\\`|\\\`${OLDUSER_ESCAPED_DATABASE_MT}\\\`"`
echo "${OTHER_USER_GRANTS}" | while read -r OTHER_GRANT
do
if [ "${OLD_USER}" = "${NEW_USER}" ]; then
echo "Rename in same user - no need to rename original db user"
else
if [ `${MYSQL} ${DEFM} -e "SELECT COUNT(*) FROM mysql.user WHERE User='${NUSER}' AND Host='${OHOST}'" -sss` -gt 0 ]; then
echo "'${NUSER}'@'${OHOST}' user already exists, a new one will not be created and the password won't be copied as it could be already used..."
else
echo "'${NUSER}'@'${OHOST}' user does not exist. Creating..."
RAND_PASS=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
${MYSQL} ${DEFM} -e "CREATE USER '${NUSER}'@'${OHOST}' IDENTIFIED BY '${RAND_PASS}'"
PASS_GRANT=`${MYSQL} ${DEFM} -e "SHOW GRANTS FOR '${OUSER}'@'${OHOST}'" | egrep " IDENTIFIED BY PASSWORD"`
PASS_GRANT=`echo ${PASS_GRANT} | rev | cut -d' ' -f 1 | rev | sed "s/'//g"`
MYSQLVER=`${MYSQL} ${DEFM} -e "SELECT version()" | egrep -o "^[0-9]+\.[0-9]+"`
if ${MYSQL} ${DEFM} -e "SHOW CREATE USER 'da_admin'@'${OHOST}';" > /dev/null 2>&1; then
${MYSQL} ${DEFM} -e "ALTER USER '${NUSER}'@'${OHOST}' IDENTIFIED WITH mysql_native_password AS '${PASS_GRANT}'"
else
${MYSQL} ${DEFM} -e "SET PASSWORD FOR '${NUSER}'@'${OHOST}' = '${PASS_GRANT}'"
fi
fi
fi
DO_OTHER_GRANT="${OTHER_GRANT}"
if [ "${OLD_USER}" != "${NEW_USER}" ]; then
DO_OTHER_GRANT=`echo ${DO_OTHER_GRANT} | sed "s/ '${OUSER}'/ '${NUSER}'/"`
fi
DO_OTHER_GRANT=`echo ${DO_OTHER_GRANT} | sed "s/\\\`${OLDUSER_DATABASE}\\\`/\\\`${NEWUSER_DATABASE}\\\`/"`
DO_OTHER_GRANT=`echo ${DO_OTHER_GRANT} | sed "s/\\\`${OLDUSER_ESCAPED_DATABASE_MT}\\\`/\\\`${NEWUSER_DATABASE}\\\`/"`
DO_OTHER_REVOKE=`echo ${OTHER_GRANT} | sed "s/^GRANT /REVOKE /"`
DO_OTHER_REVOKE=`echo ${DO_OTHER_REVOKE} | sed "s/ TO / FROM /"`
${MYSQL} ${DEFM} -e "${DO_OTHER_GRANT}"
${MYSQL} ${DEFM} -e "${DO_OTHER_REVOKE}"
if [ `${MYSQL} ${DEFM} -s -e "SELECT COUNT(*) FROM (SELECT User,Db,Host FROM mysql.db UNION SELECT User,Db,Host FROM mysql.tables_priv UNION SELECT User,Db,Host FROM mysql.columns_priv UNION SELECT User,Db,Host FROM mysql.procs_priv) tb WHERE User='${OUSER}' AND Db!='${OLDUSER_ESCAPED_DATABASE}' AND Db!='${OLDUSER_DATABASE}' AND Host='${OHOST}'"` -eq 0 ]; then
echo "'${OUSER}'@'${OHOST}' does not have privileges for other databases. Removing the user."
${MYSQL} ${DEFM} -e "DROP USER '${OUSER}'@'${OHOST}'"
else
echo "'${OUSER}'@'${OHOST}' still has privileges for other databases. Not removing the user."
fi
done
done
exit 0
else
#Error and exit if the number of tables doesn't match
echo "Database ${NEWUSER_DATABASE} doesn't have as many tables as ${OLDUSER_DATABASE} after restoration. Not removing ${OLDUSER_DATABASE}. Exiting..."
exit 1
fi
else
# If MySQL new database name already exists on the system (it shouldn't), error and exit
echo "Database ${NEWUSER_DATABASE} already exists, cannot rename the database. Exiting..."
exit 1
fi