Yeni bir kullanıcının neden tablo oluşturmasına izin verilir?


41

Yeni oluşturulan bir kullanıcının neden veritabanına bağlandıktan sonra tablo oluşturmasına izin verildiğini merak ediyorum. Bir veritabanım var 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)

Çok uzak çok iyi. Şimdi bir kullanıcı oluşturuyorum:

postgres=# CREATE ROLE dietrich ENCRYPTED PASSWORD 'md5XXX' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER

Tamam. Veritabanına bağlanmaya çalıştığımda, kullanıcının yapmasına izin verilmiyor:

$ 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.

Beklediğim bu. Şimdi garip şeyler başlıyor. Kullanıcıya veriyorum 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)

Ayrıca başka hibeler olmadan, kullanıcının bir tablo oluşturmasına izin verilir:

$ 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)

Açıkça GRANT USAGEşema üzerinde ve sonra GRANT SELECTmasalarda yapmadan önce, kullanıcının hiçbir şey yapmasına izin verilmemesi beklenirdi .

Benim hatam nerde? Neyi yanlış yapıyorum? İstediklerimi nasıl elde edebilirim (yeni bir kullanıcının açıkça uygun hakları vermeden önce hiçbir şey yapmasına izin verilmez.

Kayboldum ve yardımın büyük beğeni topluyor :)

EDIT @ daniel-verite tavsiyesinin ardından şimdi veritabanını oluşturduktan hemen sonra iptal ediyorum. Kullanıcı dietrich'in artık masa oluşturmasına izin verilmiyor. İyi. ANCAK : Şimdi, aynı zamanda veritabanının da sahibi olan project2 , tablo oluşturamaz. Hatta vermeden sonra GRANT ALL PRIVILEGES ON DATABASE project2_core TO project2ve GRANT ALL PRIVILEGES ON SCHEMA public TO project2ben bir hata olsun hiçbir şema oluşturmak üzere seçildiğini: ERROR ve ben özellikle çalıştığımda CREATE TABLE public.WHATEVER ();, ben olsun HATA: şema halk için reddedildi izni . Neyi yanlış yapıyorum?

Yanıtlar:


38

Yeni bir veritabanı oluşturduğunuzda, publicşema içerisinde herhangi bir rol oluşturma izni verilir . Bu olasılığı kaldırmak için, veritabanı oluşturulduktan hemen sonra yayınlayabilirsiniz:

REVOKE ALL ON schema public FROM public;

Düzenleme: Yukarıdaki komuttan sonra, sadece bir süper kullanıcı publicşema içerisinde pratik olmayan yeni nesneler yaratabilir . Süper kullanıcı olmayan bir foo_userkişiye bu ayrıcalık tanınması gerektiğini varsayarsak , bu işlem aşağıdakilerle yapılmalıdır:

GRANT ALL ON schema public TO foo_user;

ALLBir şema için ne anlama geldiğini bilmek için , dokümanda GRANT'a atıfta bulunmalıyız (PG 9.2'de, farklı şeyler için geçerli 14'den az GRANT ifadesi yoktur ...). Bir şema için CREATEve anlamına gelir USAGE.

Öte yandan, GRANT ALL PRIVILEGES ON DATABASE...verecek CONNECTve CREATEve TEMP, ancak CREATEbu bağlamda kalıcı tablolar değil, şemalar ile ilgilidir.

Bu hatayla ilgili olarak: herhangi bir şemasında oluşturma iznine sahip değilken ERROR: no schema has been selected to create in, şema nitelemesi olmayan bir nesneyi oluşturmaya çalışırken meydana gelir .create table foo(...)search_path


çalışıyor :) Ama hala anlamıyorum: Ben çoktan denedim REVOKE ALL ON DATABASE project2_core FROM PUBLIC;. Bunun neden bir etkisi olmadı?
andreas-h

MHH. şimdi veritabanının sahibine artık izin verilmiyor CREATE TABLE. yukarıdaki düzenlememe bakın.
andreas-h

@ andreas-h: cevabı daha fazla ayrıntı ile düzenledi
Daniel Vérité

Hata ile ilgili olarak, soruları ve
REVOKE'inizdeki

