Oracle retaining Grant for the re-created object - oracle10g

I've a grant for table T, I want this grant to be pertained after:
drop table T;
create table T(...);
is it possible?

From the Oracle Database SQL Language Reference (emphasis mine):
Dropping a table invalidates dependent objects and removes object privileges on the table. If you want to re-create the table, then you must regrant object privileges on the table, re-create the indexes, integrity constraints, and triggers for the table, and respecify its storage parameters. Truncating and replacing have none of these effects. Therefore, removing rows with the TRUNCATE statement can be more efficient than dropping and re-creating a table.
Therefore you need to explicitly add the grant statements to your script after the create table statement.

No. At the moment you drop the object, any grants on that object will be removed. When you create a new object, even if that object happens to have the same name as the old object, you'll need to re-grant whatever privileges you want on the new object. That's one reason that dropping and re-creating an object is seldom a good idea-- why do you need to drop and re-create your table?
You could, of course, identify all the grants before you drop the object and then re-create those after you create the new object. You could do that either by querying the various data dictionary tables like dba_tab_privs) or by using the dbms_metadata.get_dependent_ddl function to get the DDL for the grants.

Related

Postgresql role with no drop table permision

Is it possible to set role with access to one database, with all privileges except to drop tables?
Not really. If a user can issue CREATE TABLE, it can issue a DROP for that table as well. From the docs:
The right to drop an object, or to alter its definition in any way, is not treated as a grantable privilege; it is inherent in the owner, and cannot be granted or revoked.
And as noted by the CREATE TABLE docs:
The table will be owned by the user issuing the command.
There is no mechanism to allow a user to create tables that they do not own and therefore cannot drop.

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.

Postgres GRANT not applied on parent

I'm in trouble with grant in postgresql (version 9.3).
I'm trying to restrict a ROLE 'client_1'. I want it to be able to do only select for one table. But there is inheritance between tables.
Here is my table structure:
CREATE TABLE public.table_a (...);
CREATE TABLE table_a_partitions.child_1 (...) INHERITS (public.table_a);
CREATE TABLE table_a_partitions.child_2 (...) INHERITS (public.table_a);
GRANT SELECT ON table_a_child_1 TO client_1;
It's okay when I do a select on child_2, there is an error, but if I do a SELECT * FROM table_a; for example it also reads the forbidden table child_2. I would my client access only child_1 (and some other in the future) results when he does SELECT * FROM table_a;.
Is there a simple way to solve this problem ?
Thank you
You would need to use a VIEW in PostgreSQL 9.3 to solve this problem. If you upgrade to 9.5, however, you could use row-level security.
As a note as to why, the grant check only occurs on the level of the initial relation queried. This means if you query a view, you need access to the view's contents, but the view owner (NOT YOU) needs access to the underlying relations. This allows a view to be useful for information hiding. Similarly with inheritance, this structure allows you to forbid rows to be inserted or queried directly from partitions of a table, but to allow different queries via the parent table. So this is a consequence of design priorities, not a bug.
Before row-level security, you would basically create a view and fold in user privilege criteria into the view (with partitioning/inheritance this is also a good idea for other reasons since your insert/update/delete triggers can return exactly what the db would do even though it cannot on a table).
As for row-level security, PostgreSQL 9.5 does allow you to specify row-level policies (conditions that get appended to insert/select/update/delete queries) and that provides something a little more manageable in some cases than the view approach.

Preventing ALTER TABLE on PostgreSQL 9.4 even by the owner

We're using PostgreSQL 9.4.
We need to prevent users from doing an ALTER on a table, not even the owner of the table.
The owner of the table would have to 'grant' himself the permission to do the ALTER.
I imagine it would be like setting a 'read only flag' on the table's schema.
The table in question is being inherited from another table, if this has any importance.
The ideal solution would allow to do a message like "You can't ALTER the table because .... "
Is this achievable? and if so, how?
This is probably not what you actually want, but a potentially interesting effect:
When creating an inherited table, you have to do it as the owner of the parent table, but you can then change the owner of the child table. The new owner won't be able to drop/modify the inherited set of columns, though will still be able to change defaults/checks/triggers/etc, and to add new columns.
The simplest way to do something close to what you actually want is probably to control access by the owner role: create a separate role to access the tables, and revoke the CONNECT privilege on the database from the owner.

trigger to update object in different tablespace

I have a table X in tablespace T1 and a table Y in tabelspace T2.(Oracle DB)
I have to create a trigger in tablespace T1 that will,
on the event of updating a column C in table X,
update column D in table Y (tablespace T2).
Because they are in different tablespaces, my first question is can this be done at all?
And if yes then how it can be done? What privileges are required to do such a thing?
It has not so much to do with the tablespace. You do need privileges to insert into the table (and that particular column) though, and if the table Y is in another schema than the trigger, you need to use the qualified table name: . (In Oracle, the schemaname is the name of the user that owns the object)
CREATE TRIGGER aur_x
AFTER UPDATE OF c ON x
FOR EACH ROW
UPDATE schema_containing_y.Y SET D = ...
;
EDIT:
It just occurred to me that you might not be familiar with the distinction between schema and tablespace, so here's a short explanation. A tablespace is a logical storage container: it dedfines datafiles, growth characteristics, logging types etc. Tablespaces can then be used as to store data associated with schema objects (tables, indexes, views definitions, but also packages and stored procedure definitions etc).
A schema is a collection of objects (like tables, views, pacakages etc.) These objects are owned by a user, and as far as i am aware, in oracle the schema has an name identical to the user that owns the objects. THe objects rely on the storage provided by one or more tablespaces, but tablespaces themselves are not schema objects.
Typically, a schema is used to group functionally related objects (for example, you'd typically create one schema for one application). Tablespaces can also be created especially to store all objects of one application, but you can also create different tablespaces for tables with different characteristics.
Normally, application developers shouldn't worry too much about tablespaces. Your DBA will typically set them up in a way that is convenient for things like backup plan.