PostgreSQL - como eliminar rapidamente um usuário com privilégios existentes


122

Estou tentando criar usuários de banco de dados restritos para o aplicativo em que estou trabalhando e desejo excluir o usuário do banco de dados Postgres que estou usando para experimentar. Existe alguma maneira de descartar o usuário sem ter que revogar todos os seus direitos manualmente primeiro ou revogar todas as concessões que um usuário possui?

Respostas:


144

E se

DROP USER <username>

Este é realmente um apelido para DROP ROLE.

É necessário eliminar explicitamente quaisquer privilégios associados a esse usuário, também para mover sua propriedade para outras funções (ou soltar o objeto).

Isso é melhor alcançado por

REASSIGN OWNED BY <olduser> TO <newuser>

e

DROP OWNED BY <olduser>

Este último removerá todos os privilégios concedidos ao usuário.

Veja os documentos do postgres para o DROP ROLE e a descrição mais detalhada disso.


Adição:

Aparentemente, tentar descartar um usuário usando os comandos mencionados aqui só funcionará se você os estiver executando enquanto estiver conectado ao mesmo banco de dados do qual os GRANTS originais foram criados, conforme discutido aqui:

https://www.postgresql.org/message-id/83894A1821034948BA27FE4DAA47427928F7C29922%40apde03.APD.Satcom.Local


11
Fazendo: CREATE TABLE foo(bar SERIAL); ALTER TABLE foo OWNER TO postgres; CREATE USER testuser; GRANT ALL ON foo TO testuser; DROP USER testuser deu as mensagens de erro: ERROR: role "testuser" cannot be dropped because some objects depend on it DETAIL: access to table foo. No entanto, DROP OWNED BY testusercomo o truque, aparentemente o Postgres considera que as doações são objetos descartáveis.
millimoose

1
Por favor, esclareça, @ Tim Kane e millimoose: eu realmente não quero que as tabelas originais sejam descartadas se SUBSTITUIR SELECIONAR NO FOO TO TESTUSER e depois soltar a propriedade do TESTUSER. Acho que você está dizendo que o DROP OWNED BY está apenas retirando as doações, mas não o objeto para o qual a concessão foi feita. Corrigir?
Andrew Wolfe

1
Andrew, é melhor ler a documentação para esclarecimentos. GOTA OWNED BY vai soltar tabelas pertencentes a esse usuário. A nova atribuição de propriedade por reatribuirá essas tabelas a um usuário diferente. Escolha um.
Tim Kane

3
Se você está preocupado com o DROP OWNED, executando demais depois de executar REASSIGN OWNED quando ainda existem privilégios, você pode REVOGAR TUDO EM TODAS [TABELAS | SEQUÊNCIAS | ...] NO ESQUEMA [nome do esquema] DE [função]
jla

De fato, o comando DROP OWNED BY é um pouco ambíguo em seu significado e efeitos. Eu tive que ler o documento cuidadosamente para acertar. Obrigado pelos posts.
Sébastien Clément

49

A resposta aceita resultou em erros para mim ao tentar REASSIGN OWNED BY ou DROP OWNED BY. O seguinte funcionou para mim:

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM username;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM username;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM username;
DROP USER username;

O usuário pode ter privilégios em outros esquemas; nesse caso, você precisará executar a linha REVOKE apropriada com "public" substituído pelo esquema correto. Para mostrar todos os esquemas e tipos de privilégios para um usuário, editei o comando \ dp para fazer esta consulta:

SELECT 
  n.nspname as "Schema",
  CASE c.relkind 
    WHEN 'r' THEN 'table' 
    WHEN 'v' THEN 'view' 
    WHEN 'm' THEN 'materialized view' 
    WHEN 'S' THEN 'sequence' 
    WHEN 'f' THEN 'foreign table' 
  END as "Type"
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE pg_catalog.array_to_string(c.relacl, E'\n') LIKE '%username%';

Não tenho certeza de quais tipos de privilégios correspondem à revogação em TABLES, SEQUENCES ou FUNCTIONS, mas acho que todos eles se enquadram em um dos três.


