Redshift permissions pg_class relacl and grantor - amazon-redshift

I am creating a permissions report that includes displaying the grantor.
For table level permission, I am using relacl field from pg_class.
However, some anomalies that are confusing me ....
I have 2 super users : sadmin & suser.
suser initially granted SELECT on a table to a group; the result in pg_class was thus :
{sadmin=arwdRxtD/sadmin,"group mygroup=r/suser"}
sadmin then granted INSERT on the table to the same group.
sadmin then became the 'grantor' in pg_class:
{sadmin=arwdRxtD/sadmin,"group mygroup=ar/sadmin"}
At this stage I thought that I'd confirm to myself that Redshift does not maintain the grantor of each permission, but does log the last acting.
However, something unexpected then happened....
I revoked all the above permissions,
checked this was reflected in relacl,
while logged in as suser, granted select again.
But Pg_class is showing the grantor as sadmin, not the logged in suser !?
{sadmin=arwdRxtD/sadmin,"group mygroup=r/sadmin"}
Double checked by using "Select current_user", and I am logged in as suser.
Can anyone shed light on what's going on please??
Thanks

Related

Postgresql - running subquery doesn't show results for an user

i have this user in the database, this user only needs read permissions, here the permissions that has right now:
GRANT USAGE ON SCHEMA myschema TO "user";
GRANT SELECT ON TABLES TO "user";
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA myschema to "user";
If the runs this query didn't show results, but if I use an admin-user show me results:
SELECT "tableA"."tableA_id", "tableA"."first_name", "tableA"."last_name", "brands"."brand_id" AS "brands.brand_id",
"brands->tableB"."door_id" AS "brands.tableB.door_id", "brands->tableB"."agent_id" AS "brands.tableB.agent_id",
"brands->tableB"."tableA_id" AS "brands.tableB.tableA_id", "brands->tableB"."brand_id" AS "brands.tableB.brand_id",
"brands->tableB"."relationship_type" AS "brands.tableB.relationship_type", "agents"."agent_id" AS "agents.agent_id",
"agents"."relationship_type" AS "agents.relationship_type"
FROM "myschema"."tableA" AS "tableA"
INNER JOIN ( "myschema"."tableB" AS "brands->tableB" INNER JOIN "myschema"."brand" AS "brands" ON "brands"."brand_id" = "brands->tableB"."brand_id") ON "tableA"."tableA_id" = "brands->tableB"."tableA_id" AND "brands"."brand_id" = 1
INNER JOIN "myschema"."tableB" AS "agents" ON "tableA"."tableA_id" = "agents"."tableA_id" AND "agents"."relationship_type" = 'Employee'
WHERE "tableA"."active" = true ORDER BY "tableA"."first_name" ASC;
Any idea which privileges are need it to check this data?
Regards
Missing permissions don't influence the query result, they cause "permission denied" errors. The exceptions I know are
queries on information_schema views, which only show objects on which you have permissions
row-level security
If anything, your question suggests that row-level security is at play here.
If you need a more detailed answer, you have to add details to the question.

How to check if Redshift user can alter table

In Redshift, I am checking Users' grants. How do I know if they can alter tables?
I can know if they can drop tables because "Only the owner of the table, the schema owner, or a superuser can drop a table." - https://docs.aws.amazon.com/redshift/latest/dg/r_DROP_TABLE.html No such qualification exists for alter table: https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html
HAS_TABLE_PRIVILEGE provides info about other privileges, but not alter table: https://docs.aws.amazon.com/redshift/latest/dg/r_HAS_TABLE_PRIVILEGE.html
I got a response from AWS Support. tl;dr: alter table can be run by those, and only those, who can drop table.
"""
This is because, determining whether or not a user can alter a table, works in a similar way to that were one determines whether or not a given user can drop a table. That is, only the owner of the table, the schema owner, or a superuser can Alter a table. According to our documentation, "The right to modify or destroy an object is always the privilege of the owner only." [1].
[1] Default database user privileges - https://docs.aws.amazon.com/redshift/latest/dg/r_Privileges.html
Therefore, to see the users with alter table permissions for a specific table, there is need to determine the owner of that specific table by running the following command:
Kindly note that in this example, the 'sales' table is used. You can edit this as you see fit. To see all the table owners, the AND section of the WHERE clause can be removed.
====Query to see table owners====
SELECT n.nspname AS schema_name
, pg_get_userbyid(c.relowner) AS table_owner
, c.relname AS table_name
, CASE WHEN c.relkind = 'v' THEN 'view' ELSE 'table' END
AS table_type
, d.description AS table_description
FROM pg_class As c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_tablespace t ON t.oid = c.reltablespace
LEFT JOIN pg_description As d
ON (d.objoid = c.oid AND d.objsubid = 0)
WHERE c.relkind IN('r', 'v')
AND c.relname = 'sales'
ORDER BY n.nspname, c.relname;
You can also see all the superusers who have permissions to Alter table by running the following query:
====Query to see superusers====
SELECT usename FROM pg_user WHERE usesuper = 'true';
The combination of both results will enable you to see all the users which have alter table permissions.
"""

