Извините за длинный ответ, который на самом деле комментарий, но я его не понимаю. Ваша команда GRANT "третьей линии" хорошо работает для меня. Вот два случая, которые должны работать. Было бы здорово, если бы вы могли опубликовать несколько тестовых команд, которые воспроизводят ошибку. По крайней мере, я мог бы извлечь уроки из этого:)
Случай № 1, пользователь не существует:
mysql> SHOW GRANTS FOR my_user@"%";
ERROR 1141 (42000): There is no such grant defined for user 'my_user' on host '%'
ОК, пользователь не существует.
mysql> create database my_database;
Query OK, 1 row affected (0.00 sec)
mysql> GRANT SELECT ON my_database.* TO my_user@"%" IDENTIFIED BY 'my_password';
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW GRANTS FOR my_user@"%";
+-----------------------------------------------------------------------+
| Grants for my_user@% |
+-----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'my_user'@'%' IDENTIFIED BY PASSWORD '*CC...18' |
| GRANT SELECT ON `my_database`.* TO 'my_user'@'%' |
+-----------------------------------------------------------------------+
2 rows in set (0.00 sec)
ОК, у него есть разрешение SELECT.
Случай № 2, пользователь существует и имеет права на other_database
и my_database
тоже:
mysql> SHOW GRANTS FOR my_user@"%";
ERROR 1141 (42000): There is no such grant defined for user 'my_user' on host '%'
ОК, пользователь не существует.
mysql> create database my_database;
Query OK, 1 row affected (0.00 sec)
mysql> create database other_database;
Query OK, 1 row affected (0.01 sec)
mysql> GRANT SELECT ON my_database.* TO my_user@"%" IDENTIFIED BY 'my_password';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT SELECT ON other_database.* TO my_user@"%" IDENTIFIED BY 'my_password';
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW GRANTS FOR my_user@"%";
+-----------------------------------------------------------------------+
| Grants for my_user@% |
+-----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'my_user'@'%' IDENTIFIED BY PASSWORD '*CC...18' |
| GRANT SELECT ON `other_database`.* TO 'my_user'@'%' |
| GRANT SELECT ON `my_database`.* TO 'my_user'@'%' |
+-----------------------------------------------------------------------+
3 rows in set (0.00 sec)
Выше приведено тестовое устройство, и теперь мы предоставляем новое разрешение UPDATE
пользователю:
mysql> GRANT UPDATE ON my_database.* TO my_user@"%" IDENTIFIED BY 'my_password';
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW GRANTS FOR my_user@"%";
+-----------------------------------------------------------------------+
| Grants for my_user@% |
+-----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'my_user'@'%' IDENTIFIED BY PASSWORD '*CC...18' |
| GRANT SELECT ON `other_database`.* TO 'my_user'@'%' |
| GRANT SELECT, UPDATE ON `my_database`.* TO 'my_user'@'%' |
+-----------------------------------------------------------------------+
3 rows in set (0.00 sec)
Его разрешение не изменилось на other_database
, и он получил новое разрешение UPDATE
на my_database
и прежнее SELECT
.
На основании комментариев должно быть только UPDATE
без SELECT
.
К сожалению, в текущих версиях MySQL это невозможно сделать только одной командой. GRANT
не имеет предложения REMOVE EXISTING
.
Я думаю, что лучшее решение - @ eswald's GRANT USAGE ON ...
, но это все еще 3 команды. Другое решение -
DELETE FROM mysql.db WHERE user = 'my_user' AND host ='%' AND db = 'my_database'
но ему нужно FLUSH PRIVILEGES
, поэтому это также 3 команды.
Обходным решением может быть скрипт bash, который генерирует три команды, о которых идет речь:
#!/bin/bash
function grant {
USER=$1
PASSWORD=$2
DB=$3
PERMISSIONS=$4
echo "GRANT USAGE ON $DB TO $USER IDENTIFIED BY '$PASSWORD';"
echo "REVOKE ALL PRIVILEGES ON $DB FROM $USER;"
echo "GRANT $PERMISSIONS ON $DB TO $USER IDENTIFIED BY '$PASSWORD';"
}
grant "my_user@'%'" "my_password" "my_database.*" "SELECT, UPDATE"
Он печатает:
GRANT USAGE ON my_database.* TO my_user@'%' IDENTIFIED BY 'my_password';
REVOKE ALL PRIVILEGES ON my_database.* FROM my_user@'%';
GRANT SELECT, UPDATE ON my_database.* TO my_user@'%' IDENTIFIED BY 'my_password';
(я изменил первый GRANT SELECT
на USAGE
.)