किसी नए उपयोगकर्ता को तालिका बनाने की अनुमति क्यों है?


41

मैं सोच रहा हूं कि एक डेटाबेस से कनेक्ट होने के बाद एक नव निर्मित उपयोगकर्ता को टेबल बनाने की अनुमति क्यों है। मेरे पास एक डेटाबेस है 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)

अब तक सब ठीक है। अब मैं एक उपयोगकर्ता बनाता हूं:

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

ठीक है। जब मैं डेटाबेस से कनेक्ट करने का प्रयास करता हूं, तो उपयोगकर्ता को ऐसा करने की अनुमति नहीं है:

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

यह वही है जिसकी मुझे उम्मीद थी। अब अजीब सामान शुरू होता है। मैं उपयोगकर्ता को अनुदान देता हूं 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)

और बिना किसी और अनुदान के, उपयोगकर्ता को एक तालिका बनाने की अनुमति है:

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

मुझे उम्मीद होगी कि GRANT USAGEस्कीमा पर और फिर GRANT SELECTतालिकाओं पर स्पष्ट रूप से करने से पहले उपयोगकर्ता को कुछ भी करने की अनुमति नहीं है ।

मेरी गलती कहाँ है? मैं क्या गलत कर रहा हूं? मैं वह प्राप्त कर सकता हूं जो मैं चाहता हूं (कि एक नए उपयोगकर्ता को उसे उचित अधिकार देने से पहले कुछ भी करने की अनुमति नहीं है।

मैं हार गया, और आपकी मदद की बहुत सराहना की :)

EDIT @ daniel-verite द्वारा सलाह के बाद, मैं अब डेटाबेस बनाने के तुरंत बाद सभी को रोक देता हूं। उपयोगकर्ता डायट्रीच को किसी भी तालिका को बनाने की अनुमति नहीं है। अच्छा। लेकिन : अब, डेटाबेस के मालिक, प्रोजेक्ट 2 को भी तालिका बनाने की अनुमति नहीं है। जारी करने GRANT ALL PRIVILEGES ON DATABASE project2_core TO project2और जारी करने के बाद भी GRANT ALL PRIVILEGES ON SCHEMA public TO project2, मुझे एक त्रुटि मिलती है ERROR: कोई स्कीमा बनाने के लिए नहीं चुना गया है , और जब मैं विशेष रूप से प्रयास करता CREATE TABLE public.WHATEVER ();हूं, तो मुझे त्रुटि मिलती है : स्कीमा जनता के लिए अनुमति से इनकार कर दिया गया । मैं क्या गलत कर रहा हूं?

जवाबों:


38

जब आप एक नया डेटाबेस बनाते हैं, तो किसी भी भूमिका को publicस्कीमा में ऑब्जेक्ट बनाने की अनुमति होती है । इस संभावना को दूर करने के लिए, आप डेटाबेस निर्माण के तुरंत बाद जारी कर सकते हैं:

REVOKE ALL ON schema public FROM public;

संपादित करें: उपरोक्त आदेश के बाद, केवल एक सुपरयुसर publicस्कीमा के अंदर नई वस्तुओं का निर्माण कर सकता है , जो व्यावहारिक नहीं है। एक गैर-सुपरयुजर foo_userको यह विशेषाधिकार प्रदान किया जाना चाहिए, यह इस प्रकार किया जाना चाहिए:

GRANT ALL ON schema public TO foo_user;

ALLस्कीमा के लिए क्या मतलब है, यह जानने के लिए, हमें डॉक्टर को डॉक में संदर्भित करना चाहिए , (PG 9.2 में GRANT स्टेटमेंट के 14 से कम रूप नहीं हैं जो विभिन्न चीजों पर लागू होते हैं ...)। ऐसा प्रतीत होता है कि स्कीमा के लिए इसका अर्थ है CREATEऔर USAGE

दूसरी ओर, GRANT ALL PRIVILEGES ON DATABASE...अनुदान देगा CONNECTऔर CREATEऔर TEMP, लेकिन CREATEइस संदर्भ में स्कीमा, नहीं स्थायी टेबल से संबंधित है।

इस त्रुटि के बारे में:, ERROR: no schema has been selected to create inयह तब होता है जब स्कीमा योग्यता के बिना एक वस्तु बनाने की कोशिश की जाती है (जैसा कि create table foo(...)) इसे किसी भी स्कीमा में बनाने की अनुमति का अभाव है search_path


काम करता है :) लेकिन मैं अभी भी नहीं समझता: मैंने पहले ही कोशिश की थी REVOKE ALL ON DATABASE project2_core FROM PUBLIC;। इसका कोई प्रभाव क्यों नहीं पड़ा?
andreas-h

mhh। अब डेटाबेस के मालिक को CREATE TABLEकिसी भी अधिक की अनुमति नहीं है । ऊपर मेरा संपादन देखें।
andreas-h

@ andreas-h: ने और अधिक विवरणों के साथ उत्तर को संपादित किया
डैनियल वेरिटा

त्रुटि के संबंध में, यह प्रश्न और आपके
REVOKE

@ DanielVérité मैंने आपके पूरक के लिए एक नए उत्तर में इसके पीछे की अवधारणाओं पर विस्तार से बताया है। एक पवित्रता जांच को महत्व दिया जाएगा।
क्रेग रिंगर

19

