Using postgresql 9.6
I enabled pgcrypto using create extension pgcrypto using the postgres user.
Now i want to grant execute rights to my other db user. Unfortunately i am not able to do it. Is this possible or do you have to be a superuser to use the digest function from pgcrypto.
postgres=# GRANT EXECUTE ON FUNCTION digest TO another_user;
ERROR: syntax error at or near "digest"
LINE 1: GRANT EXECUTE ON FUNCTION digest TO another_user;
Using the answer below, I was able to successfully grant permission to execute the function. However another_user cannot execute the function. Are there other permissions that i need in order to execute this function using another_user?
another_user=> SELECT digest('whatisgoingon'::text, 'sha256'::text);
ERROR: function digest(text, text) does not exist
LINE 1: SELECT digest('whatisgoingon'::text, 'sha256'::text);
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Even though when i check permissions for the user i get back that i have permissions.
postgres=# select has_function_privilege('another_user', 'digest(text, text)', 'execute');
has_function_privilege
------------------------
t
(1 row)
Thanks
Postgres supports overloading, i.e. multiple functions with the same name but different argument lists.
When calling the function in SQL, it figures out which version you meant based on the number of parameters and their types. But when referencing the function in a DDL command (DROP, ALTER, GRANT, etc.), you need to specify exactly which version you meant, by including a list of argument types after the function name.
This is quite relevant in the case of digest, because there are actually two versions, and you need to make it clear which one you're talking about. So either:
GRANT EXECUTE ON FUNCTION digest(text,text) TO another_user
...or:
GRANT EXECUTE ON FUNCTION digest(bytea,text) TO another_user
(...or both.)
As of Postgres 10, you're allowed to omit the argument list when the function is not overloaded. This doesn't help you much in the case of digest, but at least you get a more informative error message:
postgres=# GRANT EXECUTE ON FUNCTION digest TO another_user;
ERROR: function name "digest" is not unique
HINT: Specify the argument list to select the function unambiguously.
As for your follow-up question regarding the function does not exist error, try schema-qualifying the function name, e.g. SELECT my_schema.digest(...).
If that works, it's a search path issue. You can either continue calling it with an explicit schema name, or update your search_path.
If it responds with ERROR: permission denied for schema my_schema, then you just need to GRANT USAGE ON SCHEMA my_schema TO another_user.
If it still says function my_schema.digest(text, text) does not exist, then you've probably connected to the wrong database by mistake.
Related
I have a BigQuery User Defined Function (UDF) in which the definition contains a secret:
CREATE FUNCTION mydataset.HashWithPepper(input STRING, y INT64)
RETURNS STRING
AS SHA256(input + "secret_value_acting_as_a_pepper");
secret_value_acting_as_a_pepper is being used to pepper the inputted value. That value is a secret and cannot be known by people using the function.
Is it possible to grant someone permission to call a UDF but not see the definition of it? I've looked at https://cloud.google.com/bigquery/docs/access-control#bq-permissions and noted the following:
Permission
Description
bigquery.routines.get
Get routine definitions and metadata.
So clearly I do not want to grant bigquery.routines.get to my end-users, but how do I grant permission to call the UDF? I don't see a permission in bigquery.routines.* that pertains to calling a UDF.
I do not believer there is a way to hide the UDF definition from anyone allowed to call the routine.
BigQuery does support authorized UDFs which work much like authorized views. An authorized UDF can read data from BigQuery tables without needed to grant callers access to the tables directly.
One possible solution leveraging an authorized UDF would be:
Create a PEPPER table to hold your pepper value in dataset A.
Create the UDF that selects the pepper value from the PEPPER table and uses it with the hash function. Create the UDF in database B.
Declare the UDF an authorized UDF of dataset A.
Grant users BigQuery Data Viewer privileges to dataset B. Do not grant users any access to dataset A.
I have a function named schema.func, I want to give a permission what execute schema.func to the user.
I try to use
GRANT EXECUTE ON schema.func to my_user;
but it is not working. When I perform this function it throws the error:
permission denied for schema ex
I know I can use GRANT USAGE ON SCHEMA, but this is not what I want, I just need permissions for specific functions, not all functions in the schema.
Can I do that?
First, you should allow my_user to access the other schema:
GRANT USAGE ON SCHEMA my_schema TO my_user;
This allows the execution of functions but not the access to tables. So, if my_user executes the function, it still produces an access error, if the function accesses tables etc. in my_schema. To avoid this, you may define your function as security definer:
ALTER FUNCTION my_schema.my_function(...) SECURITY DEFINER SET search_path = public;
Edit: Writing SECURITY DEFINER Functions Safely also points a way to give execute permission to specific users:
REVOKE ALL ON FUNCTION my_schema.my_function(...) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION my_schema.my_function(...) TO my_user;
Please also note the hints on setting the search_path in this section.
As per PostregSQL documentation
GRANT
The FUNCTION syntax works for plain functions, aggregate functions, and window functions, but not for procedures; use PROCEDURE for those. Alternatively, use ROUTINE to refer to a function, aggregate function, window function, or procedure regardless of its precise type.
...
ALL FUNCTIONS also affects aggregate and window functions, but not procedures, again just like the specific-object GRANT command. Use ALL ROUTINES to include procedures.
try:
GRANT EXECUTE ON ROUTINE my_schema.my_function(text) TO my_user;
assuming that your function signature is something like:
my_schema.my_function(my_par text)
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.
I don't think this is a replica question - I've seen the other responses to questions of a similar nature here:
The EXECUTE permission is denied on the user-defined table types?
Table valued parameter in a stored procedure gets execute permissions denied error
My question is - how come when I create a User-Defined Table Type with a user, why does that user not have execute permission on it?
For example, I'm logged in with user myuser, using this user I create a UDT, and a stored procedure that uses the UDT. With the same user, I then try to execute the procedure, but get the error
'The EXECUTE permission was denied on the object 'MyUdt', database 'MyDb', schema 'dbo'.'
Now, I would assume that since it's the same user that created the UDT, this would automatically have the right permissions on it? You cannot use the GRANT EXECUTE command as suggested in the above posts, as you cannot grant permissions to yourself.
In summary - I wish to create a UDT, a procedure that uses it and be able to execute it all using the same user - why am I unable to do this? Am I missing something?
Sounds like you are being a victim of Ownership and User-Schema Separation in SQL Server:
By default, when developers create objects in a schema, the objects are owned by the security principal that owns the schema, not the developer.
Even though you've been granted permission to create an object, the object it belongs to the owner of the schema into which you created the object (dbo schema). Knowing what the problem is, you can settle on one of the several possible solutions (eg. use your own schema rather than dbo, transfer the ownership explicitly, use code signing etc).
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.