PostgeSQL: Verify user privileges - database

How can I verify the privileges after granting the following to the read_only_user?
alter default privileges for role read_only_user grant all on tables to foodapp;

You can run this query to get default privileges:
SELECT
defaclrole::regrole,
defaclnamespace::regnamespace,
CASE defaclobjtype
WHEN 'r' THEN 'relation'
WHEN 'S' THEN 'sequence'
WHEN 'f' THEN 'function'
WHEN 'T' THEN 'type'
WHEN 'n' THEN 'schema'
END,
(aclexplode(defaclacl)).*
FROM pg_default_acl;
And then add a WHERE clause for the user if you want to filter it.
Or in psql you can use:
\\ddp

Your question is seems interesting. I'm mentioning some ways below please read carefully and try it in your system. Some of them might help you. :)
You can do that by following:
In One line
postgres=> \l
This command will display the information you're looking for.
like this.
postgres=> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
The docs on Privileges give an explanation of how to interpret the output. For specific privileges on a table of the current database, use \z myTable.
Undercovers psql uses the bellow query when you issue \du command.
SELECT r.rolname, r.rolsuper, r.rolinherit,
r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,
r.rolconnlimit, r.rolvaliduntil,
ARRAY(SELECT b.rolname
FROM pg_catalog.pg_auth_members m
JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)
WHERE m.member = r.oid) as memberof
, r.rolreplication
, r.rolbypassrls
FROM pg_catalog.pg_roles r
WHERE r.rolname !~ '^pg_'
ORDER BY 1;
In the case of the table.
SELECT grantee, privilege_type
FROM information_schema.role_table_grants
WHERE table_name='mytable'
This gives you this kind of output:
mail=# select grantee, privilege_type from information_schema.role_table_grants where table_name='aliases';
grantee | privilege_type
--------------+-----------------
mailreader | INSERT
mailreader | SELECT
mailreader | UPDATE
mailreader | DELETE
mailreader | TRUNCATE
mailreader | REFERENCES
mailreader | TRIGGER
(7 rows)
mail=#
Note that (at least under Postgres 9.4) the above will not work for materialized views.
Using psql meta-commands:
https://www.postgresql.org/docs/current/static/app-psql.html
Going over the page with Ctrl+F gives:
\ddp [ pattern ]
Lists default access privilege settings.
\dp [ pattern ] Lists tables, views and sequences with their
associated access privileges.
\l[+] [ pattern ] List the databases in the server and show...
access privileges.
Also mentioned above, but not found with word "privileges" on the manual page:
\du+ for roles with login and \dg+ for roles without - will have a filed "Member of" where you find roles granted to roles.
I deliberately skip function and language privileges here, found in psql manual as barely manipulated (and if you do use those privileges you won't come here for advice). same for user-defined types, domains, and so on - using "+" after the meta-command will show you privileges if applicable.
A little extreme way to check the privileges is dropping the user in the transaction, e.g.:
s=# begin; drop user x;
BEGIN
Time: 0.124 ms
ERROR: role "x" cannot be dropped because some objects depend on it
DETAIL: privileges for type "SO dT"
privileges for sequence so
privileges for schema bin
privileges for table xx
privileges for table "csTest"
privileges for table tmp_x
privileges for table s1
privileges for table test
Time: 0.211 ms
s=# rollback;
ROLLBACK
Time: 0.150 ms
When the list is longer than N, (at least in 9.3), the warning with the list of privileges is collapsed, but you still can find it full in logs...

Related

INSERT command denied to MariaDB user

Hopefully someone can help me, when the developer queried to insert data, it gives the following error.
1142 - INSERT command denied to user 'db_user'#'localhost' for table 'table_name'
I checked user privileges, the user is granted for all the permissions:
MariaDB [(none)]> show grants for 'db_user'#'localhost';
+-------------------------------------------------------------------------------------------------------------+
| Grants for db_user#localhost |
+-------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `db_user`#`localhost` IDENTIFIED BY PASSWORD '*8FBC7CD05DD7354A9EAD92EC508E27E334FE' |
| GRANT ALL PRIVILEGES ON `db`.* TO `db_user`#`localhost` |
+-------------------------------------------------------------------------------------------------------------+
How can I resolve the issue?
"USAGE grants no real privileges". Its a confusing name. So more GRANT is needed:
GRANT INSERT ON dbname.table_name TO db_user#localhost;

Can't connect to postgres on ubuntu

I have a ubuntu 20 on dreamcompute (which is cloud computing).
I create a user and a database. Here is the list of database and users (for some reason, I can't see database under a matt username).
I went into:
nano /etc/postgresql/13/main/postgresql.conf &
nano /etc/postgresql/13/main/pg_hba.conf and did the whole '*' and '0.0.0.0/0'
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+---------+-----------------------
postgres | postgres | UTF8 | C.UTF-8 | C.UTF-8 |
strapi | postgres | UTF8 | C.UTF-8 | C.UTF-8 | =Tc/postgres +
| | | | | postgres=CTc/postgres+
| | | | | hossein=CTc/postgres
template0 | postgres | UTF8 | C.UTF-8 | C.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | C.UTF-8 | C.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
as you can see you can't see Superuser and database strapi under the matt username.
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
matt | | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
ubuntu | | {}
I'm using my dream compute's ip address as my host and use my database and user and password but get error message: connection attempt time out.
Could someone please give me a pointer on why this is happening? I have been working onthis for 2 weeks now and I can't get it to work.
Error message is connection time out. That usually means that the port is blocked by a firewall. Check your cloud provider firewall settings and iptablesin your Linux box in case you have installed it.
If there was problem with permissions, the error message would be something else.
as ex4 mentioned above I needed to reachout to the company that I was renting my cloud computer from but I still could not connect to the database.
The way I went around it is that you can ssh into your database and then connect to your database as a localhost since you are ssh into your cloud computer.
In DBeaver you have a ssh tab and you can connect and then you got back to your postgres tab and fill the localhost, user, database name, and user password area and simply click connect.
Sadly this took weeks to come to this :/

Why does create table operation attach owner as 'yugabyte' to a new table yet the database to which am connected has a different owner?

I have installed yugabytedb in minikube on my laptop and created a database with owner 'Rodgers'.
Then I run the ysqlsh to execute ysql commands from the terminal, one of which is 'CREATE DATABASE ...'.
Problem
When I try connecting to the database using an external Go application by providing the application with user as 'Rodgers' and the set password, it fails to connect.
I have found out that the tables created were attached to owner 'yugabyte', not 'Rodgers'.
But the database to which I have connected and from where am running the CREATE DATABASE command belongs to Rodgers.
What's going on here?
It's best to rehearse all this using "ysqlsh". When everything works there, connecting from any client program (Python, go, ...) etc will work — as long as you have the right driver. The PostgresSQL drivers work with YugabyteDB.
The following is mainly commands for "ysqlsh" — both SQLs and so-called metacommands (the ones starting with backslash). But occasionally, there are commands that you do from the O/S prompt. So you must read the following carefully and then do what it says after each comment — mainly in "ysqlsh" but a couple of times at the O/S prompt. So you can't simply run the script "lights out".
Start with virgin YB single-node cluster (fresh from "yb-create).
$ ysqlsh -h localhost -p 5433 -d yugabyte -U yugabyte
Now follow the script.
-- Shows two "Superuser" users: "postgres" and "yugabyte" (nothing else).
\du
-- Shows two databases: "postgres" and "yugabyte" (nothing else except "system" databases).
-- Both "postgres" and "yugabyte" databases are owned by "postgres".
\l
-- Create a new "ordinary user and connect as that user.
create user rodgers login password 'p';
alter user rodgers createdb;
-- Now connect to database yugabyte as user rodgers
\c yugabyte rodgers
-- Create a new database and check it's there.
create database rog_db owner rodgers;
\l
-- Name | Owner | Encoding | Collate | Ctype | Access privileges
-- -----------------+----------+----------+---------+-------------+-----------------------
...
-- rog_db | rodgers | UTF8 | C | en_US.UTF-8 |
-- ...
-- Now connect to the new "rog_db" database. Works fine.
\c rog_db rodgers
-- Quit "ysqlsh.
\q
Connect again. Works fine.
$ ysqlsh -h localhost -p 5433 -d rog_db -U rodgers
Now carry on with the script.
-- Works fine.
create table t(k int primary key);
-- Inspect it. First "\d", then "\d t".
\d
-- List of relations
-- Schema | Name | Type | Owner
-- --------+------+-------+---------
-- public | t | table | rodgers
\d t
-- Table "public.t"
Column | Type | Collation | Nullable | Default
-- --------+---------+-----------+----------+---------
-- k | integer | | not null |
-- Indexes:
-- "t_pkey" PRIMARY KEY, lsm (k HASH)
-- This is OK for playing. But terrible for real work.
drop table t;
\c rog_db yugabyte
drop schema public;
\c rog_db rodgers
create schema rog_schema authorization rodgers;
-- For future connect commands.
alter user rodgers set search_path = 'rog_schema';
-- for here and now.
set schema 'rog_schema';
create table t(k int primary key);
\d
-- List of relations
-- Schema | Name | Type | Owner
-- ------------+------+-------+---------
-- rog_schema | t | table | rodgers
--------------------------------------------------------------------------------
I just stepped through all of this using "YB-2.2.0.0-b0" on my laptop (macOS Big Sur). It all worked fine.
Please try this in your minikube env and report back.
Regards, Bryn Llewellyn, Technical Product Manager at Yugabyte Inc.

How to delete and recreate databases in postgreSQL (error: template1 being already used)

I'm using postgreSQL with python/django and windows7.
I dropped a database from pgAdmin4. Maybe this isn't the correct way to delete a database. Maybe I nedd to do something more to sever the connection?
Anyway now I want to recreate the database but when I do (from pgAdmin4) I receive the error:
ERROR: database "template1" is being accessed by other users
DETAIL: There are 1 other session(s) using the database.
I restarted the server, even reboot the pc but I continue to receive that error. I don't know which session is using template1, maybe is my old (and deleted) database? Maybe is this (first one):
Where SQL (partially visible on the pic) is:
SELECT cl.relkind, COALESCE(cin.nspname, cln.nspname) as nspname,
COALESCE(ci.relname, cl.relname) as relname, cl.relname as indname
FROM pg_class cl
JOIN pg_namespace cln ON cl.relnamespace=cln.oid
LEFT OUTER JOIN pg_index ind ON ind.indexrelid=cl.oid
LEFT OUTER JOIN pg_class ci ON ind.indrelid=ci.oid
LEFT OUTER JOIN pg_namespace cin ON ci.relnamespace=cin.oid
WHERE cl.oid IN (SELECT objid FROM pg_shdepend WHERE refobjid=10::oid) AND cl.oid > 13317::oid
UNION ALL SELECT 'n', null, nspname, null
FROM pg_namespace nsp
WHERE nsp.oid IN (SELECT objid FROM pg_shdepend WHERE refobjid=10::oid) AND nsp.oid > 13317::oid
UNION ALL SELECT CASE WHEN typtype='d' THEN 'd' ELSE 'y' END, null, typname, null
FROM pg_type ty
WHERE ty.oid IN (SELECT objid FROM pg_shdepend WHERE refobjid=10::oid) AND ty.oid > 13317::oid
UNION ALL SELECT 'C', null, conname, null
FROM pg_conversion co
WHERE co.oid IN (SELECT objid FROM pg_shdepend WHERE refobjid=10::oid) AND co.oid > 13317::oid
UNION ALL SELECT CASE
I yet don't know how to use database, so I have no idea to what to do. Should I terminate that session?
I tried from the SQL shell but this is the first times I use it so I'm not sure to have done the things in the correct way. In particular I'm not connected like postgres but like gm (a superuser).
Server [localhost]:
Database [postgres]:
Port [5433]:
Username [postgres]: gm
Inserisci la password per l'utente gm:
psql (12.1)
I tried the comand:
postgres=# SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'elenconomi_db';
where elenconomi_db is the database I deleted, so it don't exist anymore and the comand gives error
So I tried postgres=# \list (sorry for the italian, I don't know why it's writing in italian):
Lista dei database
Nome | Proprietario | Codifica | Ordinamento | Ctype |
Privilegi di accesso
-----------+--------------+----------+--------------------+--------------------+
-----------------------
postgres | postgres | UTF8 | Italian_Italy.1252 | Italian_Italy.1252 |
template0 | postgres | UTF8 | Italian_Italy.1252 | Italian_Italy.1252 |
=c/postgres +
| | | | |
postgres=CTc/postgres
template1 | postgres | UTF8 | Italian_Italy.1252 | Italian_Italy.1252 |
=c/postgres +
| | | | |
postgres=CTc/postgres
(3 righe)
I read is better to do not drop template1, so I ask before to DROP DATABASE template1;. Should I do?
And for the next time there is a better way to drop a database and recreate it?
I saw many question like this but I can't find a solution working for me.
Close the database session that is connected to template1. Then CREATE DATABASE will succeed.
To find and close the session, use
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'template1';

Postgres permission denied for relation <table>

I'm trying to learn Postgres and Ive made two basic tables and I can't join them together.
here is my list Of relations:
Schema | Name | Type | Owner
--------+--------------+----------+----------
public | login | table | postgres
public | login_id_seq | sequence | postgres
public | users | table | test
(3 rows)
When I use the command
SELECT * FROM users JOIN login ON users.name = login.name;
I get
ERROR: permission denied for relation login
I have no idea what to do or what I did wrong.
You should grant the SELECT permission to user test:
GRANT SELECT ON login TO test;
If if might allow test to modify login, you should grant other permissions as well:
GRANT SELECT, INSERT, UPDATE, DELETE ON login TO test;
You should execute these statements as database owner or as user postgres. In general, you can use
psql -Upostgres -dtest
if you're running this command on the same machine where the Postgres server is running.
You may also change the ownership of login to test:
ALTER TABLE login OWNER TO test;
ALTER SEQUENCE login_id_seq OWNER TO test;
But have to execute this as user postgres as well.
Edit: You can try to change the user with
SET ROLE 'postgres';
as suggested by #lat long.
So this is what I did to finally get it to work...I basically just went into the login properties on pgAdmin4, found the owner and switched it to test and ran:
SELECT * FROM users JOIN login ON users.name = login.name;
and finally got what I was looking for. Surprisingly a simple fix.
The "test" user doesn't have permission to login and use the related tables. Run the query with the "postgres" user:
SET ROLE 'postgres';
Then run your query.

Resources