C, PHP, VB, .NET

Дневникът на Филип Петров


* Потребители в MySQL

Публикувано на 09 февруари 2009 в раздел Бази от Данни.

Когато работим с база от данни, то е добре да използваме точно толкова привилегии, колкото са ни необходими. Обикновено за всяка база от данни се създава потребител, който да работи с нея. Често дори се създават потребители само за конкретна таблица от база от данни.

Нека имаме база от данни с име "university". За да създадем потребител с име "philip" и парола "somepassword", изпълняваме следната команда:

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE
ON university.*
TO 'philip'@'localhost'
IDENTIFIED BY 'somepassword';

По този начин дадохме права (GRANT) за изпълнение на заявки от тип SELECT, INSERT, UPDATE, DELETE и CREATE върху всички таблици (.*) на база от данни "univeristy" на потребител с име "philip", който може да се връзва към сървъра от локалната машина. В случая такъв потребител все още не съществува и затова добавихме неговата парола. Този потребител автоматично ще бъде добавен в системната таблица с име "mysql":

Създаване на потребител

Важно е след всяка промяна на потребителски достъп чрез GRANT да изпълнявате командата:

FLUSH PRIVILEGES;

Вече можем да се автентикираме с този потребител:

E:\MySQL> mysql -u philip -p
Enter password: **********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.1.31-community MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> USE university;
Database changed

mysql> SELECT * FROM students;
Empty set (0.00 sec)

mysql> DROP TABLE students;
ERROR 1142 (42000): DROP command denied to user 'philip'@'localhost' for table 'students'

mysql> USE mysql;
ERROR 1044 (42000): Access denied for user 'philip'@'localhost' to database 'mysql'

Както виждате влязохме в MySQL клиента с потребител "philip". Изпълнихме командата "USE university", която означава "ще работим с база от данни university" и тя се изпълни успешно. Изпълнихме и една команда SELECT, която също беше изпълнена успешно, но просто таблицата се оказа празна. След това се опитахме да направим команда "DROP", но тя беше неуспешна, защото нямаме такива права. Неуспешна беше и командата "USE mysql", защото нямаме дадени права към тази база от данни.

Ако в последствие решим, че можем да добавим допълнителни права за този потребител можем да изпълним командата GRANT отново. Ето как например можем да дадем права за DROP на същия потребител:

GRANT DROP
ON university.*
TO 'philip'@'localhost';

Ако желаем да премахнем дадени привилегии, то изпълняваме заявка REVOKE:

REVOKE DROP
ON university.*
FROM 'philip'@'localhost';

По този начин потребител "philip" вече не може да изпълнява заявки от тип DROP към споменатата база от данни. Ето как можем да проверим дали определен потребител има дадени привилегии:

SELECT Select_priv, Drop_priv FROM mysql.db WHERE host="localhost" AND user="philip";
+-------------+-----------+
| Select_priv | Drop_priv |
+-------------+-----------+
| Y           | N         |
+-------------+-----------+
1 row in set (0.00 sec)

В примера проверихме дали потребител "philip" от host "localhost" има права за Select и Drop. Ето и всички видове привилегии:

Select_priv - права за "четене" от таблица
Insert_priv - добавяне на данни в таблица
Update_priv - обновяване на информация
Delete_priv - изтриване на данни
Create_priv - създаване на таблици
Drop_priv - изтриване на таблици
Lock_tables_priv - заключване на таблици
Create_tmp_table_priv - създаване на временни талблици
Grant_priv - права за даване на права на друг потребител
Index_priv - права за контрол на индекси
Alter_priv - права за промяна на дефиниции на таблица

Има и още, но те са доста по специфични и се употребяват рядко.

Изтриването на потребител е опасна операция. Винаги внимавайте когато работите със системната таблица "user" от базата от данни "mysql". Съществува реална опасност да изтриете собствения си потребител (root). Ето как можем да изтрием създадения потребител "philip":

REVOKE ALL ON university.* FROM 'philip'@'localhost';
Query OK, 0 rows affected (0.00 sec)

DELETE FROM mysql.user WHERE user="philip" and host="localhost";
Query OK, 1 row affected (0.00 sec)

FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Въобще внимавайте когато работите със системните таблици. Обикновено когато създавате база от данни си направете потребител с определени права върху нея и работете само с него. Използвайте потребител "root" само в краен случай!

В по-новите версии на MySQL горните команди за изтриване на потребител са обединени в една обща:

DROP USER 'philip'@'locahost';

Така ще изтриете потребителя от таблицата mysql.user и едновременно с това ще изтриете всичките му права върху всички бази от данни (*.*).

Също така в по-новите версии е позволено и да се преименуват потребители изключително лесно:

RENAME USER 'philip'@'localhost' TO 'petrov'@'localhost';

По този начин може да се променя както потребителското име, така и хоста от който влиза. Чрез тази команда си спестяваме доста заявки за обновяване.

За да промените паролата на потребител пък можете да използвате:

SET PASSWORD FOR 'petrov'@'localhost' = PASSWORD('novaparola');

Функцията PASSWORD() хешира паролата с SHA-1.

Накрая ако желаете да видите какви GRANT команди са изпълнени за даден потребител, то изпълнете командата:

SHOW GRANTS FOR 'petrov'@'localhost';

Обновено 08.08.2019 г. С идването на MariaDB 10.4 беше променен коренно начина, по който системата складира данните запотребителите. Там вече няма таблица mysql.user, а привилегиите са преместен в mysql.global_priv, където се складират в JSON формат. От потребителска гледна точка стандартните команди ще са непроменени.

Освен това в MariaDB 10.4 се въвежда възможност за автентикация чрез unix socket - директно с потребителя на операционната системата без да се подава парола. Важното е процесът, който се свързва с MariaDB, да е изпълнен с права на съответния потребител. Така например при първоначална инсталация се създава потребител root@localhost, който има невалидна парола - невъзможно е да се автентикирате в този акаунт по стандартния начин, но можете да влезнете в него чрез потребител root на същия компютър без парола. Това е направено с цел първоначалната инсталация да бъде значително по-сигурна.

При MariaDB 10.4 е въведен и нов алгоритъм за запазване на пароли, който в бъдеще ще замени стандартния - ed25519. Потребителите вече може да се създават чрез командата:

CREATE USER username@hostname IDENTIFIED VIA ed25519 USING PASSWORD('secret');

или чрез GRANT, както беше показано по-горе, но какво се вижда вече е възможно да се добави "VIA <алгоритъм>":

GRANT SELECT ON db.* TO username@hostname IDENTIFIED VIA ed25519 USING PASSWORD('secret');

За запазване на паролите по стандартния начин (SHA1) се използват командите от началото на статията, но трябва да се включи променлива "old_password=0" в конфигурационния файл на MariaDB (my.cnf).

 



10 коментара


  1. Здравейте! Дотук всичко ми беше ясно, но не мога да разбера как да вляза като нов потребител, който съм създал. Когато пусна Command Line Client ми изисква паролата за root. Влизам и после не знам как да сменя потребителя.

    (видях и една малка печатна грешка - навсякъде пише "пулбикации" )

  2. За съжаление ми изписва това :

    'mysql' is not recognized as an internal or external command,
    operable program or batch file.

    Надявам се да има решение.

  3. Отиди в директорията, в която е инсталиран MySQL и влез в нейната "bin" поддиректория. Например ако директорията е "c:\program files\mysql", то направи следното:

    c:
    cd
    cd "Program Files\mysql\bin"
    mysql -u username -p

  4. А как се дават права само върху определени редове от таблица?

  5. Ако е само за SELECT права - създавате VIEW и върху него давате привилегии за SELECT с GRANT.

    Ако е за други става по-сложно. Пак може с VIEW, но трудно се прави да работи перфектно. Най-често за тази цел се ползват съхранени процедури.

  6. Като дам някакви права на потребител само за определена таблица (university.students), после като искам да проверя какви права има, заявката ми връща "Empty set". Ако му дам права за цялата база (university.*), вече ми връща каквото трябва. Защо в първия случай не работи?

  7. За SHOW GRANTS си е така. Иначе със SELECT заявката ще ги изкара. В статията информацията е леко остаряла. В по-новите версии може да се прави така:

    SELECT *
    FROM information_schema.user_privileges
    WHERE grantee LIKE 'username@host';

    В системната база от данни information_schema има още таблици schema_privileges, table_privileges, че даже и column_privileges май имаше. Разгледай ги.

Добави коментар

Адресът на електронната поща няма да се публикува


*