how to drop superuser in postgres - postgresql

I have created a new user with superuser role the rentdb, when i try to drop i will get there is dependency with it relating to some pg functions.
Is there a way i can delete rentdb completely.
postgres-# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
rentdb | Superuser | {}

As documented in the manual you can either drop everything that the user owns:
drop owned by rentdb cascade;
or assign those objects to a different user:
reassign owned by rentdb to postgres;

Related

Trying to access psql after dropping a user but still got asked for entering password for the dropped user

initially I have
Role name | Attributes | Member of
------------+------------------------------------------------------------+-----------
hezhenghao | Create DB | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
and I typed
postgres=# REASSIGN OWNED BY hezhenghao to postgres
postgres-# ;
REASSIGN OWNED
postgres=# REASSIGN OWNED BY hezhenghao to postgres; REASSIGN OWNED
postgres=# DROP OWNED BY hezhenghao;
DROP OWNED
postgres=# DROP USER hezhenghao;
DROP ROLE
Now there is only one user
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
However when I type psql in terminal, I still got asked to Password for user hezhenghao:
and then I would end up with psql: FATAL: password authentication failed for user "hezhenghao"
I am new to postgres so I don't really understand what's going on here. Can someone help me with this?
If you don't specify a user with -U then psql will default to the username of the user currently logged in. In this case, it sounds like that user is hezhenghao. Use -U postgres to log in as the postgres user.

Unable to create schemas on Cloud SQL Postgres instance

I'm running into a problem with Google's Cloud SQL solution, where I'm unable to create new schemas on my database. The rules are as follows:
testdb=> \du
List of roles
Role name | Attributes | Member of
-------------------+------------------------------------------------------------+---------------------
cloudsqladmin | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
cloudsqlagent | Create role, Create DB | {cloudsqlsuperuser}
cloudsqlreplica | Replication | {}
cloudsqlsuperuser | Create role, Create DB | {}
testuser | Create role, Create DB | {cloudsqlsuperuser}
postgres | Create role, Create DB | {cloudsqlsuperuser}
Trying to create a new schema with the testuser results in a permission error.
testdb=> CREATE SCHEMA IF NOT EXISTS testschema;
ERROR: permission denied for database testdb
But I'm unable to GRANT CREATE ON DATABASE testdb TO testuser; because of the same permission issue.
Is there any way to give testuser the privilege to create schemas on its own?

Postgresql forgets grants after recreating tables

We use liquibase to manage and execute our database changes. On our DEV environment (and especially on local machines) we frequently recreate the tables to have a clean slate.
We have just migrated from MySQL to Postgres and are facing a problem related to these table recreations.
Initially we have granted our DB user with this:
GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO mydbuser;
GRANT SELECT, USAGE ON ALL SEQUENCES IN SCHEMA public TO mydbuser;
This is executed through psql after connecting to our own DB (where public is the default/only schema).
Everything is fine until we ask liquibase to recreate the tables in which case it will drop all tables and create them again.
After that it appears that mydbuser has lost all its grants on the tables.
According to several resources (like this) we need to alter the default privileges, so we obey:
GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO mydbuser;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT,INSERT,UPDATE,DELETE ON TABLES TO mydbuser;
GRANT SELECT, USAGE ON ALL SEQUENCES IN SCHEMA public TO mydbuser;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, USAGE ON SEQUENCES TO mydbuser;
However, although this seems very logical it changed nothing. All grants (even select) are still lost after recreating the tables.
What are we doing wrong or what else do we need to do?
UPDATE
\ddp shows:
Default access privileges
Owner | Schema | Type | Access privileges
----------+--------+----------+--------------------
postgres | public | sequence | mydb=rU/postgres
postgres | public | table | mydb=arwd/postgres
If trying to mimic what liquibase is doing in a simplified test case, it just works.
Quick demo with 9.3:
1) Create the objects from scratch with the postgres user:
postgres=# create database dbtest;
CREATE DATABASE
postgres=# create user mydbuser;
CREATE ROLE
postgres=# \c dbtest
You are now connected to database "dbtest" as user "postgres".
dbtest=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT,INSERT,UPDATE,DELETE ON TABLES TO mydbuser;
ALTER DEFAULT PRIVILEGES
dbtest=# create table foobar(id int);
CREATE TABLE
2) In another session let's connect with mydbuser and see if SELECT is allowed.
dbtest=> select * from foobar;
id
----
(0 rows)
Result: Yes, it's allowed. Note the result of \ddp too:
dbtest=> \ddp
Default access privileges
Owner | Schema | Type | Access privileges
----------+--------+-------+------------------------
postgres | public | table | mydbuser=arwd/postgres
(1 row)
3) Let's have postgres drop the table and recreate it:
dbtest=# drop table foobar;
DROP TABLE
dbtest=# create table foobar(id int);
CREATE TABLE
4) See if mydbuser can still SELECT from it.
$ psql -d dbtest -U mydbuser
dbtest=> select * from foobar;
id
----
(0 rows)
Result: Yes, as expected.
5) See if another user can SELECT from it.
$ psql -d dbtest -U daniel
dbtest=> select * from foobar;
ERROR: permission denied for relation foobar
Result: No, as expected.
This does not explain what doesn't work for you, but you may compare the above with the set of commands issued by liquibase.