Is there an equivalent to Oracle's user_role_privs view in Postgres?

Am trying to fetch information in Postgres equivalent to Oracle's user_role_privs.
select username,granted_role,admin_option from user_role_privs
I tried all the below views in Postgres but couldn't find the desired one
information_schema.role_table_grants
pg_roles;
pg_class;
pg_user
pg_catalog.pg_auth_members;
Can anyone suggest which view should be used to get username, granted_role and admin_option in Postgres?
You are looking for the pg_auth_members system catalog that contains relationships between roles (which feature as both users and groups in PostgreSQL).
To get the names of the users and roles, join with the pg_roles system catalog.

Get the list of users who are using database/schema/table

There is one use case in my project where i want to show the user who has got the access to use that database/schema/table in postgresql. Suppose I have created a database employee. So I want list the users who are accessing this database. Same for schema and tables. I tried this:
SELECT
*
FROM
information_schema.tables
WHERE
table_schema not in ('pg_catalog', 'information_schema') AND
table_schema not like 'pg_toast%'
But it gives information about current user has access to. I want the list of accessing users that are using that database/table/schema/column.
You can use the function has_table_privilege() to achieve what you want.
select has_table_privilege('user_name', 'schema.table', 'select');
More info here.
I suppose you need to be a superuser to get all results. Below shows all the users who have privileges, not necessarily whether they are accessing the tables.
Now you can tweak the query to join all users with list of tables -
SET search_path TO public,
schema1;
SELECT *,
usename,
has_table_privilege(usename, table_schema||'.'||table_name, 'select') as has_privilege
FROM SVV_TABLES
JOIN PG_USER
ON 1=1
WHERE table_schema = 'schema1';

What PostgreSQL query or view can determine who set a users permissions?

I am trying to revoke a database user's permissions and it seems that permissions can only be revoked by the user who granted them. There is thread here discussing the issue.
http://archives.postgresql.org/pgsql-bugs/2007-05/msg00234.php
The thread dates back to 2007 and I am not quite sure whether it is viewed as bug and whether that problem is still present in PostgreSQL 8.4 which I am using.
Is there a query or a view that can display that information? That way I can use set session authorization and revoke it.
PostgreSQL 8.4 is outdated. Check out the versioning policy for details. But since it is the standard behavior of SQL (as Tom Lane states in the linked discussion you provided), it's not likely to have changed.
Privileges are stored in the system catalog with the respective object. For instance, for a table:
SELECT n.nspname, c.relname, c.relacl
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.oid = 'myschema.mytbl'::regclass -- your tablename here
Would produce something like:
nspname | relname | relacl
----------+---------+---------------------------------------------
myschema | mytbl | {postgres=arwdDxt/postgres,fuser=r/fadmin}
The rolename after the slash is the grantor. To revoke, as user fadmin (or any superuser):
REVOKE SELECT ON TABLE myschema.mytbl FROM fuser;
There are similar *acl columns in other system tables. pg_namespace for schemas etc. See the list of system tables in the manual.
A simpler way would be to use pgAdmin and select an object in the object browser to the left. The ACL will be displayed in the properties pane, top right.