Difference between ALTER ROLE WITH CREATEDB and GRANT CREATE ON TABLESPACE - postgresql

Coming from MySQL and not knowing about ROLEs I absentmindedly tried this
GRANT CREATE ON TABLESPACE pg_default TO username;
It didn't have the desired effect. The command that I was looking for was:
ALTER ROLE username WITH CREATEDB;
But what's the difference precisely? Does giving someone the CREATEDB role implicitly give them CREATE ON TABLESPACE ...? Is there a table where I can see all this?
From the docs, GRANT CREATE ON TABLESPACE means (my emphasis):
For tablespaces, allows tables,
indexes, and temporary files to be
created within the tablespace, and
allows databases to be
created that have the
tablespace as their default
tablespace. (Note that revoking this
privilege will not alter the placement
of existing objects.)

They are completely different privileges. CREATEDB means the role can create database. If your role doesn't have that, it can't create databases, period.
Granting CREATE for a tablespace to a role means that the role will be able to use that tablespace as default tablespace for the database. So a role that has CREATEDB will be able to create a database; just not on that tablespace. Note that there's always a pg_default tablespace that will be used as default tablespace for databases that don't otherwise have a default tablespace.

Tablespaces are not the same as databases.

It looks like the first statement gives you the ability to create tablespaces. This are physical files (or spaces on your storage device) that hold the data/indexes/... of the database.
So effectively you granted two different rights with the commands.

Related

Grant READ ONLY permissions to all tables in all databases

I created new role named "support" in my PostgreSQL. Now I need grant "READ ONLY" permissions for this role an ALL exists databases/tables.
Also I need automatically granted same permissions on each DB that will created in future.
I unsuccessfully tried next queries for grant permissions in new databases (Can not select from new database tables ):
ALTER DEFAULT PRIVILEGES FOR ROLE support GRANT SELECT ON TABLES TO PUBLIC;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES to support;
ALTER DEFAULT PRIVILEGES allows you to set the privileges that will be
applied to objects created in the future. (It does not affect
privileges assigned to already-existing objects.)

Revoke access to postgres database for a role

I have created a separate role "newrole" and new schema "newschema" for a certain user that should only execute some stored functions. I have managed to revoke access to schema "public" for the current database.
Logged in as "newrole" I still have access to postgres database like this:
SELECT * FROM pg_user
I want to revoke all access to the postgres database and tried following that not work:
REVOKE ALL ON DATABASE postgres FROM newrole
When logged in as newrole I can still read the postgres database.
How do I revoke any access to the postgres admin database?
I have searched a long time but not found anything regarding access to the postgres admin database.
TIA,
This issue has nothing to do with database postgres. Instead, you want to manipulate the catalog of the current database. Every database has a catalog of information on all objects in schema pg_catalog, and in standards-compliant form in schema information_schema, so you should restrict access to those for the role in question and also for the public role because every role is also member of that role:
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM newrole;
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM public;
REVOKE ALL PRIVILEGES ON SCHEMA information_schema FROM newrole;
REVOKE ALL PRIVILEGES ON SCHEMA information_schema FROM public;
However, the system does not always honour this accross-the-board restriction, the catalogs are there for a reason and provide important functions in the database. Particularly functions may still execute.
In general, you do not want to fiddle with the catalogs unless you really know what you are doing.
you should be able to run this:
select * FROM information_schema.table_privileges where grantee = 'newrole';
to display all the privileges for newrole. With that information you should be able to explicitly revoke everything other than access to 'newschema'

Postgresql default privileges for new schema in multi-tenant Rails application

In my Rails 4 multi-tenant application, I create new schemas in Postgresql with the gem Apartment.
It works very well but I have a problem with the privileges for new schemas.
In Postgresql, I created a "backup" user to backup my database.
I defined the default privileges with :
ALTER DEFAULT PRIVILEGES FOR USER foo GRANT SELECT ON TABLES TO backup;
ALTER DEFAULT PRIVILEGES FOR USER <nom_user_ks-xxx_dbuser> GRANT SELECT ON SEQUENCES TO backup;
This works for new tables and sequences (as it's explained in Postgresql documentation) in existing schemas but it doesn't work for new schemas.
After googling hours, I can't find a solution.
What is the best way to apply default privileges for new schemas ?
Thanks

Restore database with changed privileges

We have two PostgreSQL servers. On web server1 pguser1 is the associated user who creates all database objects required to work with the web application. Let's say, all objects are in schema1.
Similarly, on server2 pguser2 creates data for Web server 2.
I have taken a schema backup (custom option in the backup window from pgadmin) from server1. When I restore to server2 I want all privileges and ownership of objects to be with pguser2 and nothing with pguser1.
How can this be achieved? If possible, an option during during restore (pg_restore command) would be preferred.
It would very much simplify your task if you GRANT privileges and ownership to a non-login role (a.k.a. group). Let's name it foo_admin. On server1 you
GRANT foo_admin TO pguser1;
On server2 you
REVOKE foo_admin FROM pguser1;
GRANT foo_admin TO pguser2;
All done. Or better yet: hack the dump file and replace 1 with 2 in the line
GRANT foo_admin TO pguser1;
.. before you restore. pguser2 has to be created first, of course.
Now, just make sure, when you create anything on server1 to
ALTER TABLE wuchtel12.game OWNER TO foo_admin;
And set privileges. You can preset privileges per schema. Something like:
ALTER DEFAULT PRIVILEGES IN SCHEMA schema1
GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLES
TO foo_admin;
ALTER DEFAULT PRIVILEGES IN SCHEMA schema1
GRANT SELECT, UPDATE, USAGE ON SEQUENCES
TO foo_admin;
This works identically on server1 and server2.
More details and links in this related answer.
You might also be interested in the Grant Wizard of pgAdmin. Details in this related answer

PostgreSQL 8.3 privileges not updated - wrong usage?

I'm having trouble granting privileges to another user in PostgreSQL 8.3. While the GRANT command gives me no error, the privileges do not show up. Do I need to "flush" them?
sirprize=# CREATE DATABASE testdb;
CREATE DATABASE
sirprize=# GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;
GRANT
sirprize=# \c testdb
You are now connected to database "testdb".
testdb=# \z
Access privileges for database "testdb"
Schema | Name | Type | Access privileges
--------+------+------+-------------------
(0 rows)
testdb=#
\z Shows your table, view, and sequence permissions, for the objects contained within the Database. It does not show permissions on the database itself. If you create a table or some other object within 'testdb', it will then show up in \z's output.
You can see which Databases exist on your system with \l (or \l+ for a bit more info).
See section 9.22. of the PostgreSQL 8.3 manual for information about how to programatically determine which permissions exist for a user on a given database.