In quale ordine PostgreSQL controlla le autorizzazioni degli oggetti?


16

Dato un ruolo nel database user1, una funzione something()definita come una procedura memorizzata e una vista creata come:

CREATE VIEW view1 AS select * from something()

E, date queste autorizzazioni:

REVOKE ALL ON FUNCTION something FROM user1
REVOKE SELECT ON view1 FROM user1

Quando corro SELECT * FROM view1, ricevo un errore permission denied for function something().

La mia domanda è: se revoco le autorizzazioni di selezione sulla vista, perché viene chiamata la funzione? Mi aspettavo di ricevere qualcosa di simile:

permission denied for relation view1

Grazie!


2
AFAIK non esiste un ordine definito in cui le autorizzazioni sono controllate.
Craig Ringer,

@CraigRinger Grazie! Immagino sia quello il comportamento previsto allora. Mentre espongo la vista in un'API, stavo cercando di evitare di rivelare i dettagli dell'implementazione della vista (dato il messaggio di errore che si lamentava delle autorizzazioni della funzione anziché della vista).
santios,

1
Sospetterei che le autorizzazioni vengano valutate più o meno allo stesso modo dei piani di query (ad es. Dal basso verso l'alto) e come tale viene valutato per primo l'oggetto più basso, che nel tuo caso è la something()funzione. Un rapido test sarebbe quello di modificare la query in modo da ottenere un piano di spiegazione diverso, regolando le autorizzazioni di conseguenza e quindi vedere se l'errore di autorizzazione viene generato sulla something()funzione o se segue come viene rivalutato il nuovo piano di esecuzione.
John Eisbrener,

Se si concedono le autorizzazioni per la funzione e le si revoca sulla vista, si dovrebbe omettere qualsiasi menzione alla funzione sottostante
amenadiel

Risposte:


3

Il problema in quel caso non riguarda esattamente l'ordine di autorizzazione, ma l'ordine di esecuzione.

In ripresa, per PostgreSQL:

1- Le viste che accedono a tabelle avranno la precedenza sull'autorizzazione delle tabelle

2- Le funzioni di visualizzazione delle viste dovranno valutare tutte le funzioni, prima di essere verificate, quindi le funzioni devono essere eseguite prima di accedere alla vista, anche se la vista non ha autorizzazioni di selezione ...

Come possiamo provarlo?

In postgresql, le viste sono in grado di darti le autorizzazioni per effettuare una selezione in una tabella, anche se l'utente non dispone di tali autorizzazioni.

Per esempio:

create view view2 as select * from table1;
revoke all on table1 from user1;
grant select on view2 to user1; 

Accedi come utente 1:

select * from table1 (permission denied) 
select * from view2 (sucess - the query executes)

Nel caso, l'utente sarà in grado di selezionare view2 anche senza avere il permesso di selezionare la tabella.

Ma cosa succede se facciamo la stessa cosa con una funzione ? Il comportamento NON è lo stesso. Consente di creare una funzione che attende 5 secondi prima di restituire 1 (quindi possiamo eseguire il debug se postgresql esegue la funzione ogni volta che chiamiamo la vista)

CREATE OR REPLACE FUNCTION something() RETURNS integer
AS 'select 1 from pg_sleep(5);'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT; --this function will delay 5 seconds

create view view1 as select * from something();
revoke all on function something() from user1;
grant select on view1 to user1; 

Accedi come utente 1:

select * from something(); (permission denied for something) 
select * from view1 (permission denied for something )

L'autorizzazione a fare la selezione sulla vista non sovrascrive l'autorizzazione della funzione, e ancora peggio se revochiamo le autorizzazioni da view1, il messaggio mostra ancora che postgresql ha interrotto la nostra query a causa della funzione, indipendentemente dall'autorizzazione della vista. (questo è esattamente ciò che sta accadendo nella domanda)

Ma la funzione viene davvero verificata per prima? Se diamo le autorizzazioni 'all' alla funzione, ma revochiamo l'autorizzazione di visualizzazione ...

grant all on function something to user1; 
revoke all on view1 from user1; 
select * from view1;
Delayed 5 seconds... (the function executed!) 
Permission denied for select on view1

Come vedi postgresql ASPETTATO 5 SECONDI prima di dire che non abbiamo il permesso di emettere la vista , mostrando che la funzione "qualcosa ()" è eseguita. Pertanto, il ritorno dei dati della funzione deve esistere prima del controllo della vista.

Quindi ora con questo test, ora sappiamo che PostgreSQL aveva bisogno di valutare tutte le funzioni prima di continuare la nostra query, è come se la query non esistesse fino a quando tutte le funzioni coinvolte non saranno completamente completate, quindi la vista non può essere risolta per postgresql sapere se abbiamo o meno il permesso di selezionarlo.

Penso che questo risponda alla tua domanda nei termini di "ordine di autorizzazione", ma perché postgresql deve valutare tutte le funzioni prima di continuare, questa è un'altra domanda ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.