O que GRANT USAGE ON SCHEMA faz exatamente?


121

Estou tentando criar um banco de dados Postgres pela primeira vez, então esta é provavelmente uma pergunta estúpida. Atribuí permissões básicas somente leitura para a função db que deve acessar o banco de dados de meus scripts php, e tenho uma curiosidade: se eu executar

GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;

há alguma necessidade de executar também

GRANT USAGE ON SCHEMA schema TO role;

?

Da documentação :

USO: Para esquemas, permite o acesso a objetos contidos no esquema especificado (assumindo que os próprios requisitos de privilégio dos objetos também sejam atendidos). Essencialmente, isso permite que o donatário "procure" objetos dentro do esquema.

Acho que, se posso selecionar ou manipular quaisquer dados contidos no esquema, posso acessar quaisquer objetos do próprio esquema. Estou errado? Se não, para que GRANT USAGE ON SCHEMAserve? E o que a documentação significa exatamente com "assumindo que os requisitos de privilégio dos próprios objetos também sejam atendidos"?

Respostas:


126

GRANTs em objetos diferentes são separados. GRANTo uso de um banco de dados não concede GRANTdireitos ao esquema interno. Da mesma forma, usar GRANTum esquema não concede direitos sobre as tabelas internas.

Se você tiver direitos a SELECTpartir de uma tabela, mas não tiver o direito de vê-la no esquema que a contém, não poderá acessar a tabela.

Os testes de direitos são feitos em ordem:

Do you have `USAGE` on the schema? 
    No:  Reject access. 
    Yes: Do you also have the appropriate rights on the table? 
        No:  Reject access. 
        Yes: Check column privileges.

Sua confusão pode surgir do fato de que o publicesquema tem um padrão GRANTde todos os direitos para a função public, da qual cada usuário / grupo é membro. Portanto, todo mundo já usa esse esquema.

A frase:

(assumindo que os próprios requisitos de privilégio dos objetos também sejam atendidos)

Está dizendo que você deve ter USAGEum esquema para usar objetos dentro dele, mas ter USAGEum esquema não é por si só suficiente para usar os objetos dentro do esquema, você também deve ter direitos sobre os próprios objetos.

É como uma árvore de diretórios. Se você criar um diretório somedircom um arquivo somefiledentro dele, configure-o para que apenas seu próprio usuário possa acessar o diretório ou o arquivo (modo rwx------no diretório, modo rw-------no arquivo), então ninguém mais poderá listar o diretório para ver se o arquivo existe.

Se você conceder direitos de leitura universal no arquivo (modo rw-r--r--), mas não alterar as permissões do diretório, não fará diferença. Ninguém pode ver o arquivo para lê-lo, porque não tem permissão para listar o diretório.

Se, em vez disso, você definir rwx-r-xr-xno diretório, definindo-o de forma que as pessoas possam listar e percorrer o diretório, mas não alterando as permissões do arquivo, as pessoas podem listar o arquivo, mas não podem lê- lo porque não teriam acesso ao arquivo.

Você precisa definir as duas permissões para que as pessoas possam realmente ver o arquivo.

Mesma coisa na pág. Você precisa de USAGEdireitos de esquema e direitos de objeto para executar uma ação em um objeto, como SELECTem uma tabela.

(A analogia cai um pouco porque o PostgreSQL ainda não tem segurança em nível de linha, então o usuário ainda pode "ver" que a tabela existe no esquema ao SELECTiniciar pg_classdiretamente. Eles não podem interagir com ela de nenhuma forma , porém, é apenas a parte da "lista" que não é exatamente a mesma.)


2
Agora está muito claro com o exemplo de diretório :) Devo dizer que isso é um problema se você inserir alguma tabela ou linha com um superusuário, por exemplo, quando você adiciona postGIS usando CREATE EXTENSION. É mais ou menos o mesmo problema com arquivos criados no Linux enquanto você su. Será bom se houver uma espécie de sudo -einstruções for em pqsl.
Marco Sulla

De qualquer forma, agora percebi que GRANTdeclarações não específicas para tabelas não são o que eu quero, pois afetam todos os bancos de dados ...: s
Marco Sulla

1
@LucasMalor Er ... não, não tem. GRANTem um esquema afeta esse esquema. GRANT ... ON ALL TABLES IN SCHEMA ...afeta todas as tabelas em um esquema em um banco de dados específico. Não há programas GRANTque afetem todos os bancos de dados (ok, exceto GRANTmembros da função para um usuário).
Craig Ringer

Ah, desculpe-me, eu executei as instruções quando estava logado como superusuário "postgres" e elas afetaram o banco de dados "postgres". Pensei que se você rodar psqlsem -d dbvocê estará operando "fora" de qualquer banco de dados, mas você está sempre conectado a um banco de dados e por padrão está conectado ao banco de dados com o mesmo nome da sua função. db = role = user = group ... é um pouco confuso: D
Marco Sulla

