web-dev-qa-db-fra.com

Que fait exactement GRANT USAGE ON SCHEMA?

J'essaie de créer pour la première fois une base de données Postgres, alors c'est probablement une question stupide. J'ai attribué des autorisations de base en lecture seule au rôle de base de données qui doit accéder à la base de données à partir de mes scripts php, et j'ai une curiosité: si j'exécute

GRANT some_or_all_privileges ON ALL TABLES IN SCHEMA schema TO role;

est-il nécessaire d'exécuter également

GRANT USAGE ON SCHEMA schema TO role;

?

De documentation :

USAGE: pour les schémas, permet d'accéder aux objets contenus dans le schéma spécifié (en supposant que les exigences en matière de privilèges de ces objets soient également remplies). Cela permet essentiellement au bénéficiaire de "rechercher" des objets dans le schéma.

Je pense que si je peux sélectionner ou manipuler les données contenues dans le schéma, je peux accéder à n’importe quel objet du schéma lui-même. Ai-je tort? Si non, quel GRANT USAGE ON SCHEMA est utilisé pour? Et que signifie exactement la documentation avec "en supposant que les exigences en matière de privilèges des objets soient également remplies"?

93
Marco Sulla

GRANTs sur différents objets sont séparés. GRANTing sur une base de données n'a pas GRANT droits sur le schéma à l'intérieur. De même, GRANTing sur un schéma n'accorde pas de droits sur les tables qu'il contient.

Si vous possédez des droits sur SELECT à partir d'une table, mais que vous n'avez pas le droit de les voir dans le schéma qui les contient, vous ne pouvez pas accéder à la table.

Les tests de droits sont effectués dans l'ordre:

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.

Votre confusion peut provenir du fait que le schéma public a une valeur par défaut GRANT de tous les droits sur le rôle public, dont chaque utilisateur/groupe est membre. Donc, tout le monde a déjà une utilisation sur ce schéma.

La phrase:

(en supposant que les propres exigences de privilège des objets soient également satisfaites)

Cela veut dire que vous devez avoir USAGE sur un schéma pour utiliser les objets qu'il contient, mais avoir USAGE sur un schéma n'est pas suffisant en soi pour utiliser les objets du schéma, vous devez également avoir des droits. sur les objets eux-mêmes.

C'est comme une arborescence de répertoires. Si vous créez un répertoire somedir contenant le fichier somefile, configurez-le de sorte que seul votre propre utilisateur puisse accéder au répertoire ou au fichier (mode rwx------ sur le répertoire, mode rw------- sur le fichier), personne d’autre ne peut répertorier le répertoire pour vérifier que le fichier existe.

Si vous accordiez des droits de lecture sur le fichier (mode rw-r--r--) mais ne changez pas les permissions du répertoire, cela ne changera rien. Personne ne pourrait voir le fichier pour le lire, car ils ne disposent pas des droits nécessaires pour répertorier le répertoire.

Si vous définissez plutôt rwx-r-xr-x sur le répertoire, le paramétrant de manière à ce que les utilisateurs puissent répertorier et parcourir ce répertoire sans modifier les autorisations de fichiers. Les utilisateurs pouvaient list le fichier mais ne pouvaient pas le lire parce qu'ils ' ne pas avoir accès au fichier.

Vous devez définir les autorisations les deux pour que les utilisateurs puissent réellement consulter le fichier.

Même chose dans Pg. Vous avez besoin à la fois des droits de schéma USAGE et des droits d'objet pour exécuter une action sur un objet, comme SELECT à partir d'une table.

(L'analogie tombe un peu dans le fait que PostgreSQL n'a pas encore de sécurité au niveau de la ligne, ainsi l'utilisateur peut toujours "voir" que la table existe dans le schéma de SELECTing à partir de pg_class directement. Ils ne peuvent interagir avec elle de quelque manière que ce soit, alors c'est juste la partie "liste" qui n'est pas tout à fait la même.)

99
Craig Ringer

Pour un système de production, vous pouvez utiliser cette configuration:

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

Eh bien, voici ma solution finale pour une base de données simple, pour 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
2
Marco Sulla