Znajdź obiekty powiązane z rolą PostgreSQL

12

Jakiś czas temu stworzyłem użytkownika PostgreSQL o nazwie user1 (PostgreSQL 9.4.9).

Chcę upuścić tego użytkownika. Dlatego najpierw cofam wszystkie uprawnienia dotyczące tabel, sekwencji, funkcji, domyślnych uprawnień i własności:

ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON SEQUENCES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM user1;

REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM user1;

REASSIGN OWNED BY user1 TO postgres;

Wydaje się jednak, że jeden obiekt pozostaje powiązany z tym użytkownikiem w 2 bazach danych:

postgres=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  1 object in database db1
1 object in database db2

Wydaje się nawet, że jest to funkcja:

postgres=# \c db1
You are now connected to database "db1" as user "postgres".
db1=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  privileges for function text(boolean)
1 object in database db2

Ale nie mogę ustalić, który obiekt jest własnością użytkownika lub jest powiązany z użytkownikiem 1.

Jeśli nie pg_dump -s db1 | grep user1dostanę rezultatu! Czy może to być obiekt globalny?

Jak mogę zidentyfikować brakujący obiekt?

Wykonałem polecenia w każdej bazie danych (db1 i db2). Nie chcę upuszczać obiektów należących do user1, chcę tylko ponownie przypisać lub usunąć granty dla tego użytkownika.

Nicolas Payart
źródło

Odpowiedzi:

10

Odpowiedz na zadane pytanie

Aby wyszukać funkcję w komunikacie o błędzie i jej właściciela:

SELECT oid::regprocedure AS function
     , pg_get_userbyid(proowner) AS owner
FROM   pg_proc
WHERE  oid = 'text(boolean)'::regprocedure;

Związane z:

Rzeczywisty problem

Komunikat o błędzie mówi:

SZCZEGÓŁY: uprawnienia do tekstu funkcyjnego (boolean)

To nie o własności, ale o przywileje .

Podręcznik dla DROP ROLE:

Przed usunięciem roli musisz upuścić wszystkie posiadane obiekty (lub ponownie przypisać ich własność) i cofnąć wszelkie uprawnienia nadane roli innym obiektom .

I dla ALTER DEFAULT PRIVILEGES:

Jeśli chcesz zrezygnować z roli, dla której zmieniono domyślne uprawnienia, konieczne jest cofnięcie zmian w jej domyślnych uprawnieniach lub użycie DROP OWNEDBY, aby pozbyć się domyślnego wpisu uprawnień dla tej roli .

Wygląda również, jakbyś wykonał tylko REASSIGN OWNEDjedną bazę danych, ale instrukcja instruuje:

Ponieważ REASSIGN OWNEDnie wpływa na obiekty w innych bazach danych, zwykle konieczne jest wykonanie tego polecenia w każdej bazie danych zawierającej obiekty należące do roli, którą należy usunąć.

Odważny nacisk moje.

I ograniczyłeś swoje polecenia za pomocą IN SCHEMA public. Porzuć tę klauzulę, aby kierować na cały DB. Ale nie przejmuj się, jest ...

Proste rozwiązanie z DROP OWNED

REASSIGN OWNED BY user1 TO postgres;
DROP OWNED BY user1;

Wszystkie obiekty roli zmieniły własność postgresna pierwsze polecenie i są teraz bezpieczne. Sformułowanie DROP OWNEDjest nieco mylące, ponieważ pozbywa się również wszystkich przywilejów i przywilejów domyślnych. Podręcznik dla DROP OWNED:

DROP OWNEDupuszcza wszystkie obiekty w bieżącej bazie danych, które są własnością jednej z określonych ról. Wszelkie uprawnienia przyznane danym rolom obiektom w bieżącej bazie danych i obiektom współdzielonym (bazy danych, obszary tabel) również zostaną cofnięte.

Powtórz we wszystkich odpowiednich bazach danych, a następnie możesz wprowadzić się do zabicia:

DROP ROLE user1;
Erwin Brandstetter
źródło
6

Poniższe zapytanie zawiera listę obiektów z właścicielami. Do wszystkich przywilejów potrzebujemy więcej.

--r = ordinary table, i = index, S = sequence, v = view, m = materialized view, c = composite type, t = TOAST table, f = foreign table
SELECT 
    n.nspname AS schema_name,
    c.relname AS rel_name,
    c.relkind AS rel_kind,
    pg_get_userbyid(c.relowner) AS owner_name
  FROM pg_class c
  JOIN pg_namespace n ON n.oid = c.relnamespace

UNION ALL

-- functions (or procedures)
SELECT
    n.nspname AS schema_name,
    p.proname,
    'p',
    pg_get_userbyid(p.proowner)
  FROM pg_proc p
  JOIN pg_namespace n ON n.oid = p.pronamespace
Sahap Asci
źródło
Nadal nie znalazłem przy tym brakującego obiektu.
Nicolas Payart
@NicolasPayart: Czy wykonujesz zapytanie w odpowiedniej bazie danych?
Erwin Brandstetter
1

Musisz najpierw połączyć się z bazą danych. W twoim przypadku byłoby to

\c db1

i

\c db2

Następnie spróbuj ponownie uruchomić instrukcje ODWOŁAJ WSZYSTKIE UPRAWNIENIA i PONOWNIE PRZEKŁADUJ WŁASNE / UPUŚĆ WŁASNE.

Samuel Anyaele
źródło
1
Hej, dziękuję za twoją pierwszą odpowiedź. Jednak przed opublikowaniem zastanów się, co to dodaje do istniejących odpowiedzi, i opisz to również w swojej odpowiedzi.
dezso,