Ich frage mich, warum ein neu erstellter Benutzer nach dem Herstellen einer Verbindung zu einer Datenbank eine Tabelle erstellen darf. Ich habe eine Datenbank 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)
So weit, ist es gut. Jetzt erstelle ich einen Benutzer:
postgres=# CREATE ROLE dietrich ENCRYPTED PASSWORD 'md5XXX' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER
Okay. Wenn ich versuche, eine Verbindung zur Datenbank herzustellen, darf der Benutzer dies nicht tun:
$ 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.
Das habe ich erwartet. Jetzt fängt das seltsame Zeug an. Ich erteile dem Benutzer 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)
Und ohne weitere Bewilligungen darf der Benutzer eine Tabelle erstellen:
$ 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)
Ich hätte erwartet, dass der Benutzer nichts tun darf, bevor ich explizit GRANT USAGE
das Schema und dann GRANT SELECT
die Tabellen bearbeitet habe.
Wo ist mein Fehler? Was mache ich falsch? Wie kann ich erreichen, was ich will (dass ein neuer Benutzer nichts tun darf, bevor er ihr explizit die entsprechenden Rechte gewährt?)?
Ich bin verloren und deine Hilfe wird sehr geschätzt :)
BEARBEITEN Nach dem Rat von @ daniel-verite widerrufe ich jetzt alle sofort nach dem Erstellen der Datenbank. Der Benutzer dietrich darf keine Tabelle mehr anlegen. Gut. ABER : Jetzt darf auch der Besitzer der Datenbank, project2 , keine Tabelle erstellen. Auch nach dem Ausstellen von GRANT ALL PRIVILEGES ON DATABASE project2_core TO project2
und GRANT ALL PRIVILEGES ON SCHEMA public TO project2
wird ein Fehler angezeigt. FEHLER: Es wurde kein Schema zum Erstellen ausgewählt. Wenn ich dies ausdrücklich versuche, CREATE TABLE public.WHATEVER ();
wird die Berechtigung FEHLER: für das öffentliche Schema verweigert . Was mache ich falsch?
quelle
REVOKE ALL ON DATABASE project2_core FROM PUBLIC;
. Warum hatte das keine Wirkung?CREATE TABLE
mehr. siehe mein edit oben.Das Entscheidende dabei ist, dass Privilegien nicht heirachisch sind und nicht von Objekten geerbt werden, die sie enthalten .
ALL
bedeutet alle Berechtigungen für dieses Objekt, nicht alle Berechtigungen für dieses Objekt und alle enthaltenen Objekte .Wenn Sie
ALL
für eine Datenbank gewähren, gewähren SieCREATE, CONNECT, TEMP
. Dies sind Aktionen für das Datenbankobjekt selbst:CONNECT
: Stellen Sie eine Verbindung zur DB herCREATE
: Erstellen Sie ein Schema ( keine Tabelle)TEMP
: Temporäre Objekte erstellen, einschließlich, aber nicht beschränkt auf temporäre TabellenJetzt hat jede PostgreSQL-Datenbank standardmäßig ein
public
Schema, das beim Erstellen der Datenbank erstellt wird. Diesem Schema sind alle Rechte für die Rollepublic
zugewiesen, zu der implizit jeder gehört. Für ein SchemaALL
bedeutetCREATE, USAGE
:CREATE
: Erstellen Sie Objekte (einschließlich Tabellen) in diesem SchemaUSAGE
: Listet Objekte im Schema auf und greift auf sie zu, wenn ihre Berechtigungen dies zulassenWenn Sie nicht das Schema angeben, in dem ein Objekt wie eine Tabelle erstellt werden soll, verwendet das Datenbankmodul
search_path
daspublic
Schema. Standardmäßig befindet sich das Schema zuerst auf dem Schema,search_path
sodass die Tabelle dort erstellt wird. Jeder hatpublic
standardmäßig Rechte , daher ist das Erstellen erlaubt. Die Rechte der Benutzer für die Datenbank sind zu diesem Zeitpunkt irrelevant, da der Benutzer nicht versucht, das Datenbankobjekt selbst zu bearbeiten, sondern nur ein darin enthaltenes Schema.Es spielt keine Rolle, dass Sie dem Benutzer keine anderen Rechte als das Gewähren
CONNECT
für die Datenbank gewährt haben , da daspublic
Schema standardmäßig allen Benutzern erlaubt, Tabellen darin zu erstellen. Daniel hat bereits erklärt, wie man dieses Recht auf Wunsch widerruft.Wenn Sie jedes Recht explizit delegieren möchten, widerrufen Sie alle öffentlichen Rechte oder löschen Sie einfach das öffentliche Schema. Sie können eine neue Vorlagendatenbank mit dieser Änderung erstellen, wenn Sie möchten. Alternativ können Sie es anwenden
template1
, aber das wird wahrscheinlich eine Menge Code von Drittanbietern beschädigen, von dem angenommen wird, dass erpublic
existiert und beschreibbar ist.Dies ist möglicherweise sinnvoller, wenn Sie sich eine Dateisystem-Analogie ansehen.
Wenn ich die Verzeichnisstruktur habe (Modus vereinfacht, um nur den Modus anzuzeigen, der für den aktuellen Benutzer gilt):
dann kann ich innen nichts erstellen
/dir1
, da ich keine schreibberechtigung habe. Wenn ich alsotouch /dir1/somefile
einen Fehler erhalte, dem die Erlaubnis verweigert wurde.Ich habe jedoch die Erlaubnis, nach innen zu schauen
/dir1
und auf enthaltene Dateien und Verzeichnisse zuzugreifen, einschließlich/dir1/dir2
. Ich habe eine schriftliche Erlaubnis amdir2
. Sotouch /dir1/dir2/somefile
wird es gelingen , auch wenn ich keine Schreibberechtigung dazu habedir1
.Gleiches gilt für Datenbanken und Schemata.
quelle
Wenn Sie nur verhindern möchten, dass neue Benutzer Tabellen erstellen, müssen Sie den folgenden Befehl ausführen:
Wenn Sie
REVOKE ALL
(wie aus anderen Antworten hervorgeht), verhindern Sie auch, dass Benutzer überUSAGE
Berechtigungen verfügen.USAGE
bedeutet, dass Benutzer die ihnen zugewiesenen Berechtigungen verwenden können. Wenn Sie diese also entfernen, können Ihre Benutzer keine Tabellen auflisten oder auf Tabellen zugreifen, auf die sie Zugriff haben.Alternativ könnten Sie auch
REVOKE CREATE
für einen bestimmten Benutzer:Siehe auch: So erstellen Sie einen schreibgeschützten Benutzer mit PostgreSQL .
quelle