@ DanielVérité Sizinkini desteklemek için yeni bir cevap olarak, bunun arkasındaki kavramları inceledim. Akıl sağlığı kontrolüne değer verilecek.
Craig Ringer

19

Burada anlaşılması gereken en önemli şey, imtiyazların heiraşik olmadıkları ve nesnelerden miras alınmadıklarıdır . bu nesne için tüm imtiyazlarALL anlamına gelmez , bu nesne ve içerilen tüm nesneler için tüm imtiyazlar değil .

Bir ALLveritabanında verdiğinizde, vermiş olursunuz CREATE, CONNECT, TEMP. Bunlar, veritabanı nesnesindeki kendiliğinden eylemlerdir:

  • CONNECT: DB'ye bağlan
  • CREATE: Bir şema oluştur ( tablo değil )
  • TEMP: Geçici tablolar dahil ancak bunlarla sınırlı olmamak üzere geçici nesneler oluşturun

Şimdi, her PostgreSQL veritabanı varsayılan olarak veritabanı publicoluşturulduğunda oluşturulan bir şemaya sahiptir. Bu şema, publicherkesin dolaylı olarak üye olduğu rolüne verilen tüm haklara sahiptir . Bir şema için, şu ALLanlama gelir CREATE, USAGE:

  • CREATE: Bu şema içinde nesneler (tablolar dahil) oluşturun
  • USAGE: Şemadaki nesneleri listele ve izinleri uygunsa onlara eriş

Bir tablo gibi bir nesne oluşturmak için şema belirtmezseniz, veritabanı alt yapısı kullanır search_pathve varsayılan olarak publicşema ilk önce search_pathtablonun orada oluşturulduğu şekildedir. Herkesin publicvarsayılan olarak hakları vardır , bu nedenle yaratmaya izin verilir. Kullanıcıların veritabanı üzerindeki hakları bu noktada önemsizdir, çünkü kullanıcı veritabanına hiçbir şey yapmaya çalışmadığı için kendi içinde bir şemadır.

Şema, tüm kullanıcıların varsayılan olarak içinde tablolar oluşturmasına izin verdiği için, kullanıcıya CONNECTveritabanına publicvermekten başka bir hak vermemiş olmanız önemli değildir . Daniel, istenirse bu hakkın nasıl iptal edileceğini zaten açıkladı.

Her hakkı açıkça devretmek istiyorsanız, herkese açık olanları iptal edin veya genel şemayı bırakın. İsterseniz bu değişikliğin uygulandığı yeni bir şablon veritabanı oluşturabilirsiniz. Alternatif olarak uygulayabilirsiniz template1, ancak bu muhtemelen publicvar olduğunu ve yazılabilir olduğunu varsayan çok sayıda 3. parti kodu kırar .


Bir dosya sistemi analojisine bakarsanız bu daha anlamlı olabilir.

Dizin yapısına sahipsem (sadece geçerli kullanıcı için geçerli olan modu göstermek için mod basitleştirilmiştir):

/dir1           mode=r-x
/dir1/dir2      mode=rwx

o zaman içinde hiçbir şey yaratamam /dir1, çünkü yazma iznim yok. Öyleyse touch /dir1/somefileizin almazsam hatam olur.

Ancak, ben bunu içine bakmak iznine sahip /dir1ve erişim de dahil olmak üzere dosya ve dizinleri, içeriyordu /dir1/dir2. Yazma iznim var dir2. Yani touch /dir1/dir2/somefileedecek başarılı ben yazma yetkiniz yok olsa bile, dir1.

Veritabanları ve şemaları ile aynı şey.


7

Yalnızca yeni kullanıcıların tablo oluşturmasını engellemek istiyorsanız, aşağıdaki komutu çalıştırmanız gerekir:

REVOKE CREATE ON SCHEMA public FROM public;

Siz REVOKE ALL(diğer cevapların da önerdiği gibi), kullanıcıların USAGEizin almasını da önlersiniz . USAGEBu, kullanıcıların kendilerine atanan izinleri kullanabileceği anlamına gelir;

Alternatif olarak, REVOKE CREATEbelirli bir kullanıcı için de yapabilirsiniz :

REVOKE CREATE ON schema public FROM myuser;

Ayrıca bakınız: PostgreSQL ile salt okunur bir kullanıcı nasıl oluşturulur ?

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.