the way to set grant option is given by role - postgresql

I am using a postgresql.
My goal is that grant option should be granted by role
According to Recommendation document said that I have to remove 'public' grantee
When I typed
SELECT grantee, privilege_type
FROM information_schema.role_table_grants
group by grantee, privilege_type;
I got a screenshot what I have done.
To sum up, I want to hide these 2 marked lines. or try not to show up in that query sentence.
what should I do?
p.s I already had used:
revoke update, select on information_schema.role_table_grants from public;
but nothing changed!

Related

How to get PUBLIC role's granted privilege list in postgres?

As the documentation said:
PUBLIC can be thought of as an implicitly defined group that always includes all roles. Any particular role will have the sum of privileges granted directly to it, privileges granted to any role it is presently a member of, and privileges granted to PUBLIC.
We can grant privileges for PUBLIC like this:
GRANT SELECT ON table_1 TO PUBLIC;
GRANT USAGE ON SCHEMA schema_1 TO PUBLIC;
GRANT EXECUTE ON FUNCTION func_1 TO PUBLIC;
If I want to revoke such public privileges, I should know the granted privilege list first. But I can't find a good way to get the list because PUBLIC is not a role, thus many builtin functions like has_table_privilege cannot be used.
Now I have found some tables in information_schema may help, but there are still some attributes like SCHEMA I cannot find a list for them.
How to get the PUBLIC's granted SCHEMA privilege list? Or is there a better way to get all the privileges?
-- get granted table and view privileges
SELECT table_schema, table_name, string_agg(privilege_type, ',') AS privileges
FROM information_schema.table_privileges
WHERE grantee='PUBLIC' AND table_schema NOT LIKE 'pg_%' AND table_schema != 'information_schema'
GROUP BY table_schema, table_name;
-- get granted function privileges
SELECT routine_schema, routine_name, string_agg(privilege_type, ',') AS privileges
FROM information_schema.routine_privileges
WHERE grantee='PUBLIC' AND routine_schema NOT LIKE 'pg_%' AND routine_schema != 'information_schema'
GROUP BY routine_schema, routine_name;
Privileges for a table are stored in pg_class.relacl which is an array of aclitem.
The content of such an aclitem is documented in the manual, specifically:
An empty grantee field in an aclitem stands for PUBLIC.
So to find all tables (or other objects) that have something granted to the public role, one needs to find entries where at least one aclitem starts with = ("empty grantee field")
There is a contains operator #> for aclitems that can be used to check for specific privileges. But
I couldn't find a way to specify an aclitem value that would search match all privileges granted to public (relacl #> '=*' doesn't seem to work in all cases).
So a workaround might be to simply convert the items to text and use a LIKE condition:
select c.relnamespace::regnamespace::text as table_schema,
c.relname as table_name,
c.relacl
from pg_class c
where relnamespace not in ('pg_catalog'::regnamespace, 'information_schema'::regnamespace)
and exists (select *
from unnest(c.relacl) as x(acl)
where x.acl::text like '=%')

how to view UDF grants in redshift

Team,
could you help me to get the sql query to find out below :
1) I grant "USAGE ON LANGUAGE PLPYTHONU" to TESTUSER1 on database TESTDB1. How to find out whether this user has this permission granted in that specific DB testdb1 ?
testdb1=>grant USAGE ON LANGUAGE PLPYTHONPU to testuser1;
2) I grant execute permission on one function to TESTUSER1. how to find whether this user has this permission granted in that specific db testdb1 ?
testdb1=> grant execute on function schema1.fun1(float,float) to testuser1;
GRANT
Thanks
1) How to check the permissions for USAGE ON LANGUAGE PLPYTHONU
select lanname,lanacl from pg_language where lanname = 'plpythonu';
lanacl contains the user name if the permission is given.
ex)
dev=# select lanname,lanacl from pg_language where lanname = 'plpythonu';
lanname | lanacl
-----------+----------------------------------------------
plpythonu | {rdsdb=U/rdsdb,my_test_user=U/rdsdb}
(1 row)
2) How to check the permissions for EXECUTE ON FUNCTION
SELECT proname,proacl FROM pg_proc WHERE proname='<function-name>'
proacl contains the user name if the permission is given.
ex)
dev=# SELECT proname,proacl FROM pg_proc WHERE proname='f_greater';
proname | proacl
-----------+---------------------------------------------------------------------------------------
f_greater | {=X/admin,admin=X/admin,my_test_user=X/admin}
(1 row)
Unfortunately, it looks like there is no convenient default macro to get those kind of info nicely. Since there is no notion of databases for LANGUAGE or UDF, you don't need to specify the database name in those queries.

Check Postgres access for a user

I have looked into the documentation for GRANT Found here and I was trying to see if there is a built-in function that can let me look at what level of accessibility I have in databases. Of course there is:
\dp and \dp mytablename
But this does not show what my account has access to. I would like to see ALL the tables I have access to. Can anyone tell me if there is a command that can check my level of access in Postgres (whether I have SELECT, INSERT, DELETE, UPDATE privileges)? And if so, what would that command be?
You could query the table_privileges table in the information schema:
SELECT table_catalog, table_schema, table_name, privilege_type
FROM information_schema.table_privileges
WHERE grantee = 'MY_USER'
For all users on a specific database, do the following:
# psql
\c your_database
select grantee, table_catalog, privilege_type, table_schema, table_name from information_schema.table_privileges order by grantee, table_schema, table_name;
Use this to list Grantee too and remove (PG_monitor and Public) for Postgres PaaS Azure.
SELECT grantee,table_catalog, table_schema, table_name, privilege_type
FROM information_schema.table_privileges
WHERE grantee not in ('pg_monitor','PUBLIC');

how to create duplicate role of a user in postgres

I need a new user but it should be granted all those privileges that the other existing user/role has.
e.g.
User A has SELECT privileges on Table1
User A has EXECUTE privileges on Table2
...
If a new User B is created, I need the same privileges as,
User B has SELECT privileges on Table1
User B has EXECUTE privileges on Table2
...
Dont ask why :/
Actually User A has custom privileges on different tables, schemas, and functions; so its very tedious and lengthy process to manually grant permissions to the new user. Any help would be good.
Try something like:
GRANT A TO B;
It will grant all right of role A to B.
For details read this chapter of the manual.
First understand that roles and users are the same thing. In fact there isn't a thing called a user really, it's just a ROLE with a LOGIN option.
Second roles can be granted to other roles.
Third priviledges on roles can be inherited.
So assuming you have created your user a like:
CREATE ROLE A LOGIN;
GRANT SELECT ON table1 TO a;
GRANT EXECUTE ON FUNCTION xxx TO a;
You should be able to create a second role that mirrors the first role like:
CREATE ROLE b LOGIN;
GRANT a TO b;
I had to write the pgpsql code to loop through the privileges of User A and grant it to User B. It was done without any problem.
create or replace function update_user_privileges() returns text as
$$
declare
info record;
str text;
begin
/*Grant privileges to user B the same as with user A for a given table schema*/
str:='';
FOR info IN
select * from information_schema.table_privileges where table_schema='public' and grantee = 'A'
LOOP
/*append the tables' name, for which we are assigning privileges from user A to B*/
str:= str ||info.table_name || ',';
/*this is the main statement to grant any privilege*/
execute 'GRANT '|| info.privilege_type ||' on table public.'|| info.table_name || ' to B';
END LOOP;
return str;
end
$$ language 'plpgsql';
Usage: Copy/paste this code to crate this function and then do
select update_user_privileges();
**You have to adapt it for your table-schema and table-names. Hope it helps anyone
Here's a quick way to create grant statements for newuser, by copying all grants on db mydb to grantee myuser.
pg_dump mydb -s | egrep '^(GRANT|REVOKE).+TO "myuser"' | sed -E "s/\"myuser\"/\"newuser\"/g"
Note: The -s flag makes pg_dump execute quickly, because it's only dumping schema info.
Example output
GRANT SELECT,INSERT,UPDATE ON TABLE tabl1e TO "newuser";
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE table2 TO "newuser";
GRANT ALL ON PROCEDURE myprocedure(ids bigint[]) TO "newuser";
Simply run the output SQL grants or pipe them to psql and you're all set.
I used following method to create a new user same as an existing user using Ubuntu.
Get a full dump of existing database.
Use the following command to extract every line with the user you want to clone.
cat /path/to/db_dump_file | grep "existing_user_name" >> /path/to/extract.sql
Open extract.sql with a text editor and replace existing username with new username.
Remove unwanted queries (if any).
Now you have new SQL queries to create the new user.
This worked for me just fine. Hope this will help someone.

How to revoke all group roles from login role

How to revoke all group roles from login role? Is there a way how to do this automatically?
Since you can GRANT / REVOKE several roles at once, a single DO command with dynamic SQL would be simpler / faster (set-based operations are regularly faster in RDBMS than looping):
DO
$do$
DECLARE
_role regrole := 'my_role'; -- provide valid role name here
_memberships text := (
SELECT string_agg(m.roleid::regrole::text, ', ')
FROM pg_auth_members m
WHERE m.member = _role
);
BEGIN
IF _memberships IS NULL THEN
RAISE NOTICE 'No group memberships found for role %.', _role;
ELSE
RAISE NOTICE '%',
-- EXECUTE
format('REVOKE %s FROM %s', _memberships, _role);
END IF;
END
$do$;
The code is in debug mode. Comment RAISE NOTICE '%', and un-comment EXECUTE to prime the bomb.
DO and string_agg() require Postgres 9.0 or later.
The object identifier type regrole was added with Postgres 9.5
Casting to regrole verifies role names on input and double-quotes where necessary when outputting text - so no SQL-injection possible.
Effectively executes a command like:
REVOKE role_a, role_b FROM my_user;
Doesn't break with maliciously formed role names:
REVOKE role_a, role_b, "FROM postgres; DELETE * FROM usr; --" FROM my_user;
Note the double quotes around the trick-name.
Raises a notice if no role memberships are found.
This revokes all memberships in other roles. It's all just roles to Postgres, some have the LOGIN privilege ("user roles"), others don't ("group roles").
Think need to query all the roles
select usename, rolname
from pg_user
join pg_auth_members on (pg_user.usesysid=pg_auth_members.member)
join pg_roles on (pg_roles.oid=pg_auth_members.roleid)
and LOOP through the result to REVOKE rolname FROM usename;