MySQL: Как изменить пароль внутри ХП?
От: mika747  
Дата: 02.01.11 21:20
Оценка:
Использую 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, или так задумано?

И вообще, как это делается по-нормальному? Как правильно
реализовать защиту от неправильного аргумента (возможно инъекции)?
Как лучше шифровать пароль?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.