AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 35316
Accepted
andreas-h
andreas-h
Asked: 2013-02-24 08:52:36 +0800 CST2013-02-24 08:52:36 +0800 CST 2013-02-24 08:52:36 +0800 CST

Por que um novo usuário tem permissão para criar uma tabela?

  • 772

Eu estou querendo saber por que um usuário recém-criado tem permissão para criar uma tabela depois de se conectar a um banco de dados. Eu tenho um banco de dados project2_core,:

postgres=# \l
                                          List of databases
     Name      |    Owner     | Encoding  |   Collate   |    Ctype    |       Access privileges       
---------------+--------------+-----------+-------------+-------------+-------------------------------
 postgres      | postgres     | SQL_ASCII | C           | C           | 
 project2_core | atm_project2 | UTF8      | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2
 template0     | postgres     | SQL_ASCII | C           | C           | =c/postgres                  +
               |              |           |             |             | postgres=CTc/postgres
 template1     | postgres     | SQL_ASCII | C           | C           | =c/postgres                  +
               |              |           |             |             | postgres=CTc/postgres
(5 rows)

Até agora tudo bem. Agora eu crio um usuário:

postgres=# CREATE ROLE dietrich ENCRYPTED PASSWORD 'md5XXX' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER

OK. Quando tento me conectar ao banco de dados, o usuário não tem permissão para fazer isso:

$ psql -h localhost -p 5432 -U dietrich -W project2_core
Password for user dietrich: 
psql: FATAL:  permission denied for database "project2_core"
DETAIL:  User does not have CONNECT privilege.

Isto é o que eu esperava. Agora as coisas estranhas começam. Eu concedo ao usuário CONNECT:

postgres=# GRANT CONNECT ON DATABASE project2_core TO dietrich;
GRANT
postgres=# \l
                                          List of databases
     Name      |    Owner     | Encoding  |   Collate   |    Ctype    |       Access privileges       
---------------+--------------+-----------+-------------+-------------+-------------------------------
 postgres      | postgres     | SQL_ASCII | C           | C           | 
 project2_core | atm_project2 | UTF8      | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2+
               |              |           |             |             | dietrich=c/project2
 template0     | postgres     | SQL_ASCII | C           | C           | =c/postgres                  +
               |              |           |             |             | postgres=CTc/postgres
 template1     | postgres     | SQL_ASCII | C           | C           | =c/postgres                  +
               |              |           |             |             | postgres=CTc/postgres
(5 rows)

E sem mais concessões, o usuário tem permissão para criar uma tabela:

$ psql -h localhost -p 5432 -U dietrich -W project2_core
Password for user dietrich: 
psql (9.2.3)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.

project2_core=> create table adsf ();
CREATE TABLE
project2_core=> \d
        List of relations
 Schema | Name | Type  |  Owner   
--------+------+-------+----------
 public | adsf | table | dietrich
(1 row)

Eu esperava que o usuário não tivesse permissão para fazer nada antes que eu fizesse explicitamente GRANT USAGEno esquema e depois GRANT SELECTnas tabelas.

Onde está o meu erro? O que estou fazendo errado? Como posso conseguir o que quero (que um novo usuário não tenha permissão para fazer nada antes de conceder explicitamente a ele os direitos apropriados.

Estou perdido, e sua ajuda é muito apreciada :)

EDITAR Seguindo o conselho de @daniel-verite, agora revogo tudo imediatamente após criar o banco de dados. O usuário dietrich não tem mais permissão para criar uma tabela. Bom. MAS : Agora, também o proprietário do banco de dados, project2 , não tem permissão para criar uma tabela. Mesmo depois de emitir GRANT ALL PRIVILEGES ON DATABASE project2_core TO project2e GRANT ALL PRIVILEGES ON SCHEMA public TO project2, recebo um erro ERROR: nenhum esquema foi selecionado para criar em , e quando tento especificamente CREATE TABLE public.WHATEVER ();, recebo ERROR: permission denied for schema public . O que estou fazendo errado?

postgresql permissions
  • 3 3 respostas
  • 75797 Views

