Ошибка нет доступа к схеме postgresql

Can’t create tables in public schema as non-superuser

postgres — super user.

What I’ve done:

ALTER SCHEMA public owner to postgres;  

CREATE USER admin WITH PASSWORD 'my-password';   

GRANT USAGE, CREATE ON SCHEMA public TO postgres;   
GRANT USAGE, CREATE ON SCHEMA public TO admin;    

CREATE DATABASE mydb;    
GRANT ALL ON DATABASE mydb TO admin;

privileges:

postgres=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description       
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =UC/postgres        +| 
        |          | admin=UC/postgres    | 
(1 row)

what I got:

enter image description here

How to create tables in public schema?

vvvvv's user avatar

vvvvv

25.7k19 gold badges50 silver badges81 bronze badges

asked Oct 18, 2022 at 12:06

Merkalov Anton's user avatar

2

The first comment nailed the most likely reason this is happening. Quoting the release announcement:

PostgreSQL 15 also revokes the CREATE permission from all users except a database owner from the public (or default) schema.

The reason your fix didn’t work is that all actions you took on database postgres in regards to user admin‘s privileges on schema public concern only that schema within the database postgres. Schema public on database postgres is not the same schema public as the one on newly created mydb.

Also, this:

GRANT ALL ON DATABASE mydb TO admin;

grants privileges on the database itself, not things within the database. admin can now drop the database, for example, still without being able to create tables in schema public. My guess is that you wanted to make admin also the owner of mydb, in which case you need to add

ALTER DATABASE mydb OWNER TO admin;

Or you need to repeat your GRANT USAGE, CREATE ON SCHEMA public TO admin; on mydb.

Here’s some more documentation on secure schema usage patterns the PostgreSQL 15 change was based on.

answered Oct 18, 2022 at 13:14

Zegarek's user avatar

ZegarekZegarek

6,8791 gold badge14 silver badges24 bronze badges

5

You have created the DB after having granted the privileges on the public schema. Chances are your admin user is using the new DB, which only have the default priviledges

answered Oct 18, 2022 at 13:12

JGH's user avatar

JGHJGH

16.1k4 gold badges31 silver badges48 bronze badges

In PostgreSQL 15, a fundamental change took place which is relevant to every user who happens to work with permissions: The default permissions of the public schema have been modified. This is relevant because it might hurt you during application deployment. You need to be aware of how it may affect you.

Creating users

Many people work as superusers only. This is not recommended and can lead to serious security issues. I recommend creating separate users to run your application. In PostgreSQL, you can create a new user using the CREATE USER or the CREATE ROLE command. The difference between these two options is that CREATE USER sets the LOGIN privilege directly while CREATE ROLE will set this attribute to NOLOGIN.
In this example, you’ll create a “demo” user, as shown in the next listing:

security=# CREATE USER demo LOGIN;
CREATE ROLE

Once this is done, you can reconnect to the database. The \c command is a good way to do that if you happen to use psql. If you’re running some other client, reconnect using the new user:

security=# \c security demo
You are now connected to database "security" as user "demo".
security=> SELECT current_user;
current_user
--------------
demo
(1 row)

“current_user” will return the database user which is currently connected.

The public schema in PostgreSQL 15 and privilege escalation attacks

In PostgreSQL 14 and in prior versions, by default anybody can create a table. The new table will simply end up in the PUBLIC schema. The problem with this approach is that the public schema can quickly turn into a trash can containing all kinds of used and unused tables – which is neither desirable nor recommended. An even bigger problem is security: almost any privilege escalation attack on a PostgreSQL database requires the attacker to create malicious objects. See for example this blog about abusing SECURITY DEFINER functions for more details. The public schema is the perfect vector for such a privilege escalation attack. Therefore PostgreSQL has made a major leap forward and changed this behavior. In version 15, only the database owner can create objects in the public schema.

Check out the following listing:

security=> CREATE TABLE foo (id int);
ERROR: permission denied for schema public
LINE 1: CREATE TABLE foo (id int);

PostgreSQL will error out and tell you that you don’t have permissions to create something inside the PUBLIC schema without explicitly specifying who is allowed to do that beforehand. It is now necessary to grant permissions to a user explicitly. Here’s how it works:

How to grant permissions on the PUBLIC schema

security=> \c security postgres
You are now connected to database "security" as user "postgres".
security=# GRANT ALL ON SCHEMA public TO demo;
GRANT

Let’s connect to PostgreSQL as a superuser and set USAGE + CREATE = ALL permissions on the PUBLIC schema. Once this is done, you can go ahead and create objects in this schema:

security=# \c security demo
You're now connected to database "security" as user "demo".
security=> CREATE TABLE foo (id int);
CREATE TABLE

The table will belong to the “demo” user who created the table:

security=> \d
List of relations
Schema | Name | Type  | Owner
-------+------+-------+-------
public | foo  | table | demo
(1 row)

Now, only the user “demo” and the database owner can create objects in the public schema.

Finally…

To see how to deal with closing the security hole in PostgreSQL versions prior to v15, see my blog about common security issues.

For more info on PostgreSQL security, there is no way around encrypting client / server connections using SSL in PostgreSQL. I created a blog post about this important topic and invite you to read it.


In order to receive regular updates on important changes in PostgreSQL, subscribe to our newsletter, or follow us on Twitter, Facebook, or LinkedIn.

The first comment nailed the most likely reason this is happening. Quoting the release announcement:

PostgreSQL 15 also revokes the CREATE permission from all users except a database owner from the public (or default) schema.

