Dalam urutan apa PostgreSQL memeriksa izin objek?


16

Diberikan peran basis data,, user1fungsi yang something()didefinisikan sebagai prosedur tersimpan dan tampilan dibuat seperti:

CREATE VIEW view1 AS select * from something()

Dan, mengingat izin ini:

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

Ketika saya menjalankan SELECT * FROM view1, saya mendapatkan kesalahan permission denied for function something().

Pertanyaan saya adalah, jika saya mencabut izin pilih pada tampilan, mengapa fungsinya dipanggil? Saya mengharapkan untuk menerima sesuatu seperti:

permission denied for relation view1

Terima kasih!


2
AFAIK tidak ada urutan yang ditentukan untuk memeriksa izin.
Craig Ringer

@CraigRinger Terima kasih! Saya kira itulah perilaku yang diharapkan. Saat saya mengekspos tampilan dalam api, saya mencoba untuk menghindari mengungkapkan detail implementasi tampilan (mengingat pesan kesalahan mengeluh tentang izin fungsi alih-alih tampilan).
santios

1
Saya akan menduga izin dievaluasi dalam banyak rencana permintaan mode yang sama (misalnya dari bawah ke atas), dan dengan demikian objek terendah dievaluasi terlebih dahulu, yang dalam kasus Anda adalah something()fungsinya. Tes cepat akan mengubah kueri sehingga Anda mendapatkan rencana menjelaskan yang berbeda, menyesuaikan izin yang sesuai, dan kemudian melihat apakah kesalahan izin dilemparkan pada something()fungsi atau jika mengikuti bagaimana rencana eksekusi baru sedang dievaluasi kembali.
John Eisbrener

Jika Anda memberikan izin pada fungsi dan mencabutnya pada tampilan, itu harus menghilangkan penyebutan fungsi yang mendasarinya
amenadiel

Jawaban:


3

Masalah dalam kasus itu bukan tentang urutan izin, tetapi urutan eksekusi.

Dalam resume, untuk PostgreSQL:

1- Tampilan yang mengakses tabel akan menimpa izin tabel

2 - Tampilan fungsi acessing, perlu mengevaluasi semua fungsi, sebelum diperiksa - jadi fungsi harus dieksekusi sebelum mengakses tampilan, bahkan jika tampilan tidak memiliki izin pilih ...

Bagaimana kita bisa membuktikannya?

Dalam postgresql, tampilan dapat memberi Anda izin untuk melakukan pemilihan dalam tabel, bahkan jika pengguna tidak memiliki izin ini.

Sebagai contoh:

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

Masuk sebagai pengguna 1:

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

Dalam hal ini, pengguna akan dapat memilih view2 bahkan tidak memiliki izin untuk memilih tabel.

Tetapi bagaimana jika kita melakukan hal yang sama dengan suatu fungsi ? Tingkah lakunya TIDAK sama. Mari kita membuat fungsi yang menunggu 5 detik sebelum mengembalikan 1 (jadi kita bisa men-debug jika postgresql menjalankan fungsi setiap kali kita memanggil tampilan)

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; 

Masuk sebagai pengguna 1:

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

Izin untuk melakukan pilih pada tampilan tidak mengesampingkan izin fungsi, dan bahkan terburuk jika kita mencabut izin dari view1, pesan masih menunjukkan bahwa postgresql menghentikan kueri kami karena fungsinya, tidak peduli apa pun izin tampilan tersebut. (itulah yang terjadi dalam pertanyaan)

Tetapi apakah fungsinya benar-benar diperiksa terlebih dahulu? Jika kami memberikan izin 'semua' ke fungsi, tetapi cabut izin tampilan ...

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

Seperti yang Anda lihat postgresql MENUNGGU 5 DETIK sebelum mengatakan bahwa kami tidak memiliki izin untuk menampilkan tampilan , menunjukkan bahwa fungsi "sesuatu ()" dijalankan. Jadi pengembalian data fungsi harus ada sebelum pemeriksaan tampilan.

Jadi sekarang dengan tes ini, kita sekarang tahu bahwa PostgreSQL perlu mengevaluasi terlebih dahulu semua fungsi sebelum melanjutkan permintaan kita, sama seperti permintaan masih belum ada sampai semua fungsi yang terlibat selesai sepenuhnya, sehingga tampilan tidak dapat dipecahkan untuk postgresql hingga tahu apakah kami memiliki atau tidak izin untuk memilihnya.

Saya pikir ini menjawab pertanyaan Anda dalam hal "urutan izin", tetapi mengapa postgresql perlu mengevaluasi semua fungsi sebelum melanjutkan, itu adalah pertanyaan lain ...

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.