3 respostas

  • Voted
  1. Best Answer
    Daniel Vérité
    2013-02-24T09:50:57+08:002013-02-24T09:50:57+08:00

    Quando você cria um novo banco de dados, qualquer função tem permissão para criar objetos no publicesquema. Para remover essa possibilidade, você pode emitir imediatamente após a criação do banco de dados:

    REVOKE ALL ON schema public FROM public;
    

    Edit: após o comando acima, apenas um superusuário pode criar novos objetos dentro do publicesquema, o que não é prático. Supondo que um não superusuário foo_userdeva receber esse privilégio, isso deve ser feito com:

    GRANT ALL ON schema public TO foo_user;
    

    Para saber o que ALLsignifica para um esquema, devemos nos referir a GRANT no doc , (no PG 9.2 existem nada menos que 14 formas de instruções GRANT que se aplicam a coisas diferentes...). Parece que para um esquema significa CREATEe USAGE.

    Por outro lado, GRANT ALL PRIVILEGES ON DATABASE...concederá CONNECTe CREATEe TEMP, mas CREATEneste contexto se refere a esquemas, não a tabelas permanentes.

    Com relação a este erro: ERROR: no schema has been selected to create in, ocorre ao tentar criar um objeto sem qualificação de esquema (como em create table foo(...)) sem a permissão para criá-lo em qualquer esquema do search_path.

    • 67
  2. Craig Ringer
    2014-12-03T18:11:56+08:002014-12-03T18:11:56+08:00

    A coisa crucial a entender aqui é que os privilégios não são hierárquicos e não são herdados de objetos que contêm . ALLsignifica todos os privilégios para este objeto nem todos os privilégios para este objeto e todos os objetos contidos .

    Quando você concede ALLem um banco de dados, está concedendo CREATE, CONNECT, TEMP. Estas são ações no próprio objeto de banco de dados:

    • CONNECT: Conecte-se ao banco de dados
    • CREATE: Crie um esquema ( não uma tabela)
    • TEMP: Crie objetos temporários, incluindo mas não limitado a tabelas temporárias

    Agora, cada banco de dados PostgreSQL por padrão tem um publicesquema que é criado quando o banco de dados é criado. Esse esquema tem todos os direitos concedidos ao role public, do qual todos são membros implicitamente. Para um esquema, ALLsignifica CREATE, USAGE:

    • CREATE: Crie objetos (incluindo tabelas) dentro deste esquema
    • USAGE: Listar objetos no esquema e acessá-los se suas permissões permitirem

    Se você não especificar o esquema para criar um objeto como uma tabela, o mecanismo de banco de dados usará o search_path, e por padrão o publicesquema será o primeiro a search_pathser criado lá. Todos têm direitos publicpor padrão, então a criação é permitida. Os direitos dos usuários no banco de dados são irrelevantes neste momento, pois o usuário não está tentando fazer nada com o objeto do banco de dados, apenas um esquema dentro dele.

    Não importa se você não concedeu ao usuário nenhum direito além de conceder CONNECTno banco de dados, porque o publicesquema permite que todos os usuários criem tabelas nele por padrão. Daniel já explicou como revogar esse direito, se desejar.

    Se você deseja delegar todos os direitos explicitamente, revogue todos de public ou simplesmente elimine o esquema público. Você pode criar um novo banco de dados de modelo com essa alteração aplicada, se desejar. Como alternativa, você pode aplicá-lo a template1, mas isso provavelmente quebrará muitos códigos de terceiros que assumem que publicexistem e são graváveis.


    Isso pode fazer mais sentido se você observar uma analogia do sistema de arquivos.

    Se eu tiver a estrutura de diretórios (modo simplificado para mostrar apenas o modo que se aplica ao usuário atual):

    /dir1           mode=r-x
    /dir1/dir2      mode=rwx
    

    então não posso criar nada dentro /dir1do , porque não tenho permissão de gravação. Então, se eu touch /dir1/somefilereceber um erro de permissão negada.

    No entanto, tenho permissão para olhar dentro /dir1e acessar arquivos e diretórios contidos, incluindo /dir1/dir2. Eu tenho permissão de gravação em dir2. Então touch /dir1/dir2/somefileterá sucesso , mesmo que eu não tenha permissão de gravação para dir1.

    Mesma coisa com bancos de dados e esquemas.

    • 28
  3. Adrian Macneil
    2016-08-19T16:11:56+08:002016-08-19T16:11:56+08:00

    Se você deseja apenas impedir que novos usuários criem tabelas, você precisa executar o seguinte comando:

    REVOKE CREATE ON SCHEMA public FROM public;
    

    Se você REVOKE ALL(como outras respostas sugerem), também impedirá que os usuários tenham USAGEpermissões. USAGEsignifica que os usuários podem usar as permissões atribuídas a eles, portanto, se você remover isso, seus usuários não poderão listar ou acessar as tabelas às quais eles têm acesso.

    Alternativamente, você também pode REVOKE CREATEpara um usuário específico:

    REVOKE CREATE ON schema public FROM myuser;
    

    Veja também: Como criar um usuário somente leitura com PostgreSQL .

    • 9

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve