Saya bertanya-tanya mengapa pengguna yang baru dibuat diizinkan untuk membuat tabel setelah terhubung ke database. Saya memiliki satu database, project2_core
:
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------------+--------------+-----------+-------------+-------------+-------------------------------
postgres | postgres | SQL_ASCII | C | C |
project2_core | atm_project2 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
Sejauh ini baik. Sekarang saya membuat pengguna:
postgres=# CREATE ROLE dietrich ENCRYPTED PASSWORD 'md5XXX' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER
Baik. Ketika saya mencoba terhubung ke database, pengguna tidak diizinkan untuk melakukannya:
$ psql -h localhost -p 5432 -U dietrich -W project2_core
Password for user dietrich:
psql: FATAL: permission denied for database "project2_core"
DETAIL: User does not have CONNECT privilege.
Ini yang saya harapkan. Sekarang hal-hal aneh dimulai. Saya memberikan pengguna CONNECT
:
postgres=# GRANT CONNECT ON DATABASE project2_core TO dietrich;
GRANT
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
---------------+--------------+-----------+-------------+-------------+-------------------------------
postgres | postgres | SQL_ASCII | C | C |
project2_core | atm_project2 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | project2=CTc/project2+
| | | | | dietrich=c/project2
template0 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | SQL_ASCII | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(5 rows)
Dan tanpa hibah lebih lanjut, pengguna diizinkan untuk membuat tabel:
$ psql -h localhost -p 5432 -U dietrich -W project2_core
Password for user dietrich:
psql (9.2.3)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.
project2_core=> create table adsf ();
CREATE TABLE
project2_core=> \d
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | adsf | table | dietrich
(1 row)
Saya berharap bahwa pengguna tidak diizinkan untuk melakukan apa pun sebelum saya secara eksplisit melakukannya GRANT USAGE
pada skema dan kemudian GRANT SELECT
pada tabel.
Di mana kesalahan saya? Apa yang saya lakukan salah? Bagaimana saya bisa mencapai apa yang saya inginkan (bahwa pengguna baru tidak diizinkan melakukan apa pun sebelum secara eksplisit memberinya hak yang sesuai.
Saya tersesat, dan bantuan Anda sangat dihargai :)
EDIT Mengikuti saran dari @ daniel-verite, saya sekarang membatalkan semua segera setelah membuat database. Dietrich pengguna tidak diizinkan membuat tabel lagi. Baik. TETAPI : Sekarang, juga pemilik basis data, project2 , tidak diperbolehkan membuat tabel. Bahkan setelah mengeluarkan GRANT ALL PRIVILEGES ON DATABASE project2_core TO project2
dan GRANT ALL PRIVILEGES ON SCHEMA public TO project2
, saya mendapatkan galat ERROR: tidak ada skema yang dipilih untuk dibuat , dan ketika saya mencoba secara khusus CREATE TABLE public.WHATEVER ();
, saya mendapatkan ERROR: izin ditolak untuk skema publik . Apa yang saya lakukan salah?
sumber
REVOKE ALL ON DATABASE project2_core FROM PUBLIC;
. mengapa ini tidak berpengaruh?CREATE TABLE
lagi. lihat hasil edit saya di atas.Hal penting untuk dipahami di sini adalah bahwa hak istimewa tidak bersifat heirachical dan tidak diwarisi dari benda yang mengandung .
ALL
berarti semua hak istimewa untuk objek ini tidak semua hak istimewa untuk objek ini dan semua objek yang ada .Ketika Anda memberikan
ALL
pada database, Anda memberiCREATE, CONNECT, TEMP
. Ini adalah tindakan pada objek database itu sendiri:CONNECT
: Hubungkan ke DBCREATE
: Buat skema ( bukan tabel)TEMP
: Membuat objek sementara, termasuk tetapi tidak terbatas pada tabel tempSekarang, setiap database PostgreSQL secara default memiliki
public
skema yang dibuat ketika database dibuat. Skema ini memiliki semua hak yang diberikan kepada peranpublic
, di mana setiap orang secara implisit menjadi anggota. Untuk suatu skema,ALL
berartiCREATE, USAGE
:CREATE
: Membuat objek (termasuk tabel) dalam skema iniUSAGE
: Daftar objek dalam skema dan akses jika izin mereka memungkinkanJika Anda tidak menentukan skema untuk membuat objek seperti tabel di, mesin database menggunakan
search_path
, dan secara defaultpublic
skema pertama padasearch_path
sehingga tabel dibuat di sana. Setiap orang memiliki hak untukpublic
secara default, sehingga pembuatannya diperbolehkan. Hak-hak pengguna pada database tidak relevan pada saat ini, karena pengguna tidak mencoba melakukan apa pun untuk objek database itu sendiri, hanya skema di dalamnya.Tidak masalah bahwa Anda belum memberikan hak apa pun kepada pengguna selain memberikan
CONNECT
pada basis data, karenapublic
skema tersebut memungkinkan semua pengguna untuk membuat tabel di dalamnya secara default. Daniel sudah menjelaskan cara mencabut hak itu jika diinginkan.Jika Anda ingin mendelegasikan setiap hak secara eksplisit, cabut semua dari publik, atau cukup jatuhkan skema publik. Anda dapat membuat database template baru dengan perubahan ini diterapkan jika Anda mau. Bergantian Anda dapat menerapkannya
template1
, tetapi itu kemungkinan akan merusak banyak kode pihak ke-3 yang menganggappublic
ada dan dapat ditulisi.Ini mungkin lebih masuk akal jika Anda melihat analogi sistem file.
Jika saya memiliki struktur direktori (mode disederhanakan untuk hanya menampilkan mode yang berlaku untuk pengguna saat ini):
maka saya tidak dapat membuat apa pun di dalam
/dir1
, karena saya tidak memiliki izin menulis. Jadi jika sayatouch /dir1/somefile
saya akan mendapatkan izin ditolak kesalahan.Namun, saya lakukan memiliki izin untuk melihat ke dalam
/dir1
dan akses yang terkandung file dan direktori, termasuk/dir1/dir2
. Saya sudah menulis izindir2
. Jaditouch /dir1/dir2/somefile
akan berhasil , meskipun saya tidak punya izin tertulis untukdir1
.Hal yang sama dengan database dan skema.
sumber
Jika Anda hanya ingin mencegah pengguna baru membuat tabel, Anda perlu menjalankan perintah berikut:
Jika Anda
REVOKE ALL
(seperti jawaban lain menyarankan), Anda juga akan mencegah pengguna memilikiUSAGE
izin.USAGE
berarti bahwa pengguna dapat menggunakan izin yang diberikan kepada mereka, jadi jika Anda menghapusnya maka pengguna Anda tidak akan dapat membuat daftar atau mengakses tabel yang mereka memiliki akses.Atau, Anda juga bisa
REVOKE CREATE
untuk pengguna tertentu:Lihat juga: Cara membuat pengguna hanya-baca dengan PostgreSQL .
sumber