Apa sebenarnya yang dilakukan GRANT USAGE ON SCHEMA?

121

Saya mencoba membuat database Postgres untuk pertama kalinya, jadi ini mungkin pertanyaan yang bodoh. Saya menetapkan izin baca-saja dasar ke peran db yang harus mengakses database dari skrip php saya, dan saya ingin tahu: jika saya mengeksekusi

GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;

apakah ada kebutuhan untuk mengeksekusi juga

GRANT USAGE ON SCHEMA schema TO role;

?

Dari dokumentasi :

PENGGUNAAN: Untuk skema, izinkan akses ke objek yang terdapat dalam skema yang ditentukan (dengan asumsi bahwa persyaratan hak istimewa objek juga terpenuhi). Pada dasarnya, ini memungkinkan penerima untuk "mencari" objek dalam skema.

Saya rasa jika saya dapat memilih atau memanipulasi data apa pun yang terdapat dalam skema, saya dapat mengakses objek apa pun dari skema itu sendiri. Apakah aku salah? Jika tidak, untuk apa GRANT USAGE ON SCHEMAdigunakan? Dan apa arti dokumentasi sebenarnya dengan "mengasumsikan bahwa persyaratan hak istimewa objek juga terpenuhi"?

Marco Sulla
sumber

Jawaban:

126

GRANTs pada objek yang berbeda terpisah. GRANTing pada database tidak GRANTberhak atas skema di dalamnya. Demikian pula, GRANTmenggunakan skema tidak memberikan hak atas tabel di dalamnya.

Jika Anda memiliki hak untuk SELECTdari tabel, tetapi tidak memiliki hak untuk melihatnya dalam skema yang memuatnya maka Anda tidak dapat mengakses tabel.

Uji hak dilakukan dengan urutan:

Do you have `USAGE` on the schema? 
    No:  Reject access. 
    Yes: Do you also have the appropriate rights on the table? 
        No:  Reject access. 
        Yes: Check column privileges.

Kebingungan Anda mungkin timbul dari kenyataan bahwa publicskema memiliki default GRANTsemua hak atas peran public, di mana setiap pengguna / grup adalah anggotanya. Jadi setiap orang sudah menggunakan skema itu.

Frasa:

(dengan asumsi bahwa persyaratan hak istimewa objek juga terpenuhi)

Mengatakan bahwa Anda harus memiliki USAGEskema untuk menggunakan objek di dalamnya, tetapi memiliki USAGEskema tidak dengan sendirinya cukup untuk menggunakan objek dalam skema, Anda juga harus memiliki hak atas objek itu sendiri.

Ini seperti pohon direktori. Jika Anda membuat direktori somedirdengan file somefiledi dalamnya kemudian mengaturnya sehingga hanya pengguna Anda sendiri yang dapat mengakses direktori atau file (mode rwx------pada dir, mode rw-------pada file) maka tidak ada orang lain yang dapat membuat daftar direktori untuk melihat bahwa file tersebut ada.

Jika Anda memberikan hak membaca dunia atas file (mode rw-r--r--) tetapi tidak mengubah izin direktori, tidak ada bedanya. Tidak ada yang dapat melihat file untuk membacanya, karena mereka tidak memiliki hak untuk mencantumkan direktori.

Jika Anda malah menyetel rwx-r-xr-xpada direktori, menyetelnya sehingga orang dapat membuat daftar dan melintasi direktori tetapi tidak mengubah izin file, orang dapat membuat daftar file tetapi tidak dapat membacanya karena mereka tidak memiliki akses ke file.

Anda perlu menyetel kedua izin agar orang benar-benar dapat melihat file tersebut.

Hal yang sama di Pg. Anda memerlukan USAGEhak skema dan hak objek untuk melakukan tindakan pada objek, seperti SELECTdari tabel.

(Analoginya jatuh sedikit di yang PostgreSQL tidak memiliki keamanan tingkat baris lagi, jadi pengguna masih bisa "melihat" bahwa tabel ada dalam skema oleh SELECTing dari pg_classlangsung. Mereka tidak bisa berinteraksi dengan cara apapun , meskipun, jadi hanya bagian "daftar" yang tidak persis sama.)

Craig Ringer
sumber
2
Sekarang sangat jelas dengan contoh direktori :) Saya harus mengatakan ini adalah masalah jika Anda memasukkan beberapa tabel atau baris dengan superuser, misalnya ketika Anda menambahkan postGIS menggunakan CREATE EXTENSION. Ini kurang lebih masalah yang sama dengan file yang dibuat di Linux saat Anda su. Akan lebih baik jika ada semacam sudo -epernyataan for di pqsl.
Marco Sulla
Bagaimanapun sekarang saya menyadari bahwa GRANTpernyataan yang tidak spesifik untuk tabel bukanlah yang saya inginkan, karena mereka mempengaruhi semua database ...: s
Marco Sulla
1
@LucasMalor Er ... tidak, mereka tidak. GRANTpada skema yang mempengaruhi skema itu. GRANT ... ON ALL TABLES IN SCHEMA ...mempengaruhi semua tabel dalam skema dalam database tertentu. Tidak ada GRANTyang mempengaruhi semua database (ok, kecuali GRANTkeanggotaan peran untuk pengguna).
Craig Ringer
Ah permisi, saya mengeksekusi pernyataan ketika saya login sebagai superuser "postgres", dan mereka mempengaruhi database "postgres". Saya pikir jika Anda menjalankan psqltanpa -d dbAnda mengoperasikan "di luar" db apa pun, tetapi Anda selalu terhubung ke db dan secara default Anda terhubung ke db dengan nama yang sama dari peran Anda. db = role = user = group ... ini agak membingungkan: D
Marco Sulla
@LucasMalor Pikirkan seperti ini. Secara default Anda terhubung ke DB dengan nama yang sama dengan peran login ("pengguna") yang Anda sambungkan. "Pengguna" hanyalah peran yang memiliki WITH LOGIN; pada dasarnya, semuanya bisa menjadi grup, dan grup dapat diatur untuk dapat masuk.
Craig Ringer
72

