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?
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;
La vue
role_usage_grants
Identifie les privilègesUSAGE
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 premierGRANT
ouREVOKE
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: