Search code examples
postgresqlsql-grant

Postgresql ignores lack of EXECUTE permission if USAGE permission is granted on containing schema


From http://www.postgresql.org/docs/9.1/static/sql-grant.html:

USAGE

...

For schemas, allows access to objects contained in the specified schema (assuming that the objects' own privilege requirements are also met). Essentially this allows the grantee to "look up" objects within the schema. Without this permission, it is still possible to see the object names, e.g. by querying the system tables. ...

...

However, running the following script through psql seems to show that although the lack of a SELECT permission causes an error, lack on an EXECUTE permission does not, which contradicts the documentation as the 'own privilege requirement' is not met.

CREATE DATABASE testdb WITH OWNER postgres ENCODING 'UTF8';
\connect testdb
CREATE ROLE testrole;
CREATE SCHEMA testschema;
GRANT USAGE ON SCHEMA testschema TO testrole;
SET search_path TO testschema;

CREATE FUNCTION testfunc ()
RETURNS VOID
AS $$
BEGIN
  RAISE NOTICE 'IN TESTFUNC';
  RAISE NOTICE 'Current user: %', current_user;
END;
$$
LANGUAGE plpgsql;

CREATE TABLE testtable
(
  testrow INT
);

INSERT INTO testtable (testrow) VALUES (1), (2), (3);

SET ROLE testrole;

SELECT testfunc();
SELECT * FROM testtable;

RESET ROLE;

Output:

$ psql -f usage.sql
CREATE DATABASE
You are now connected to database "testdb" as user "postgres".
CREATE ROLE
CREATE SCHEMA
GRANT
SET
CREATE FUNCTION
CREATE TABLE
INSERT 0 3
SET
psql:usage.sql:27: NOTICE:  IN TESTFUNC
psql:usage.sql:27: NOTICE:  Current user: testrole
 testfunc 
----------

(1 row)

psql:usage.sql:28: ERROR:  permission denied for relation testtable
RESET

Have I missed something or am using the permissions incorrectly?


Solution

  • The schema is not what matters here, what you're seeing is the default execute permissions of functions. Consider this excerpt from the CREATE FUNCTION documentation:

    Another point to keep in mind is that by default, execute privilege is granted to PUBLIC for newly created functions (see GRANT for more information). Frequently you will wish to restrict use of a security definer function to only some users. To do that, you must revoke the default PUBLIC privileges and then grant execute privilege selectively.