The reason your fix didn’t work is that all actions you took on database postgres in regards to user admin‘s privileges on schema public concern only that schema within the database postgres. Schema public on database postgres is not the same schema public as the one on newly created mydb.

Also, this:

GRANT ALL ON DATABASE mydb TO admin;

grants privileges on the database itself, not things within the database. admin can now drop the database, for example, still without being able to create tables in schema public. My guess is that you wanted to make admin also the owner of mydb, in which case you need to add

ALTER DATABASE mydb OWNER TO admin;

Or you need to repeat your GRANT USAGE, CREATE ON SCHEMA public TO admin; on mydb.

Here’s some more documentation on secure schema usage patterns the PostgreSQL 15 change was based on.

I’m trying to view the raw data from the AACT Database in pgAdmin 4. I’m on a Mac computer. When I just try to view the first 100 rows from the ‘complete_oncology’ table, I get the below error:

ERROR: permission denied for schema public
LINE 1: SELECT * FROM public.complete_oncology
                      ^
SQL state: 42501
Character: 15

Do I have insufficient permissions? If yes, how do I grant myself permissions to view this table? I am able to see other tables from different Schemas in the AACT database. I’ve read some users suggest granting myself permissions with something like the below, but no luck:

GRANT SELECT ON complete_oncology TO PUBLIC

This just turns up an error:

ERROR:  relation "complete_oncology" does not exist
SQL state: 42P01

asked Apr 27, 2021 at 2:57

cpburke94's user avatar

If you get a «permission denied» for public.complete_oncology, but a «relation does not exist» for oncology, that can only mean only one thing: you do not have USAGE permissions on the public schema.

Get the owner of the schema to run

GRANT USAGE ON SCHEMA public TO your_user;

Then you should be able to see the table. If you still lack permissions on the table itself, get the owner to grant you SELECT on the table as well.

answered Apr 27, 2021 at 3:19

Laurenz Albe's user avatar

Laurenz AlbeLaurenz Albe

190k17 gold badges175 silver badges229 bronze badges

1

  1. go to preferences setting on popsql
  2. connections
  3. delete connection that you have
  4. add new connection
    fill the form
    -connection name ( up to you)
    -Turn on Connection type «connect directly from my computer»
    -hostname : localhost (before you can type localhost, turn on the connection type «connect directly from mycomputer»)
    -port : 3306
    -database name : same as you create before on cmd sql
    -username : root

answered Oct 9, 2022 at 10:58

Tienho's user avatar

1

Логический уровень: база данных, пользователи, права.

1. создайте новый кластер PostgresSQL 13
2. зайти в кластер под postgres:
3. Создайте новую базу данных testdb и коннектимся:
CREATE DATABASE testdb;
c testdb
# Ответ: Вы подключены к базе данных "testdb" как пользователь "postgres".
5. создайте новую схему testnm
Просмотр схем:
имя владелец
public postgres
testnm postgres
Права супервользователя:
postgres=# select rolname from pg_roles where rolsuper;
 rolname
----------
 postgres
6. Создайте новую таблицу t1 с одной колонкой c1 типа integer
CREATE TABLE t1(c1 integer);
7. Вставьте строку со значением c1=1
INSERT INTO t1 values(1);
  1. Создать новую роль readonly:
Просмотр ролей:
Имя роли Список ролей и Атрибутов Член ролей
postgres Суперпользователь, Создает: роли, БД, Репликация, Пропускать RLS {}
readonly Вход запрещен {}
  1. Дать роли «readonly» право на подключение к базе данных testdb:
grant connect on DATABASE testdb TO readonly;
Ответ: Grant
  1. Дать роли «readonly» право на использование схемы testnm:
grant usage on SCHEMA testnm to readonly;
11. Дать роли «readonly» право на select для всех таблиц схемы testnm:
grant SELECT on all TABLEs in SCHEMA testnm TO readonly;
12. Создать пользователя testread с паролем 12345;
sudo adduser testread sudo
passwd testread
vim /etc/postgresql/14/main/pg_hba.conf
host all dbowner 0.0.0.0/0 scram-sha-256
psql -U dbowner -h 192.168.0.16 -d postgres
select pg_reload_conf();
postgres=# CREATE DATABASE priz;
# Отвте: CREATE DATABASE
CREATE USER dbowner with password '12345';
CREATE USER testread with password '12345';
CREATE USER v7UserDev;
CREATE DATABASE priz2 OWNER v7UserDev;
# Права на директорию, для запуска БД:
chmod 0750 /backup/restore
Просмотр пользователей из представления:
select usename, usesuper from pg_catalog.pg_user;
usename usesuper
postgres t
testread f
  1. Дать роль readonly пользователю testread:
ALTER USER dbowner WITH SUPERUSER;
GRANT superuser TO dbowner;
grant readonly TO testread;
  1. Зайди под пользователем testread в б.д. testdb;
