Permission to create VIEW for table with SELECT right - oracle

I'm granted SELECT on table NOTMYSCHEMA.XYZ but Oracle does not allow me to create VIEW that includes this table! What's the purpose of this ban? I assume if I can see the table content then I should be allowed to make a view showing this table content by default.

Privileges Required to Create Views
To create a view, you must meet the following requirements:
You must have been granted the CREATE VIEW (to create a view in your schema) or CREATE ANY VIEW (to create a view in another user's schema) system privilege, either explicitly or through a role.
You must have been explicitly granted the SELECT, INSERT, UPDATE, or DELETE object privileges on all base objects underlying the view or the SELECT ANY TABLE, INSERT ANY TABLE, UPDATE ANY TABLE, or DELETE ANY TABLE system privileges. You may not have obtained these privileges through roles.
Additionally, in order to grant other users access to your view, you must have received object privilege(s) to the base objects with the GRANT OPTION option or appropriate system privileges with the ADMIN OPTION option. If you have not, grantees cannot access your view."

Related

Oracle, privilege from role doesn't give access to table

I need to move some views to a new user(newUser)
The views are to reference tables from the initial schema(originalUser.Table1).
There is a role with 'select' privilege on originalUser.Table1: role1.
If I grant 'role1' to 'newUser' I get ORA-00942 'table or view does not exist' when
create view newUser.View1 as select * from originalUser.Table1
But if I grant the privilege directly:
grant select on originalUser.Table1 to newUser
everything works fine and view gets created.
What can be wrong with the 'role' approach?
This is the documented behaviour; from the 19c create view section (emphasis added):
The owner of the schema containing the view must have the privileges necessary to either select (READ or SELECT privilege), insert, update, or delete rows from all the tables or views on which the view is based. The owner must be granted these privileges directly, rather than through a role.
Apart from the added complexity that role-granted privileges would add to potentially invalidating a view - if a role was removed from a user, all of the privileges under it, including in chained roles, would have to be evaluated to see if any table access was affected, and then which objects depended on that - roles can be disabled or require passwords etc.
This restriction is similar to the one that disables riles in any named PL/SQL block (procedure, function, package, trigger) created with definer's rights.

How to create a user in Oracle that could only view the source code without changing them and view table fields?

How to create a user in Oracle that could only view the source code of packages and procedures without changing them and view table fields but not the data in tables?
I know that you could grant a view to specific user, but how to deny access to tables data without hiding fields?
I appreciate any help.
There is a role to view data dictionary info. So the user will be able to view the definition of the tables, view, packages, system objects, etc.
grant select_catalog_role to user;
Or the Select Any Dictionary grant.
But with this grants the user will be able to see many more data than he needs.
An alternative is to grant select on DBA_SOURCE, DBA_TABLES views.
See a discution on dba.stackexchange.com here.
I've found a solution.
You need to create a view on DBA_SOURCE and grant a user SELECT on this view. In that case user will be able to see the code of packages and procedures and table structures, but not execute them.

GRANT INSERT on tables participating in an updateable view

The given database contains a masterdata (MD) Schema and an application specific Schema (APP). In the APP Schema we have a view which provides the applications data from one table in the scheme joined with data from the MD Schema.
Example: Think of an address book application, which holds an address table, but cities and ZIP codes are joined from a masterdata table in another Schema which is maintained centrally.
CREATE VIEW view_adress AS
SELECT app.ID, app.Street, app.ZIP, zip.CITYNAME
FROM APP.adress app
LEFT OUTER JOIN MD.zipcodes zip
ON app.ZIP = zip.ZIP
This is very simplified. The actual view I use is a lot more complicated like that and therefore I implemented an INSTEAD OF INSERT, UPDATE Trigger to map INSERTs on the view to the correct base table in my APP Schema.
The application users (role) is granted SELECT,INSERT,UPDATE,DELETE on all tables inside this APP Schema. They are also granted SELECT on that zipcode table in the master data Schema.
When I insert on that view, I get an "ORA-01720: Grant Option Does Not Exist"... I don't know the exact cause of this error, but it can be assumed that the INSTEAD-OF Trigger never INSERTS on the ZIP Code Table, only on the address table.
I understand, that granting the application users INSERT privilege on the zipcode table would probably resolve this issue, but I am feeling uncomfortable granting INSERTs on tables to users which they never should edit in any way, because these are only lookups.
Is there another, possibly "the correct way" to solve this?
By "insufficient permissions error" do you mean this?
ORA-01720: grant option does not exist for 'MD.ZIPCODES'
*Cause: A grant was being performed on a view or a view was being replaced
and the grant option was not present for an underlying object.
*Action: Obtain the grant option on all underlying objects of the view or
revoke existing grants on the view.
If so, the solution is that you need to grant the relevant permissions to the schema owning the view - not to the roles that use the view:
grant insert on md.zipcodes to app with grant option;
It's true that you are still having to grant a permission that is logically not required, but you are not granting it to users, only the app schema.

Select statement stops working when wrapped in view [Oracle]

I have a select statement in a stored procedure that I'd like to pull out and put into a view. The select statement pulls from dba_tables, dba_tab_partitions, and dba_tab_subpartitions.
If I run the statement on its own, it works fine. If I wrap it in a create view statement:
CREATE OR REPLACE VIEW "MYSCHEMA"."V_XWMS_TEST"
(
"OWNER"
,"SEGMENT_NAME"
,"PARTITION_NAME"
,"SEGMENT_TYPE"
,"TABLESPACE_NAME"
)
AS
SELECT "OWNER"
,"SEGMENT_NAME"
,"PARTITION_NAME"
,"SEGMENT_TYPE"
,"TABLESPACE_NAME"
FROM
[Original query]
then depending on which user I'm logged in as, I get either ORA-01031: insufficient privileges or ORA-00942: table or view does not exist. Again, with both users I can create views and I can run this select statement, but I can't run the select statement in the context of creating a view.
This might be caused by the difference between the system privilege SELECT ANY DICTIONARY and the role SELECT_CATALOG_ROLE.
On the surface they do the same thing by granting users access to the data dictionary. Either one of them would enable a user to run a query against tables like DBA_TABLES.
The difference is that roles are not enabled when creating objects with definer's rights, and views are always definer's rights. So to make the view work the user will need the system privilege SELECT ANY DICTIONARY, or a similar direct grant on individual objects.
ORA-01031: insufficient privileges or ORA-00942: table or view does not exist.
This error means that the new table from which the view is created doesn't have synonyms and grants created to be accessed by the schema in which the view is created.

ORA-01031: insufficient privileges when selecting view

When I try to execute a view that includes tables from different schemas an ORA-001031 Insufficient privileges is thrown. These tables have execute permission for the schema where the view was created. If I execute the view's SQL Statement it works. What am I missing?
Finally I got it to work. Steve's answer is right but not for all cases. It fails when that view is being executed from a third schema. For that to work you have to add the grant option:
GRANT SELECT ON [TABLE_NAME] TO [READ_USERNAME] WITH GRANT OPTION;
That way, [READ_USERNAME] can also grant select privilege over the view to another schema
As the table owner you need to grant SELECT access on the underlying tables to the user you are running the SELECT statement as.
grant SELECT on TABLE_NAME to READ_USERNAME;
Q. When is the "with grant option" required ?
A. when you have a view executed from a third schema.
Example:
schema DSDSW has a view called view_name
a) that view selects from a table in another schema (FDR.balance)
b) a third shema X_WORK tries to select from that view
Typical grants:
grant select on dsdw.view_name to dsdw_select_role;
grant dsdw_select_role to fdr;
But: fdr gets
select count(*) from dsdw.view_name;
ERROR at line 1:
ORA-01031: insufficient privileges
issue the grant:
grant select on fdr.balance to dsdw with grant option;
now fdr:
select count(*) from dsdw.view_name;
5 rows
Let me make a recap.
When you build a view containing object of different owners, those other owners have to grant "with grant option" to the owner of the view. So, the view owner can grant to other users or schemas....
Example:
User_a is the owner of a table called mine_a
User_b is the owner of a table called yours_b
Let's say user_b wants to create a view with a join of mine_a and yours_b
For the view to work fine, user_a has to give "grant select on mine_a to user_b with grant option"
Then user_b can grant select on that view to everybody.
If the view is accessed via a stored procedure, the execute grant is insufficient to access the view. You must grant select explicitly.
If the view is accessed via a stored procedure, the execute grant is insufficient to access the view. You must grant select explicitly.
simply type this
grant all on to public;
To use a view, the user must have the appropriate privileges but only for the view itself, not its underlying objects. However, if access privileges for the underlying objects of the view are removed, then the user no longer has access. This behavior occurs because the security domain that is used when a user queries the view is that of the definer of the view. If the privileges on the underlying objects are revoked from the view's definer, then the view becomes invalid, and no one can use the view. Therefore, even if a user has been granted access to the view, the user may not be able to use the view if the definer's rights have been revoked from the view's underlying objects.
Oracle Documentation
http://docs.oracle.com/cd/B28359_01/network.111/b28531/authorization.htm#DBSEG98017
you may also create view with schema name
for example create or replace view schema_name.view_name as select..

Resources