What privileges could be missing in the case of granted permission to call a package that is calling a package? - sql

I can unfortunately not provide any code, but I will try to explain as best as I can and will provide additional information as necessary.
There are 3 different schemas at play in this scenario: X_SCHM, APPS, and HR
APPS has a package called X_PKG to run some functionality for a resource, and X_PKG also makes a call to a procedure in package HR_EMPLOYEE_API, owned by HR schema. APPS grants execute privileges on X_PKG to X_SCHM, and X_SCHM can successfully call procedures inside X_PKG.
However, I want to move as much away from APPS and into X_SCHM, so the package body of X_PKG is copied over to a new X2_PKG in X_SCHM. X2_PKG still needs to call a procedure in HR_EMPLOYEE_API, so a grant is given to X_SCHM to execute that package.
Now when X_SCHM tries to call X2_PKG, which is by all accounts identical to X_PKG owned by APPS, it successfully enters HR_EMPLOYEE_API owned by HR and then starts running into "table or view does not exist" errors inside of it, a problem that APPS or X_SCHM running X_PKG owned by APPS does not run into.
I'm not sure if this is an issue of additional grants needing to be made. I would think since X_SCHM has execute privilege on HR_EMPLOYEE_API that procedures it calls from HR_EMPLOYEE_API would be able to access tables owned by HR, unless there's information I'm missing regarding packages needing their own granted privileges separate from the schemas that own them.
Please let me know where I can be clearer or provide more information to get this issue solved.

The package HR_EMPLOYEE_API is defined as AUTHID CURRENT_USER. This means that all the code inside the package is executed as the user who is calling it. So basically you have 3 choices :
1) You leave the package in the APPS User as suggested by #Sudipta Mondal. It sounds like the safest choice.
2) If X2_PKG is defined as AUTHID DEFINER, you could try to copy all the direct rights from APPS to X_SCHM and hope for the best. But it's really not that good because i'm quite sure that APPS has a lot of rights. Luckily you don't have to bother with permissions obtained through roles as they don't apply in packages. try something like that
select 'GRANT '||PRIVILEGE||' ON '||OWNER||'.'||TABLE_NAME||' TO X_SCHM;' FROM DBA_TAB_PRIVS WHERE GRANTEE = 'APPS';
3) Try to figure out which rights to add either by trial and error or by fetching them from DBA_DEPENDENCIES if they are referenced :
select REFERENCED_OWNER, REFERENCED_TYPE, REFERENCED_NAME from dba_dependencies where NAME = 'HR_EMPLOYEE_API';
I, personally, agree with Sudipta Mondal, you should probably reconsider moving it if not mandatory.

Related

How to create a role that can access only selected tables during runtime

I'm running a SAP HANA database in HDI container and created a corresponding HDI Container admin. I would like to be able to grant users (for support purpose) access not to the whole schema, but only to a few selected tables. How to do it? All examples I found online look like this - and grant access only to a whole schema
CREATE ROLE SCHEMA_NAME.ROLE_NAME NO GRANT TO CREATOR;
GRANT SELECT ON SCHEMA SCHEMA_NAME TO ROLE_NAME;
I know there is an option to use .hdbrole file during deployment, where also object privileges can be written up, but it seems I would have to run deployment each time whenever I need to create a new role. And I would like to create these roles right from the SQL console. Is it possible? And if yes, how to do it?
By running the CREATE ROLE and GRANT commands in the SQL console you create catalog/runtime roles.
These cannot be transported to any other container or DB but only live in this very instance of the database.
Now, that is usually not what you want to have when dealing with HDI containers or containerized applications in general.
Creating schema objects on the fly commonly leads to operational challenges (who has access to what, where, when, why, how?) and should rather be avoided.
But, sure, you can simply connect to the container with any user that has appropriate permissions and run those commands. That includes the usual GRANT SELECT on <table_name> TO <role>; it doesn't have to be the whole schema.

The SELECT permission was denied on the object 'fn_dblog', database 'mssqlsystemresource', schema 'sys'

I created a user and gave him access to run sp. That sp also has to update a table based on the type of work.
But when the user runs sp, it gives an error:
The SELECT permission was denied on the object 'fn_dblog', database 'mssqlsystemresource', schema 'sys'.
Does anyone have a solution to this problem?
The required permission to use the fn_dblog system table-valued function is sysadmin role membership.
Importantly, this function is undocumented so it should not be used in application code, especially to update a table.
EDIT:
Your comment indicates the function is used in a trigger. You could create a certificate and certificate user that's a sysadmin role member as described here and then sign the trigger with that certificate. That will confer sysadmin permissions to the trigger code and allow non-sysadmin users to use the function but only in the context of the trigger.
I would normally include an example T-SQL script in my answer but I want to strongly discourage you from going down the path of using the undocumented system function in app code.
You have a classic XY problem that needs to be solved differently. Ask a new question about how to provide the functionality you need without using fn_dblog. Include your existing code in the question.

