I have a user db_owner who is owner to my database called 'Sales'.
Now i have to create two groups(sales_ro and sales_riu) and then i will add users to this groups.
sales_ro group should inherit(from db_owner) read access on tables and execute on functions in Sales db
sales_riu group should inherit(from db_owner) insert and update access on tables and execute on functions in Sales db.
can we create such two groups in Postgres ?
You don't need to create groups to achieve this. You can just create Roles and assign them to the users you want. For example:
CREATE ROLE sales_ro;
CREATE ROLE sales_riu;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO sales_ro;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO sales_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO sales_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT EXECUTE ON FUNCTIONS TO sales_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT,INSERT,UPDATE ON TABLES TO sales_riu;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT EXECUTE ON FUNCTIONS TO sales_riu;
After that just grant role to expected users:
GRANT sales_ro TO your_user_1;
GRANT sales_riu TO your_user_2;
Please refer link 1 and link 2 to know more about ALTER DEFAULT PRIVILEGES and CREATE ROLE respectively.
Quoting below points from above links:
CREATE ROLE adds a new role to a PostgreSQL database cluster. A role
is an entity that can own database objects and have database
privileges; a role can be considered a “user”, a “group”, or both
depending on how it is used.
A role having the LOGIN attribute can be thought of as a user. Roles
without this attribute are useful for managing database privileges
Related
I have an application schema U32_C5 and another schema MIG_SRC which has some tables and then we have a ROLE RO_ROLE on which we have some grants of tables from Schema U32_C5.
The RO_ROLE is assigned to another Schema MRGO_RO which is Read Only.
Here I need to grant select on tables from MIG_SRC to MRGO_RO catch here is that the process which and from where I can include these grants is run from application schema U32_C5 in production so when I tried to to something like below it says table or view does not exists (which seems to be obvious)
execute Grant from U32_C5
grant select on MIG_SRC.MOBILE_CELLPHONE_PAIRINGS to MRGO_RO;
Another way which I think of is creating DB link on MRGO_RO for MIG_SRC Schema but it enables read/write operation as well on MIG_SRC tables which is not allowed on production.
DB Links is present on U32_C5 Schema for MIG_SRC Schema
So looking for a way to accomplish above task without creating DB Link any suggestion is welcome.
Sample Script of requirement what I want to achieve Please Remember I cannot and do not want Login to MIG_SRC and only way I am looking for is to do it by using U32_C5 and without DBA HELP
A RO ROLE Created by DBA's
Create role RO_ROLE;
/* Create application schema, table inside it and grant select on it to RO_ROLE*/
CREATE USER U32_C5 IDENTIFIED BY U32_C5 DEFAULT TABLESPACE;
GRANT ALTER SESSION TO U32_C5;
GRANT CREATE SESSION TO U32_C5;
GRANT CREATE database link TO U32_C5;
GRANT CREATE table TO U32_C5;
create table U32_C5_test_tab (id number);
grant select on U32_c5.U32_C5_Test_tab to RO_ROLE;
/* Create Read Only schema, grant RO_ROLE to it */
CREATE USER mrgo_ro IDENTIFIED BY mrgo_ro DEFAULT TABLESPACE;
GRANT ALTER SESSION TO mrgo_ro;
GRANT CREATE SESSION TO mrgo_ro;
grant ro_role to mrgo_ro;
/* Create SRC schema, table inside it */
CREATE USER MIG_SRC IDENTIFIED BY MIG_SRC DEFAULT TABLESPACE;
GRANT ALTER SESSION TO MIG_SRC;
GRANT CREATE SESSION TO MIG_SRC;
GRANT CREATE database link TO MIG_SRC;
GRANT CREATE table TO MIG_SRC;
create table mig_src_test_tab (id number);
/* login to Apllication Schema U32_C5 */
sqlplus U32_C5/U32_C5#SID
grant select on mig_src.mig_src_test_tab to mrgo_ro; -- for me it gives error here at this step table or does not exist
/* login to Read Only Schema mrgo_ro */
sqlplus mrgo_ro/mrgo_ro#SID
select * from mig_src.mig_src_test_tab;
or
select * from mig_src_test_tab;
If I understood you correctly, then WITH GRANT OPTION is what you're missing.
Once someone (A) grants privileges on their own objects to someone else (B), and that (B) has to "forward" those privileges to (C), then it is the WITH GRANT OPTION that helps.
Documentation says:
Specify WITH GRANT OPTION to enable the grantee to grant the object privileges to other users and roles.
Restriction on Granting WITH GRANT OPTION You can specify WITH GRANT OPTION only when granting to a user or to PUBLIC, not when granting to a role.
It means that you should grant privileges directly, not via role. That fact doesn't have to be a drawback because of named PL/SQL procedures, where privileges acquired via roles won't work anyway, so you might end up in direct grants anyway.
Other option - which you might consider - is related to what you said:
when I tried to to something like below it says table or view does not exists
If you created a synonym for those tables, then you wouldn't get such an error.
Database link isn't an option, as you said - by using it, you have full access (as you have to know username/password to create the DB link, and that isn't really read only access).
Currently I am using this to grant permissions:
grant select on all tables in schema public to <user_name>;
alter default privileges in schema public grant select on tables to <user_name>;
According to the documentation, the second statement should have resolved the problem. It does not however auto grant permissions to user_name when a new table is added to the public schema.
I am using this user (user_name) to copy data over to another database.
Found the answer. It is in this line in the ALTER DEFAULT PRIVILEGES documentation.
You can change default privileges only for objects that will be created by yourself or by roles that you are a member of.
I was using alter default privileges from a different user than the one creating the tables.
Make sure to set the role to the user creating the table before the alter default privilege statement:
SET ROLE <user_that_creates_new_tables>;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO <user_name>;
To grant default privileges, you need to grant to the user you are creating the table with.
You are creating the tables as SA_user, but reading the tables as READ_user. Your code needs to look like:
ALTER DEFAULT PRIVILEGES
FOR USER SA_user
IN SCHEMA schema_name
GRANT SELECT ON TABLES TO READ_user;
So whenever the SA_user creates a table, it will grant select rights for the READ_user.
I was looking for same thing, I found other way to solve this. Based on postgresql documentation we can create event trigger, so when new table is created, grant query will execute automatically. So no matter who created new table, other user allowed to use it.
CREATE OR REPLACE FUNCTION auto_grant_func()
RETURNS event_trigger AS $$
BEGIN
grant all on all tables in schema public to <username>;
grant all on all sequences in schema public to <username>;
grant select on all tables in schema public to <username>;
grant select on all sequences in schema public to <username>;
END;
$$ LANGUAGE plpgsql;
CREATE EVENT TRIGGER auto_grant_trigger
ON ddl_command_end
WHEN TAG IN ('CREATE TABLE', 'CREATE TABLE AS')
EXECUTE PROCEDURE auto_grant_func();
I can create a role in postgresql.
CREATE ROLE myname WITH LOGIN PASSWORD 'pass';
and I can set privilages on a database schema for this user.
GRANT USAGE ON SCHEMA public TO myname;
and select privilages to a user.
GRANT SELECT ON ALL TABLES IN SCHEMA public TO myname;
But I have so many users in my database. I do not want to set these privilages to all of my users. Actually I want to create role groupnames:
viewer
editor
admin
And
viewer will be select privilages on all tables,
editor will be select, insert and update privilages on all tables.
my users will be in these groups.
How can I do this?
CREATE ROLE viewer;
CREATE ROLE editor;
CREATE ROLE admin;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO viewer;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO viewer;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT,INSERT,UPDATE ON TABLES TO editor;
GRANT some_other_privs_to_admin_group
after that just grant group to user:
GRANT editor TO your_user;
and so on
https://www.postgresql.org/docs/current/static/sql-alterdefaultprivileges.html
https://www.postgresql.org/docs/current/static/sql-createrole.html
CREATE ROLE adds a new role to a PostgreSQL database cluster. A role
is an entity that can own database objects and have database
privileges; a role can be considered a “user”, a “group”, or both
depending on how it is used.
and
A role having the LOGIN attribute can be thought of as a user. Roles
without this attribute are useful for managing database privileges
For this very reason it is advisable to use "groups", that is roles (usually with NOLOGIN) to which you add the users (by granting the role to them).
In your case:
CREATE ROLE viewer;
GRANT <whatever> TO viewer;
GRANT viewer TO myname;
Then myname will enjoy all the privileges granted to viewer, and you don't have to mess around with granting and revoking privileges to every user.
I have been tasked to host HTML & PHP files of a website on one virtual machine and to set up a Postgresql database on another virtual machine.
I recently installed Postgresql and have been using the official Postgresql Documentation to learn how to create databases, create user and grant & revoke rights.
After having created a database named mfc_dst, I was ordered to create 4 differents users and this is where I have a problem :
-The first user has to be named admin and must be the only other user than the pre-existing user named postgres to have unlimited rights.
-The second (named cfc) and third user (named sec) must only have the SELECT and UPDATE privileges on all tables of the mfc_dst database.
-And the fourth/last user (named prof) must only be able to view a table named devoir from the database named mfc_dst.
To accomplish this, I used 2 different scripts :
CREATEandGRANT.sql
REVOKE ALL ON ALL TABLES IN SCHEMA public TO cfc;
REVOKE ALL ON ALL TABLES IN SCHEMA public TO sec;
REVOKE ALL ON ALL TABLES IN SCHEMA public TO prof;
GRANT CONNECT ON DATABASE mfc_dst TO admin;
GRANT CONNECT ON DATABASE mfc_dst TO cfc;
GRANT CONNECT ON DATABASE mfc_dst TO sec;
GRANT CONNECT ON DATABASE mfc_dst TO prof;
GRANT SELECT,UPDATE
ON ALL TABLES IN SCHEMA public
TO cfc;
GRANT SELECT,UPDATE
ON ALL TABLES IN SCHEMA public
TO sec;
GRANT SELECT ON devoir TO prof;
and this other one :
REVOKE.sql
REVOKE ALL ON TABLE professeur FROM PUBLIC;
REVOKE ALL ON TABLE reserver FROM PUBLIC;
REVOKE ALL ON TABLE salle FROM PUBLIC;
REVOKE ALL ON TABLE semaine FROM PUBLIC;
REVOKE ALL ON TABLE surveiller FROM PUBLIC;
Thanks to these 2 scripts, I was able to prevent the user named prof from seeing other tables, but the problem I have is that the users named cfc,sec and prof are still all three able to create tables and to drop them.
Is it possible to know how to prevent them from doing this and if possible, in the future, prevent newly created users from having such rights/privileges ?
Thank you in advance
All Postgres users implicitly are also automatically members of the public role, which grants them all permissions on the public schema. You can remove permissions from the public role with
revoke all on database mfc_dst from public;
revoke all on schema public from public;
Additionally, consider defining a new schema for your data tables, so that you can issue grant statements without having to deal further with the public role. If you do this, you can also set the search path to include your custom schema and to exclude the public schema.
Also, you might want to create a group role for the cfc and sec users and assign permissions to that role, rather than to the users individually. This will make future maintenance easier.
I am running PostgreSQL 9.3.1. I have test database and backup user which is used to backup the database. I have no problems with granting privileges to all current tables, but I have to grant privileges each time the new table is added to schema.
createdb test
psql test
test=# create table foo();
CREATE TABLE
test=# grant all on all tables in schema public to backup;
GRANT
test=# create table bar();
CREATE TABLE
psql -U backup test
test=> select * from foo;
test=> select * from bar;
ERROR: permission denied for relation bar
Is it possible to grant access to tables which will be created in future without making user owner of the table?
It looks like the solution is to alter default privileges for backup user:
alter default privileges in schema public grant all on tables to backup;
alter default privileges in schema public grant all on sequences to backup;
From the comment by Matt Schaffer:
As caveat, the default only applies to the user that executed the
alter statement. This confused me since I was driving most of my
permissions statements from the postgres user but creating tables from
an app user. In short, you might need something like this depending on
your setup:
ALTER DEFAULT PRIVILEGES FOR USER webapp IN SCHEMA public GRANT SELECT ON SEQUENCES TO backup;
ALTER DEFAULT PRIVILEGES FOR USER webapp IN SCHEMA public GRANT SELECT ON TABLES TO backup;
Where webapp is the user that will be creating new tables in the futrue and backup is the user that will be able to read from new tables created by webapp.
If you want the backup user to have access to the future tables of userN,
you must run the code below under each userN who creates new tables,
because ALTER DEFAULT PRIVILEGES...
works only for objects by that user under whom you run ALTER DEFAULT PRIVILEGES...
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO backup;
I am trying to create a role, grant connect access to the role and then alter default privileges to keep access for future objects. However, it seems that the below command doesn't work at role level.
alter default privileges in schema public grant all on tables to backup;
I followed the below documentation but seems that there are two command do not work for roles.
DOC: https://aws.amazon.com/blogs/database/managing-postgresql-users-and-roles/
First command:
GRANT CONNECT ON DATABASE mydatabase TO readonly;
Second command:
GRANT USAGE ON SCHEMA myschema TO readonly;
(For ROLES usually it needs TO ROLE, I also tried TO ROLE but still doesn't work.