There're two schema in db, I create a materialized view -- 'MV1' and grant it successfully,selecting from it in other schema is ok.
GRANT select ON schemaA.MV_CA_REVENU_MS_GEO TO read;
/
GRANT select ON schemaA.MV_CA_REVENU_MS_GEO TO write;
/
GRANT update ON schemaA.MV_CA_REVENU_MS_GEO TO write;
/
But while compiling the procedure, there's error message says 'table or view does not exist' for 'MV1'. The procedure code is:
create or replace
PROCEDURE SP_NAME (args ... ) is
.
.
begin
INSERT INTO tableName(
.
.
) SELECT ...
FROM (SELECT ...
FROM MV1 -- **schemaA.MV1 doesn't work either**
WHERE
end SP_NAME;
/
GRANT EXECUTE ON schemaB.SP_NAME TO read;
GRANT DEBUG ON schemaB.SP_NAME TO read;
GRANT EXECUTE ON schemaB.SP_NAME TO write;
GRANT DEBUG ON schemaB.SP_NAME TO write;
/
CREATE or replace PUBLIC SYNONYM SP_NAME FOR schemaB.SP_NAME;
/
I try to add schemaA in front of MV1, it doesn't work. Is there any other step should I take a check?
Are "read" and "write" schema names or role names? Permissions in Oracle granted indirectly via roles are not available when compiling stored procedures, functions, and packages
Related
I am attempting to create a package in which I drop and create a table using a CTAS query. This table needs to be refreshed frequently and columns are add/removed all the time from the underlying data. Since the structure of the table is constantly changing, it would be quite cumbersome to update merge/update queries each refresh to account for the new/missing columns. Currently, I have external scripts that do simple drops and creates but I need to centralize this in the database; therefore I am attempting to create a package to do it; however, I am having trouble with privileges.
As proof of concept, the following code works when ran as an anonymous block:
create table my_test_table as select * from dual; --create test table
declare
v_count int;
begin
select count(*) into v_count from all_tab_columns where table_name = upper('my_test_table');
if v_count >= 1 then
execute immediate 'drop table my_test_table';
end if;
execute immediate q'[
create table my_test_table as
select * from dual
]';
end;
select * from my_test_table; -- shows expected results
But when creating a package to do the same thing;
CREATE OR REPLACE PACKAGE test_pkg AS
PROCEDURE test_procedure;
END test_pkg;
CREATE OR REPLACE package body test_pkg as
procedure test_procedure
is
v_count int;
begin
select count(*) into v_count from all_tab_columns where table_name = upper('my_test_table');
if v_count >= 1 then
execute immediate 'drop table my_test_table';
end if;
execute immediate q'[
create table my_test_table as
select * from dual
]';
end test_procedure;
end test_pkg;
/
and testing with the following code:
create table my_test_table as select * from dual; --make sure table exists
execute TEST_PKG.TEST_PROCEDURE; --results in errors
select * from my_test_table; --table does not exist; therefore, DROP statement works but not CREATE
I get the following errors (in regards to executing TEST_PKG.TEST_PROCEDURE):
ORA-01031: insufficient privileges
ORA-06512: at test_pkg, line 15
When testing for the existence of the test table after executing the package, I can see that it no longer exists. This means the DROP statement is working but the CREATE TABLE statement is resulting in the insufficient privileges error.
Any and all insight into what privileges I need to create the table from within the package would be immensely helpful.
Create a table in procedure is only alowed when you have "Create table" or "create any table" privilege but granted directly to user (granted by role is not working).
https://docs.oracle.com/cd/B19306_01/network.102/b14266/authoriz.htm#i1008334
PL/SQL Blocks and Roles
The use of roles in a PL/SQL block depends on whether it is an
anonymous block or a named block (stored procedure, function, or
trigger), and whether it executes with definer's rights or invoker's
rights.
Named Blocks with Definer's Rights
All roles are disabled in any named PL/SQL block (stored procedure,
function, or trigger) that executes with definer's rights. Roles are
not used for privilege checking and you cannot set roles within a
definer's rights procedure.
To check system privileges granted directly to your user (not by role/roles), you can run this query from your user:
SELECT * FROM USER_SYS_PRIVS;
The package you've created, in the absence of a AUTHID CURRENT_USER clause is a definer's rights package. It can only do things that are allowed by privileges granted directly to the definer of the package. "Directly" is the key point here -- privileges granted through enabled roles are not honored during the package execution.
You've probably got the RESOURCE or similar role enabled for your user, which would explain why you can create the table during testing but not via your package procedure.
Try granting the CREATE TABLE and UNLIMITED TABLESPACE system privileges directly to your user and then recreate the package. (If that works, replace UNLIMITED TABLESPACE with quotas on the appropriate tablespace(s) in your database).
I need to grant permission to a specific user to create stored procedures in PostgreSQL without writing permissions to other tables. The stored procedure should read and write only in one table.
I've already setup the read permission to that table, but I'm struggling with the writting permissions.
GRANT CONNECT ON DATABASE production_database TO user;
GRANT USAGE ON SCHEMA public TO user;
GRANT SELECT ON table TO user;
If you want to write a procedure in PL/PGSQL you need to use PostgreSQL 11 or 12.
In PostgreSQL there is no explicit privilege to create a procedure or a function.
However you can try:
to create a specific schema just for the procedure
to grant USAGE to this schema only to the specific user
to create the procedure with SECURITY DEFINER as the table owner
Example:
create user myuser password 'myuser';
--
create table public.t(x int);
--
create schema myschema;
--
create or replace procedure myschema.myproc(param int)
language plpgsql
as
$$
declare
v int;
begin
insert into public.t values(param);
end;
$$
security definer
set search_path='';
--
grant usage on schema myschema to myuser;
Here the table owner is superuser postgres and the table schema is public:
With this script:
\c postgres myuser
select * from t;
call myschema.myproc(1);
\c postgres postgres
select * from t;
I get:
You are now connected to database "postgres" as user "myuser".
select * from t;
psql:cp.sql:25: ERROR: permission denied for table t
call myschema.myproc(1);
CALL
You are now connected to database "postgres" as user "postgres".
select * from t;
x
---
1
(1 row)
How can I create correct roles-tree for postgresql database for users which can do this:
read only (select) data (A)
A + modify (insert, delete, update) data (B)
B + create tables (C)
C + create tables and also all special privileges (D)
I checked documentation about roles and default privileges, but nothing helps me understand how Postgres work with roles. My actual script for create sample roles:
create database daba;
create role "ra" nologin noinherit; -- default read only role
grant connect on database "daba" to "ra";
grant usage on schema public to "ra" with grant option;
grant select on all tables in schema public to "ra" with grant option;
-- ingore sequences and functions now
create role "rb" nologin inherit;
grant "ra" to "rb"; -- grant connect, grant select
grant insert, update, delete on all tables in schema public to "rb" with grant option;
create role "rc" nologin inherit;
grant "rb" to "rc";
grant all privileges on schema public to "rc" with grant option;
grant all privileges on all tables in schema public to "rc" with grant option;
create role "rd" nologin inherit;
grant "rc" to "rd";
grant "postgres" to "rd";
-- default privileges for new created tables
-- only "rc" and "rd" can create table, "ra" can read it
alter default privileges for role "rc", "rd" in schema public grant select on tables to "ra" with grant option;
-- "rb" and higher can insert, update or delete also
alter default privileges for role "rc", "rd" in schema public grant insert, update, delete on tables to "rb" with grant option;
-- roles done, create users
create role "ua" login encrypted password 'ua' in role "ra";
create role "ub" login encrypted password 'ub' in role "rb";
create role "uc" login encrypted password 'uc' in role "rc";
create role "ud" login encrypted password 'ud' in role "rd";
OK, roles and users are created, now test with errors on lines:
-- connect as "ud"
create table ud_a (a numeric); -- OK
insert into ud_a values (1); -- OK
select * from ud_a; -- OK -- 1 row
-- connect as "uc"
select * from ud_a; -- SQL Error [42501]: ERROR: permission denied for relation ud_a
-- As user "uc" I cannot insert value, or drop table
insert into ud_a values (2); -- **SQL Error [42501]: ERROR: permission denied for relation ud_a**
drop table ud_a; -- **SQL Error [42501]: ERROR: must be owner of relation ud_a**
-- But I can create new table! As "uc":
create table uc_a (a numeric); -- OK
insert into uc_a values (2); -- OK
-- After this when i connect as more powerfull user - "ud"
-- I cannot even read from this table even though my user "ud" is created under role "rd" with "grant 'rc' to 'rd'":
select * from uc_a; -- SQL Error [42501]: ERROR: permission denied for relation uc_a
-- Connect as "ua" for read only return also errors for selects:
select * from ud_a; -- SQL Error [42501]: ERROR: permission denied for relation ud_a
select * from uc_a; -- SQL Error [42501]: ERROR: permission denied for relation uc_a
Cleaning:
-- as "postgres":
drop owned by "ud"; drop owned by "uc"; drop owned by "ub"; drop owned by "ua";
drop role "ud"; drop role "uc"; drop role "ub"; drop role "ua";
drop owned by "rd"; drop owned by "rc"; drop owned by "rb"; drop owned by "ra";
drop role "rd"; drop role "rc"; drop role "rb"; drop role "ra";
drop database daba;
I need to create role structure where user A can select all tables created by user C or D and all users inherit from prveious level (so everything which can select user A can select also user B, C and D) and also role D which can drop table created by user under role C and so on...
Can you help me with this?
While creating packages in oracle it is asking for previlage.. what shall i do..
I tried
SQL> GRANT CREATE PACKAGE TO C##SA ;
showing error
GRANT CREATE PACKAGE TO C##SA
*
ERROR at line 1:
ORA-00990: missing or invalid privilege
It is
create (any) procedure
Privileges:
http://docs.oracle.com/cd/E11882_01/timesten.112/e21642/privileges.htm#TTSQL340
GRANT CREATE any procedure TO C##SA ;
You can try these below views.
SELECT * FROM USER_SYS_PRIVS;
SELECT * FROM USER_TAB_PRIVS;
SELECT * FROM USER_ROLE_PRIVS;
grant create session, create procedure to user identified by user;
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9532924000346535486
I am trying to access information from an Oracle meta-data table from within a function. For example (purposefully simplified):
CREATE OR REPLACE PROCEDURE MyProcedure
IS
users_datafile_path VARCHAR2(100);
BEGIN
SELECT file_name INTO users_datafile_path
FROM dba_data_files
WHERE tablespace_name='USERS'
AND rownum=1;
END MyProcedure;
/
When I try to execute this command in an sqlplus process, I get the following errors:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/5 PL/SQL: SQL Statement ignored
6/12 PL/SQL: ORA-00942: table or view does not exist
I know the user has access to the table, because when I execute the following command from the same sqlplus process, it displays the expected information:
SELECT file_name
FROM dba_data_files
WHERE tablespace_name='USERS'
AND rownum=1;
Which results in:
FILE_NAME
--------------------------------------------------------------------------------
/usr/lib/oracle/xe/oradata/XE/users.dbf
Is there something I need to do differently?
Make sure that SELECT is not only grantet through a role, but that the user actually has the grant. Grants by roles do not apply to packages. See this post at asktom.oracle.com.
Also, try sys.dba_data_files instead of dba_data_files.
Specify WITH GRANT OPTION to enable the grantee to grant the object privileges to other users and roles.
GRANT SELECT ON dba_data_files TO YOUR_USER WITH GRANT OPTION;
Have you tried prefixing the table name with sys. as in
FROM sys.dba_data_files
For selecting data from dba_data_files, grant select from SYS user to USER. Example:
GRANT SELECT ON dba_data_files TO YOUR_USER;
After that recompile your Procedure.