web-dev-qa-db-fra.com

GRANT SELECT ON SEQUENCE réussit, mais sans effet?

J'essaie d'accorder un accès sélectif aux séquences d'un utilisateur/rôle à un autre. Il n'y a aucune erreur lorsque j'exécute la commande, mais une fois exécutée, le deuxième rôle ne peut pas afficher les séquences. J'ai exécuté la même commande exacte sur plusieurs autres services/instances de base de données qui ont réussi, ce n'est qu'un mauvais comportement.

J'ai couru les deux:

GRANT SELECT ON ALL SEQUENCES IN SCHEMA schema_name TO new_role;

Selon la recommandation ici:

Et comme je le mentionne ci-dessus, cela a réussi sur d'autres schémas de base de données sur différentes machines. J'ai également essayé individuellement:

GRANT SELECT ON SEQUENCE some_id_sequence TO new_role;

et

GRANT SELECT ON SEQUENCE public.some_id_sequence TO new_role;

Cela n'a également aucun effet. Lorsque vous êtes connecté à partir de new_role Je vois:

select * from information_schema.role_usage_grants ; 
...
(0 rows)

Des résultats similaires (ou leur absence) lors de l'exécution de \ds.

Je peux voir d'après le rôle précédent que la séquence devrait être "accordable" (quoi que cela signifie, je ne trouve aucune documentation à ce sujet)

live@live ~ => select * from information_schema.role_usage_grants limit 1;
┌──────────┬──────────┬────────────────┬───────────────┬──────────────┬─────────────┬────────────────┬──────────────┐
│ grantor  │ grantee  │ object_catalog │ object_schema │  object_name │ object_type │ privilege_type │ is_grantable │
├──────────┼──────────┼────────────────┼───────────────┼──────────────┼─────────────┼────────────────┼──────────────┤
│ old_role │ old_role │ old_role       │ public        │ some_id_seq  │ SEQUENCE    │ USAGE          │ YES          │
└──────────┴──────────┴────────────────┴───────────────┴──────────────┴─────────────┴────────────────┴──────────────┘
(1 row) 

Je ne sais donc pas vraiment où regarder ce point. L'ancien rôle semble avoir la capacité d'accorder la sélection à d'autres rôles et ne génère pas d'erreur lors de la tentative d'exécution de la commande, mais le nouveau rôle n'a toujours pas accès.

Les résultats de \dn+

\dn+
                  List of schemas
┌───────────┬──────────┬────────────────────────┬─────────────┐
│  Name     │ Owner    │ Access privileges      │ Description │
├───────────┼──────────┼────────────────────────┼─────────────┤
│ new_role  │ old_role │ old_role=UC/old_role  ↵│             │
│           │          │ new_role=U/old_role    │             │
│ public    │ old_role │                        │             │
└───────────┴──────────┴────────────────────────┴─────────────┘
(2 rows)

\du+ new_role
                   List of roles
┌───────────┬────────────┬───────────┬─────────────┐
│ Role name │ Attributes │ Member of │ Description │
├───────────┼────────────┼───────────┼─────────────┤
│ new_role  │            │ {}        │             │
└───────────┴────────────┴───────────┴─────────────┘

Les résultats de \dp

\dp some_id_sequence
                                     Access privileges
┌────────┬──────────────────┬──────────┬───────────────────────┬───────────────────┬──────────┐
│ Schema │       Name       │   Type   │ Access privileges     │ Column privileges │ Policies │
├────────┼──────────────────┼──────────┼───────────────────────┼───────────────────┼──────────┤
│ public │ some_id_sequence │ sequence │ old_role=rwU/old_role │                   │          │
│        │                  │          │ new_role=r/old_role   │                   │          │
└────────┴──────────────────┴──────────┴───────────────────────┴───────────────────┴──────────┘

Question: Comment puis-je déterminer ce qui empêche l'application des subventions de séquence?

3
Mitch Kent

Accorder SELECT (ou USAGE) sur la séquence n'est pas suffisant si elle est contenue dans un schéma pour lequel l'utilisateur n'a aucune autorisation. Je crois que c'est le cas parce que votre schéma nommé public n'est pas public. Si c'était le cas, il aurait des autorisations qui ressembleraient à ça:

test=> \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =UC/postgres         | 

