I have a database called funnycode. I also have a user called funnycode_user.
How do I grant default privileges to funnycode_user so that the user can:
Create a database under the name funnycode.
User can connect to any future database with the name funnycode, but not other databases.
User can select from all tables and has access to all sequences on any future database under the name funnycode but not other databases.
Is this possible in Postgres? If so, how? I read the documentation here, but I don't see how this:
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT INSERT ON TABLES TO funnycode_user;
Is tied to a specific database, in my case that would be the funnycode database?
The user that creates a database automatically owns that database (unless a different owner is specified) and thus automatically has all privileges on the database. You don't need any additional grants to enable that user creating and using tables in the database.
So if you give funnycode_user the create database privilege, he can create any database he wants, not just funnycode. There is no way to prevent that.
Every new database that is created automatically grants the connect privilege to the role public. If you don't want funnycode_user to connect to other database, you need to revoke that privilege from the public role for every database.
Another way of limiting access to a specific database for a specific user, is through pg_hba.conf
You would need an entry like that:
# TYPE DATABASE USER ADDRESS METHOD
host funnycode funnycode_user 0.0.0.0/0 md5
The entry 0.0.0.0/0 means that funnycode_user can connect from any IP address. Even if funnycode_user created other databases, he wouldn't be able to connect to them.
I think the better (cleaner) way is to not give that user the privilege to create database. Just create that database once, make funnycode_user the owner and that's it.
E.g. as the superuser run:
create user funnycode_user password 'VerySecret';
create database funnycode owner = funnycode_user;
You only need to do that once (or after funnycode_user decides to drop the database) and you don't need to give funnycode_user the privilege to create databases.
Related
I want to give access to multiple users to create tables in external schema in Redshift. I can make a user owner of the schema and he can create it, but how do I grant other user same access without altering schema ownership. I tried to make a role as the owner of the schema which doesn't work.
As per documentation -
To create external tables, you must be the owner of the external schema or a superuser.
Is there any workaround?
In postgres, you can GRANT or REVOKE privileges like:
REVOKE ALL ON SCHEMA public FROM PUBLIC;
GRANT USAGE ON SCHEMA public TO <myuser>;
My question; If each database has a schema PUBLIC, then are you revoking or granting for this all databases? If so, what if you only want to alter the schema permissions of one database?
The context: I want to GRANT SELECT, INSERT, DELETE to one user for only one scheme in one database. I want to do this without being connected to the DB. Or is the way to do this simply by also handling CONNECT permissions to actual databases. So if they can only connect to one database, it doesn't matter if you say "all" PUBLIC schemas?
There are a lot of questions here; I'll try to restore order.
It is a good idea to revoke CREATE from the public schema in all databases.
But you absolutely have to connect to each database in turn to do that.
A beautiful solution might be that you do it on database template1. Then every new database will automatically be set up correctly, since CREATE DATABASE copies the template database.
To give users permission to a schema in all databases, you again have to connect to all databases in turn.
It is also a good idea to REVOKE ALL on all databases from PUBLIC and grant the CONNECT privilege selectively.
This time, you can do it without connecting to each database, because databases are shared objects — the pg_database catalog is accessible from each database.
I want create users that only can execute functions from one database. Not view source functions, procedures, select, etc of any database.
Thanks.
This should do it:
Allow the user to connect to only the correct database, either with permissions on the database object (you have to REVOKE the CONNECT privilege granted to PUBLIC by default first) or with suitable entries in pg_hba.conf.
In the one database where the user can connect, it should have USAGE privilege on the schemas that contain the functions.
Create functions with SECURITY INVOKER that belong to a user that has the rights to access the required objects.
REVOKE EXECUTE on all functions from PUBLIC and GRANT it to the user as required.
There is no supported way in PostgreSQL to keep a user that can log on from seeing the source code of functions. You can try to REVOKE SELECT ON pg_proc FROM PUBLIC, but don't be surprised if you get problems with client programs like pgAdmin or psql.
I installed PostgreSQL 9 database (migration from Oracle10g) and I am realy confused by user/role management. When I create new user using SQL command like CREATE USER or CREATE ROLE, or by Navicat tool, created user can see all databases! He realy can connect them! Although he can't select any data from table, he can see table objects and sequences and so on. I was trying revoke connect privilegia but no effect. I was expected the new user has no privilegia and cant see anything. I really don't know why he can.
From http://www.postgresql.org/docs/9.2/static/sql-grant.html#SQL-GRANT-DESCRIPTION-OBJECTS (emphasis mine):
PostgreSQL grants default privileges on some types of objects to PUBLIC. No privileges are granted to PUBLIC by default on tables, columns, schemas or tablespaces. For other types, the default privileges granted to PUBLIC are as follows: CONNECT and CREATE TEMP TABLE for databases; EXECUTE privilege for functions; and USAGE privilege for languages. The object owner can, of course, REVOKE both default and expressly granted privileges. (For maximum security, issue the REVOKE in the same transaction that creates the object; then there is no window in which another user can use the object.) Also, these initial default privilege settings can be changed using the ALTER DEFAULT PRIVILEGES command.
In order to remove all privileges (including CONNECT) for all unspecified users on a database, use:
REVOKE ALL PRIVILEGES ON DATABASE <database> FROM public;
See also:
PostgreSQL: View database connect permissions
http://wiki.postgresql.org/wiki/Shared_Database_Hosting
You probably also need to modify the pg_hba.conf file. By default, a local installation doesn't do authorization checks.
I want to create a postgres user that can access only one database on the postgres server at all.
Currently my flow is:
create database database1;
create user user1 with password 'pass';
grant all privileges on database database1 to user1;
but user1 can still see a list of dbs, users, tables etc. Is there a way to prevent that user from seeing that info? The user needs to be able to write to and read from that db.
Thanks a lot.
Each user can see other databases and roles listed, but should not be able to see tables in other databases, ever.
If you revoke CONNECT privilege on all databases except the allotted one, the user will not be able to access the contents of other databases.
Roles and database names are global, and not readily blockable. You can try Frank Heikens suggestion of selective revocations on the system tables, but you take risks to do that. PostgreSQL developers on the usenet mailing lists have discouraged tampering with access to the system catalogs.
Psql, among other tools, assumes they will be available and functions poorly without them.
Why is knowing the names of other databases and roles so bad?
REVOKE the SELECT permissions on the information_schema and some sections in the system catalog.
By default any objects you create are created in the public schema. Also, any users that you create have CREATE and USAGE privileges on the public schema. You should revoke CREATE and USAGE to the public schema for this user, or you should change the default access level. You'll also need to move the database to which this user has access into the user's schema, or a schema accessible to the user. See DDL Schemas in the Postgres manual.