Gestion des utilisateurs
Au sommaire :
Introduction
Pendant l'année, nous avons créé plusieurs base de données avec le login root.
Mais ce ne sont pas les seules bases de données existant sur votre serveur MySQL. Connectez-vous avec l'utilisateur "root" (sinon certaines bases de données vous seront cachées) et exécutez la requête suivante sous l'onglet :
SHOW DATABASES;
Database |
information_schema |
… |
mysql |
performance_schema |
Nos bases sont bien là, en compagnie de quelques autres :
Les utilisateurs et leurs privilèges
Privilèges des utilisateurs
Lorsque l'on
se connecte à MySQL, on le fait avec un utilisateur. Chaque
utilisateur possède une série de privilèges relatifs aux données
stockées sur le serveur : le privilège de sélectionner les données,
de les modifier, de créer des objets, etc.
Ces privilèges peuvent exister à plusieurs niveaux : base de
données, tables, colonnes, procédures, etc.
Par exemple, on peut créer un utilisateur et lui donner des privilèges avec les commandes suivantes :
CREATE USER 'debase'@'localhost' identified by 'secret'
GRANT ALL PRIVILEGES ON cafe.* TO 'student'@'localhost';
Cette requête a donné tous les droits sur la base de données cafe à l'utilisateur debase@'localhost'.
Stockage des utilisateurs et privilèges
Toutes ces
informations sont stockées dans la base de données
mysql.
Les utilisateurs sont stockés dans la table user, avec leurs
privilèges globaux (c'est-à-dire valables au niveau du serveur, sur
toutes les bases de données). La base mysql possède par
ailleurs quatre tables permettant de stocker les privilèges des
utilisateurs à différents niveaux.
Modifications
Il est tout à fait possible d'ajouter, de modifier et de supprimer des utilisateurs en utilisant des requêtes INSERT, UPDATE ou DELETE directement sur la table mysql.user. De même pour leurs privilèges, avec les tables mysql.db, mysql.tables_priv, mysql.columns_priv et mysql.procs_priv.
Cependant, en général, on utilise plutôt des commandes dédiées à cet usage. Ainsi, pas besoin de se soucier de la structure de ces tables, et le risque d'erreur est moins grand. Ce sont ces commandes que nous allons décortiquer dans la suite de ce chapitre.
Tout comme on peut préciser la table à laquelle appartient une colonne en préfixant le nom de la colonne par le nom de la table, nom_table.nom_colonne, il est possible de préciser à quelle base de données appartient une table, nom_bdd.nom_table, voire de préciser à la fois la table et la base de données dans laquelle se trouve une colonne : nom_bdd.nom_table.nom_colonne.
Création, modification et suppression des utilisateurs
Syntaxe pour la création et la suppression
Voici les requêtes à utiliser pour créer et supprimer un utilisateur :
-- Création
CREATE USER 'login'@'hote' [IDENTIFIED BY 'mot_de_passe'];
-- Suppression
DROP USER 'login'@'hote';
Utilisateur
L'utilisateur est donc défini par deux éléments :
Login
Le login est un simple identifiant. Vous pouvez le choisir comme vous voulez. Il n'est pas obligatoire de l'entourer de quotes, sauf s'il contient des caractères spéciaux comme -ou @. C'est cependant conseillé.
Hôte
L'hôte est l'adresse à partir de laquelle l'utilisateur va se connecter. Si l'utilisateur se connecte à partir de la machine sur laquelle le serveur MySQL se trouve, on peut utiliser 'localhost'. Sinon, on utilise en général une adresse IP ou un nom de domaine.
Exemples
CREATE USER 'max'@'localhost' IDENTIFIED BY 'maxisthebest';
CREATE USER 'elodie'@'194.28.12.4' IDENTIFIED BY 'toto1';
CREATE USER 'gabriel'@'arb.brab.net' IDENTIFIED BY 'jenesaispas';
Il est également possible de permettre à un utilisateur de se connecter à partir de plusieurs hôtes différents (sans devoir créer un utilisateur par hôte) : en utilisant le joker %, on peut préciser des noms d'hôtes partiels ou permettre à l'utilisateur de se connecter à partir de n'importe quel hôte.
Exemples
-- thibault peut se connecter à partir de n'importe quel hôte dont l'adresse IP commence par 194.28.12.
CREATE USER 'thibault'@'194.28.12.%' IDENTIFIED BY 'basketball8';
-- joelle peut se connecter à partir de n'importe quel hôte du domaine brab.net
CREATE USER 'joelle'@'%.brab.net' IDENTIFIED BY 'singingisfun';
-- anna peut se connecter à partir de n'importe quel hôte
CREATE USER 'anna'@'%' IDENTIFIED BY 'anna21';
Comme pour le login, les quotes ne sont pas obligatoires, sauf si un caractère spécial est utilisé (comme le joker %, par exemple). Notez que, si vous ne précisez pas d'hôte, c'est comme si vous autorisiez tous les hôtes. 'hannah'@'%' est donc équivalent à 'hannah'.
Les quotes se placent indépendamment autour du login et autour de l'hôte. N'entourez pas tout par des quotes : CREATE USER 'marie@localhost' créera un utilisateur dont le login est 'marie@localhost', autorisé à se connecter à partir de n'importe quel hôte.
Renommer l'utilisateur
Pour modifier l'identifiant d'un utilisateur (login et/ou hôte), on peut utiliser RENAME USER ancien_utilisateur TO nouvel_utilisateur.
Exemple :on renomme max en maxime, en gardant le même hôte.
RENAME USER 'max'@'localhost' TO 'maxime'@'localhost';
Mot de passe
Le mot de passe de l'utilisateur est donné par la clause IDENTIFIED BY. Cette clause n'est pas obligatoire, auquel cas l'utilisateur peut se connecter sans donner de mot de passe. Ce n'est évidemment pas une bonne idée du point de vue de la sécurité. Évitez au maximum les utilisateurs sans mot de passe.
Lorsqu'un mot de passe est précisé, il n'est pas stocké tel quel dans la table mysql.user. Il est d'abord hashé, et c'est cette valeur hashée qui est stockée.
Modifier le mot de passe
Pour
modifier le mot de passe d'un utilisateur, on peut utiliser la
commande SET
PASSWORD (à
condition d'avoir les privilèges nécessaires, ou d'être connecté
avec l'utilisateur dont on veut changer le mot de passe).
Cependant, cette commande ne hashe pas le mot de passe
automatiquement. Il faut donc utiliser la
fonction PASSWORD().
Exemple
SET PASSWORD FOR 'thibault'@'194.28.12.%' = PASSWORD('basket8');
Supprimer un utilisateur
DROP USER thibault;
Il faut bien évidemment avoir les droits pour supprimer un utilisateur. Le faire sous root.
Les privilèges - introduction
Lorsque l'on
crée un utilisateur avec CREATE
USER, celui-ci
n'a au départ aucun privilège, aucun droit.
En SQL, avoir un privilège, c'est avoir l'autorisation d'effectuer
une action sur un objet.
Un utilisateur sans aucun privilège ne peut rien faire d'autre que se connecter. Il n'aura pas accès aux données, ne pourra créer aucun objet (base/table/procédure/autre) ni en utiliser.
Les différents privilèges
Il existe de nombreux privilèges dont voici une sélection des plus utilisés (à l'exception des privilèges particuliers ALL, USAGE et GRANT OPTION que nous verrons plus loin).
Privilèges du CRUD
Les privilèges SELECT, INSERT, UPDATE et DELETE permettent aux utilisateurs d'utiliser ces mêmes commandes.
Privilèges concernant les tables, les vues et les bases de données
Privilège |
Action autorisée |
CREATE TABLE |
Création de tables |
CREATE TEMPORARY TABLE |
Création de tables temporaires |
CREATE VIEW |
Création de vues (il faut également avoir le privilège SELECTsur les colonnes sélectionnées par la vue) |
ALTER |
Modification de tables (avec ALTER TABLE) |
DROP |
Suppression de tables, vues et bases de données |
Autres privilèges
Privilège |
Action autorisée |
CREATE ROUTINE |
Création de procédures stockées (et de fonctions stockées - non couvertes dans ce cours) |
ALTER ROUTINE |
Modification et suppression de procédures stockées (et de fonctions stockées) |
EXECUTE |
Exécution de procédures stockées (et de fonctions stockées) |
INDEX |
Création et suppression d'index |
TRIGGER |
Création et suppression de triggers |
LOCK TABLES |
Verrouillage de tables (sur lesquelles on a le privilège SELECT) |
CREATE USER |
Gestion d'utilisateur (commandes CREATE USER, DROP USER, RENAME USER et SET PASSWORD) |
Les différents niveaux d'application des privilèges
Lorsque l'on accorde un privilège à un utilisateur, il faut également préciser à quoi s'applique ce privilège.
Niveau |
Application du privilège |
*.* |
Privilège global : s'applique à toutes les bases de données, à tous les objets. Un privilège de ce niveau sera stocké dans la table mysql.user. |
* |
Si aucune base de données n'a été préalablement sélectionnée (avec USE nom_bdd), c'est l'équivalent de *.* (privilège stocké dans mysql.user). Sinon, le privilège s'appliquera à tous les objets de la base de données que l'on utilise (et sera stocké dans la table mysql.db). |
nom_bdd.* |
Privilège de base de données : s'applique à tous les objets de la base nom_bdd (stocké dans mysql.db). |
nom_bdd.nom_table |
Privilège de table (stocké dans mysql.tables_priv). |
nom_table |
Privilège de table : s'applique à la table nom_table de la base de données dans laquelle on se trouve, sélectionnée au préalable avec USE nom_bdd (stocké dans mysql.tables_priv). |
nom_bdd.nom_routine |
S'applique à la procédure (ou fonction) stockée nom_bdd.nom_routine (privilège stocké dans mysql.procs_priv). |
Les privilèges peuvent aussi être restreints à certaines colonnes, auquel cas ils seront stockés dans la table mysql.columns_priv. Nous verrons comment restreindre un privilège à certaines colonnes avec la commande GRANT.
Ajout et révocation de privilèges
Ajout de privilèges
Pour pouvoir ajouter un privilège à un utilisateur, il faut posséder le privilège GRANT OPTION. Pour l'instant, seul l'utilisateur "root" le possède. Étant donné qu'il s'agit d'un privilège un peu particulier, nous n'en parlerons pas tout de suite. Connectez-vous donc avec "root" pour exécuter les commandes de cette partie.
Syntaxe
La commande pour ajouter des privilèges à un utilisateur est la suivante :
GRANT privilege [(liste_colonnes)] [, privilege [(liste_colonnes)], ...]
ON [type_objet] niveau_privilege
TO utilisateur [IDENTIFIED BY mot_de_passe];
· privilege : le privilège à accorder à l'utilisateur (SELECT, CREATE VIEW, EXECUTE…) ;
· (liste_colonnes) : facultatif - liste des colonnes auxquelles le privilège s'applique ;
· niveau_privilege : niveau auquel le privilège s'applique (*.*, nom_bdd.nom_table…) ;
· type_objet : en cas de noms ambigus, il est possible de préciser à quoi se rapporte le niveau, TABLE ou PROCEDURE.
On peut accorder plusieurs privilèges en une fois : il suffit de séparer les privilèges par une virgule. Si l'on veut restreindre tout ou partie des privilèges à certaines colonnes, la liste doit en être précisée pour chaque privilège.
Exemples
1. On crée un utilisateur 'john'@'localhost', en lui donnant les privilèges SELECT, INSERT et DELETE sur la table cafe.serveur, et UPDATE sur les colonnes rueserv, cpserv, villeserv de la table cafe.serveur.
CREATE USER 'john'@'localhost' IDENTIFIED BY 'exemple2021';
GRANT SELECT,
UPDATE (rueserv, cpserv, villeserv),
DELETE,
INSERT
ON cafe.serveur
TO 'john'@'localhost';
2. On accorde le privilège SELECT à l'utilisateur 'john'@'localhost' sur la table cafe.facture.
GRANT SELECT
ON TABLE cafe.facture -- On précise que c'est une table (facultatif)
TO 'john'@'localhost';
3. On accorde à 'john'@'localhost' le privilège de créer et d'exécuter des procédures stockées dans la base de données cafe.
GRANT CREATE ROUTINE, EXECUTE
ON cafe.*
TO 'john'@'localhost';
Révocation de privilèges
Pour retirer un ou plusieurs privilèges à un utilisateur, on utilise la commande REVOKE.
REVOKE privilege [, privilege, ...]
ON niveau_privilege
FROM utilisateur;
Exemple
REVOKE DELETE
ON cafe.serveur
FROM 'john'@'localhost';
Privilèges particuliers
Les privilèges ALL, USAGE et GRANT OPTION
Pour terminer avec les différents privilèges, nous allons parler de trois privilèges un peu particuliers.
ALL
Le privilège ALL (ou ALL PRIVILEGES), comme son nom l'indique, représente tous les privilèges. Accorder le privilège ALL revient donc à accorder tous les droits à l'utilisateur. Il faut évidemment préciser le niveau auquel tous les droits sont accordés (on octroie tous les privilèges possibles sur une table, ou sur une base de données, etc.).
Un privilège fait exception : GRANT OPTION n'est pas compris dans les privilèges représentés par ALL.
Exemple :on accorde tous les droits sur la table conso à 'john'@'localhost'.
GRANT ALL
ON cafe.conso
TO 'john'@'localhost';
USAGE
À l'inverse de ALL, le privilège USAGE signifie "aucun privilège". L'utilisateur pourra juste se connecter à mysql.
GRANT OPTION
Nous voici
donc au fameux privilège GRANT
OPTION. Un
utilisateur ayant ce privilège est autorisé à utiliser la
commande GRANT,
pour accorder des privilèges à d'autres utilisateurs.
Ce privilège n'est pas compris dans le
privilège ALL. Par
ailleurs, un utilisateur ne peut accorder que les privilèges qu'il
possède lui-même.
On peut accorder GRANT OPTION de deux manières :
· comme un privilège normal, après le mot GRANT ;
Exemple : on accorde les privilèges SELECT, UPDATE, INSERT, DELETE et GRANT OPTION sur la base de données cafe à 'joseph'@'localhost'.
GRANT SELECT, UPDATE, INSERT, DELETE, GRANT OPTION
ON cafe.*
TO 'joseph'@'localhost' IDENTIFIED BY 'ploc4';
-- OU
GRANT SELECT, UPDATE, INSERT, DELETE
ON cafe.*
TO 'joseph'@'localhost' IDENTIFIED BY 'ploc4'
WITH GRANT OPTION;
Le privilège ALL doit s'utiliser tout seul. Il n'est donc pas possible d'accorder GRANT OPTION et ALL de la manière suivante : GRANT ALL, GRANT OPTION… Il est nécessaire dans ce cas d'utiliser WITH GRANT OPTION.
Particularité des triggers, vues et procédures stockées
Les
triggers, les vues et les procédures stockées (ainsi que les
fonctions stockées, non couvertes par ce cours) ont un système
spécial quant à la vérification des privilèges des
utilisateurs.
En effet, ces objets sont créés dans le but d'être exécutés dans le
futur, et l'utilisateur créant un tel objet pourrait bien être
différent de l'utilisateur se servant de l'objet. Il y a donc deux
types d'utilisateurs potentiels pour ces types d'objet : celui
ayant défini l'objet, et celui utilisant l'objet. Quels privilèges
faut-il vérifier lorsqu'une procédure est exécutée ? Lorsque la
requête SELECT
d'une vue est exécutée ?
Par défaut, ce sont les privilèges du définisseur (celui qui a défini l'objet) qui sont vérifiés. Ce qui veut dire qu'un utilisateur pourrait exécuter une procédure agissant sur des tables sur lesquelles il n'a lui-même aucun privilège, l'important étant les privilèges de l'utilisateur ayant défini la procédure. Bien entendu, un utilisateur doit toujours avoir le privilège EXECUTE pour exécuter une procédure stockée. Les privilèges du définisseur concernent les instructions à l'intérieur de la procédure ou du trigger (ou de la requête SELECT pour une vue).
Exemple :avec l'utilisateur etudiant, on définit une procédure faisant une requête SELECT sur la table conso. On exécute ensuite cette procédure avec l'utilisateur john, qui n'a aucun droit sur la table conso.
Utilisateur etudiant :
USE cafe;
DELIMITER |
CREATE PROCEDURE test_definer()
BEGIN
SELECT * FROM conso;
END |
DELIMITER ;
Utilisateur john :
USE cafe;
SELECT * FROM conso;
CALL test_definer();
L'utilisateur john n'a aucun droit sur conso. La requête SELECT échoue donc avec le message d'erreur suivant :
ERROR 1142 (42000): SELECT command denied to user 'john'@'localhost' for table conso
Par contre, john a le droit d'exécuter les procédures de la base de données cafe. Il exécute donc sans problème test_definer(), qui lui affiche le contenu de conso. Les privilèges vérifiés au niveau des instructions exécutées par la procédure sont en effet ceux de l'utilisateur etudiant ayant défini celle-ci.