PostgreSQL
La base de données la plus sophistiquée au monde.

Ouverture de session

Navigation

Contactez-nous

Administration du site :
"equipe chez postgresqlfr point org"

Contact presse :
"fr chez postgresql point org"

Contact association :
"bureau chez postgresqlfr point org"

Questions PostgreSQL :
 IRC :
  serveur irc.freenode.net
  canal #postgresqlfr

Recherche

Accéder aux archives

« Octobre 2008  
Lun Mar Mer Jeu Ven Sam Dim
  2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31  

Syndication

Flux XML

Sondage

Quelle est la version de PostgreSQL la plus répandue sur vos serveurs ?
8.3
10%
8.2
42%
8.1
40%
8.0
2%
7.4
6%
7.3 ou antérieure
0%
Nombre de votes: 48

PostgreSQL 8.3.1 REVOKE, SET ROLE, BUG?

Technique - général | PostgreSQL 8.3.1 REVOKE, SET ROLE, BUG?

Par MonnierEric le 26/05/2008 - 14:50

Bonjour,

J'utilise PostgreSQL 8.3.1 sur Windows XP

Je dois supprimer une liste d’utilisateurs.

Contexte :
- Un utilisateur peut avoir accordé des droits à d'autres utilisateurs sur ses propres objets.
- Un utilisateur peut avoir accordé un droit de transmission (GRANT OPTION).
- Ce phénomène est réaliste car il s'agit de bases de données utilisées à des fins pédagogiques.

Avant d'écrire le script ad hoc, j'ai fait quelques tests pour m'assurer que la suppression des droits accordés était possible :
- C'est le super utilisateur postgres qui retire les droits accordés avant la suppression des objets.
- Lorsqu'un droit a été transmis indirectement via la clause GRANT OPTION, postgres n'arrive pas à le retirer.
Le message semble indiquer que la commande a été correctement exécutée mais en réalité le droit n'est pas retiré. POURQUOI?

Pourtant, la documentation précise : " Si un superutilisateur choisit d'exécuter une commande GRANT ou REVOKE, la commande est exécutée comme si elle était lancée par le propriétaire de l'objet affecté"

Donc, il me semble que la suppression par postgres, d'un droit transmis indirectement devrait être possible.

La méthode consistant à exécuter préalablement un SET ROLE fonctionne mais n'est pas idéale dans le contexte de mon développement.

Pouvez-vous me dire pourquoi le super utilisateur postgres ne peut pas retirer tous les types de droits accordés, quel que soit le moyen utilisé (ex. clause WITH GRANT OPTION) ?

Par avance, merci de votre réponse.

Eric Monnier

Un exemple valant mille mots :

--------------- Postgres ---------------

CREATE ROLE "UserA" LOGIN
PASSWORD 'UserA'
NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE;

CREATE ROLE "UserB" LOGIN
PASSWORD 'UserB'
NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE;

CREATE ROLE "UserC" LOGIN
PASSWORD 'UserC'
NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE;

CREATE SCHEMA "UserA"
AUTHORIZATION "UserA";

CREATE SCHEMA "UserB"
AUTHORIZATION "UserB";

CREATE SCHEMA "UserC"
AUTHORIZATION "UserC";

--------------- UserA ---------------

CREATE TABLE "UserA"."tableUserA"
(
"Numero" integer,
"Nom" character varying,
"Prenom" character varying,
CONSTRAINT "Pk_tableUserA" PRIMARY KEY ("Numero")
);

GRANT USAGE ON SCHEMA "UserA" TO "UserB";
GRANT USAGE ON SCHEMA "UserA" TO "UserC";
GRANT ALL ON TABLE "UserA"."tableUserA" TO "UserB" WITH GRANT OPTION;

--------------- UserB ---------------

GRANT ALL ON TABLE "UserA"."tableUserA" TO "UserC" WITH GRANT OPTION;

--------------- Super Utilisateur postgres ---------------

-- extrait de pg_class avant le REVOKE

relname | relacl
-----------+-----------------------------------------------------------------------
tableUserA | {UserA=arwdxt/UserA,UserB=a*r*w*d*x*t*/UserA,UserC=a*r*w*d*x*t*/UserB}

REVOKE ALL ON TABLE "UserA"."tableUserA" FROM "UserC";
Query returned successfully with no result in 31 ms.

extrait de pg_class après le REVOKE

relname | relacl
-----------+-----------------------------------------------------------------------
tableUserA | {UserA=arwdxt/UserA,UserB=a*r*w*d*x*t*/UserA,UserC=a*r*w*d*x*t*/UserB}
-- aucun droit n’a été supprimer.

Options d'affichage des commentaires

Sélectionnez la méthode d'affichage des commentaires que vous préférez, puis cliquez sur "Sauvegarder les paramètres" pour activer vos changements.

Un peu tricky... doc pas claire.

Jean-Paul Argudo/ = 27 Mai, 2008 - 14:53

Bonjour,

Tout d'abord, je vous remercie chaleureusement pour la qualité de votre question. J'essaierai d'être à la hauteur pour la réponse.

Tout simplement, si nous avions plus souvent des questions de cette qualité, commentées, avec un exemple, où on sent que la personne a fait un réel travail de recherche en amont, nous aurions bien plus d'efficacité, et peut-être 80% des questions... n'existeraient pas :)

Pour vous répondre globalement, la documentation n'est pas vraiment précise sur ce point particulier.

Le superuser ("postgres" le plus souvent) peut effectivement se faire passer pour le PROPRIÉTAIRE de la table (UserA dans votre exemple), et agir comme le propriétaire le ferait.

En revanche, quand c'est UserB qui donne les droits à UserC, ce n'est pas UserA qui le fait, donc dans l'ACL on voit que les droits de UserC lui ont été donnés par UserB (chaîne "UserC=a*r*w*d*x*t*/UserB").

Ainsi, le superuser peut se faire passer pour UserA... mais PAS UserB!

Si vous voulez supprimer les droits de UserB donnés par UserA, tout en étant connecté superuser c'est possible:

$ psql -U postgres test

test=# REVOKE ALL ON TABLE "UserA"."tableUserA" FROM "UserB";
ERREUR: des privilèges dépendants existent
HINT: Utilisez CASCADE pour les révoquer aussi.

test=# REVOKE ALL ON TABLE "UserA"."tableUserA" FROM "UserB" cascade;
REVOKE

test=# select rolname as Owner,relacl as ACL from pg_class,pg_roles where relname='tableUserA' and pg_class.relowner = pg_roles.oid;
owner | acl
-------+----------------------
UserA | {UserA=arwdxt/UserA}
(1 ligne)

La suppression en cascade est OBLIGATOIRE puisque UserB avait donné des droits à UserC... Et POSSIBLE parceque les droits de UserB avaient été donnés par UserA, et que le superuser "postgres" ne peut se faire passer QUE pour le propriétaire de la table, soit UserA.

Une solution dans votre cas et de gérer les droits de la table uniquement par UserA, ou alors de faire supprimer les droits par UserB...

En espérant avoir été clair :-/

--
Jean-Paul ARGUDO
http://dalibo.com | http://dalibo.org


Ok merci

MonnierEric/ = 29 Mai, 2008 - 09:05

Bonjours,
je vous remercie beaucoup pour cette réponse. Elle confirme en effet se que je pensai.
je vais continuer à SET ROLE pour mes traitements.
Il est quand même étrange de ne pas pouvoir supprimer les droits (à ce niveau) en étant connecté en super utilisateur.

Monnier


© PostgreSQLFr, tous droits réservés.
Site déclaré à la CNIL sous le numéro 1074678, conformément à la Loi en vigueur.