Comment interroger toutes les SUBVENTIONS accordées à un objet dans postgres?
Par exemple, j'ai table "mytable":
GRANT SELECT, INSERT ON mytable TO user1
GRANT UPDATE ON mytable TO user2
J'ai besoin de quelque chose qui me donne:
user1: SELECT, INSERT
user2: UPDATE
Je l'ai déjà trouvé:
SELECT grantee, privilege_type
FROM information_schema.role_table_grants
WHERE table_name='mytable'
\z mytable
de psql vous donne toutes les subventions d’une table, mais vous devez ensuite les diviser par utilisateur.
Si vous voulez vraiment une ligne par utilisateur, vous pouvez grouper par bénéficiaire (nécessite PG9 + pour string_agg)
SELECT grantee, string_agg(privilege_type, ', ') AS privileges
FROM information_schema.role_table_grants
WHERE table_name='mytable'
GROUP BY grantee;
Cela devrait produire quelque chose comme:
grantee | privileges
---------+----------------
user1 | INSERT, SELECT
user2 | UPDATE
(2 rows)
Essayez la requête ci-dessous. Il vous donnera la liste de tous les utilisateurs et de leurs autorisations sur la table.
select a.tablename,b.usename,HAS_TABLE_PRIVILEGE(usename,tablename, 'select') as select,
HAS_TABLE_PRIVILEGE(usename,tablename, 'insert') as insert,
HAS_TABLE_PRIVILEGE(usename,tablename, 'update') as update,
HAS_TABLE_PRIVILEGE(usename,tablename, 'delete') as delete,
HAS_TABLE_PRIVILEGE(usename,tablename, 'references') as references from pg_tables a , pg_user b
where a.tablename='your_table_name';
Cette requête répertorie toutes les tables de toutes les bases de données et schémas (décommentez les lignes de la clause WHERE
pour filtrer certaines bases de données, schémas ou tables), avec les privilèges affichés dans l'ordre qu'il est facile de voir si un privilège spécifique est accordé ou non:
SELECT grantee
,table_catalog
,table_schema
,table_name
,string_agg(privilege_type, ', ' ORDER BY privilege_type) AS privileges
FROM information_schema.role_table_grants
WHERE grantee != 'postgres'
-- and table_catalog = 'somedatabase' /* uncomment line to filter database */
-- and table_schema = 'someschema' /* uncomment line to filter schema */
-- and table_name = 'sometable' /* uncomment line to filter table */
GROUP BY 1, 2, 3, 4;
Exemple de sortie:
grantee |table_catalog |table_schema |table_name |privileges |
--------|----------------|--------------|---------------|---------------|
PUBLIC |adventure_works |pg_catalog |pg_sequence |SELECT |
PUBLIC |adventure_works |pg_catalog |pg_sequences |SELECT |
PUBLIC |adventure_works |pg_catalog |pg_settings |SELECT, UPDATE |
...
Ajouter à la réponse de @ shruti
Pour interroger les autorisations de toutes les tables d'un schéma pour un utilisateur donné
select a.tablename,
b.usename,
HAS_TABLE_PRIVILEGE(usename,tablename, 'select') as select,
HAS_TABLE_PRIVILEGE(usename,tablename, 'insert') as insert,
HAS_TABLE_PRIVILEGE(usename,tablename, 'update') as update,
HAS_TABLE_PRIVILEGE(usename,tablename, 'delete') as delete,
HAS_TABLE_PRIVILEGE(usename,tablename, 'references') as references
from pg_tables a,
pg_user b
where schemaname='your_schema_name'
and b.usename='your_user_name'
order by tablename;
Voici un script qui génère des requêtes de subvention pour une table particulière. Il omet les privilèges du propriétaire.
SELECT
format (
'GRANT %s ON TABLE %I.%I TO %I%s;',
string_agg(tg.privilege_type, ', '),
tg.table_schema,
tg.table_name,
tg.grantee,
CASE
WHEN tg.is_grantable = 'YES'
THEN ' WITH GRANT OPTION'
ELSE ''
END
)
FROM information_schema.role_table_grants tg
JOIN pg_tables t ON t.schemaname = tg.table_schema AND t.tablename = tg.table_name
WHERE
tg.table_schema = 'myschema' AND
tg.table_name='mytable' AND
t.tableowner <> tg.grantee
GROUP BY tg.table_schema, tg.table_name, tg.grantee, tg.is_grantable;