W politycznie poprawnym sensie to, o co właśnie prosiłeś, jest niemożliwe. Dlaczego ?
Uprawnienie SUPER jest uprawnieniem globalnym, a nie uprawnieniem na poziomie bazy danych.
Po utworzeniu użytkownika za pomocą
grant all privileges on db1.* to user1@'%' with grant option;
zapełniłeś tabelę mysql.user
użytkownik = użytkownik1 i host = '%'. Wszystkie pozostałe kolumny (uprawnienia globalne) były domyślnie ustawione na „N”. Jedną z tych kolumn jest Super_priv
. Oto tabela:
mysql> desc mysql.user;
+------------------------+-----------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Password | char(41) | NO | | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
| Create_tablespace_priv | enum('N','Y') | NO | | N | |
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | NULL | |
| x509_issuer | blob | NO | | NULL | |
| x509_subject | blob | NO | | NULL | |
| max_questions | int(11) unsigned | NO | | 0 | |
| max_updates | int(11) unsigned | NO | | 0 | |
| max_connections | int(11) unsigned | NO | | 0 | |
| max_user_connections | int(11) unsigned | NO | | 0 | |
| plugin | char(64) | YES | | | |
| authentication_string | text | YES | | NULL | |
| password_expired | enum('N','Y') | NO | | N | |
+------------------------+-----------------------------------+------+-----+---------+-------+
43 rows in set (0.00 sec)
mysql>
Super_priv
pojawia się zaraz po Show_db_priv
.
Wprowadzono uprawnienia na poziomie bazy danych mysql.db
. Tutaj jest to:
mysql> desc mysql.db;
+-----------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| Db | char(64) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
+-----------------------+---------------+------+-----+---------+-------+
22 rows in set (0.00 sec)
mysql>
Zauważ, że Super_priv
nie istnieje w mysql.db
.
Aby wizualizować to w kategoriach czystego SQL, zaloguj się jako użytkownik1 i uruchom SHOW GRANTS;
Dane wyjściowe będą miały dwa wiersze:
GRANT USAGE ON *.* TO user1@'%' ...
GRANT ALL PRIVILEGES ON db1.* TO user1@'%' ...
Możesz spróbować hacka, ale normalnie nie polecałbym go.
KROK 01) Zaloguj się do mysql jako root @ localhost (powinien mieć wszystkie uprawnienia)
KROK 02) Uruchom to zapytanie
UPDATE mysql.user SET Super_Priv='Y' WHERE user='user1' AND host='%';
KROK 03) Uruchom to zapytanie
FLUSH PRIVILEGES;
To teoretycznie powinno działać. Wtedy użytkownik 1 może działać (nie udzielam żadnych gwarancji).
AKTUALIZACJA 19.12.2014, 15:24 EST
Właśnie zapytał Metafaniel
Świetne wyjaśnienie, dzięki. Jeśli jednak nie polecasz w ten sposób rozwiązania problemu, to jaki inny sposób jest najlepszy, aby przyznać użytkownikowi ten Super_priv? Dzięki! - Metafaniel
Ponieważ użytkownik z dostępem tylko do DB nie może mieć SUPER , jedyne, co można zrobić, to ręcznie zmienić DEFINER w zrzutu. Podstawowym pomysłem byłoby mysqldump samych procedur do pliku tekstowego. Następnie edytuj definicję do user1@'%'
. Następnie powinieneś być w stanie przeładować.
To samo dla widoków
Miałem dokładnie ten sam problem. To co zrobiłem to:
I problem rozwiązany.
PRZESTROGA: Czy istnieje jakieś zagrożenie w przyznawaniu uprawnień SUPER użytkownikowi?
źródło
Zaloguj się z użytkownikiem root, wybierz bazę danych i uruchom następujące zapytanie SQL
SET @ @ global.sql_mode = 'NO_ENGINE_SUBSTITUTION'
źródło