Ответ: подключиться к серверу через UNIX сокет «/var/run/postgresql/.s.PGSQL.5432» не удалось
ALTER USER testread LOGIN;
Ответ: подключиться к серверу через UNIX сокет «/var/run/postgresql/.s.PGSQL.5432» не удалось
q
exit
sudo -u postgres psql -U testread -h 127.0.0.1 -W -d testdb
Ответ: SSL-соединение (протокол: TLSv1.3, шифр: TLS_AES_256_GCM_SHA384, бит: 256, сжатие: выкл.)
15.
select * from t1;
# Ответ: нет доступа к таблице t1
dt
Схема|Имя|Тип|Владелец|
:----|:--------|:--------|:--------:
public|t1|таблица|postgres
Дадим доступ из-под postgres:
c testdb
GRANT SELECT, UPDATE, INSERT ON t1 TO testread;
q
exit
sudo -u postgres psql -U testread -h 127.0.0.1 -W -d testdb
dt
Схема Имя Тип Владелец Права для столбцов Политики
public t1 таблица postgres=arwdDxt/postgres+testread=arw/postgres
Ответ: с1 / 1 строка
  1. Создадим таблицу t1 заново с явным указанием имени схемы testnm
su postgres
psql
drop table t1;
CREATE TABLE testnm.t1(i int);
INSERT INTO testnm.t1 values (1), (2);
Ответ: INSERT 0 2
Ответ: ОШИБКА: отношение «testnm.t1» не существует СТРОКА 1: select * from testnm.t1;
Ответ: «$user», public
SET search_path TO testnm,public;
SHOW search_path;
Ответ: testnm, public
Схема Имя Тип Владелец Права для столбцов Политики
testnm t1 таблица
Ответ: i 1 2 (2 строки)
grant connect on DATABASE testdb TO testread;
grant SELECT, UPDATE, INSERT on all TABLEs in SCHEMA testnm TO testread;
q
exit
sudo -u postgres psql -U testread -h 127.0.0.1 -W -d testdb
select * from t1;
Ответ: ОШИБКА: отношение «t1» не существует
Ответ: i 1 2 (2 строки)
create table t2(c1 integer); 
insert into t2 values (2);
Ответ: i 2 (1 строка)
  1. Как убрать эти права?
c testdb postgres; 
revoke CREATE on SCHEMA public FROM public; 
revoke all on DATABASE testdb FROM public; 
q
exit
sudo -u postgres psql -U testread -h 127.0.0.1 -W -d testdb
create table t3(c1 integer);
ОШИБКА: нет доступа к схеме public.
Все задания выполнены.

This happens when not having USAGE privilege on any of the schemas of search_path. By default the pseudo-role public (all users) has this privilege on the publicschema, so this error happens only after revoking it explicitly with:

revoke usage on schema public from public;

This is required when it’s not desirable that people peek into other people schemas, even without selecting data from tables (which is granted through different privileges).

If this REVOKE hasn’t been done in that database, it may have happened in the template database by which new databases are modelled (see CREATE DATABASE).


When a user has USAGE privilege, but lacks CREATE privilege on the schema, it’s a different error when trying to create an object: permission denied for schema public.

To check the privileges inside psql, use dn+ public.

By default (shown with extended display x for readability):

# dn+ public
List of schemas
-[ RECORD 1 ]-----+-----------------------
Name              | public
Owner             | postgres
Access privileges | postgres=UC/postgres
                  | =UC/postgres
Description       | standard public schema

lack of a rolename before = means it’s for all roles (=public)

Without public USAGE privilege

Name              | public
Owner             | postgres
Access privileges | postgres=UC/postgres
                  | =C/postgres
Description       | standard public schema

Without public USAGE or CREATE privileges

Name              | public
Owner             | postgres
Access privileges | postgres=UC/postgres
Description       | standard public schema

This happens when not having USAGE privilege on any of the schemas of search_path. By default the pseudo-role public (all users) has this privilege on the publicschema, so this error happens only after revoking it explicitly with:

revoke usage on schema public from public;

This is required when it’s not desirable that people peek into other people schemas, even without selecting data from tables (which is granted through different privileges).

If this REVOKE hasn’t been done in that database, it may have happened in the template database by which new databases are modelled (see CREATE DATABASE).


When a user has USAGE privilege, but lacks CREATE privilege on the schema, it’s a different error when trying to create an object: permission denied for schema public.

To check the privileges inside psql, use dn+ public.

By default (shown with extended display x for readability):

# dn+ public
List of schemas
-[ RECORD 1 ]-----+-----------------------
Name              | public
Owner             | postgres
Access privileges | postgres=UC/postgres
                  | =UC/postgres
Description       | standard public schema

lack of a rolename before = means it’s for all roles (=public)

Without public USAGE privilege

Name              | public
Owner             | postgres
Access privileges | postgres=UC/postgres
                  | =C/postgres
Description       | standard public schema

Without public USAGE or CREATE privileges

Name              | public
Owner             | postgres
Access privileges | postgres=UC/postgres
Description       | standard public schema

Я запускаю Postgres 10.4 и в настоящее время сбит с толку, поскольку не могу предоставить доступ к схеме другой роли.

Что я хочу сделать:

У меня одна роль с одной схемой, и я хочу получить доступ к схеме и ее таблицам из другой роли. Итак, я сделал как обычно (что работало с другими схемами):

grant usage on schema myschema to newuser;

grant select on all tables in schema myschema to newuser;

Оба этих оператора выполнялись как владелец схемы. При этом я не столкнулся с какими-либо ошибками.

Когда я вхожу в систему как новый пользователь и пытаюсь выбрать некоторые данные:

select * from myschema.table;

Я получаю сообщение об ошибке:

SQL Error [42501]: ERROR: permission denied for schema myschema

Я вижу, что у нового пользователя есть нужные привилегии в таблице «information_schema.role_table_grants»

Он также работал с другой ролью и другой схемой. Я невежественен.


Ответы
2

Это определенно работает, как указано в моем вопросе, проблема заключалась в том, что я не использовал владельца схемы.

