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?

millimoose
fonte

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

Tim Kane
fonte
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.

Sasha Kondrashov
fonte
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

Eric E
fonte
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;
CD4
fonte
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 ;
Preti
fonte
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";
gavenkoa
fonte
0

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

$ dropuser someuser
Super Nova
fonte
-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.

Meshach Marimuthu
fonte
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