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 INSERTUPDATE  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 ALLUSAGE  et GRANT OPTION  que nous verrons plus loin).

Privilèges du CRUD

Les privilèges SELECTINSERTUPDATE  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 USERDROP USERRENAME 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 (SELECTCREATE VIEWEXECUTE…) ;

·      (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 SELECTINSERT  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 SELECTUPDATEINSERTDELETE  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.