Поэтому всегда убедитесь, что вы предоставляете доступ к схеме от роли владельца.

Шаг 1
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA name_schema TO name_user;

Шаг 2
GRANT USAGE ON SCHEMA name_schema TO name_user;

Другие вопросы по теме

In Postgres I created the following table inside a db called testing:

CREATE TABLE category_google_taxonomy (
    category_id integer references category ON UPDATE CASCADE ON DELETE CASCADE,
    google_taxonomy_id integer references google_taxonomy ON UPDATE CASCADE ON DELETE     CASCADE
);

When I try to populate the table:

INSERT INTO category_google_taxonomy (category_id, google_taxonomy_id) VALUES
(1,7),
(2,12);

I get the following error:

ERROR:  permission denied for schema public
LINE 1: SELECT 1 FROM ONLY "public"."category" x WHERE "category_id"...
                       ^
QUERY:  SELECT 1 FROM ONLY "public"."category" x WHERE "category_id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x

I read up a bit and eventually granted ALL PRIVILEGES out of exasperation, but it still doesn’t work:

testing=# GRANT ALL PRIVILEGES ON public.category TO testing;
GRANT

testing=# dp category_google_taxonomy
                                   Access privileges
 Schema |           Name           | Type  |    Access privileges    | Column access privileges 
--------+--------------------------+-------+-------------------------+--------------------------
 public | category_google_taxonomy | table | testing=arwdDxt/testing | 
                                           : super=arwdDxt/testing 


testing=# dp category
                           Access privileges
 Schema |   Name   | Type  |   Access privileges    | Column access privileges 
--------+----------+-------+------------------------+--------------------------
 public | category | table | testing=arwdDxt/super | category_id:
                                                :   testing=arwx/super
(1 row)

On @Daniel’s suggestion I tried GRANT USAGE ON schema public TO super;, now when I run the INSERT command I get:

ERROR:  permission denied for relation category
CONTEXT:  SQL statement "SELECT 1 FROM ONLY "public"."category" x WHERE "category_id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x"

Here is the relevant part of d:

public | category                               | table    | super
public | category_google_taxonomy               | table    | testing

NataNov

0 / 0 / 0

Регистрация: 09.04.2021

Сообщений: 4

1

Создание пользователя с правами на таблицы в схеме

09.04.2021, 14:54. Показов 4679. Ответов 1

Метки нет (Все метки)


Добрый день!
Изучаю PostgreSql и не могу разобраться в следующем.
Хочу создать пользователя с правами выбора из всех таблиц некоторой схемы в БД.
Все дальнейшие действия делаю в утилите psql под суперпользователем postgres:

SQL
1
2
3
4
5
6
7
8
CREATE DATABASE my_db;
c my_db
CREATE schema my_schema;
SET search_path TO my_schema,public;
CREATE TABLE my_table (f1 int2,f2 text);
INSERT INTO my_table VALUES (1,'aaa');
CREATE ROLE user1 login password 'user1';
GRANT SELECT ON ALL TABLES IN schema my_schema TO user1;

Затем подключаюсь к базе my_db под пользователем user1:

c my_db user1

До сих пор все шло прекрасно. Но дальше пытаюсь сделать select от имени пользователя user1:

SQL
1
SELECT * FROM my_schema.my_table;

выходит ошибка — нет доступа к схеме my_schema

пытаюсь по другому:

SQL
1
2
SET search_path TO my_schema,public;
SELECT * FROM my_table;

Ошибка — нет доступа к таблице my_table!

Что я делаю не так?!

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

0

grgdvo

1184 / 914 / 367

Регистрация: 02.09.2012

Сообщений: 2,785

10.04.2021, 09:09

2

Лучший ответ Сообщение было отмечено NataNov как решение

Решение

Схема — такой же объект базы, как и таблицы.
Вы дали доступ на все таблицы в схеме, но не дали доступ к самой схеме.
См. что-то типа

SQL
1
GRANT USAGE ON SCHEMA my_schema TO user1;

1

Настройка:

Я подключен к автономному (база данных в файле) HSQLDB с JDBC. Соединение открывается при запуске программы и закрывается при выходе. Пользователь был создан с правами ADMIN.

Я использовал диспетчер базы данных hsqldb.jar, чтобы создать в своей базе данных таблицу под названием КОМПОНЕНТЫ. Он находится в схеме PUBLIC, и я смог добавлять и вычитать из него записи с помощью диспетчера баз данных.

Я использую следующий код, который вызывается в основном методе, чтобы доказать, что я могу правильно запрашивать свою базу данных:

public static void displayAllRows() {
    String sql = "SELECT * FROM INFORMATION_SCHEMA.AUTHORIZATIONS";
    try (
        Statement stmt = CONN.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        ) {

        System.out.println("Authorizations Table:");
        while(rs.next()) {
        StringBuilder bf = new StringBuilder();
        bf.append(rs.getString("AUTHORIZATION_NAME")).append(": ");
        bf.append(rs.getString("AUTHORIZATION_TYPE")).append(", ");
        System.out.println(bf.toString());
        }
    } catch (SQLException ex) {
        Logger.getLogger(CompManager.class.getName()).log(Level.SEVERE, null, ex);
    }
}

Выходные данные приведенного выше кода верны на основе использования оператора SELECT * FROM INFORMATION_SCHEMA.AUTHORIZATIONS в средстве диспетчера баз данных.

Проблема:

