Question about CREATE TABLE ... CLONE {COPY GRANTS} behaviour - clone

I am new to Snowflake and I am confused about the CREATE TABLE ... CLONE COPY GRANTS explanations of the documentation and what I see when trying:
The CREATE TABLE … CLONE syntax includes the COPY GRANTS keywords, which affect a new table clone as follows: https://docs.snowflake.com/en/sql-reference/sql/create-clone.html [1]
If the COPY GRANTS keywords are used, then the new object clone does not inherit any explicit access privileges granted on the original table but does inherit any future grants defined for the object type in the schema (using the GRANT … TO ROLE … ON FUTURE syntax).
If the COPY GRANTS keywords are not used, then the new object inherits any explicit access privileges granted on the original table but does not inherit any future grants defined for the object type in the schema.
Object Cloning: https://docs.snowflake.com/en/sql-reference/sql/grant-privilege.html [2]
When a database is cloned, the schemas in the cloned database copy the future privileges from the source schemas. This maintains consistency with the regular object grants, in which the grants of the source object (i.e. database) are not copied to the clone, but the grants on all the children objects (i.e. schemas in the database) are copied to the clones.
When a schema is cloned, the future grants from the source schema are not copied to the clone.
When an object in a schema is cloned, any future grants defined for this object type in the schema are applied to the cloned object unless the COPY GRANTS option is specified in the CREATE statement for the clone operation; in that case, the new object retains the access permissions of the original object and does not inherit any future grants for objects of that type.
The link 1. of the documentation indicates that not using COPY GRANTS inherits the source table privileges but not the future ones and the link 2. (bold line) indicates that not using COPY GRANTS inherits the future privileges
I am quite confused of the interpretation.
Moreover I tried to clone a table with and without the COPY GRANTS option : with COPY GRANTS the initial privileges of the source table appears in the clone, without COPY GRANT there are no privileges (except the OWNER). But in the 2 cases future grants on the source table never inherits the clone table.
Could someone help me in the understanding ? 😊
Thanks a lot,
Regards,
Cyril

It seems you found a bug on the documents. When you use COPY GRANTS, the cloned table will inherit any explicit access privileges granted on the original table.
create role test_role;
create table test_table (v varchar);
grant update on future tables in schema public to test_role;
grant select on test_table to role test_role;
show grants on test_table;
+-----------+------------+--------------+
| privilege | granted_on | grantee_name |
+-----------+------------+--------------+
| OWNERSHIP | TABLE | ACCOUNTADMIN |
| SELECT | TABLE | TEST_ROLE |
+-----------+------------+--------------+
create table clone_table_nocp clone test_table;
create table clone_table_yescp clone test_table copy grants;
show grants on clone_table_nocp; -- has future grants of schema
+-----------+--------------+
| privilege | grantee_name |
+-----------+--------------+
| OWNERSHIP | ACCOUNTADMIN |
| UPDATE | TEST_ROLE |
+-----------+--------------+
show grants on clone_table_withcp; -- inherited access privileges, but does not have future grants
+-----------+--------------+
| privilege | grantee_name |
+-----------+--------------+
| OWNERSHIP | ACCOUNTADMIN |
| SELECT | TEST_ROLE |
+-----------+--------------+
I will contact with the documentation team to fix it.

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.

does create table privilege give object privileges like select and delete?

I use windows 7 and oracle 11g , so when i created user test and give an him create table privilege:
grant create table to test;
I notice that this user can also do select,insert,delete on the table that he created but i don't give him any object privileges.
is create table privilege mean all object privileges are granted?
Table owner can do everything with that table - all DML and DDL actions (selects, inserts, updates, deletes, alters, drops, ... everything).
If you want to let other users do something with your tables, then you'll have to grant those privileges to 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.

How to provide Vertica user with read-only access to certain specified system tables?

