PostgreSQL: cómo eliminar rápidamente a un usuario con privilegios existentes

122

Estoy tratando de crear usuarios de base de datos restringidos para la aplicación en la que estoy trabajando y quiero eliminar el usuario de la base de datos de Postgres que estoy usando para experimentar. ¿Hay alguna forma de eliminar al usuario sin tener que revocar primero todos sus derechos manualmente o revocar todas las concesiones que tiene un usuario?

milimosa
fuente

Respuestas:

144

Qué tal si

DROP USER <username>

Este es en realidad un alias de DROP ROLE.

Debe eliminar explícitamente cualquier privilegio asociado con ese usuario, también para mover su propiedad a otros roles (o eliminar el objeto).

Esto se logra mejor

REASSIGN OWNED BY <olduser> TO <newuser>

y

DROP OWNED BY <olduser>

Este último eliminará cualquier privilegio otorgado al usuario.

Consulte los documentos de postgres para DROP ROLE y la descripción más detallada de esto.


Adición:

Aparentemente, intentar eliminar a un usuario usando los comandos mencionados aquí solo funcionará si los está ejecutando mientras está conectado a la misma base de datos de la que se hicieron los GRANTS originales, como se explica aquí:

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

Tim Kane
fuente
11
Haciendo: CREATE TABLE foo(bar SERIAL); ALTER TABLE foo OWNER TO postgres; CREATE USER testuser; GRANT ALL ON foo TO testuser; DROP USER testuser dio a los mensajes de error: ERROR: role "testuser" cannot be dropped because some objects depend on it DETAIL: access to table foo. Sin embargo, DROP OWNED BY testuserhizo el truco, aparentemente Postgres considera que las subvenciones son objetos soltables.
millimoose
1
Por favor, aclare, @Tim Kane y millimoose: Realmente no quiero que se eliminen las tablas originales si CONCEDO SELECCIONAR FOO A TESTUSER y luego DEJARLO DE TESTUSER. Creo que estás diciendo que DROP OWNED BY solo está eliminando las subvenciones, pero no elimina el objeto al que se otorgó la subvención. ¿Correcto?
Andrew Wolfe
1
Andrew, es mejor leer la documentación para aclaraciones. DROP PROPIEDAD DE será eliminar tablas propiedad de ese usuario. REASSIGN OWNED BY reasignará esas tablas a un usuario diferente. Elige uno.
Tim Kane
3
Si le preocupa que DROP OWNED saque demasiado después de hacer REASSIGN OWNED cuando todavía hay privilegios, puede REVOCAR TODO EN TODAS LAS [TABLAS | SECUENCIAS | ...] EN ESQUEMA [nombre de esquema] DE [función]
jla
De hecho, el comando DROP OWNED BY es un poco ambiguo en su significado y efectos. Tuve que leer el documento con atención para hacerlo bien. Gracias por sus posts, chicos.
Sébastien Clément
49

La respuesta aceptada resultó en errores para mí al intentar REASIGNAR PROPIEDAD DE o DROP OWNED BY. Lo siguiente funcionó para mí:

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;

El usuario puede tener privilegios en otros esquemas, en cuyo caso tendrá que ejecutar la línea REVOKE apropiada con "público" reemplazado por el esquema correcto. Para mostrar todos los esquemas y tipos de privilegios de un usuario, edité el comando \ dp para realizar 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%';

No estoy seguro de qué tipos de privilegios corresponden a la revocación en TABLAS, SECUENCIAS o FUNCIONES, pero creo que todos caen bajo uno de los tres.

Sasha Kondrashov
fuente
12
Tuve que agregar este también:REVOKE ALL PRIVILEGES ON DATABASE db_name FROM username;
Wojciech Jakubas
3
También privilegios de esquema.
greatvovan
2
Para privilegios de esquema:revoke USAGE on SCHEMA some_schema from username;
Alphaaa
Intenté esto pero el problema persiste en mi caso. Lo publiqué como una pregunta separada en stackoverflow.com/questions/61168608/…
Andrus
17

También tenga en cuenta, si ha concedido explícitamente:

CONNECT ON DATABASE xxx TO GROUP ,

deberá revocar esto por separado de DROP OWNED BY, usando:

REVOKE CONNECT ON DATABASE xxx FROM GROUP

Eric E
fuente
Había intentado todo lo anterior y todavía no funcionaba para mí, hasta que me desplacé un poco más hacia abajo, así que ahora me queda algo de cabello. Algunos. : D gracias !!
Mitch Kent
6

Tuve que agregar una línea más para REVOKE ...

Despues 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;

Todavía recibía el error: el nombre de usuario no se puede eliminar porque algunos objetos dependen de él DETALLE: privilegios para el esquema público

Me estaba perdiendo esto:

REVOKE USAGE ON SCHEMA public FROM username;

Entonces pude dejar el papel.

DROP USER username;
CD4
fuente
También puede necesitar revocar privilegios para 'SCHEMA pg_catalog' si, por ejemplo, ha creado un usuario para pg_rewind que tiene privilegios sobre funciones como pg_read_binary_file.
GreenReaper
5

Esto es lo que finalmente funcionó para mí:

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
fuente
2

No hay REVOKE ALL PRIVILEGES ON ALL VIEWS, así que terminé con:

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 $$;

y 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 que lo siguiente tenga éxito:

drop role "XUSER";
Gavenkoa
fuente
0

En la línea de comandos, hay un comando dropuserdisponible para eliminar al usuario de postgres.

$ dropuser someuser
SuperNova
fuente
-19

Enfrenté el mismo problema y ahora encontré una manera de resolverlo. Primero debe eliminar la base de datos del usuario que desea eliminar. Entonces, el usuario puede eliminarse fácilmente.

Creé un usuario llamado "msf" y luché un tiempo para eliminar al usuario y recrearlo. Seguí los pasos a continuación y lo logré.

1) Suelta la base de datos

dropdb msf

2) soltar al usuario

dropuser msf

Ahora conseguí eliminar al usuario con éxito.

Meshach Marimuthu
fuente
2
Este es un enfoque increíblemente de talar y grabar, ya que me habría requerido recrear el esquema de la base de datos para cada iteración de mi trabajo. (Lo que implicaba tener permisos detallados en un esquema de base de datos existente; es decir, es mejor si el esquema de la base de datos permanece intacto).
millimoose