Затем я запускаю упрощенный код ниже. Единственные изменения коснулись оператора SELECT, и я удалил все из блока try (чтобы ничто не могло случайно вызвать ошибку).

private static final Connection CONN = ConnectionManager.getInstance().getConnection();

public static void displayAllRows() {
    String sql = "SELECT * FROM COMPONENTS";
    try (
        Statement stmt = CONN.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        ) {


    } catch (SQLException ex) {
        Logger.getLogger(CompManager.class.getName()).log(Level.SEVERE, null, ex);
    }
}

Это вызывает исключение: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: COMPONENTS.

Я также пробовал использовать PUBLIC.COMPONENTS в заявлении. Однако, когда я копирую / вставляю этот оператор в диспетчер баз данных, он работает нормально (я вошел в систему с одним и тем же пользователем в обоих местах).

Вопрос:

Я, наверное, делаю что-то не так, учитывая, насколько я новичок в базах данных. Что я могу сделать, чтобы второй запрос был успешным?

Я искал SO и Интернет и нашел сотни сообщений об этом конкретном исключении, но оно выбрасывается в таких широких обстоятельствах, что решения не помогли.

Ответ:

Каким-то образом я случайно подключился к другой базе данных с помощью своей программы, чем с помощью диспетчера баз данных. Решение помещало весь путь к файлу в строку подключения к базе данных вместо использования относительной ссылки

Вы подключаетесь к двум разным базам данных. Вероятно, URL-адрес вашей базы данных указывает путь к файлу относительно каталогов, в которых вы запускаете DatabaseManager и ваше приложение. Используйте абсолютные пути или пути, в которых используется символ ~ для обозначения каталога user.home.

Поскольку вы новичок в базах данных, было бы проще запустить сервер HSQLDB и подключиться к нему из вашего приложения и из DatabaseManager, используя один и тот же URL-адрес.


1

fredt
1 Май 2016 в 23:57

In Postgres I created the following table inside a db called testing:

CREATE TABLE category_google_taxonomy (
    category_id integer references category ON UPDATE CASCADE ON DELETE CASCADE,
    google_taxonomy_id integer references google_taxonomy ON UPDATE CASCADE ON DELETE     CASCADE
);

When I try to populate the table:

INSERT INTO category_google_taxonomy (category_id, google_taxonomy_id) VALUES
(1,7),
(2,12);

I get the following error:

ERROR:  permission denied for schema public
LINE 1: SELECT 1 FROM ONLY "public"."category" x WHERE "category_id"...
                       ^
QUERY:  SELECT 1 FROM ONLY "public"."category" x WHERE "category_id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x

I read up a bit and eventually granted ALL PRIVILEGES out of exasperation, but it still doesn’t work:

testing=# GRANT ALL PRIVILEGES ON public.category TO testing;
GRANT

testing=# dp category_google_taxonomy
                                   Access privileges
 Schema |           Name           | Type  |    Access privileges    | Column access privileges 
--------+--------------------------+-------+-------------------------+--------------------------
 public | category_google_taxonomy | table | testing=arwdDxt/testing | 
                                           : super=arwdDxt/testing 


testing=# dp category
                           Access privileges
 Schema |   Name   | Type  |   Access privileges    | Column access privileges 
--------+----------+-------+------------------------+--------------------------
 public | category | table | testing=arwdDxt/super | category_id:
                                                :   testing=arwx/super
(1 row)

On @Daniel’s suggestion I tried GRANT USAGE ON schema public TO super;, now when I run the INSERT command I get:

ERROR:  permission denied for relation category
CONTEXT:  SQL statement "SELECT 1 FROM ONLY "public"."category" x WHERE "category_id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x"

Here is the relevant part of d:

public | category                               | table    | super
public | category_google_taxonomy               | table    | testing

Перейти к контенту

The first comment nailed the most likely reason this is happening. Quoting the release announcement:

PostgreSQL 15 also revokes the CREATE permission from all users except a database owner from the public (or default) schema.

The reason your fix didn’t work is that all actions you took on database postgres in regards to user admin‘s privileges on schema public concern only that schema within the database postgres. Schema public on database postgres is not the same schema public as the one on newly created mydb.

Also, this:

GRANT ALL ON DATABASE mydb TO admin;

grants privileges on the database itself, not things within the database. admin can now drop the database, for example, still without being able to create tables in schema public. My guess is that you wanted to make admin also the owner of mydb, in which case you need to add

ALTER DATABASE mydb OWNER TO admin;

Or you need to repeat your GRANT USAGE, CREATE ON SCHEMA public TO admin; on mydb.

Here’s some more documentation on secure schema usage patterns the PostgreSQL 15 change was based on.

I kept getting this error when using flyway to deploy database changes. I do some manual setup first, such as creating the database, so flyway wouldn’t need those super-admin permissions.

My Fix

I had to ensure that the database user that flyway job used had ownership rights to the public schema, so that the flyway user could then assign the right to use the schema to other roles.

Additional setup Details

I am using AWS RDS (both regular and Aurora), and they don’t allow super users in the databases. RDS reserves super users for use by AWS, only, so that consumers are unable to break the replication stuff that is built in. However, there’s a catch-22 that you must be an owner in postgres to be able to modify it.

My solution was to create a role that acts as the owner (‘owner role’), and then assign both my admin user and the flyway user to the owner role, and use ALTER scripts for each object to assign the object’s owner to the owner role.