ERROR: permission denied for relation tablename on Postgres while trying a SELECT as a readonly user

GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
The readonly user can connect, see the tables but when it tries to do a simple select it gets:
ERROR: permission denied for relation mytable
SQL state: 42501
This is happening on PostgreSQL 9.1
What I did wrong?
Here is the complete solution for PostgreSQL 9+, updated recently.
CREATE USER readonly WITH ENCRYPTED PASSWORD 'readonly';
GRANT USAGE ON SCHEMA public to readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
-- repeat code below for each database:
GRANT CONNECT ON DATABASE foo to readonly;
\c foo
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly; --- this grants privileges on new tables generated in new database "foo"
GRANT USAGE ON SCHEMA public to readonly;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
Thanks to https://jamie.curle.io/creating-a-read-only-user-in-postgres/ for several important aspects
If anyone find shorter code, and preferably one that is able to perform this for all existing databases, extra kudos.
Try to add
GRANT USAGE ON SCHEMA public to readonly;
You probably were not aware that one needs to have the requisite permissions to a schema, in order to use objects in the schema.
This worked for me:
Check the current role you are logged into by using:
SELECT CURRENT_USER, SESSION_USER;
Note: It must match with Owner of the schema.
Schema | Name | Type | Owner
--------+--------+-------+----------
If the owner is different, then give all the grants to the current user role from the admin role by :
GRANT 'ROLE_OWNER' to 'CURRENT ROLENAME';
Then try to execute the query, it will give the output as it has access to all the relations now.
make sure your user has attributes on its role. for example:
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
flux | | {}
postgres | Superuser, Create role, Create DB, Replication | {}
after performing the following command:
postgres=# ALTER ROLE flux WITH Superuser;
ALTER ROLE
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
flux | Superuser | {}
postgres | Superuser, Create role, Create DB, Replication | {}
it fixed the problem.
see tutorial for roles and stuff here: https://www.digitalocean.com/community/tutorials/how-to-use-roles-and-manage-grant-permissions-in-postgresql-on-a-vps--2
You should execute the next query:
GRANT ALL ON TABLE mytable TO myuser;
Or if your error is in a view then maybe the table does not have permission, so you should execute the next query:
GRANT ALL ON TABLE tbm_grupo TO myuser;

Postgres unable to create db after granting privs to role

I'm sure I'm missing something simple, but I've created the following:
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+-----------------------------------------+-----------
admin | No inheritance, Create DB, Cannot login | {}
postgres | Superuser, Create role, Create DB | {}
wade | | {admin}
(Note that Cannot login and No inheritance don't affect what's happening to wade, here. See the PostgreSQL documentation for role membership to understand why. —bignose)
However, when I try to create a db, I get:
bin wwilliam$ createdb -U wade test
Password:
createdb: database creation failed: ERROR: permission denied to create database
What am I missing?
An excerpt from the manual:
The INHERIT attribute governs inheritance of grantable privileges (that is, access privileges for database objects and role memberships). It does not apply to the special role attributes set by CREATE ROLE and ALTER ROLE. For example, being a member of a role with CREATEDB privilege does not immediately grant the ability to create databases, even if INHERIT is set; it would be necessary to become that role via SET ROLE before creating a database.
(Emphasis mine).
In documentation:
The role attributes LOGIN, SUPERUSER, CREATEDB, and CREATEROLE can be thought of as special privileges, but they are never inherited as ordinary privileges on database objects are. You must actually SET ROLE to a specific role having one of these attributes in order to make use of the attribute
So you must activate admin role using SET ROLE admin; before creating DB.