@LucasMalor Pense assim. Por padrão, você se conecta a um banco de dados com o mesmo nome da função de login ("usuário") com a qual se conecta. "Usuários" são apenas funções que possuem WITH LOGIN; essencialmente, tudo pode ser um grupo e os grupos podem ser configurados para permitir o login.
Craig Ringer

72

Para um sistema de produção, você pode usar esta configuração:

--ACCESS DB
REVOKE CONNECT ON DATABASE nova FROM PUBLIC;
GRANT  CONNECT ON DATABASE nova  TO user;

--ACCESS SCHEMA
REVOKE ALL     ON SCHEMA public FROM PUBLIC;
GRANT  USAGE   ON SCHEMA public  TO user;

--ACCESS TABLES
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC ;
GRANT SELECT                         ON ALL TABLES IN SCHEMA public TO read_only ;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write ;
GRANT ALL                            ON ALL TABLES IN SCHEMA public TO admin ;

adminTambém não deve ser concedido CREATEno esquema?
Dan

2
Os acessos são alocados de acordo com um modelo hierárquico: BD -> ESQUEMA -> TABELAS . Com GRANT USAGE ON SCHEMA, o usuário administrador não pode criar uma tabela, mas pode fazê-lo com ALL GRANT ALL ON SCHEMA....
bilelovitch

@bilelovitch: você quer dizer grant all on schema public to admin? PS: Eu adicionei também grant usage, select on all sequences in schema public to read_only/read_write; grant execute on all functions in schema public to read_only/read_write;
Marco Sulla

2

Bem, esta é minha solução final para um banco de dados simples, para Linux:

# Read this before!
#
# * roles in postgres are users, and can be used also as group of users
# * $ROLE_LOCAL will be the user that access the db for maintenance and
#   administration. $ROLE_REMOTE will be the user that access the db from the webapp
# * you have to change '$ROLE_LOCAL', '$ROLE_REMOTE' and '$DB'
#   strings with your desired names
# * it's preferable that $ROLE_LOCAL == $DB

#-------------------------------------------------------------------------------

//----------- SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - START ----------//

cd /etc/postgresql/$VERSION/main
sudo cp pg_hba.conf pg_hba.conf_bak
sudo -e pg_hba.conf

# change all `md5` with `scram-sha-256`
# save and exit

//------------ SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - END -----------//

sudo -u postgres psql

# in psql:
create role $ROLE_LOCAL login createdb;
\password $ROLE_LOCAL
create role $ROLE_REMOTE login;
\password $ROLE_REMOTE

create database $DB owner $ROLE_LOCAL encoding "utf8";
\connect $DB $ROLE_LOCAL

# Create all tables and objects, and after that:

\connect $DB postgres

revoke connect on database $DB from public;
revoke all on schema public from public;
revoke all on all tables in schema public from public;

grant connect on database $DB to $ROLE_LOCAL;
grant all on schema public to $ROLE_LOCAL;
grant all on all tables in schema public to $ROLE_LOCAL;
grant all on all sequences in schema public to $ROLE_LOCAL;
grant all on all functions in schema public to $ROLE_LOCAL;

grant connect on database $DB to $ROLE_REMOTE;
grant usage on schema public to $ROLE_REMOTE;
grant select, insert, update, delete on all tables in schema public to $ROLE_REMOTE;
grant usage, select on all sequences in schema public to $ROLE_REMOTE;
grant execute on all functions in schema public to $ROLE_REMOTE;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on tables to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on sequences to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on functions to $ROLE_LOCAL;

alter default privileges for role $ROLE_REMOTE in schema public
    grant select, insert, update, delete on tables to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant usage, select on sequences to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant execute on functions to $ROLE_REMOTE;

# CTRL+D

1
Qual usuário deve ser usado para "# Criar todas as tabelas e objetos, e depois disso:"? Quem é o dono das mesas e demais objetos no seu caso?
Christophe Furmaniak

@ChristopheFurmaniak você está certo, eu corrigi o processo. O dono do banco de dados e seus objetos é $ ROLE_LOCAL e, após criar a estrutura do banco de dados, devemos retornar ao superusuário do postgres.
Marco Sulla

Acredito que você tenha um problema nos comandos "ALTER DEFAULT PRIVILEGES ...". Este comando é usado para acionar a concessão de privilégios a um usuário (função) quando um usuário diferente (função) cria um objeto. Ver página 11, seção 7.1, deste documento para esclarecimentos. Atualmente, seu ROLE_REMOTE não terá acesso a nenhum objeto que ROLE_LOCAL criaria. Os comandos ROLE_LOCAL estão apenas dando privs que a função já possui como proprietário desses objetos. O mesmo vale para os comandos ROLE_REMOTE.
emispowder
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.