I missed the public schema, since that was auto-created when I created the database script manually. The public schema defaulted to my admin role rather than the shared owner role. So when the flyway user tried to assign public schema permissions to other roles, it didn’t have the authority to do that. An error was not thrown during flyway execution, however.

I kept getting this error when using flyway to deploy database changes. I do some manual setup first, such as creating the database, so flyway wouldn’t need those super-admin permissions.

My Fix

I had to ensure that the database user that flyway job used had ownership rights to the public schema, so that the flyway user could then assign the right to use the schema to other roles.

Additional setup Details

I am using AWS RDS (both regular and Aurora), and they don’t allow super users in the databases. RDS reserves super users for use by AWS, only, so that consumers are unable to break the replication stuff that is built in. However, there’s a catch-22 that you must be an owner in postgres to be able to modify it.

My solution was to create a role that acts as the owner (‘owner role’), and then assign both my admin user and the flyway user to the owner role, and use ALTER scripts for each object to assign the object’s owner to the owner role.

I missed the public schema, since that was auto-created when I created the database script manually. The public schema defaulted to my admin role rather than the shared owner role. So when the flyway user tried to assign public schema permissions to other roles, it didn’t have the authority to do that. An error was not thrown during flyway execution, however.

In Postgres I created the following table inside a db called testing:

CREATE TABLE category_google_taxonomy (
    category_id integer references category ON UPDATE CASCADE ON DELETE CASCADE,
    google_taxonomy_id integer references google_taxonomy ON UPDATE CASCADE ON DELETE     CASCADE
);

When I try to populate the table:

INSERT INTO category_google_taxonomy (category_id, google_taxonomy_id) VALUES
(1,7),
(2,12);

I get the following error:

ERROR:  permission denied for schema public
LINE 1: SELECT 1 FROM ONLY "public"."category" x WHERE "category_id"...
                       ^
QUERY:  SELECT 1 FROM ONLY "public"."category" x WHERE "category_id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x

I read up a bit and eventually granted ALL PRIVILEGES out of exasperation, but it still doesn’t work:

testing=# GRANT ALL PRIVILEGES ON public.category TO testing;
GRANT

testing=# dp category_google_taxonomy
                                   Access privileges
 Schema |           Name           | Type  |    Access privileges    | Column access privileges 
--------+--------------------------+-------+-------------------------+--------------------------
 public | category_google_taxonomy | table | testing=arwdDxt/testing | 
                                           : super=arwdDxt/testing 


testing=# dp category
                           Access privileges
 Schema |   Name   | Type  |   Access privileges    | Column access privileges 
--------+----------+-------+------------------------+--------------------------
 public | category | table | testing=arwdDxt/super | category_id:
                                                :   testing=arwx/super
(1 row)

On @Daniel’s suggestion I tried GRANT USAGE ON schema public TO super;, now when I run the INSERT command I get:

ERROR:  permission denied for relation category
CONTEXT:  SQL statement "SELECT 1 FROM ONLY "public"."category" x WHERE "category_id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x"

Here is the relevant part of d:

public | category                               | table    | super
public | category_google_taxonomy               | table    | testing

Я запускаю Postgres 10.4 и в настоящее время сбит с толку, поскольку не могу предоставить доступ к схеме другой роли.

Что я хочу сделать:

У меня одна роль с одной схемой, и я хочу получить доступ к схеме и ее таблицам из другой роли. Итак, я сделал как обычно (что работало с другими схемами):

grant usage on schema myschema to newuser;

grant select on all tables in schema myschema to newuser;

Оба этих оператора выполнялись как владелец схемы. При этом я не столкнулся с какими-либо ошибками.

Когда я вхожу в систему как новый пользователь и пытаюсь выбрать некоторые данные:

select * from myschema.table;

Я получаю сообщение об ошибке:

SQL Error [42501]: ERROR: permission denied for schema myschema

Я вижу, что у нового пользователя есть нужные привилегии в таблице «information_schema.role_table_grants»

Он также работал с другой ролью и другой схемой. Я невежественен.


Ответы
2

Это определенно работает, как указано в моем вопросе, проблема заключалась в том, что я не использовал владельца схемы.

Поэтому всегда убедитесь, что вы предоставляете доступ к схеме от роли владельца.

Шаг 1
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA name_schema TO name_user;

Шаг 2
GRANT USAGE ON SCHEMA name_schema TO name_user;

Другие вопросы по теме

NataNov

0 / 0 / 0

Регистрация: 09.04.2021

Сообщений: 4

1

Создание пользователя с правами на таблицы в схеме

09.04.2021, 14:54. Показов 4679. Ответов 1

Метки нет (Все метки)


Добрый день!
Изучаю PostgreSql и не могу разобраться в следующем.
Хочу создать пользователя с правами выбора из всех таблиц некоторой схемы в БД.
Все дальнейшие действия делаю в утилите psql под суперпользователем postgres:

SQL
1
2
3
4
5
6
7
8
CREATE DATABASE my_db;
c my_db
CREATE schema my_schema;
SET search_path TO my_schema,public;
CREATE TABLE my_table (f1 int2,f2 text);
INSERT INTO my_table VALUES (1,'aaa');
CREATE ROLE user1 login password 'user1';
GRANT SELECT ON ALL TABLES IN schema my_schema TO user1;

Затем подключаюсь к базе my_db под пользователем user1:

c my_db user1

До сих пор все шло прекрасно. Но дальше пытаюсь сделать select от имени пользователя user1:

SQL
1
SELECT * FROM my_schema.my_table;

выходит ошибка — нет доступа к схеме my_schema