यहाँ समझने के लिए महत्वपूर्ण बात यह है कि विशेषाधिकार विषम नहीं होते हैं और वस्तुओं से विरासत में नहीं मिलते हैं । ALLइसका मतलब है इस वस्तु के लिए सभी विशेषाधिकार नहीं इस वस्तु के लिए सभी विशेषाधिकारों और सभी निहित वस्तुओं

जब आप ALLकिसी डेटाबेस पर अनुदान देते हैं, तो आप अनुदान दे रहे होते हैं CREATE, CONNECT, TEMP। ये डेटाबेस वस्तु पर कार्रवाई कर रहे हैं

  • CONNECT: DB से कनेक्ट करें
  • CREATE: एक स्कीमा बनाएं ( तालिका नहीं )
  • TEMP: अस्थायी ऑब्जेक्ट्स बनाएँ, जिसमें टेम्पर टेबल तक सीमित नहीं है

अब, प्रत्येक PostgreSQL डेटाबेस को डिफ़ॉल्ट रूप से एक publicस्कीमा बनाया जाता है जो डेटाबेस बनाते समय बनाया जाता है। इस स्कीमा में भूमिका के लिए सभी अधिकार हैं public, जिनमें से हर कोई एक सदस्य है। स्कीमा के लिए, ALLइसका मतलब है CREATE, USAGE:

  • CREATE: इस स्कीमा के भीतर ऑब्जेक्ट्स (तालिकाओं सहित) बनाएँ
  • USAGEस्कीमा में वस्तुओं को सूचीबद्ध करें और यदि उनकी अनुमति हो तो उन्हें एक्सेस करें

यदि आप स्कीमा को तालिका में एक ऑब्जेक्ट बनाने के लिए निर्दिष्ट नहीं करते हैं, तो डेटाबेस इंजन का उपयोग करता है search_path, और डिफ़ॉल्ट रूप से publicस्कीमा पहले है, search_pathइसलिए तालिका वहां बनाई गई है। publicडिफ़ॉल्ट रूप से सभी के अधिकार हैं , इसलिए निर्माण की अनुमति है। डेटाबेस पर उपयोगकर्ताओं के अधिकार इस बिंदु पर अप्रासंगिक हैं, क्योंकि उपयोगकर्ता डेटाबेस में कुछ भी करने की कोशिश नहीं कर रहा है, अपने आप में, केवल एक स्कीमा है।

इससे कोई फर्क नहीं पड़ता कि आपने उपयोगकर्ता CONNECTको डेटाबेस पर अनुदान के अलावा कोई अधिकार नहीं दिया है , क्योंकि publicस्कीमा डिफ़ॉल्ट रूप से सभी उपयोगकर्ताओं को इसमें टेबल बनाने की अनुमति देता है। डैनियल ने पहले ही समझाया कि वांछित होने पर उस अधिकार को कैसे रद्द किया जाए।

यदि आप स्पष्ट रूप से हर अधिकार को सौंपना चाहते हैं, तो सभी को सार्वजनिक से हटा दें, या बस सार्वजनिक स्कीमा को छोड़ दें। यदि आप चाहें तो इस परिवर्तन के साथ एक नया टेम्प्लेट डेटाबेस बना सकते हैं। वैकल्पिक रूप से आप इसे लागू कर सकते हैं template1, लेकिन यह 3 जी पार्टी कोड के बहुत सारे को तोड़ देगा जो मानता है कि publicमौजूद है और लेखन योग्य है।


यदि आप किसी फ़ाइल सिस्टम सादृश्य को देखते हैं तो यह और अधिक समझ में आता है।

यदि मेरे पास निर्देशिका संरचना है (केवल उस मोड को दिखाने के लिए सरल है जो वर्तमान उपयोगकर्ता पर लागू होता है):

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

तब मैं कुछ भी नहीं बना सकता /dir1, क्योंकि मेरे पास लिखित अनुमति नहीं है। इसलिए अगर मुझे touch /dir1/somefileकोई अनुमति अस्वीकृत त्रुटि मिलेगी।

हालांकि, मैं कर अंदर देखने के लिए अनुमति है /dir1और उपयोग करने के लिए निहित फ़ाइलों और निर्देशिकाओं सहित /dir1/dir2। मैंने अनुमति पर लिखा है dir2। तो सफलtouch /dir1/dir2/somefile होगा , भले ही मेरे पास लिखने की अनुमति नहीं है ।dir1

डेटाबेस और स्कीमा के साथ एक ही बात।


7

यदि आप केवल नए उपयोगकर्ताओं को टेबल बनाने से रोकना चाहते हैं, तो आपको निम्नलिखित कमांड चलाने की आवश्यकता है:

REVOKE CREATE ON SCHEMA public FROM public;

यदि आप REVOKE ALL(अन्य उत्तरों के अनुसार सुझाव देते हैं), तो आप उपयोगकर्ताओं को USAGEअनुमति देने से भी रोकेंगे । USAGEइसका मतलब है कि उपयोगकर्ता उन्हें सौंपी गई अनुमतियों का उपयोग कर सकते हैं, इसलिए यदि आप उन्हें हटा देते हैं तो आपके उपयोगकर्ता उन तालिकाओं को सूचीबद्ध या एक्सेस नहीं कर पाएंगे, जिन तक वे पहुंच सकते हैं।

वैकल्पिक रूप से, आप REVOKE CREATEकिसी विशिष्ट उपयोगकर्ता के लिए भी कर सकते हैं :

REVOKE CREATE ON schema public FROM myuser;

यह भी देखें: एक रीड ओनली PostgreSQL के साथ उपयोगकर्ता बनाने के लिए कैसे

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.