How to grant usage on generator syntax - permissions

I'm usually not the one working with Firebird language, but I have to fix access to generators in order to continue working. There is one line in my script: set generator order_gen to 0 that doesn't work anymore.
I'm trying: GRANT USAGE ON GENERATOR ORDER_GEN TO USER MAHE, but I still get the error ...no permission for ALTER access to GENERATOR ORDER_GEN ....
Should I be granting a different privilege to be able to set the generator, or am I not using the correct syntax here?

Assuming Firebird 3.0 or higher, the USAGE privilege only grants the privilege for using NEXT VALUE FOR <sequence> and GEN_ID(<sequence>, <n>). As mentioned in the documentation:
For sequences (generators), the USAGE privilege only grants the
right to increment the sequence using the GEN_ID function or NEXT VALUE FOR. The SET GENERATOR statement is a synonym for ALTER SEQUENCE …​ RESTART WITH …​, and is considered a DDL statement. By
default, only the owner of the sequence and administrators have the
rights to such operations. The right to set the initial value of any
sequence can be granted with GRANT ALTER ANY SEQUENCE, which is not
recommend for general users.
As mentioned, GRANT ALTER ANY SEQUENCE should be a last resort. Depending on the actual problem being solved, you could also do something like calling gen_id(order_gen, 0 - gen_id(order_gen, 0)) (e.g. as select gen_id(order_gen, 0 - gen_id(order_gen, 0)) from rdb$database) (this is a loophole/workaround, see also Inconsistency between ALTER and USAGE privileges for sequences (generators). in the Firebird issue tracker).
Alternatively, you should ask your database administrator to execute this script/statement, or - if you have the RDB$ADMIN privilege yourself - to ensure you specify that role when connecting to the database (if you don't explicitly specify the role, you don't get the administrator privileges).

Related

How can I insert records into Postgres with RLS when user has `grant all` perms and a loose policy

I'm new to Postgres' RLS feature. I believe I'm following the documentation appropriately, but am getting unexpected behavior. Consider the following case:
i have a table named report_files
this table has a simple policy, policy <name> for all using (true)
the user has grant all permissions on the table (grant all on all tables in schema testing to testuser;, along with grant execute on all functions ... and grant usage for the schema as well)
the user can now read all fields in the table, but cannot insert records, against expectation
Here's a really short snippet from psql demonstrating the aforementioned: https://gist.github.com/cdaringe/85dd9a7b1278afe4770869dc494216f3
I have set a permissive policy, which clearly evaluates OK as evidenced by the successful select command.
What can I troubleshoot to get the insert to work?
Thanks!
ERROR: permission denied for sequence report_files_id_seq
It looks to me like you need to grant your user permission to use the id sequence: report_files_id_seq
You should be able to do this with the following
GRANT USAGE, SELECT ON SEQUENCE report_files_id_seq TO testuser;
Or to bulk add all tables:
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA <insert schema name here>
ALL is equivalent to USAGE, SELECT, UPDATE
As I cannot comment yet, I will add some input as an answer if anyone arrives on this thread like me today.
Yes, you have to grant permissions on sequence(s) separately, in addition to the privileges already granted on the table(s). In fact it is what you have to do.
Even if your table is dependant on the sequence object, they are both different objects from the RDBMS point of view, so they require distinct privileges.
As for your indices example, index in a sub-object of a table, and no additional privilege is required to be able to make use of indices so no further action than the index creation is needed.
Moreover, be careful to prefix the sequence name in case it is stored in a schema which is not the default one (public) and which is not in your search_path.
If that is not the case, you may encounter a permission denied error even though you have all necessary privilege on the sequence you aim to work with.

Grant permission to role if exists in SAP HANA

I have a HANA database deployment set up using Flyway and the HANA JDBC driver that creates and populates a schema. Something I would also like to do as part of the deployment is grant a particular database role read access to that schema. However, in order to avoid migration errors, I'd first like to verify that this role exists, and I can't get this part of the logic to work.
The closest I've come is
DO
BEGIN
DECLARE I INTEGER;
SELECT COUNT(*) INTO I
FROM roles
WHERE role_name = 'MYROLE';
IF I > 0
THEN
GRANT SELECT ON SCHEMA myschema TO MYROLE;
END IF;
END;
but this fails with
SQL State : HY000
Error Code : 7
Message : SAP DBTech JDBC: [7] (at 140): feature not supported: DDL statements other than CREATE/DROP TABLE is/are not supported in anonymous block: line 9 col 9 (at pos 140)
Location : db/migration/V1.10__my_script.sql (snip)
Line : 1
Statement : DO
I also tried this via trying to create a temporary stored procedure and executing that - same problem with DDL statements not being supported.
The problems:
I need to do an IF-THEN-ELSE based on the result of a select query
HANA doesn't seem to support nesting a SELECT statement inside an IF clause, so I need to save the result in a variable and use that instead
Declaring variables is only supported inside blocks, such as anonymous blocks or the bodies of stored procedures
Blocks also forbid executing most DDL statements - GRANT being one of them.
At this point, I'm not sure if what I'm trying to do is even possible. Pointers would be very much appreciated.
Your code should work with a few modifications like the following:
DO
BEGIN
DECLARE I INTEGER;
SELECT COUNT(*) INTO I
FROM roles
WHERE role_name = 'MYROLE';
IF :I > 0 THEN
exec 'GRANT SELECT ON SCHEMA myschema to MYROLE';
END IF;
END;
To access the I variable value in the IF statement you need to use the : notation.
As you mentioned some DDL statements are not directly supported in SQL Script, but you can use the EXEC command to run them as dynamic SQL commands.
Generally speaking, this approach to handle privileges is rather problematic since the outcome of your procedure, that is what privileges exactly are available to MYROLE, is dependent on
if there already exists a role with the same name
what privileges the security context that runs the procedure is allowed to grant
SAP HANA provides HDI (HANA Deployment Infrastructure) repository object type .hdbrole that allows to bundle privileges into roles and have those deployed fully (or not at all) upon installation time. This approach also allows updating privilege assignments to roles even after the role had been assigned to other roles and users without the need for re-assignment.
Dynamically building roles and assigning privileges makes it much harder to understand when, where and why privileges are assigned to roles/users. That is typically not what you want; instead, you like to have privileges assigned at a well-known place in your application and nowhere else. Therefore the pointer is to actually not use your procedure but to use the HANA tools available for role-definition.
All that is explained in a lot more detail in the SAP HANA documentation.