пытаюсь по другому:

SQL
1
2
SET search_path TO my_schema,public;
SELECT * FROM my_table;

Ошибка — нет доступа к таблице my_table!

Что я делаю не так?!

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

0

grgdvo

1184 / 914 / 367

Регистрация: 02.09.2012

Сообщений: 2,785

10.04.2021, 09:09

2

Лучший ответ Сообщение было отмечено NataNov как решение

Решение

Схема — такой же объект базы, как и таблицы.
Вы дали доступ на все таблицы в схеме, но не дали доступ к самой схеме.
См. что-то типа

SQL
1
GRANT USAGE ON SCHEMA my_schema TO user1;

1

Допустим, я сделал эту «простую» реализацию БД в Postgres.

postgres=# CREATE ROLE my_role;
           CREATE DATABASE my_db;
           GRANT ALL ON DATABASE my_db TO my_role;
           CREATE SCHEMA my_schm AUTHORIZATION my_role;

А потом я хочу сделать таблицу:

postgres=#CREATE TABLE IF NOT EXIST my_db.my_schm.table(...);

И получил следующую ошибку: cross-database references are not implemented: "my_db.my_schm.table"

После этого я попытался создать таблицу, подключенную к базе данных (т.е. c my_db), и получил следующую ошибку:

schema "my_schm"does not exist

Итак, я не понимаю поведения этих ошибок. Предполагается, что роль имеет все разрешения для базы данных (и да, я также пробовал использовать SET ROLE my_role;), но когда я прошу показать схемы в my_db действительно my_schm не существует, но в Postgres он есть. Может кто-нибудь объяснить мне, пожалуйста, почему это происходит? А также как сгруппировать таблицы в my_schm?

1 ответ

Лучший ответ

Схемы существуют только в одной базе данных и создаются в текущей базе данных: вы создали свою схему в базе данных postgres, а не в mydb.

Вам необходимо сначала подключиться к базе данных mydb, чтобы создать схему в базе данных mydb.


3

