Использую MySQL 5.5.8 без SSL...
Все пользователи наделены только привилегией EXECUTE.
Они вызывают хранимые процедуры и функции (SECURITY
DEFINER), созданные под другим пользоваетелем, имеющим
необходимые права на БД и таблицы. Вроде обычно все
так и делают, но в самом начале столкнулся с трудностью.
Хочу дать пользователю менять свой пароль, но если делать
SET PASSWORD = PASSWORD('new_password');
то строка с новым паролем может быть перехвачена, не важно,
сниффером, или администратором БД...
1) Тут сразу лирическое отступление: выражение вида
SELECT PASSWORD('new_password');
выполняется на сервере или все-же libmysql справляется
с этим самостоятельно?
В общем, захотелось написать ХП, принимающий шифрованный
пароль, но тут засада: оба нижеприведенных варианта не
работают!!!
DECLARE strPassHash CHAR(41);
SET strPassHash=...;
1) SET PASSWORD = PASSWORD(strPass);
2) SET PASSWORD = strPassHash;
Конечно, можно прямо в MySQL.User сделать что-то типа
UPDATE mysql.user SET Password=strPassHash
WHERE User=strUserName AND Host=strHostName;
FLUSH PRIVILEGES;
Однако, это возбраняемый хак, а главное, что должно
быть в strHostName?
Например, если в таблице стоит "%", и я, допустим,
подключился с 192.168.0.2 и в mysql.User есть несколько
записей для strUserName как узнать какую из них модифицировать?
Таким образом, я добрел до такого (упрощенно) динамического SQL:
DELIMITER //
DROP PROCEDURE IF EXISTS SET_PASSWORD//
CREATE PROCEDURE SET_PASSWORD(IN NewPassword CHAR(32))
LANGUAGE SQL NOT DETERMINISTIC SQL SECURITY DEFINER COMMENT ''
BEGIN
DECLARE strPass CHAR(41);
SET strPass=PASSWORD(NewPassword);
SET @szSQL_Query=CONCAT("SET PASSWORD='",strPass,"'");
PREPARE SQL_Query FROM @szSQL_Query;
EXECUTE SQL_Query;
DEALLOCATE PREPARE SQL_Query;
END//
DELIMITER ;
Нои тут не обошлось без проблем. Созданная с SECURITY DEFINER,
эта процедура меняет пароль не вызывающего, а создавшего ХП
пользователя. Пришлось поставить SECURITY INVOKER.
Это баг MySQL, или так задумано?
И вообще, как это делается по-нормальному? Как правильно
реализовать защиту от неправильного аргумента (возможно инъекции)?
Как лучше шифровать пароль?