SQL Server signature on stored procedure using certificate

I'm confused by the example at this link. A similar example exists here but I prefer the first one. Briefly here is the summary of my confusion:
A user (examplecertuser) is created from the certificate.
Rights are granted to the user (examplecertuser) created from the certificate.
A signature is added to the stored procedure using the certificate.
Then a test is done using a separate login (testuser) that has no relation to the previous. This is what I don't understand.
I'm not sure why the examplecertuser is created or what purpose it serves. More importantly, since no connection is made between the login (testuser) and the certificate created user (examplecertuser), this means that ANY LOGIN is able to run the stored procedure. I verified this by creating another login and having it also run the stored procedure.
I am looking into this to avoid database ownership chaining as per all the recommendations I read. My goal is to grant a user the ability to run a stored procedure which spans several databases but limit them to just running that stored procedure. Using the example I see listed, I think I would be granting everyone the ability to run the stored procedure with no way to limit others from it.
To rephrase the question in a more direct format, "how do you use the sample in the link to only allow selected logins to run the stored procedure?" The user (examplecertuser) seems to be the key to authorization but I don't see any linke between the user and a login.
Code signing gives you the ability to grant permissions to an underlying object under certain circumstances (as opposed to any time). Say, for instance, that I have a table with sensitive information in it. I don't want just anybody selecting from it (that is, writing "select * from myTable"), but I'm okay with giving them access through a stored procedure (so I can limit what they can select with business logic). So I go through the exercise of signing the stored procedure. I can still grant (or deny) execute permissions on the procedure to individual users. But when the permissions are checked for the underlying objects that the stored procedure accesses, it will apply the permissions of the module signing user (examplecertuser in your example).
With respect to your specific questions
Only users that are granted execute permission on the stored procedure will be able to run it
In order have this permission span multiple databases, you'll need to create the certificate and associated user in each database.

How do I grant a database role execute permissions on a schema? What am I doing wrong?

I am using SQL Server 2008 Express edition.
I have created a Login , User, Role and Schema.
I have mapped the user to the login, and assigned the role to the user.
The schema contains a number of tables and stored procedures.
I would like the Role to have execute permissions on the entire schema.
I have tried granting execute permission through management studio and through entering the command in a query window.
GRANT EXEC ON SCHEMA::schema_name TO role_name
But When I connect to the database using SQL management studio (as the login I have created) firstly I cannot see the stored procedures, but more importantly I get a permission denied error when attempting to run them.
The stored procedure in question does nothing except select data from a table within the same schma.
I have tried creating the stored procedure with and without the line:
WITH EXECUTE AS OWNER
This doesn't make any difference.
I suspect that I have made an error when creating my schema, or there is an ownership issue somewhere, but I am really struggling to get something working.
The only way I have successfully managed to execute the stored procedures is by granting control permissions to the role as well as execute, but I don't believe this is the correct, secure way to proceed.
Any suggestions/comments would be really appreciated.
Thanks.
There are couple of issues that I can see in your case.
First of all you would need View Definition granted for you to be able to see the objects in the Management studio.
I would recommend this if you want the role to have all permissions,
GRANT EXECUTE, SELECT, INSERT, UPDATE, DELETE, VIEW DEFINITION
ON Schema::SchemaName TO [RoleName/LoginName]
Also make sure the owner of your user-defined schema is "dbo".

Create a New user ORACLE with full access to an specific SCHEMA

How can create a New user in ORACLE with full access (alter, delete, select, inset, debug, etc) to an only one specific SCHEMA.
Cannot be done. In Oracle privileges are granted on specific objects, unless you have the highpowered ANY privileges, which grant access to any object in any schema.
This is one of those things which seems quite annoying but actually is quite sound. There is no good business reason for granting privileges on all on the objects in a schema en masse. Either
the second schema really needs just a sub-set of privilges on a sub-set of objects; or
the second schema is entirely unnecessary.
Now it may be that the sub-set in the first instance is a very large sub-set. But laziness is not an excuse for poor security practices.
What we can do is generate the grant statements from the data dictionary:
select 'grant select on '||table_name||' to B'
from user_tables
/
(for a script to be run by user A).
This is still better than granting privileges on the schema, because it means at least any new object added by user A will not automatically be propagated to B without an additional action and, hence, without some additional thought as to whether it is appropriate.
You could use a PROXY user. Its not quite the same thing as it allows one database user to connect as another but using their own password.
You can therefore have multiple users, each with their own password, using the same schema.
An example of the code is here.