We're looking to set up a user in our Vertica database that can see certain system tables, (projections, projection_storage and views), but we don't want this user to be a dbadmin, because we don't want them to have write privileges on these tables. I've tried using GRANT statements to give a regular user access to these tables, but that doesn't seem to work. Each user can only see their own own records in those tables. Is there a way to set up a user as I describe, or do we need to have this user be a dbadmin?
Our use case is that we need a user that can get a list of the schemas that exist in our database and iterate through each schema, gathering information to store in one central location. If our user is granted usage on the individual schemas, then they can get a list of those schemas, but they aren't able to access the necessary records in the projection_storage and views tables.
Thank you!
Granting USAGE on the schema to the user or role is not enough for users to see its projections in projection_storage table. If the user or the role has SELECT access on the table, then projections for those tables can be viewed in projection_storage. I am in Vertica 7.1, and I was able to view projection records by granting SELECT permission just to the role instead of granting to individual user ID.
If the user does not need to access tables but needs to list out tables in the schema for some reporting purpose, one option would be to periodically dump the content of projection_storage to a different table and grant proper privileges on this table to the user.
Just for the sake of maintaince you should create database roles !! and then give acces to those roles to your users . Other-wise the maintainance will be hell to you !!
Normally, I just give a user USAGE on a schema. And then "GRANT SELECT on to ;"
Do they have INSERT permissions on those tables?
Granting select access to the role on the table , does not grant complete access to metadata tables like projection_storage . This seems to be a bug. In order to get complete access select needs to be granted to individual user id.
You can follow the below steps to create a user with select privileges to a schema .
I ll follow this with a example ,In my test database I have a schema 'sid' with a table 'student_table'.
1) Login as a admin on your database .
[dbadmin#localhost bin]$ vsql -u
User name: dbadmin
Password:
2) Create the user with a password
dbadmin=> create user test identified by 'R';
CREATE USER
3) Give the newly created user a Grant for the usage on the database.
dbadmin=> Grant ALL on database vertica to test;
GRANT PRIVILEGE
4) You can then grant the user the Usage to the schema
dbadmin=> Grant Usage on Schema sid to test;
GRANT PRIVILEGE
5) Finally provide the select grant to the user on the table .
dbadmin=> Grant select on sid.student_table to test ;
GRANT PRIVILEGE
dbadmin=> \q
6) Login with the new user 'test' , You will be able to access both projection storage and
your table sid.student_table
[dbadmin#localhost bin]$ vsql -u
vsql: Warning: The -u option is deprecated. Use -U.
User name: test
Password:
Welcome to vsql, the Vertica Analytic Database interactive terminal.
test=> select * From sid.student_table;
Student_ID | Last_name | First_Name | Class_Code | Grade_pt
------------+-----------+------------+------------+--------------------
9999 | T_ | S% | PG | 98.700000000000000
(1 row)
test=> select * From projection_storage;
-[ RECORD 1 ]-----------+-----------------------------------------
node_name | v_vertica_node0001
projection_id | 45035996273836526
projection_name | Student_Table_DBD_1_rep_tet1_v1_node0001
projection_schema | sid
projection_column_count | 6
row_count | 9
used_bytes | 375
wos_row_count | 0
wos_used_bytes | 0
ros_row_count | 9
ros_used_bytes | 375
ros_count | 1
anchor_table_name | Student_Table
anchor_table_schema | sid
anchor_table_id | 45035996273756612

Difference between a user and a schema in Oracle?

What is the difference between a user and a schema in Oracle?
From Ask Tom
You should consider a schema to be the user account and collection of all objects therein
as a schema for all intents and purposes.
SCOTT is a schema that includes the EMP, DEPT and BONUS tables with various grants, and
other stuff.
SYS is a schema that includes tons of tables, views, grants, etc etc etc.
SYSTEM is a schema.....
Technically -- A schema is the set of metadata (data dictionary) used by the database,
typically generated using DDL. A schema defines attributes of the database, such as
tables, columns, and properties. A database schema is a description of the data in a
database.
I believe the problem is that Oracle uses the term schema slightly differently from what it generally means.
Oracle's schema (as explained in Nebakanezer's answer): basically the set of all tables and other objects owned by a user account, so roughly equivalent to a user account
Schema in general: The set of all tables, sprocs etc. that make up the database for a given system / application (as in "Developers should discuss with the DBAs about the schema for our new application.")
Schema in sense 2. is similar, but not the same as schema in sense 1. E.g. for an application that uses several DB accounts, a schema in sense 2 might consist of several Oracle schemas :-).
Plus schema can also mean a bunch of other, fairly unrelated things in other contexts (e.g. in mathematics).
Oracle should just have used a term like "userarea" or "accountobjects", instead of overloadin "schema"...
From WikiAnswers:
A schema is collection of database objects, including logical structures such as tables, views, sequences, stored procedures, synonyms, indexes, clusters, and database links.
A user owns a schema.
A user and a schema have the same name.
The CREATE USER command creates a user. It also automatically creates a schema for that user.
The CREATE SCHEMA command does not create a "schema" as it implies, it just allows you to create multiple tables and views and perform multiple grants in your own schema in a single transaction.
For all intents and purposes you can consider a user to be a schema and a schema to be a user.
Furthermore, a user can access objects in schemas other than their own, if they have permission to do so.
Think of a user as you normally do (username/password with access to log in and access some objects in the system) and a schema as the database version of a user's home directory. User "foo" generally creates things under schema "foo" for example, if user "foo" creates or refers to table "bar" then Oracle will assume that the user means "foo.bar".
This answer does not define the difference between an owner and schema but I think it adds to the discussion.
In my little world of thinking:
I have struggled with the idea that I create N number of users where I want each of these users to "consume" (aka, use) a single schema.
Tim at oracle-base.com shows how to do this (have N number of users and each of these users will be "redirected" to a single schema.
He has a second "synonym" approach (not listed here). I am only quoting the CURRENT_SCHEMA version (one of his approaches) here:
CURRENT_SCHEMA Approach
This method uses the CURRENT_SCHEMA session attribute to automatically
point application users to the correct schema.
First, we create the schema owner and an application user.
CONN sys/password AS SYSDBA
-- Remove existing users and roles with the same names.
DROP USER schema_owner CASCADE;
DROP USER app_user CASCADE;
DROP ROLE schema_rw_role;
DROP ROLE schema_ro_role;
-- Schema owner.
CREATE USER schema_owner IDENTIFIED BY password
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;
GRANT CONNECT, CREATE TABLE TO schema_owner;
-- Application user.
CREATE USER app_user IDENTIFIED BY password
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp;
GRANT CONNECT TO app_user;
Notice that the application user can connect, but does not have any
tablespace quotas or privileges to create objects.
Next, we create some roles to allow read-write and read-only access.
CREATE ROLE schema_rw_role;
CREATE ROLE schema_ro_role;
We want to give our application user read-write access to the schema
objects, so we grant the relevant role.
GRANT schema_rw_role TO app_user;
We need to make sure the application user has its default schema
pointing to the schema owner, so we create an AFTER LOGON trigger to
do this for us.
CREATE OR REPLACE TRIGGER app_user.after_logon_trg
AFTER LOGON ON app_user.SCHEMA
BEGIN
DBMS_APPLICATION_INFO.set_module(USER, 'Initialized');
EXECUTE IMMEDIATE 'ALTER SESSION SET current_schema=SCHEMA_OWNER';
END;
/
Now we are ready to create an object in the schema owner.
CONN schema_owner/password
CREATE TABLE test_tab (
id NUMBER,
description VARCHAR2(50),
CONSTRAINT test_tab_pk PRIMARY KEY (id)
);
GRANT SELECT ON test_tab TO schema_ro_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON test_tab TO schema_rw_role;
Notice how the privileges are granted to the relevant roles. Without
this, the objects would not be visible to the application user. We now
have a functioning schema owner and application user.
SQL> CONN app_user/password
Connected.
SQL> DESC test_tab
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
ID NOT NULL NUMBER
DESCRIPTION VARCHAR2(50)
SQL>
This method is ideal where the application user is simply an
alternative entry point to the main schema, requiring no objects of
its own.
It's very simple.
If USER has OBJECTS
then call it SCHEMA
else
call it USER
end if;
A user may be given access to schema objects owned by different Users.
Schema is an encapsulation of DB.objects about an idea/domain of intrest, and owned by ONE user. It then will be shared by other users/applications with suppressed roles. So users need not own a schema, but a schema needs to have an owner.
--USER and SCHEMA
The both words user and schema are interchangeble,thats why most people get confusion on this words below i explained the difference between them
--User User is a account to connect database(Server). we can create user by using CREATE USER user_name IDENTIFIED BY password .
--Schema
Actually Oracle Database contain logical and physical strucutre to process the data.The Schema Also Logical Structure to process the data in Database(Memory Component). Its Created automatically by oracle when user created.It Contains All Objects created by the user associated to that schema.For Example if i created a user with name santhosh then oracle createts a schema called santhosh,oracle stores all objects created by user santhosh in santhosh schema.
We can create schema by CREATE SCHEMA statement ,but Oracle Automatically create a user for that schema.
We can Drop the schema by using DROP SCHEMA schama_name RESTRICT statement but it can not delete scehema contains objects,so to drop schema it must be empty.here the restrict word forcely specify that schema with out objects.
If we try to drop a user contain objects in his schema we must specify CASCADE word because oracle does not allow you to delete user contain objects.
DROP USER user_name CASCADE
so oracle deletes the objects in schema and then it drops the user automatically,Objects refered to this schema objects from other schema like views and private synonyms goes to invalid state.
I hope now you got the difference between them,if you have any doubts on this topic,please feel free to ask.
Thank you.
A user account is like relatives who holds a key to your home, but does not own anything i.e. a user account does not own any database object...no data dictionary...
Whereas a schema is an encapsulation of database objects. It's like the owner of the house who owns everything in your house and a user account will be able to access the goods at the home only when the owner i.e. schema gives needed grants to it.
A schema and database users are same but if schema has owned database objects and they can do anything their object but user just access the objects, They can't DO any DDL operations until schema user give you the proper privileges.
Based on my little knowledge of Oracle... a USER and a SCHEMA are somewhat similar. But there is also a major difference. A USER can be called a SCHEMA if the "USER" owns any object, otherwise ... it will only remain a "USER". Once the USER owns at least one object then by virtue of all of your definitions above.... the USER can now be called a SCHEMA.
User: Access to resource of the database. Like a key to enter a house.
Schema: Collection of information about database objects. Like Index in your book which contains the short information about the chapter.
Look here for details
For most of the people who are more familiar with MariaDB or MySQL this seems little confusing because in MariaDB or MySQL they have different schemas (which includes different tables, view , PLSQL blocks and DB objects etc) and USERS are the accounts which can access those schema. Therefore no specific user can belong to any particular schema. The permission has be to given to that Schema then the user can access it. The Users and Schema is separated in databases like MySQL and MariaDB.
In Oracle schema and users are almost treated as same. To work with that schema you need to have the permission which is where you will feel that the schema name is nothing but user name. Permissions can be given across schemas to access different database objects from different schema. In oracle we can say that a user owns a schema because when you create a user you create DB objects for it and vice a versa.
Schema is a container of objects.
It is owned by a user.
Well, I read somewhere that if your database user has the DDL privileges then it's a schema, else it's a user.

Resources