pifor
24 Май 2020 в 10:56

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    !
    информация о разделе

    user posted image Данный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных — обсуждаем в разделе «Базы данных: общие вопросы». Убедительная просьба — соблюдать «Правила форума» и не пренебрегать «Правильным оформлением своих тем». Прежде, чем создавать тему, имеет смысл заглянуть в раздел «Базы данных: FAQ», возможно там уже есть ответ.

    >
    разные пользователи и доступ
    , не могу разобраться с ролями

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему

      


    Сообщ.
    #1

    ,
    13.10.15, 19:17

      Senior Member

      ****

      Рейтинг (т): 13

      Здравствуйте, Господа!
      Сразу предупрежу: в PostgreSQL я пока еще совсем новичок.
      Опишу проблему на примере, думаю так станет понятнее.

      ExpandedWrap disabled

        #psql

        postgres=# CREATE USER user1 WITH password ‘password’;

        postgres=# CREATE DATABASE db1;

        postgres=# GRANT ALL PRIVILEGES ON DATABASE db1 TO user1;

        postgres=# CREATE USER user2 WITH password ‘password’;

        postgres=# GRANT ALL PRIVILEGES ON DATABASE db1 TO user2;

        postgres=# q

        #psql -U user1 db1

        db1=# CREATE SEQUENCE user_ids;

        db1=# CREATE TABLE users (id INTEGER PRIMARY KEY DEFAULT NEXTVAL(‘user_ids’), login CHAR(64), password CHAR(64));

        db1=# INSERT INTO users (login, password) VALUES («u1», «p1»);

        db1=# q

        #psql -U user2 db1

        db1=# INSERT INTO users (login, password) VALUES («u2», «p2»);

        ОШИБКА:  нет доступа к отношению users

      Вот тут я в растерянности. Оба пользователя ALL PRIVILEGES для db1, но второй, т.е. не создатель таблицы, добавлять записи не может.
      Как это побороть?


      grgdvo



      Сообщ.
      #2

      ,
      14.10.15, 12:36

        Member

        **

        Рейтинг (т): 21

        Опция ALL PRIVILEGES для DATABASE подразумевает CREATE, CONNECT и кажется TEMP привилегии для базы данных.
        Так вот CREATE позволяет создавать ТОЛЬКО схемы в рамках базы данных.
        А для схемы вы не предоставили прав, соответственно получили ошибку доступа.


        HighMan



        Сообщ.
        #3

        ,
        14.10.15, 14:57

          Senior Member

          ****

          Рейтинг (т): 13

          Цитата grgdvo @ 14.10.15, 12:36

          Опция ALL PRIVILEGES для DATABASE подразумевает CREATE, CONNECT и кажется TEMP привилегии для базы данных.
          Так вот CREATE позволяет создавать ТОЛЬКО схемы в рамках базы данных.
          А для схемы вы не предоставили прав, соответственно получили ошибку доступа.

          Простите бестолкового, а как для схем предоставить привилегии?
          Если, возможно, напишите запрос на основе моего примера.
          Спасибо!

          Сообщение отредактировано: HighMan — 14.10.15, 14:58


          grgdvo



          Сообщ.
          #4

          ,
          14.10.15, 20:28

            Member

            **

            Рейтинг (т): 21

            Цитата HighMan @ 14.10.15, 14:57

            Простите бестолкового, а как для схем предоставить привилегии?

            В конце я неправ, забываешь как оно работает, когда не пользуешься.
            Для схемы (как объекта) тоже будет недостаточно прав :(

            Нужны команды конкретно на таблицу или ALL TABLES IN SCHEMA.
            И права нужно раздавать после создания таблицы, либо умудриться использовать ALTER DEFAULT PRIVILEGES.

            Для вашего примера скорее всего правильный порядок будет такой

            ExpandedWrap disabled

              ~ # psql -U postgres

              postgres=# CREATE USER user1 WITH password ‘password’;

              postgres=# CREATE USER user2 WITH password ‘password’;

              postgres=# CREATE DATABASE db1;

              postgres=# q

            db1 создается со схемой public по умолчанию, в которой пользователи уже могут создавать таблицы (и т.д.), поэтому user1 и user2 смогут создать свои объекты базы

            ExpandedWrap disabled

              ~ # psql -U user1 db1

              db1=# CREATE SEQUENCE user_ids;

              db1=# CREATE TABLE users (id INTEGER PRIMARY KEY DEFAULT NEXTVAL(‘user_ids’), login CHAR(64), password CHAR(64));

              db1=# INSERT INTO users (login, password) VALUES (‘u1’, ‘p1’);

              db1=# q

            теперь к user_ids и users доступ имеет только user1, ибо он владелец этих объектов.
            Назначаем права user2

            ExpandedWrap disabled

              ~ # psql -U postgres db1

              db1=# GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO user2;

              db1=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO user2;

            Теперь user2 имеет все привилегии на таблицы и последовательнсти, которые УЖЕ БЫЛИ СОЗДАНЫ на данный момент в схеме.

            ExpandedWrap disabled

              ~ # psql -U user2 db1

              db1=# INSERT INTO users (login, password) VALUES (‘u2’, ‘p2’);

            Сообщение отредактировано: grgdvo — 14.10.15, 20:28


            HighMan



            Сообщ.
            #5

            ,
            14.10.15, 20:30

              Senior Member

              ****

              Рейтинг (т): 13

              Цитата grgdvo @ 14.10.15, 20:28

              Цитата HighMan @ 14.10.15, 14:57

              Простите бестолкового, а как для схем предоставить привилегии?

              В конце я неправ, забываешь как оно работает, когда не пользуешься.
              Для схемы (как объекта) тоже будет недостаточно прав :(

              Нужны команды конкретно на таблицу или ALL TABLES IN SCHEMA.
              И права нужно раздавать после создания таблицы, либо умудриться использовать ALTER DEFAULT PRIVILEGES.

              Для вашего примера скорее всего правильный порядок будет такой

              ExpandedWrap disabled

                ~ # psql -U postgres

                postgres=# CREATE USER user1 WITH password ‘password’;

                postgres=# CREATE USER user2 WITH password ‘password’;

                postgres=# CREATE DATABASE db1;

                postgres=# q

              db1 создается со схемой public по умолчанию, в которой пользователи уже могут создавать таблицы (и т.д.), поэтому user1 и user2 смогут создать свои объекты базы

              ExpandedWrap disabled

                ~ # psql -U user1 db1

                db1=# CREATE SEQUENCE user_ids;

                db1=# CREATE TABLE users (id INTEGER PRIMARY KEY DEFAULT NEXTVAL(‘user_ids’), login CHAR(64), password CHAR(64));

                db1=# INSERT INTO users (login, password) VALUES (‘u1’, ‘p1’);

                db1=# q

              теперь к user_ids и users доступ имеет только user1, ибо он владелец этих объектов.
              Назначаем права user2

              ExpandedWrap disabled

                ~ # psql -U postgres db1

                db1=# GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO user2;

                db1=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO user2;

              Теперь user2 имеет все привилегии на таблицы и последовательнсти, которые УЖЕ БЫЛИ СОЗДАНЫ на данный момент в схеме.

              ExpandedWrap disabled

                ~ # psql -U user2 db1

                db1=# INSERT INTO users (login, password) VALUES (‘u2’, ‘p2’);

              Спасибо большое!
              Постараюсь завтра проверить!

              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

              0 пользователей:

              • Предыдущая тема
              • Базы данных: SQL
              • Следующая тема

              Рейтинг@Mail.ru

              [ Script execution time: 0,0347 ]   [ 15 queries used ]   [ Generated: 30.01.23, 08:58 GMT ]  

              1 Answer

              There is a foreign key in a table referring to a table in the schema in question, to which the table owner role does not have permission. Foreign key checks are done with the permissions of the role that own the table, not the role performing the query.

              The query is actually doing the internal foreign key check.

              Found an explanation on sharingtechknowledge.blogspot.fi

              answered Feb 13, 2015 at 15:52

              jnas's user avatar

              jnasjnas

              82610 silver badges14 bronze badges

              2

              • Thank you, kind stranger! How is anybody supposed to conclude this from the given error message?…

                Jun 27, 2022 at 13:42

              • Error messages can be a bit misleading and motivated this little question and answer that you found. It seems to be valid still though quite old already.

                Aug 1, 2022 at 6:17

              Понравилась статья? Поделить с друзьями:

              Интересное по теме:

            • Ошибка ноль на триколор тв что делать
            • Ошибка нет доступа к интернету
            • Ошибка ниссан теана j31 с1110
            • Ошибка номер 11 котел иммергаз
            • Ошибка номер 0x80070057

            • 0 0 голоса
              Рейтинг статьи
              Подписаться
              Уведомить о
              guest

              0 комментариев
              Старые
              Новые Популярные
              Межтекстовые Отзывы
              Посмотреть все комментарии