Che cosa fa esattamente l'uso di GRANT USAGE ON SCHEMA?


121

Sto cercando di creare per la prima volta un database Postgres, quindi questa è probabilmente una domanda stupida. Ho assegnato i permessi di sola lettura di base al ruolo db che deve accedere al database dai miei script php, e ho una curiosità: se eseguo

GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;

c'è bisogno di eseguire anche

GRANT USAGE ON SCHEMA schema TO role;

?

Dalla documentazione :

UTILIZZO: per gli schemi, consente l'accesso agli oggetti contenuti nello schema specificato (assumendo che siano soddisfatti anche i requisiti di privilegio degli oggetti). In sostanza, ciò consente al beneficiario di "cercare" oggetti all'interno dello schema.

Penso che se posso selezionare o manipolare qualsiasi dato contenuto nello schema, posso accedere a qualsiasi oggetto dello schema stesso. Ho sbagliato? In caso contrario, a cosa GRANT USAGE ON SCHEMAserve? E cosa significa esattamente la documentazione con "presumere che anche i requisiti di privilegio degli oggetti siano soddisfatti"?

Risposte:


126

GRANTI messaggi su oggetti diversi sono separati. GRANTing su un database non ha GRANTdiritti sullo schema all'interno. Allo stesso modo, l' GRANTing su uno schema non concede i diritti sulle tabelle all'interno.

Se si dispone dei diritti per SELECTda una tabella, ma non il diritto di visualizzarla nello schema che la contiene, non è possibile accedere alla tabella.

I test dei diritti vengono eseguiti in ordine:

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.

La tua confusione può derivare dal fatto che lo publicschema ha un valore predefinito GRANTdi tutti i diritti sul ruolo public, di cui ogni utente / gruppo è membro. Quindi tutti hanno già utilizzato quello schema.

La frase:

(supponendo che siano soddisfatti anche i requisiti di privilegio degli oggetti)

Sta dicendo che devi avere USAGEsu uno schema per usare gli oggetti al suo interno, ma avere USAGEsu uno schema non è di per sé sufficiente per usare gli oggetti all'interno dello schema, devi anche avere i diritti sugli oggetti stessi.

È come un albero di directory. Se crei una directory somedircon un file somefileal suo interno, impostala in modo che solo il tuo utente possa accedere alla directory o al file (modalità rwx------sulla directory , modalità rw-------sul file), nessun altro può elencare la directory per vedere che il file esiste.

Se dovessi concedere i diritti di lettura globale sul file (modalità rw-r--r--) ma non modificare i permessi della directory, non farebbe differenza. Nessuno può vedere il file per leggerlo, perché non ha i diritti per elencare la directory.

Se invece si imposta rwx-r-xr-xsulla directory, impostandola in modo che le persone possano elencare e attraversare la directory ma senza modificare i permessi del file, le persone potrebbero elencare il file ma non potrebbero leggerlo perché non avrebbero accesso al file.

È necessario impostare entrambe le autorizzazioni affinché le persone possano effettivamente visualizzare il file.

Stessa cosa a Pg. Hai bisogno sia dei USAGEdiritti dello schema che dei diritti dell'oggetto per eseguire un'azione su un oggetto, come SELECTda una tabella.

(L'analogia cade un po 'in quanto PostgreSQL non ha ancora la sicurezza a livello di riga, quindi l'utente può ancora "vedere" che la tabella esiste nello schema SELECTinserendola pg_classdirettamente. Non può interagire con essa in alcun modo , però, quindi è solo la parte "elenco" che non è esattamente la stessa.)


2
Ora è molto chiaro con l'esempio della directory :) Devo dire che questo è un problema se inserisci qualche tabella o riga con un superutente, ad esempio quando aggiungi postGIS usando CREATE EXTENSION. È più o meno lo stesso problema con i file creati su Linux mentre sei su. Sarà utile se c'è una sorta di sudo -eistruzioni for in pqsl.
Marco Sulla

Cmq ora mi sono accorto che GRANTaffermazioni non specifiche per tabelle non sono quello che voglio, visto che interessano tutti i database ...: s
Marco Sulla

1
@ LucasMalor Er ... no, non lo fanno. GRANTsu uno schema influisce su quello schema. GRANT ... ON ALL TABLES IN SCHEMA ...influisce su tutte le tabelle in uno schema in un database particolare. Non ci sono messaggi GRANTche influiscono su tutti i database (ok, tranne che GRANTper l'appartenenza al ruolo a un utente).
Craig Ringer

Ah scusatemi, ho eseguito le istruzioni quando sono stato registrato come superutente "postgres" e hanno influenzato il database "postgres". Pensavo che se corri psqlsenza -d dbstai operando "fuori" da qualsiasi db, ma sei sempre connesso ad un db e di default sei connesso al db con lo stesso nome del tuo ruolo. db = role = user = group ... è un po 'confuso: D
Marco Sulla

@LucasMalor Pensala in questo modo. Per impostazione predefinita ci si connette a un DB con lo stesso nome del ruolo di login ("utente") con cui ci si connette. Gli "utenti" sono solo ruoli che hanno WITH LOGIN; in sostanza, tutto può essere un gruppo e i gruppi possono essere impostati per essere in grado di accedere.
Craig Ringer

72

Per un sistema di produzione, puoi utilizzare questa configurazione:

--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 ;

Non dovrebbe adminessere concesso anche CREATEsullo schema?
Dan

2
Gli accessi sono allocati secondo un modello gerarchico: BD -> SCHEMA -> TABELLE . Con GRANT USAGE ON SCHEMA, l'utente amministratore non può creare una tabella ma può farlo con ALL GRANT ALL ON SCHEMA....
bilelovitch

@bilelovitch: vuoi dire grant all on schema public to admin? PS: ho aggiunto anche 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

Bene, questa è la mia soluzione finale per un semplice db, per 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

1
Quale utente deve essere utilizzato per "# Crea tutte le tabelle e gli oggetti, e dopo:"? Chi è il proprietario dei tavoli e degli altri oggetti nel tuo caso?
Christophe Furmaniak

@ChristopheFurmaniak hai ragione, ho corretto il processo. Il proprietario del db e dei suoi oggetti è $ ROLE_LOCAL e, dopo aver creato la struttura del db, dobbiamo tornare al superuser postgres.
Marco Sulla

Credo che tu abbia un problema con i comandi "ALTER DEFAULT PRIVILEGES ...". Questo comando viene utilizzato per attivare la concessione di privilegi a un utente (ruolo) quando un utente (ruolo) diverso crea un oggetto. Vedere pagina 11, sezione 7.1, di questo documento per chiarimenti. Attualmente il tuo ROLE_REMOTE non avrà accesso a nessun oggetto che ROLE_LOCAL creerebbe. I comandi ROLE_LOCAL forniscono solo i priv che il ruolo ha già come proprietario di quegli oggetti. Lo stesso vale per i comandi ROLE_REMOTE.
Emispowder
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.