I want to get view list for which the current user has select privilege. I understand that we cant get privilage details for views directly unlike tables. In case of tables I have view called 'ALL_TAB_PRIVS'.
How to get the list of view objects those are accessable for current user?
Thanks in Advance.
The ALL_TAB_PRIVS view includes VIEWS in its result set. In fact it includes all objects, so it will also show you procedures on which you have EXECUTE privileges.
Quite why it is called ALL_TAB+PRIVS rather than ALL_OBJ_PRIVS I don't know. I agree it's confusing. However it is correctly documented in the Oracle Reference.
Incidentally, there is a view USER_TAB_PRIVS which shows you the privileges of the current user without having to restrict on GRANTEE.
Related
Why did all my tables disappear after changing the user? I created a new user and granted all privileges, but my database is empty after I log in with this new user ? If I log in with the original user they all come back, but I need to work with the tables with the new created user.
I know I can re-create them, but I would like to have them without doing this.
In the connections tab, expand the connection and go to "Other Users" at the bottom of the list and you will see the list of users and, expanding those, their tables (and other objects) that you have at least the SELECT privilege on.
If you want to refer to tables owned by another user in a query then specify the schema name as well as the table name:
SELECT *
FROM other_schema.table_name;
Is there any way to get the user (not the role) that created a view?
I tried desc, show, grants on view but couldn't get the specific user
The INFORMATION_SCHEMA.QUERY_HISTORY* table-functions have a USER_NAME column, and you can filter on the QUERY_TEXT to find the view's CREATE-statement.
This should work unless the views were created with a variable. For example: CREATE OR REPLACE VIEW IDENTIIER($MY_VAR)... where MY_VAR is a variable containing the name of the view.
UPDATE
INFORMATION_SCHEMA.QUERY_HISTORY table-functions return results for the past 7 days. Also see the ACCOUNT_USAGE.QUERY_HISTORY table functions, which return results for the past 365 days, with a 45 minute lag.
UPDATE 2
You can also use conventions such as:
Give each user their own schema, composed from their name or initials
Ask users to put their name or initials in the view COMMENT
Or ask users to prefix or suffix their views with their initials
If the views are created with a script or a stored procedure, then you can automate the above.
Lastly, while it's not a best practice, you can in fact create a separate role for each user. This however creates a lot of administrative overhead, especially as you scale, and is not recommended.
I am trying to create a view in Redshift.But when I close the session and again reopen it then given view is not present.How can I create a view that exists even if my session expires?
Views are not session dependent. They'll exist in storage like any other table.
Are you prefixing your create view [] statement with a schema name i.e. create view schemaname.viewname? If not, the view will either get created in your public schema or the default schema search path.
A way to troubleshoot is to go through the different schema listed and then find out where your view has been created.
If you find your view in public schema, you'll get to know that if no default search path is set and schemaname is not mentioned while creating tables/views, it gets created in the public schema by default.
If you find your view in any other schema, you'll get to know what your search path is.
Views are persistent.
Some possible reasons why you can't see the view:
You are connecting as a different user who has a different Schema search path
You are connecting to a different database
You created the view in a different schema and when you reconnected you went to a default schema
Adding to previous answers, the view dependencies (tables that are used in the view definition) might be dropped and view is dropped consequently.
The scenario : an Oracle 11g database containing some sensitive user data that could result legal liabilities if disclosed to the wrong party.
The desired effect : only a certain user, connecting from a certain IP, can see the column that contains this sensitive user data
I am not sure that hidden columns or virtual columns are the right ways to do this. It seems that Fine-Grained Access Control could help. I am not sure of what is the best solution. The restriction by IP is probably done at the listener level?
The question :
How can we restrict the visibility of a column so it is only available only to a specific user? All the other users would never see the column, not even when doing a "DESC TABLE_WITH_SENSITIVE_DATA"
Thanks for any tips.
Simplest way to do this is to create a view on the table that does not contain all of the columns. Don't grant select on the table, but only on the view.
The "proper" way to do this is with Fine-Grained Access Control (Virtual Private Database), which can replace the contents of columns with a NULL if certain conditions are not met.
See the example here: http://docs.oracle.com/cd/B28359_01/network.111/b28531/vpd.htm#autoId17
You can probably build this sort of functionality yourself if you're feeling both impoverished and skilled.
Do you the ability to modify roles and create views? Perhaps you could create two separate views and grant access to two different roles for that table. All users that are restricted from seeing the sensitive data would belong to a "restricted" role and the others would have access to the "unrestricted" role. You would need to grant privileges on each view to the appropriate role.
It is important to note that there are restrictions on updating the underlying data associated with a view. As explained here, views that contain set operators, aggregates and GROUP BY DISTINCT and joins and not modifiable.
Like the title says, I've been asked to come up with an estimate for retrofitting an existing asp application.
The current security mechanism controls access to different parts of the application (page-level restrictions), but has no mechanism for flagging individual records as restricted. Assigning rights to a user (using the existing, custom access management code) is no problem, but enforcing the rights is a different matter - each asp page has embedded sql - there's no use of stored procs, objects, etc.
Is the only solution to modify each table and query, or is there a better way? Any pointers, suggestions or prayers would be welcome.
This is classic asp, running on IIS6, against an oracle database.
Update: Here's a user scenario.
We have users, managers, directors, and VPs. The managers can see data created by users who report to them, but not users who report to other managers. Users can't see data created by any managers. Same thing with directors - they can see down, but their reports can't see up.
This sounds like an ideal time to implement row-level security. Oracle has a package DBMS_RLS that allows you to define arbitrary access policies that can be applied to one or more tables that limit what rows a particular user is allowed to see. Conceptually, when a user issues a query with no filters on a protected table, i.e.
SELECT *
FROM my_table
Oracle automatically and transparently inserts a WHERE clause defined by your security policy that limits the result set. You shouldn't need to make any changes to the SQL your application is executing.
Assuming you need maximum granularity, the ability to "grant" each and any row to any of very many users, then you have a many-to-many relation, yes?
So apply the following pattern:
Add a tables of users.
Then, for each restricted table, so the following:
Rename it tablename + "_base".
create a many-to-many table that
associates that table's id with a
user id, called tablename +
"allowed_user".
create a view with the name table
name that joins tablename_base to
table_name_allowed_user, with a
select* from tablename_base and
user_id from tablename_allowed_user.
This view should meet Oracle's
requirements rto be "inherently
updatable."
Now comes the hard part. You need to add "and user_id = $user_id" to every query. Find the various functions you're using to make queries. Wrap those function(s) in ones that gets the user id from the session and add that predicate.
One passable way to do this is to read select string, find the all "where"s (for subqueries there may be more that one), and replace it with "where (user = $user) and ". For queries that don't have a where, you'll need to insert this before any "group by" or "order by". This is fragile, so obviously you'll test that this works for all pages (you have an automated test for all pages, right?), and add hacks to cover special cases.
"update" statements won't have to change; "inserts" will presumably insert both to the view and then do a separate insert to the table's "allow_user" table with the id of the inserting user, to automatically grant teh inserting user acces to what he inserted.
If your number of users is more limited, or you're restricting types of users, you can go with a strategy of multiple views named for the user or type; then you'd replace tables names in the queries with the appropriate views.