Separate and restrict data access using schemas - postgresql

I am an Oracle DBA, new to PostgreSQL. I have a requirement to separate some modules data, so that one module will not have access to read the data of another module.
I read about the use of schemas in PostgreSql which is somewhat different than the use of it in Oracle. However seems like it is recommended to use the method of different schemas for separation and management - just like in Oracle.
However, when I create 2 schemas - connected to the same database and same user - I can do a select from the other schema's table.
That is, for example, if I have schema A owning table a, and schema B owning table b, when I set the search path to schema B I can do a select on schema’s A table a without any problem.
I couldn't find a way to revoke this privilege from schema B.
The only I could find then to separate access to data, is using different roles, that is to create role A with schema A, and role B with schema B. then I can grant and revoke access from user B in order for it to see what I want from role's A tables.
Is this correct? Am I missing something?

if I have schema A owning table a
A schema does not "own" a table in Postgres - a user does. This is the same as in Oracle - the difference (and maybe where your confusion arises) is that in Oracle in a regular user can't create tables outside of a schema that has the same name as the user account.
So if user arthur creates a table in schema_a and one in schema_b, both tables are owned by arthur - not "the schema".
If you used different schemas/users in Oracle to separate data and to prevent access to the other user's tables, then you need two users and two schemas in Postgres as well.
The default search_path in Postgres is setup in a way, that (unqualified) tables are always first searched (and created) in a schema with the same name as the user running the statement.
So if you create two users and a schema with the user's name for each user, you pretty much have the same setup as in Oracle:
create user arthur with password 'foobar';
create schema arthur authorization arthur; --<< this is what Oracle does "automatically"
create user bob with password 'verysecret';
create schema bob authorization bob;
Now, if bob creates a table, that table is created in the schema bob and is owned by the user bob. User arthur has not privileges to access that table.
If you never need to share data between those users (or schemas), then you can create two databases, create two users and let both users create everything in the public schema of "their" database.

Related

GRANT/REVOKE from all tables in database

I've created a database in Postgres, like so:
CREATE DATABASE mydb
I've created a user (role), like so:
CREATE USER myuser
I would now like to GRANT certain permissions (e.g. SELECT) to this user for all tables in this database. How can I achieve this?
The closest thing I can find is the GRANT ... ON ALL TABLES IN SCHEMA someschema, but I don't think this addresses the issue, since a single "database" can have multiple "schema", and I'd like these permissions to apply to all existing tables in all existing schema, as well as all future tables in all future schema.
Similarly, what would then be the equivalent to REVOKE all permissions for all tables in a database?

Replacing schema name when sharing sql script with other users

When collaborating with colleagues I need to change the schema name every time I receive a SQL script (Postgres).
I am only an ordinary user of a corporate database (no permissions to change anything). Also, we are not allowed to create tables in PUBLIC schema. However, we can use (read-only) all the tables from BASE schema.
It is cumbersome for the team of users, where everybody is creating SQL scripts (mostly only for creating tables), which need to be shared amongst others. Every user has its own schema.
Is it possible to change the script below, where I will share the script to another user without the need for the other user to find/replace the schema, in this case, user1?
DROP TABLE IF EXISTS user1.table1;
CREATE TABLE user1.table1 AS
SELECT * FROM base.table1;
You can set the default schema at the start of the script (similar to what pg_dump generates):
set search_path = user1;
DROP TABLE IF EXISTS table1;
CREATE TABLE table1 AS
SELECT * FROM base.table1;
Because the search path was change to contain user1 as the first schema, tables will be searched in that schema when dropping and creating. And because the search path does not include any other schema, no other schema will be consulted.
If you
However the default search_path is "$user", public which means that any unqualified table will be searched or created in a schema with the same name as the current user.
Caution
Note that a DROP TABLE will drop the table in the first schema found in that case. So if table1 doesn't exist in the user's schema, but in the public schema, it would be dropped from the public schema. So for your use-case setting the path to exactly one schema might be more secure.

Change owner of Postgres table automatically?

I have a database shared by many users, all the users are in a group "example" and the vast majority of objects in the database are owned by "example". Very occasionally a user will create a new table - that table gets assigned to the user who created it and so the other users are unable to alter the new table.
Is there a way to have the ownership of a table automatically set to the group "example" and not the user who created the table or a way to set up a trigger that happens after a CREATE TABALE or a way to set up group/permissions such that all users will be considered owners of objects regardless of who actually created them?
You could change the default privileges this way:
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO PUBLIC;
or to give write access:
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT,INSERT,UPDATE,DELETE ON TABLES TO PUBLIC;
https://www.postgresql.org/docs/9.0/static/sql-alterdefaultprivileges.html
You probably want to use an EVENT TRIGGER
This is doable in all versions of Pg from 9.3 forward but depending on your version might require different approaches since the structures for event triggers have improved significantly.
In earlier versions you could look through the table catalogs for items owned by the current user. In newer versions you can use pg_event_trigger_ddl_commands to get the information you need. you want to run the command at ddl end.

how can we identified schema name in sybase ase 15.5?

I am trying to get schema name in sybase database.
First I have create login(user1) from sa user and than i have connect with user1 by giving login name(user1) and password now i have tried to create table by giving following command:-
create table user1.table1(
emp_id int not null,
name varchar(80) not null
)
but it was showing access denied error than i have logged-in from sa user and grant sa_role to user1 and then again i have run above mention query for create table and table were created successfully.
here I am not exactly getting that user1 is schema name or not or how can I identified schema name?
I want to also know that is there any role except sa_role for grant create insert delete table ,views and all other objects of sybase database.
Sybase ASE does not use the schema concept that SQL Server and Oracle use. Objects are located inside a database, and owned by a user - no other logical separations are there. So your syntax is wrong.
create table table1
(
emp_id int not null,
name varchar(80) not null
)
Sybase ASE Create Table
Additionally, Sybase/SAP best practices tells us all database objects should be created/owned by dbo with permissions granted to groups/roles/users to access those objects. Users who own database objects can not be removed, so if User1 gets fired, you will have to identify all the objects he owns, and change the ownership of those objects before his account can be deleted.
So for your example, the dbo user (typically sa) would create the objects, then GRANT permissions (INSERT/UPDATE/DELETE/etc) to the groups/roles/users who need access.
More information on managing user permissions can be found in the Sybase ASE System Administrators Guide Vol 1.
And more information about Roles/Groups from the System Admin Guide.

Postgresql user with specific privileges

In Postgresql how would I create a user that can do everything expect create roles, drop databases, drop roles, drop tables but it can create a database.
Essentially this user will be used to access a database for an application that stores, updates and retrieves data and the user can create a database.
You create a user and make that user the owner of the database:
The following has to be done as a superuser:
create user arthur password 'verysecret';
create database arthur_db owner = arthur;
Now arthur can do anything in that database.