Untuk sistem produksi, Anda dapat menggunakan konfigurasi ini:

--ACCESS DB
REVOKE CONNECT ON DATABASE nova FROM PUBLIC;
GRANT  CONNECT ON DATABASE nova  TO user;

--ACCESS SCHEMA
REVOKE ALL     ON SCHEMA public FROM PUBLIC;
GRANT  USAGE   ON SCHEMA public  TO user;

--ACCESS TABLES
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC ;
GRANT SELECT                         ON ALL TABLES IN SCHEMA public TO read_only ;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write ;
GRANT ALL                            ON ALL TABLES IN SCHEMA public TO admin ;
bilelovitch.dll
sumber
Tidak adminjuga harus diberikan CREATEpada skema?
Dan
2
Akses dialokasikan sesuai dengan model hierarki: BD -> SCHEMA -> TABLES . Dengan GRANT USAGE ON SCHEMA, pengguna admin tidak dapat membuat tabel tetapi dia dapat melakukannya dengan ALL GRANT ALL ON SCHEMA....
bilelovitch
@bilelovitch: maksud Anda grant all on schema public to admin? PS: Saya menambahkan juga grant usage, select on all sequences in schema public to read_only/read_write; grant execute on all functions in schema public to read_only/read_write;
Marco Sulla
2

Nah, ini adalah solusi terakhir saya untuk db sederhana, untuk Linux:

# Read this before!
#
# * roles in postgres are users, and can be used also as group of users
# * $ROLE_LOCAL will be the user that access the db for maintenance and
#   administration. $ROLE_REMOTE will be the user that access the db from the webapp
# * you have to change '$ROLE_LOCAL', '$ROLE_REMOTE' and '$DB'
#   strings with your desired names
# * it's preferable that $ROLE_LOCAL == $DB

#-------------------------------------------------------------------------------

//----------- SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - START ----------//

cd /etc/postgresql/$VERSION/main
sudo cp pg_hba.conf pg_hba.conf_bak
sudo -e pg_hba.conf

# change all `md5` with `scram-sha-256`
# save and exit

//------------ SKIP THIS PART UNTIL POSTGRES JDBC ADDS SCRAM - END -----------//

sudo -u postgres psql

# in psql:
create role $ROLE_LOCAL login createdb;
\password $ROLE_LOCAL
create role $ROLE_REMOTE login;
\password $ROLE_REMOTE

create database $DB owner $ROLE_LOCAL encoding "utf8";
\connect $DB $ROLE_LOCAL

# Create all tables and objects, and after that:

\connect $DB postgres

revoke connect on database $DB from public;
revoke all on schema public from public;
revoke all on all tables in schema public from public;

grant connect on database $DB to $ROLE_LOCAL;
grant all on schema public to $ROLE_LOCAL;
grant all on all tables in schema public to $ROLE_LOCAL;
grant all on all sequences in schema public to $ROLE_LOCAL;
grant all on all functions in schema public to $ROLE_LOCAL;

grant connect on database $DB to $ROLE_REMOTE;
grant usage on schema public to $ROLE_REMOTE;
grant select, insert, update, delete on all tables in schema public to $ROLE_REMOTE;
grant usage, select on all sequences in schema public to $ROLE_REMOTE;
grant execute on all functions in schema public to $ROLE_REMOTE;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on tables to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on sequences to $ROLE_LOCAL;

alter default privileges for role $ROLE_LOCAL in schema public
    grant all on functions to $ROLE_LOCAL;

alter default privileges for role $ROLE_REMOTE in schema public
    grant select, insert, update, delete on tables to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant usage, select on sequences to $ROLE_REMOTE;

alter default privileges for role $ROLE_REMOTE in schema public
    grant execute on functions to $ROLE_REMOTE;

# CTRL+D
Marco Sulla
sumber
1
Pengguna mana yang harus digunakan untuk "# Membuat semua tabel dan objek, dan setelah itu:"? Siapa pemilik tabel dan objek lain dalam kasus Anda?
Christophe Furmaniak
@ChristopheFurmaniak Anda benar, saya mengoreksi prosesnya. Pemilik db dan objeknya adalah $ ROLE_LOCAL dan, setelah membuat struktur db, kita harus kembali ke postgres superuser.
Marco Sulla
Saya yakin Anda memiliki masalah dalam perintah "ALTER DEFAULT PRIVILEGES ...". Perintah ini digunakan untuk memicu pemberian hak istimewa kepada satu pengguna (peran) ketika pengguna yang berbeda (peran) membuat objek. Lihat halaman 11, bagian 7.1, dari dokumen ini untuk klarifikasi. Saat ini ROLE_REMOTE Anda tidak akan memiliki akses ke objek apa pun yang akan dibuat ROLE_LOCAL. Perintah ROLE_LOCAL hanya memberikan privasi yang sudah dimiliki peran sebagai Pemilik objek tersebut. Hal yang sama berlaku untuk perintah ROLE_REMOTE.
emispowder