sql >> Database teknologi >  >> RDS >> PostgreSQL

AFTER LOGON(Oracle) trigger i PostgreSQL med udvidelse – login_hook

Inden du går ind i detaljerne, tak til forfatteren af ​​'login hook'-udvidelsen for at udvikle og vedligeholde den.

Mange gange har jeg i Oracle til Postgres migreringsøvelse set brugen af ​​Oracle Database Event trigger – EFTER LOGON ON. Dens ene type Oracle-database/brugerhændelsesudløser (LOGON), der udløses, når en bruger opretter forbindelse til en database, bruges typisk til at indstille brugermiljøet og udføre funktioner forbundet med sikre applikationsroller.

Lad os f.eks. sige, at vi har en applikationsbruger, hvor vi ønskede, at han skulle oprette forbindelse fra applikationen KUN og ikke fra andre programmer eller klienter (Oracle/SQL*Plus). Dette kan opnås ved at oprette en databasehændelsesudløser EFTER LOGON PÅ i Oracle.

Postgres understøtter de fleste standardudløsere, men der er ingen AFTER LOGON trigger. For at løse problemet valgte jeg login_hook udvidelse, der gjorde arbejdet ret godt.

Lad os se, hvad vi skal konvertere fra Oracle til Postgres ved hjælp af udvidelse. Der er en trigger i Oracle, der forhindrer applikationsbrugerne i at oprette forbindelse til databasen fra andre programmer/klienter(sqlplus).

CREATE OR REPLACE TRIGGER program_restrict
AFTER LOGON ON DATABASE
BEGIN
    FOR x IN (SELECT username, program FROM SYS.v_$session WHERE audsid = USERENV ('sessionid'))
    LOOP
    IF LTRIM (RTRIM (x.username)) = 'MIGUSER' AND UPPER(substr(x.program,1,7)) = 'SQLPLUS'
    THEN
      raise_application_error(-20999,'Not authorized to use in the Production environment!');
    END IF;
    END LOOP;
END program_restrict;

Fra ovenstående kode er det tydeligt, at MIGUSER (applikationsbruger) er begrænset til at oprette forbindelse via SQL*PLUS klient og ethvert forsøg, som brugeren gør, vil resultere i følgende fejl:

[oracle@rrr ~]$ rlsqlplus miguser/miguser
... <trimmed banner>
ERROR:
ORA-04088: error during execution of trigger 'SYS.PROGRAM_RESTRICT'
ORA-00604: error occurred at recursive SQL level 1
ORA-20999: Not authorized to use in the Production environment!
ORA-06512: at line 6
ORA-06512: at line 6

For at omgå ovenstående krav skal vi først kompilere udvidelsen login_hook i Postgres. Trin er meget enkle som enhver anden udvidelseskompilering

--Download zip/Git clone the extension
https://github.com/splendiddata/login_hook

-- Set the pg_config in your path
[root@node1-centos8 ~]# export PATH=/usr/pgsql-13/bin:$PATH

-- change to login_hook directory and run make/make install
[root@node1-centos8 ~]# cd login_hook
[root@node1-centos8 login_hook]# make
[root@node1-centos8 login_hook]# make install

-- add the login_hook.so to session_preload_libraries and restart the database

[root@node1-centos8 ~]# grep -i session_preload /var/lib/pgsql/13/data/postgresql.conf
session_preload_libraries = 'login_hook'
[root@node1-centos8 ~]# systemctl restart postgresql-13.service

-- connect to the database and create the extension
[postgres@node1-centos8 ~]$ psql
psql (13.1)
Type "help" for help.

postgres=# create extension login_hook;
CREATE EXTENSION

Nu er vi alle klar til at bruge denne udvidelse. I vores tilfælde vil vi forhindre applikationsbrugeren i at bruge Postgres-klienten psql . For at gøre dette skal du bruge skabelonfunktionen på login_hook udvidelsessiden og rediger den for at fange klientens applikationsnavn fra pg_stat_activity se og afslut det ved hjælp af pg_terminate_backend() system funktion. Bemærk:Du kan bruge den samme skabelonfunktion til flere formål til at administrere applikationsbrugeren.

CREATE OR REPLACE FUNCTION login_hook.login() RETURNS VOID LANGUAGE PLPGSQL AS $$
DECLARE
    ex_state   TEXT;
    ex_message TEXT;
    ex_detail  TEXT;
    ex_hint    TEXT;
    ex_context TEXT;
	rec record;
BEGIN
	IF NOT login_hook.is_executing_login_hook()
	THEN
	    RAISE EXCEPTION 'The login_hook.login() function should only be invoked by the login_hook code';
	END IF;
	
	BEGIN
    for rec in select pid,usename,application_name from pg_stat_activity where application_name ilike 'psql%'
    loop
          if rtrim(rec.usename) = 'miguser' and rtrim(rec.application_name) = 'psql' then
            raise notice 'Application users(%) restricted to connect with any clients(%)',rec.usename,rec.application_name;
            perform pg_terminate_backend(rec.pid);
          end if;
    end loop;
	EXCEPTION
	   WHEN OTHERS THEN
	       GET STACKED DIAGNOSTICS ex_state   = RETURNED_SQLSTATE
	                             , ex_message = MESSAGE_TEXT
	                             , ex_detail  = PG_EXCEPTION_DETAIL
	                             , ex_hint    = PG_EXCEPTION_HINT
	                             , ex_context = PG_EXCEPTION_CONTEXT;
	       RAISE LOG e'Error in login_hook.login()\nsqlstate: %\nmessage : %\ndetail  : %\nhint    : %\ncontext : %'
	               , ex_state
	               , ex_message
	               , ex_detail
	               , ex_hint
	               , ex_context;
    END	;       
END$$;

-- Give exeuction grant on the function. 
GRANT EXECUTE ON FUNCTION login_hook.login() TO PUBLIC;

Lad os nu se, om applikationsbrugeren kan bruge Postgres psql for at oprette forbindelse til databasen.

[postgres@node1-centos8 ~]$ psql -U miguser -d postgres -p 5432
NOTICE:  Application users(miguser) restricted to connect with any clients(psql)
psql: error: FATAL:  terminating connection due to administrator command
CONTEXT:  SQL statement "SELECT pg_terminate_backend(rec.pid)"
PL/pgSQL function login_hook.login() line 20 at PERFORM
SQL statement "select login_hook.login()

Fedt nok. Vi er i stand til at forhindre applikationsbrugernes forbindelser fra ethvert andet program/klient i Postgres.

Tak.

–Raghav


  1. Hvad er databasebegrænsninger?

  2. PG::UndefineretTabel:FEJL:Relationen eksisterer ikke med en korrekt Rails-navngivning og -konvention

  3. Android-fejl:Kan ikke udføre denne handling, fordi forbindelsespuljen er blevet lukket

  4. SQL Sådan opdateres SUM for kolonne over gruppe i samme tabel