Privileges/security for stored procedure in DB2 LUW - sql

UPDATED question:
The core of my problem is: The stored procedure I (User1) created is not able to select from the some specific table (table1 created by another user (User2)) due to:
CREATE OR REPLACE PROCEDURE TEST_SCHEMA.TEST_PROCEDURE(OUT r_count INTEGER)
LANGUAGE SQL
BEGIN
SET r_count = (SELECT COUNT(*) FROM TEST_SCHEMA.TABLE1);
END
OK. No rows were affected
SQLWarning: Code: 20480 SQL State: 0168Y
--- The newly defined object "TEST_SCHEMA.TEST_PROCEDURE" is marked as invalid because it references an object "TEST_SCHEMA.TABLE1" which is
not defined or is invalid, or the definer does not have privilege to
access it.. SQLCODE=20480, SQLSTATE=0168Y, DRIVER=4.22.29
However, when I select from table1 in a normal query window there is no problem, hence I thought something was wrong about the security option on the stored procedure
SELECT COUNT(*) FROM TEST_SCHEMA.TABLE1
Table and stored procedure names are fully qualified. The stored procedure is created and executed by user1. The privilege given to the user1, to select from table1 , is a group privilege.

The procedure creator must have the corresponding privilege on statically referenced table either directly or via roles.
CREATE PROCEDURE (SQL) statement:
Authorization
The privileges held by the authorization ID of the
statement must include at least one of the following authorities:
If the implicit or explicit schema name of the procedure does not exist, IMPLICIT_SCHEMA authority on the database.
If the schema name of the procedure refers to an existing schema, CREATEIN privilege on the schema.
DBADM authority
The privileges held by the authorization ID of the statement must also
include all of the privileges necessary to invoke the SQL statements
that are specified in the procedure body.
To replace an existing procedure, the authorization ID of the
statement must be the owner of the existing procedure (SQLSTATE
42501).
Group privileges are not considered for any table or view specified in
the CREATE PROCEDURE (SQL) statement.

Related

unable to execute sql procedure on oracle live sql