12
Eu tive que adicionar este também:REVOKE ALL PRIVILEGES ON DATABASE db_name FROM username;
Wojciech Jakubas

3
Também privilégios de esquema.
22819 greatvovan

2
Para privilégios de esquema:revoke USAGE on SCHEMA some_schema from username;
Alphaaa

Eu tentei isso, mas o problema persiste no meu caso. Eu postei como uma pergunta separada em stackoverflow.com/questions/61168608/…
Andrus

17

Observe também, se você concedeu explicitamente:

CONNECT ON DATABASE xxx TO GROUP ,

você precisará revogá-lo separadamente do DROP OWNED BY, usando:

REVOKE CONNECT ON DATABASE xxx FROM GROUP


Eu tinha tentado tudo acima e isso ainda não estava funcionando para mim, até que eu rolei um pouco mais adiante, então agora tenho um pouco de cabelo. Alguns. : D obrigado !!
Mitch Kent

6

Eu tive que adicionar mais uma linha para REVOKE ...

Depois de correr:

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM username;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM username;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM username;

Eu ainda estava recebendo o erro: o nome de usuário não pode ser descartado porque alguns objetos dependem dele. DETAIL: privilégios para o esquema public

Eu estava sentindo falta disso:

REVOKE USAGE ON SCHEMA public FROM username;

Então eu fui capaz de largar o papel.

DROP USER username;

Também pode ser necessário revogar privilégios para 'SCHEMA pg_catalog' se você, por exemplo, criou um usuário para pg_rewind que possui privilégios sobre funções como pg_read_binary_file.
GreenReaper 14/04

5

Aqui está o que finalmente funcionou para mim:

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA myschem FROM user_mike;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA myschem FROM user_mike;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA myschem FROM user_mike;
REVOKE ALL PRIVILEGES ON SCHEMA myschem FROM user_mike;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschem REVOKE ALL ON SEQUENCES FROM user_mike;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschem REVOKE ALL ON TABLES FROM user_mike;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschem REVOKE ALL ON FUNCTIONS FROM user_mike;
REVOKE USAGE ON SCHEMA myschem FROM user_mike;
REASSIGN OWNED BY user_mike TO masteruser;
DROP USER user_mike ;

2

Não existe REVOKE ALL PRIVILEGES ON ALL VIEWS, então terminei com:

do $$
DECLARE r record;
begin
  for r in select * from pg_views where schemaname = 'myschem'
  loop
    execute 'revoke all on ' || quote_ident(r.schemaname) ||'.'|| quote_ident(r.viewname) || ' from "XUSER"';
  end loop;
end $$;

e habitual:

REVOKE ALL PRIVILEGES ON DATABASE mydb FROM "XUSER";
REVOKE ALL PRIVILEGES ON SCHEMA myschem FROM "XUSER";
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA myschem FROM "XUSER";
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA myschem FROM "XUSER";
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA myschem FROM "XUSER";

para o seguinte ter sucesso:

drop role "XUSER";

0

Na linha de comando, existe um comando dropuserdisponível para eliminar o usuário do postgres.

$ dropuser someuser

-19

Enfrentei o mesmo problema e agora encontrei uma maneira de resolvê-lo. Primeiro, você deve excluir o banco de dados do usuário que deseja eliminar. Em seguida, o usuário pode ser facilmente excluído.

Criei um usuário chamado "msf" e lutei um pouco para excluir o usuário e recriá-lo. Segui as etapas abaixo e obtive sucesso.

1) Solte o banco de dados

dropdb msf

2) largue o usuário

dropuser msf

Agora, o usuário caiu com sucesso.


2
Essa é uma abordagem inacreditavelmente de corte e queima, pois exigiria que eu recriasse o esquema do banco de dados para cada iteração do meu trabalho. (Que envolveu ter permissões de grão fino em um esquema de banco de dados existente;. Ou seja, é melhor se o esquema de banco de dados permanece intocado)
millimoose
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.