Privileges Necessary for Prepared Statement Execute Batch

I have a small section of code using the PreparedStatement .addBatch() and .executeBatch() methods.
However, I am getting the following exception:
java.sql.BatchUpdateException: ORA-01031: insufficient privileges
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10500)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:230)
blah blah blah
I can execute most SQL statements fine, but not the batch operations. Do I need a specific privilege granted to my database user to use these operations?
Edit
If I need a particular privilege other than INSERT/UPDATE, which privilege do I need?
Edit 2
Turns out that my DBA didn't want to give my account the permissions it needed. Thanks to everyone for their help.
I'm not 100% but i think you don't need any special privileges to execute batch operation.
Probably your db user already has received the role CONNECTION or at least "CREATE SESSION" privilege.
You can do following thing
grant all on your_table to your_user;
where all means DELETE, INSERT, REFERENCES, SELECT, TRIGGER, UPDATE.
or select only relevant privileges.
grant DELETE, INSERT, SELECT, UPDATE on your_table to your_user.
if you are using sequence in your in you query. You have to also grant.
GRANT USAGE ON your_sequence to your_user
if you are using any custom package or function in your in you query. You have to also grant.
GRANT execute ON your_package to your_user

SAP Hana Revoke all Priviledge and roles from User

Anyone have written a stored procedure which can remove all assigned roles/privileges from given user ? I like to do this without looking up each role assigned or privilege assigned.
Similar like below statement but without listing each role and privileges one by one. Removal all roles/privilege in one single statement regardless of what role assigned. This is for user termination process.
CALL REVOKE_ACTIVATED_ROLE('RoleName','username');
Well if you really want the procedure, I'm using this one and it works.
It removes all the granted roles from the user. Run it if you know what you are doing.
create procedure myCleanupUser(in i_user varchar(20)) as
begin
declare cursor Roles for
SELECT ROLE_NAME FROM "PUBLIC"."EFFECTIVE_ROLES"
where USER_NAME=i_user AND GRANTEE_TYPE='USER' AND ROLE_NAME <> 'PUBLIC';
for role as Roles do
call REVOKE_ACTIVATED_ROLE(role.ROLE_NAME,i_user);
end for;
end;
There's no such standard functionality available and I recommend to be very careful with automatically revoking privileges. If the user himself granted privileges that he got granted with ADMIN OPTION or with GRANT OPTION to other users and these privileges get revoked, this leads to a recursive revocation of those granted privileges.
In short: this can become nasty.
For user termination, it's sufficient from a security point of view to disable the logon.
Other than that, it's pretty straight forward to query system view GRANTED_ROLES and GRANTED_PRIVILEGES to generate the REVOKE statements.

Cannot find table v$parameter in Oracle

I want to get the number of sessions in Oracle using the SQL query:
SELECT value FROM v$parameter WHERE name = 'sessions'
But I get this error:
Error starting at line 1 in command:
SELECT value FROM v$parameter WHERE name = 'sessions'
Error at Command Line:1 Column:18
Error report:
SQL Error: ORA-00942: table or view does not exist
00942. 00000 - "table or view does not exist"
*Cause:
*Action:
Maybe the Oracle user that I use is not privileged?
Generally the better approach is to use a procedure and grant the necessary privileges to this procedure. However if you want use SQL directly, you can grant SELECT_CATALOG_ROLE or SELECT ANY DICTIONARY to the user.
Probably. To grant the rights, you need to use the table name as V_$PARAMETER. It comes from some restriction when granting rights on dynamic views.
If you want to use SQL directly (referring to the second option in the accepted answer)
As of Feb 2023, using Oracle version 19, this works...
Connect as SYSTEM and run
grant SELECT ANY DICTIONARY to <user>;
But SELECT_CATALOG_ROLE didn't work for me...
grant SELECT_CATALOG_ROLE to ...;
There are documented differences between the two here:
http://www.petefinnigan.com/weblog/archives/00001461.htm
This is where the author gives the following info and warning:
Well, SELECT_CATALOG_ROLE allows access to some things Oracle deemed not allowed by SELECT ANY DICTIONARY so we need to be careful of granting this role on these grounds. BUT, the overwhelming issue for me is that SELECT_CATALOG_ROLE gives access to 4539 objects and SELECT ANY DICTIONARY gives access to 6228 objects (both numbers in 18c XE)
I am not sure why Oracle do not publish the full list of exclusions in SELECT ANY DICTIONARY but they do publish all of the main tables. We can easily find out anyway. For me, i want to know what does SELECT ANY DICTIONARY really mean. I want to know what i am actually granting if I give out that privilege; well it means access to 6228 tables and views in 18cXE
Both of these rights should not be used; they are a sledgehammer to crack a peanut. If someone needs access to V$SESSION or V$DATABASE and there is a legitimate reason to have that access then grant access on the individual views not SELECT ANY DICTIONARY or SELECT_CATALOG_ROLE.
using the privileges: - select any table, alter any table when running the grant as SYS with SYSDBA in Oracle 12c solved the issue for me.