I created a procedure
create or replace procedure dba_role
as
user varchar2(200);
ref varchar2(200);
begin
insert into dba_role_privs(grantee,granted_role) (select user as grantee,granted_role from dba_role_privs where grantee=ref);
end;
The procedure is getting created but I'm not able to execute the procedure. I've tried different methods to execute it by passing parameters but nothing worked.
Can anyone please tell how to execute this procedure in oracle live SQL
the parameters to be passed are both strings(varchars)
for example:
I've tried "Execute dba_role('alex','hunter');
The error is
**ORA-06550: line 1, column 7:
**PLS-00306: wrong number or types of arguments in call to 'DBA_ROLE' **
As well as missing the two parameters that you are trying to pass (parameters should appear in brackets immediately following the procedure name, as explained in d r's answer), you can't insert into a DBA view. For one thing, it's not in your schema (unless you are creating your procedure as SYS, which you should never do because SYS is reserved for Oracle internals) and you haven't been granted INSERT privilege, but also because it is defined with multiple joins and unions etc and is therefore not an updatable view. Even it it were, your procedure only specifies two of its seven columns.
Even if you did have privileges and it was updatable and you supplied all of the values, directly updating internal data dictionary tables is unsupported and could damage your database. If you want to grant a privilege to a role you should use the GRANT command:
grant reports_user to hr;
To revoke the grant,
revoke reports_user from hr;
create or replace procedure
dba_role(p_user IN VarChar2, p_ref IN VarChar2) AS
begin
insert into dba_role_privs(grantee, granted_role) (select p_user as grantee, granted_role from dba_role_privs where grantee = p_ref);
end dba_role;
/
Above is how it should be defined - with two VarChar2 parameters. And below is how to call it:
Begin
dba_role('alex', 'hunter');
End;
/
The problem with your code was that user and ref were declared as variables within the scope of the procedure (not as parameters) so, when the procedure was called with parameters (like I did above) then you tryed to pass two parameters to the procedure not accepting any. On the other side, if you call it without parameters (just as dba_role;) then user and ref were both Null.

SQL Dynamic Query Insertion with SQL user which has execute permission on stored procedure

I have a user in sql database which has execute permission on the stored procedure. On Store Procedure i am trying to insert into the table by : EXEC (#insertQuery)
But i get following error
System.Data.SqlClient.SqlException (0x80131904): The INSERT permission was denied on the object ''table_name'', database ''db name'', schema ''dbo''.Unexpected error occurred!
I have looked into EXECUTE AS Clause also this will work , Is there any method beside this ? Safe one .
Thank You
I think you want to use the WITH EXECUTE AS clause when you create the stored procedure. You can read about it here.
You can define the stored procedure to execute as the OWNER of the stored procedure. This is very, very handy. You can prevent users from directly modifying tables. But, you can give them access to stored procedures that can modify the tables.
An alternative to EXECUTE AS is with module signing. This requires more configuration than EXECUTE AS but has the advantage of retaining the callers identity without granting direct permissions to the user and can be extended for cross-database access.
Below is an example script gleaned from Erland Sommarskog's excellent and thorough article on Giving Permissions through Stored Procedures.
CREATE TABLE dbo.testtbl (a int NOT NULL,
b int NOT NULL);
INSERT dbo.testtbl (a, b) VALUES (47, 11);
GO
CREATE PROCEDURE example_sp AS
SELECT SYSTEM_USER, USER, name, type, usage FROM sys.user_token;
EXEC ('SELECT a, b FROM testtbl');
GO
-- Create the certificate.
CREATE CERTIFICATE examplecert
ENCRYPTION BY PASSWORD = 'All you need is love'
WITH SUBJECT = 'Certificate for example_sp',
START_DATE = '20020101', EXPIRY_DATE = '20200101';
GO
-- Create the certificate user and give it rights to access the test table.
CREATE USER examplecertuser FROM CERTIFICATE examplecert;
GRANT SELECT ON dbo.testtbl TO examplecertuser;
GO
-- Sign the procedure.
ADD SIGNATURE TO dbo.example_sp BY CERTIFICATE examplecert
WITH PASSWORD = 'All you need is love';
GO
--users need proc execute permissions but not table permissions
GRANT EXECUTE ON dbo.example_sp TO YourUserOrRole;
GO

Error during stored procedure creation in DB2 database

I am struggling with schemas while creating a stored procedure in DB2 database ( 10.5 version ).
My user name is XYZ but I have to create a Stored procedure for schema ABC.
When I am trying to execute the create procedure sql I get error message which looks like Schema related
Create procedure ABC.customInsert(
IN temp INTEGER
)
BEGIN
INSERT INTO ABC.One_Column_table VALUES ( temp );
END
Error Message:
Error:DB2 SQL error:SQLCODE:-551, SQLSTATE: 42501,
SQLERRMC:XYZ;INSERT;ABC.One_Column_table
My current schema was showing XYZ earlier. ( result of select current_Schema from sysibm.sysdummy1).
I have changed it to ABC. ( using SET CURRENT SCHEMA ABC). But still the same problem.
I am able to insert, select, create UDT etc in ABC schema but the problem exists only during stored procedure creation.
Any idea what am I doing wrong ?
Based on your error message, SQLCODE -551 means that the user "XYZ" does not have the "INSERT" privilege on the table "ABC.One_Column_table".
Since you imply that you, when connected as XYZ, can insert into the table by issuing simple INSERT statements, it is possible that you possess the INSERT privilege indirectly, via a group membership. Group privileges are ignored for SQL statements in stored procedures, functions or triggers, as explained in this IBM technote.
You have two options:
Grant the required privileges on ABC.One_Column_table to the user XYZ directly.
Create a role (using the CREATE ROLE statement), grant the table privileges to that role, then grant the role to the user XYZ.
If you are curious, such behaviour is caused by the fact that static SQL statement (e.g. in a stored procedure) authorization is checked only during compilation, and the compiled code can then be executed without additional authorization checks. Groups are maintained outside the DB2 database, by the operating system, and it is possible that group membership changes after the stored procedure is compiled and without the database security administrator's knowledge. If group privileges were effective for static SQL, it would allow users who weren't originally authorized to run particular statements (i.e. were not members of the authorized group at the compilation time) still execute those statements, thus creating a security risk.
Roles, on the other hand, are maintained within the database itself by the database security administrator and thus are part of the same security landscape.

dbms_metadata.get_ddl not working

I want to get the DDL of Table CARD_TABLE in XT schema
SQL> select dbms_metadata.get_ddl('TABLE','CARD_TABLE','XT') from dual;
ERROR:
ORA-31603: object "CARD_TABLE" of type TABLE not found in
schema "XT"
ORA-06512: at "SYS.DBMS_METADATA", line 5746
ORA-06512: at "SYS.DBMS_METADATA", line 8333
ORA-06512: at line 1
But my select Query works
select count(*) from XT.CARD_TABLE;
count(*)
---------
0
I queried dba_objects it still got the table:
SQL> select owner,object_type from DBA_OBJECTS
where object_name='CARD_TABLE' 2
3 ;
PUBLIC SYNONYM
XT TABLE PARTITION
XT TABLE PARTITION
XT TABLE PARTITION
XT TABLE
XT TABLE PARTITION
VAT TABLE
7 rows selected.
From the dbms_metadata documentation:
If nonprivileged users are granted some form of access to an object in someone else's schema, they will be able to retrieve the grant specification through the Metadata API, but not the object's actual metadata.
So unless you're connected as a privileged user, you can't see the DDL for another user's objects. You would need to connect as SYS, or have the SELECT_CATALOG_ROLE role granted to your user to be able to get XT's object definition.
Even with that role:
In stored procedures, functions, and definers-rights packages, roles (such as SELECT_CATALOG_ROLE) are disabled. Therefore, such a PL/SQL program can only fetch metadata for objects in its own schema. If you want to write a PL/SQL program that fetches metadata for objects in a different schema (based on the invoker's possession of SELECT_CATALOG_ROLE), you must make the program invokers-rights.
If you're calling dbms_metadata from an anonymous PL/SQL block that doesn't matter, but if you're calling it from a procedure you will have to include an AUTHID clause in the procedure declaration, adding AUTHID CURRENT_USER.
grant SELECT_CATALOG_ROLE to <user> with delegate option;
it work for me. Do this after modify procedure
grant SELECT_CATALOG_ROLE to procedure <procedure name>;

Facing an error : table or view does not exist

I am using insert statement and trying to insert data into the database table. I am using stored procedures.
But I am getting this error while doing so.
Message: ORA-00942: table or view does
not exist ORA-06512
I checked if the tables/stored procedures are present or not and everything is in place. Also there is no typo in table names or in sp. If I run the part of SP from query editor it works fine but when I execute the entire SP it throws an error.
I tried the steps provided by Stephen but since I have logged in with the same user/owner when I run Grant command it gives me an error saying 'Cannot Grant/revoke on own'.
One more addition to this. I have a stored procedure SP1 in which I am using a select statement as
Select a from table_name where condition;
When I execute this seperately, it returns me some results. But when I execute sp it gives an error at the same line where it is written.
Can anyone help me out to resolve this issue. I am using SQL +.
Thanks in advance
Vijay
Justin's answer is correct but let me expand a bit.
Everyone who said that the table doesn't exist didn't read your whole post. Since you are able to:
If I run the part of SP from query editor it works fine
Obviously the table is there.
Obviously you have some access to it. Otherwise this wouldn't work when it clearly does.
but when I execute the entire SP it throws an error.
This is because Oracle distinguishes between permissions granted directly and those granted via a role.
Say I do this:
Create Table TABLE_A
Create Role READ_ONLY
Grant Select on TABLE_A to READ_ONLY
Grant READ_ONLY to VIJAY
In a SQL Window/prompt you could query that table without issue. So now you need to create a view
Create VIJAY.VIEW_A as SELECT * FROM TABLE_A
You'll get the error that TABLE_A does exist. Because a view is compiled, like a procedure it runs without any roles. Since it runs without the READ_ONLY role, it's blind to the fact that TABLE_A exists. Now what I need to do is
Grant Select on TABLE_A to VIJAY.
Now that you have a direct permission, you can compile a view or procedure/package that uses that table.
Does the table exist in the schema where the stored procedure exists? If not, the simplest explanation is that the owner of your procedure has been granted access to the table via a role not via a direct grant. A definer's rights stored procedure needs to have direct access to the objects it accesses. A quick way to test this is to disable roles for the session, i.e.
SQL> set role none;
SQL> <<execute your query>>
If that generates the error, the problem is the lack of a direct grant.
In Oracle you can choose if the stored procedure is executed with the rights of the invoker or the definer: http://download.oracle.com/docs/cd/E11882_01/appdev.112/e17126/subprograms.htm#i18574
Check if the AUTHID property of the stored procedure is correct and if the resulting user has appropriate permissions.
Well, put very simply, the table that you are trying to insert data into does not exist in the database you are connected to. You need to check both those things (i.e. what are you connected to, and is the table there and accessible for the user context you are using).
As Joe Stefanelli said .. there are a lot of possibilities for the error being shown here.
Check whether:
You are connecting to the correct Oracle Instance.
You have permissions to query or perform processing on table that you are referencing in your query.
There is a difference between ordinary select statements and procedures. Procedures in oracle do not respect the roles assigned to a user; rather the permission needs to be explicitly granted to the user. For more information read the following linkORA-00942