Here is a proposed patch for the issue discussed in <http://archives.postgresql.org/pgsql-hackers/2012-07/msg00569.php>:
I'd propose getting rid of lanplistrusted, at least for access checking. Instead, just don't install USAGE privileges by default for those languages. The reason is that there is value in having a role that can deploy schemas, possibly containing functions in untrusted languages, without having to be a full superuser. Just like you can have a user that can create roles without being a superuser. It turned out that actually getting rid of lanpltrusted would be too invasive, especially because some language handlers use it to determine their own behavior. So instead the lanpltrusted attribute now just determined what the default privileges of the language are, and all the checks the require superuserness to do anything with untrusted languages are removed.
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 9144eec..3988de3 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -3838,8 +3838,8 @@ <title><structname>pg_language</> Columns</title> <entry> True if this is a trusted language, which means that it is believed not to grant access to anything outside the normal SQL execution - environment. Only superusers can create functions in untrusted - languages. + environment. Untrusted languages don't have default privileges + assigned. </entry> </row> diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml index 0995b13..891f472 100644 --- a/doc/src/sgml/ref/create_language.sgml +++ b/doc/src/sgml/ref/create_language.sgml @@ -121,9 +121,7 @@ <title>Parameters</title> <para><literal>TRUSTED</literal> specifies that the language does not grant access to data that the user would not otherwise have. If this key word is omitted - when registering the language, only users with the - <productname>PostgreSQL</productname> superuser privilege can - use this language to create new functions. + when registering the language, no default privileges are assigned. </para> </listitem> </varlistentry> diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 0bf5356..5c90c68 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -2560,13 +2560,6 @@ static AclMode pg_aclmask(AclObjectKind objkind, Oid table_oid, AttrNumber attnu pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple); - if (!pg_language_tuple->lanpltrusted) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("language \"%s\" is not trusted", - NameStr(pg_language_tuple->lanname)), - errhint("Only superusers can use untrusted languages."))); - /* * Get owner ID and working copy of existing ACL. If there's no ACL, * substitute the proper default. @@ -2576,7 +2569,10 @@ static AclMode pg_aclmask(AclObjectKind objkind, Oid table_oid, AttrNumber attnu &isNull); if (isNull) { - old_acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId); + if (pg_language_tuple->lanpltrusted) + old_acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId); + else + old_acl = make_empty_acl(); /* There are no old member roles according to the catalogs */ noldmembers = 0; oldmembers = NULL; @@ -3823,7 +3819,10 @@ static AclMode pg_aclmask(AclObjectKind objkind, Oid table_oid, AttrNumber attnu if (isNull) { /* No ACL, so build default ACL */ - acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId); + if (((Form_pg_language) GETSTRUCT(tuple))->lanpltrusted) + acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId); + else + acl = make_empty_acl(); aclDatum = (Datum) 0; } else diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index c858511..897e170 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -854,23 +854,11 @@ languageOid = HeapTupleGetOid(languageTuple); languageStruct = (Form_pg_language) GETSTRUCT(languageTuple); - if (languageStruct->lanpltrusted) - { - /* if trusted language, need USAGE privilege */ - AclResult aclresult; - - aclresult = pg_language_aclcheck(languageOid, GetUserId(), ACL_USAGE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_LANGUAGE, - NameStr(languageStruct->lanname)); - } - else - { - /* if untrusted language, must be superuser */ - if (!superuser()) - aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_LANGUAGE, - NameStr(languageStruct->lanname)); - } + /* need USAGE privilege on language */ + aclresult = pg_language_aclcheck(languageOid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_LANGUAGE, + NameStr(languageStruct->lanname)); languageValidator = languageStruct->lanvalidator; diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 9b71c75..dfb8305 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -8964,11 +8964,10 @@ static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer, NULL, "", plang->dobj.catId, 0, plang->dobj.dumpId); - if (plang->lanpltrusted) - dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId, "LANGUAGE", - qlanname, NULL, plang->dobj.name, - lanschema, - plang->lanowner, plang->lanacl); + dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId, "LANGUAGE", + qlanname, NULL, plang->dobj.name, + lanschema, + plang->lanowner, plang->lanacl); free(qlanname); diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index e8930cb..f22dc79 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -457,9 +457,13 @@ SELECT oid FROM atestp2; -- ok \c - REVOKE ALL PRIVILEGES ON LANGUAGE sql FROM PUBLIC; GRANT USAGE ON LANGUAGE sql TO regressuser1; -- ok -GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail -ERROR: language "c" is not trusted -HINT: Only superusers can use untrusted languages. +GRANT USAGE ON LANGUAGE c TO regressuser1; -- ok +SELECT has_language_privilege('c', 'USAGE'), has_language_privilege('public', 'c', 'USAGE'); + has_language_privilege | has_language_privilege +------------------------+------------------------ + t | f +(1 row) + SET SESSION AUTHORIZATION regressuser1; GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail WARNING: no privileges were granted for "sql" diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index d4d328e..f23cc11 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -300,7 +300,8 @@ CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2); REVOKE ALL PRIVILEGES ON LANGUAGE sql FROM PUBLIC; GRANT USAGE ON LANGUAGE sql TO regressuser1; -- ok -GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail +GRANT USAGE ON LANGUAGE c TO regressuser1; -- ok +SELECT has_language_privilege('c', 'USAGE'), has_language_privilege('public', 'c', 'USAGE'); SET SESSION AUTHORIZATION regressuser1; GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers