Postgresql user with specific privileges - postgresql

In Postgresql how would I create a user that can do everything expect create roles, drop databases, drop roles, drop tables but it can create a database.
Essentially this user will be used to access a database for an application that stores, updates and retrieves data and the user can create a database.

You create a user and make that user the owner of the database:
The following has to be done as a superuser:
create user arthur password 'verysecret';
create database arthur_db owner = arthur;
Now arthur can do anything in that database.

Related

Create a user who cannot see other bank objects

How do I create a user who does not see any bank object. Only the materialized view that I will release to him via grant?
I create the user like this:
CREATE USER PAPER WITH LOGIN PASSWORD 'secure password' NOSUPERUSER NOINHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinite';
GRANT SELECT ON vw_visao TO user;
but when I logged in with him on pgadmin3 they can see the entire structure of the bank.
Like seeing how many tables you have, the functions and the sql within the functions and the ddl of the tables. Do not select anything for lack of privilege.
I am trying to prevent the user from being allowed to execute these commands.
There are several interesting options, see some examples:
\d list the database tables
\dv list database views
\di list enter code here the indexes of the database
\db list the tablespaces
\l list the databases
\dg list existing roles (users or groups)
\conninfo displays information about the current connection
\h list SQL commands
\h command displays details about the command
There is no way to do that inside a single database in PostgreSQL.
One possibility would be to use a postgres_fdw foreign table to refer to a table in a different database, whose definition could not be seen.

How to add admin user to existing postgres database?

We have an existing postgres database gsrdb in production with superuser gsr. We have been doing all the database maintenance with that user gsr. Also, the same user gsr is used by our app service to do transactions on the database.
We want to change this now. We want a separate superuser gsr_admin(whose credentials are managed by Vault) that can do the dba maintenance but still have our app service use existing user gsr.
The problem I am facing is that all the database objects so far are owned by gsr user and if I run updates, as user gsr_admin, on the database w.r.t. either table constraints or sequences it fails saying error: must be owner of relation...blah blah
How can I fix this?
So I was thinking if I could create a superuser admin group role called admin_group and reassign all the ownerships of all the database objects to it from user gsr and then alter both users gsr and gsr_admin to belong to this admin group role. Wouldn't that way everything that has been created so far would be owned by role admin_group ? And whether I create new objects as a user gsr or as gsr_admin either of them can still update the objects?
I might be wrong. Would really appreciate some inputs.
Simply run
ALTER ROLE gsr NOSUPERUSER;
ALTER ROLE gsr RENAME TO gsr_admin; -- needs a new password now
CREATE ROLE gsr LOGIN;
GRANT USAGE ON SCHEMA myschema TO gsr;
GRANT SELECT, INSERT, UPDATE, DELETE
ON ALL TABLES IN SCHEMA myschema TO gsr;
Similarly, grant USAGE on sequences and other required privileges. You may want to run some ALTER DEFAULT PRIVILEGES for future objects as well.

Permission denied for relation <table_name>

So I'm making this app and I'm using Postgres and I've already created a database, a user and a password and granted all privileges on the database to the user I've created.
The thing is, when I switch the database in psql using \c <database_name> I get in just fine and can use queries on it.
But when I run psql using postgres://user_name:password#localhost:5432/databasename on terminal and try to select * from the <table_name> it gives me this message
permission denied for relation <table_name>
Can you please tell me what to do, I've had this problem before and I had to create another database or change the user but I want a better solution please.
PS: I've tried to use this :
GRANT ALL PRIVILEGES ON TABLE <table_name> to <user_name>
This is how I created and accessed my database:
rawan95=# create database food ;
CREATE DATABASE
rawan95=# create user meal with password '123';
CREATE ROLE
rawan95=# grant all privileges on database food to meal;
GRANT
rawan95=# \c food
You are now connected to database "food" as user "rawan95".
After that, I've built it using
food=# \i src/database/db_build.sql
BEGIN
DROP TABLE
CREATE TABLE
INSERT 0 1
COMMIT
Then I selected data from the table just fine, but when I try to access it using this, I get an error: psql postgres://meal:123#localhost:5432/food
food=> select * from foods;
ERROR: permission denied for relation foods
You are granting the privileges before you create the tables.
As there are no tables at that moment nothing is granted. The tables you created are not owned by the user meal but the user rawan95 (which the \c command told you).
Plus: granting "all privileges" on a database, does not grant any select privilege. As documented in the manual "all privileges" are: CREATE, CONNECT, TEMPORARY, TEMP. The CREATE privilege would allow the user meal to create tables in that database.
If you want all those tables to be owned by the user meal you need to run your setup script after you connected as the user meal (the \c command did not change the current user)
If you do want rawan95 to be the owner of the tables, you need to either grant the select privilege after creating all tables:
grant select on all tables in schema public to meal;
Or, you can change the default privilege before creating the tables (before running db_build.sql), so that they are applied to all tables in the future:
alter default privileges in schema public
grant select on all tables to meal;
The alter default privileges only has an effect for tables that are created after that. So to fix your current setup, you need to first grant select on the existing tables, and the change the default privileges for all tables that are created in the future.
Have you granted usage on the schema? Without that the table permissions are useless.
GRANT USAGE ON SCHEMA schema_name TO username
EDIT: Based on comment thread below we have established.
The table is in public schema.
The table belongs to rawan95 but the schema does not (public schema belongs to root postgres user).
The OP is attempting to connect and access the table as user 'meal' they have granted table permissions using the rawan95 user but are unable to grant schema permissions.
From the above, the problem could still be that the user 'meal' does not have usage on the public schema. If you are on Linux the quickest way to sort this is to switch to the super user to make this change from terminal:
sudo -u postgres psql -c "GRANT USAGE ON SCHEMA public TO meal"
FURTHER EDIT - having read your new clarification this is not correct (or at least not useful). The issue is as pointed out by the other answerer that you didn't have a table at the time you did the grant.

