PostgreSQL - как быстро удалить пользователя с существующими привилегиями


122

Я пытаюсь сделать ограниченных пользователей БД для приложения, над которым я работаю, и хочу удалить пользователя базы данных Postgres, которого я использую для экспериментов. Есть ли способ удалить пользователя без необходимости сначала отозвать все его права вручную или отозвать все предоставленные пользователю права?

Ответы:


145

Как насчет

DROP USER <username>

На самом деле это псевдоним для DROP ROLE.

Вы должны явно отказаться от любых привилегий, связанных с этим пользователем, а также передать его право собственности другим ролям (или удалить объект).

Лучше всего это достигается

REASSIGN OWNED BY <olduser> TO <newuser>

и

DROP OWNED BY <olduser>

Последний удалит любые привилегии, предоставленные пользователю.

См. Документацию postgres для DROP ROLE и более подробное описание этого.


Дополнение:

По-видимому, попытка отбросить пользователя с помощью упомянутых здесь команд будет работать только в том случае, если вы выполняете их, будучи подключенными к той же базе данных, из которой были сделаны исходные ГРАНТЫ, как обсуждается здесь:

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


11
Выполнение: CREATE TABLE foo(bar SERIAL); ALTER TABLE foo OWNER TO postgres; CREATE USER testuser; GRANT ALL ON foo TO testuser; DROP USER testuser дали сообщения об ошибках: ERROR: role "testuser" cannot be dropped because some objects depend on it DETAIL: access to table foo. Однако DROP OWNED BY testuserсвое дело сделал, видимо, Постгрес считает гранты удаляемыми объектами.
millimoose

1
Пожалуйста, поясните, @Tim Kane и millimoose: я действительно не хочу, чтобы исходные таблицы отбрасывались, если я GRANT SELECT ON FOO TO TESTUSER, а затем DROP OWNED BY TESTUSER. Я думаю, вы говорите, что DROP OWNED BY удаляет только гранты, но не отбрасывает объект, которому был предоставлен грант. Верный?
Эндрю Вулф

1
Андрей, лучше прочитать документацию для уточнения. DROP СОБСТВЕННОСТЬЮ будет удалять таблицы , принадлежащие этому пользователю. REASSIGN OWNED BY переназначит эти таблицы другому пользователю. Выбери один.
Тим Кейн

3
Если вы беспокоитесь о том, что DROP OWNED BY заберет слишком много после выполнения REASSIGN OWNED, когда еще есть привилегии, вы можете ОТМЕНИТЬ ВСЕ ДЛЯ ВСЕХ [ТАБЛИЦЫ | ПОСЛЕДОВАТЕЛЬНОСТИ | ...] IN SCHEMA [имя схемы] FROM [роль]
jla 05

Действительно, команда DROP OWNED BY несколько неоднозначна по своему значению и последствиям. Мне пришлось внимательно прочитать документ, чтобы все было правильно. Спасибо за сообщения, ребята.
Себастьен Клеман,

49

Принятый ответ привел к ошибкам при попытке REASSIGN OWNED BY или DROP OWNED BY. У меня сработало следующее:

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;

Пользователь может иметь привилегии в других схемах, и в этом случае вам нужно будет запустить соответствующую строку REVOKE, заменив «public» на правильную схему. Чтобы показать все схемы и типы привилегий для пользователя, я отредактировал команду \ dp, чтобы сделать этот запрос:

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%';

Я не уверен, какие типы привилегий соответствуют аннулированию для ТАБЛИЦ, ПОСЛЕДОВАТЕЛЬНОСТЕЙ или ФУНКЦИЙ, но я думаю, что все они подпадают под одну из трех.


12
Я должен был добавить и это:REVOKE ALL PRIVILEGES ON DATABASE db_name FROM username;
Войцех Якубас

3
Также привилегии схемы.
greatvovan

2
Для привилегий схемы:revoke USAGE on SCHEMA some_schema from username;
Alphaaa

Я пробовал это, но в моем случае проблема не исчезла. Я разместил его как отдельный вопрос в stackoverflow.com/questions/61168608/…
Андрус

17

Также обратите внимание, если вы явно предоставили:

CONNECT ON DATABASE xxx TO GROUP ,

вам нужно будет отозвать это отдельно от DROP OWNED BY, используя:

REVOKE CONNECT ON DATABASE xxx FROM GROUP


Я перепробовал все, что описано выше, и у меня все еще не получалось, пока я не прокрутил немного дальше до этого, так что теперь у меня остались волосы. Некоторые. : D спасибо !!
Митч Кент

6

Пришлось добавить еще одну строчку в REVOKE ...

После запуска:

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;

Я все еще получаю сообщение об ошибке: имя пользователя не может быть удалено, потому что некоторые объекты зависят от него. ДЕТАЛИ: привилегии для схемы public

Мне не хватало этого:

REVOKE USAGE ON SCHEMA public FROM username;

Потом я смог отказаться от роли.

DROP USER username;

Вам также может потребоваться отозвать привилегии для «SCHEMA pg_catalog», если вы, например, создали пользователя для pg_rewind, который имеет привилегии над такими функциями, как pg_read_binary_file.
GreenReaper

5

Вот что наконец сработало для меня:

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

Нет REVOKE ALL PRIVILEGES ON ALL VIEWS, поэтому я закончил:

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

и обычно:

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

для достижения успеха:

drop role "XUSER";

0

В командной строке dropuserдоступна команда для удаления пользователя из postgres.

$ dropuser someuser

-19

Я столкнулся с той же проблемой и теперь нашел способ ее решить. Сначала вам нужно удалить базу данных пользователя, которого вы хотите удалить. Тогда пользователя можно будет легко удалить.

Я создал пользователя с именем «msf» и некоторое время пытался удалить пользователя и воссоздать его. Я выполнил следующие шаги, и мне это удалось.

1) Отбросить базу данных

dropdb msf

2) отпустите пользователя

dropuser msf

Теперь у меня пользователь успешно сбросился.


2
Это невероятно простой подход, поскольку он потребовал бы от меня воссоздания схемы базы данных для каждой итерации моей работы. (Это предполагает наличие детализированных разрешений для существующей схемы базы данных; то есть лучше, если схема базы данных останется нетронутой.)
millimoose
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.