par opposition au manque de privilèges d'accès indiqué dans la question. Cela est également cohérent avec le fait que les mêmes commandes fonctionnent dans vous d'autres instances: vraisemblablement le schéma public de ces autres bases de données est l'original, pas une version supprimée/recréée différemment ou avec ses autorisations supprimées.

En tant que solutions possibles, envisagez de faire, en tant que propriétaire du schéma:

 GRANT ALL ON SCHEMA public TO public;

ou le plus limité

 GRANT ALL ON SCHEMA public TO new_role;

ou encore plus limité

 GRANT USAGE ON SCHEMA public TO new_role;
2
Daniel Vérité

Le manuel:

La vue role_usage_grants Identifie les privilèges USAGE accordés sur différents types d'objets où le constituant ou le bénéficiaire est un rôle actuellement activé.

Rien de plus n'apparaîtra après GRANT SELECT .... Essayez plutôt:

GRANT USAGE ON SEQUENCE public.some_id_sequence TO new_role;

.. si c'est bien ce que vous voulez. Le privilège SELECT a une utilisation limitée pour un SEQUENCE, il permet currval() et lastval() .
Typiquement, vous voulez le privilège USAGE qui permet également le crucial nextval() en plus de ce qui précède. Pour travailler avec une colonne serial, par exemple. Voir:

Alors, pourquoi voyez-vous cette ligne déroutante dans votre test après avoir accordé SELECT?

live@live ~ => select * from information_schema.role_usage_grants limit 1;
┌──────────┬──────────┬────────────────┬───────────────┬──────────────┬─────────────┬────────────────┬──────────────┐
│ grantor  │ grantee  │ object_catalog │ object_schema │  object_name │ object_type │ privilege_type │ is_grantable │
├──────────┼──────────┼────────────────┼───────────────┼──────────────┼─────────────┼────────────────┼──────────────┤
│ old_role │ old_role │ old_role       │ public        │ some_id_seq  │ SEQUENCE    │ USAGE          │ YES          │
└──────────┴──────────┴────────────────┴───────────────┴──────────────┴─────────────┴────────────────┴──────────────┘

Le propriétaire d'un objet dispose automatiquement de tous les privilèges. Par conséquent, pg_class.relacl Commence avec les privilèges NULL - signifiant par défaut. Une fois que ce propriétaire accorde des privilèges à un autre rôle, son propre privilège est entré explicitement en plus - apparaissant ainsi également dans les vues du schéma d'informations. Ou, en citant la source :

Si la colonne "Privilèges d'accès" est vide pour un objet donné, cela signifie que l'objet a des privilèges par défaut (c'est-à-dire que sa colonne de privilèges est nulle). Les privilèges par défaut incluent toujours tous les privilèges pour le propriétaire et peuvent inclure certains privilèges pour PUBLIC selon le type d'objet, comme expliqué ci-dessus. Le premier GRANT ou REVOKE sur un objet instanciera les privilèges par défaut (produisant, par exemple, {miriam=arwdDxt/miriam}), Puis les modifiera selon la demande spécifiée.

Généralement, pour déboguer des choses non triviales, je préfère regarder les tables pg_catalog, Qui sont la principale source de vérité. pg_class.relacl dans ce cas particulier:

SELECT relnamespace::regnamespace, relname, relacl
FROM   pg_class
WHERE  relname = 'some_id_sequence';

Ou \z (Abréviation de \dp) Dans psql :

\z some_id_sequence

En supposant que old_role Est le propriétaire, vous devriez voir:

{old_role=rwU/old_role,new_role=r/old_role} - après GRANT SELECT...
{old_role=rwU/old_role,new_role=U/old_role} - après GRANT USAGE ...
{old_role=rwU/old_role,new_role=rU/old_role} - après avoir accordé les deux

Et NULL (vide en psql) avant d'accorder quoi que ce soit.

Votre sortie ajoutée montre que new_role a réellement le privilège SELECT, vous venez de chercher la mauvaise vue. Il semble que new_role manque de privilèges sur le schéma public - qui sont normalement accordés à PUBLIC par défaut.


En plus: les colonnes IDENTITY dans Postgres 11 ou une version ultérieure évitent les tracas. Celles-ci utilisent tout aussi bien les séquences, en interne, mais implicitement détenues par la colonne IDENTITY et avec les privilèges appropriés automatiquement. Ensuite, vous n'avez pas besoin de subventions distinctes pour les séquences. Voir:

2
Erwin Brandstetter