Separate and restrict data access using schemas

I am an Oracle DBA, new to PostgreSQL. I have a requirement to separate some modules data, so that one module will not have access to read the data of another module.
I read about the use of schemas in PostgreSql which is somewhat different than the use of it in Oracle. However seems like it is recommended to use the method of different schemas for separation and management - just like in Oracle.
However, when I create 2 schemas - connected to the same database and same user - I can do a select from the other schema's table.
That is, for example, if I have schema A owning table a, and schema B owning table b, when I set the search path to schema B I can do a select on schema’s A table a without any problem.
I couldn't find a way to revoke this privilege from schema B.
The only I could find then to separate access to data, is using different roles, that is to create role A with schema A, and role B with schema B. then I can grant and revoke access from user B in order for it to see what I want from role's A tables.
Is this correct? Am I missing something?
if I have schema A owning table a
A schema does not "own" a table in Postgres - a user does. This is the same as in Oracle - the difference (and maybe where your confusion arises) is that in Oracle in a regular user can't create tables outside of a schema that has the same name as the user account.
So if user arthur creates a table in schema_a and one in schema_b, both tables are owned by arthur - not "the schema".
If you used different schemas/users in Oracle to separate data and to prevent access to the other user's tables, then you need two users and two schemas in Postgres as well.
The default search_path in Postgres is setup in a way, that (unqualified) tables are always first searched (and created) in a schema with the same name as the user running the statement.
So if you create two users and a schema with the user's name for each user, you pretty much have the same setup as in Oracle:
create user arthur with password 'foobar';
create schema arthur authorization arthur; --<< this is what Oracle does "automatically"
create user bob with password 'verysecret';
create schema bob authorization bob;
Now, if bob creates a table, that table is created in the schema bob and is owned by the user bob. User arthur has not privileges to access that table.
If you never need to share data between those users (or schemas), then you can create two databases, create two users and let both users create everything in the public schema of "their" database.

how to set up user accounts in PostgreSQL for Web based application

I’m developing a web based application with PostgreSQL as the back End Database & perl handling the scripting
I hold the login info in a separate file similar to advice here where to store global database connection parameters so depending on what the script needs to achieve it could point to different login credentials Currently it’s the default PostgreSQL account this obviously needs changing.
I need to get my head around how to set up user accounts in PostgreSQL
I think I need two one that allows users to query the Database eg web_user the other will need to submit changes eg web_admin.
The web_admin account will need to log into the webpage
In pgAdmin or on the command line how do I create the login Rolls and give the what ever the required permissions are?
EDIT Please Clarify
I’ve had a stab at creating two accounts but am unclear if this is correct way to do it
CREATE USER web_user PASSWORD 'password1';
GRANT SELECT to web_user on Table1; // Read Only
CREATE USER web_admin PASSWORD 'password2';
GRANT SELECT,INSERT,UPDATE,DELETE to web_admin on Table1; // Read Insert and update / delete rows within a existing table but not able to create, alter or delete a Table or column
Edit 2 ooops
So I’ve executed the following in pgAdmin window
CREATE USER web_user PASSWORD 'password1';
GRANT SELECT to web_user in schema PUBLIC; // Read Only
CREATE USER web_admin PASSWORD 'password2';
GRANT SELECT,INSERT,UPDATE,DELETE to web_admin in schema PUBLIC
The web_user account allows just read access to a database the problem the web_admin account has the same read access
I’ve tried drop web_user & revoke by
revoke all privileges on database mydb from web_admin;
but it fails with errors about dependencies listing all tables in mydb
I've attempted to see what privileges web_admin actually has but have been unable to.
How do I drop this account
What is wrong with the syntax for grant web_user?
To create users you can use CREATE USER command in SQL. (it is the same as CREATE ROLE ... WITH LOGIN) Afterwards you use GRANT to grant privileges.
I'm not sure what you mean by "default PostgreSQL account". If you are talking about "postgres" account, it's superuser, and has rights to everything.
The topic of privileges, and securing is quite complex, I wrote about it at least couple of times:
How to grant privileges on all tables in PostgreSQL < 9.0
How to grant privileges on all tables in PostgreSQL > 9.0
How to secure your database