From c6367df506b6f39b63b5ff85304b5618e0f61fb2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 24 Sep 2002 23:14:25 +0000 Subject: [PATCH] Change default privileges for languages and functions to be PUBLIC USAGE and PUBLIC EXECUTE, respectively. Per discussion about easing updates from prior versions. --- doc/src/sgml/ref/grant.sgml | 39 +++++++++++++++--------- src/backend/catalog/aclchk.c | 4 +-- src/backend/utils/adt/acl.c | 8 +++-- src/bin/initdb/initdb.sh | 4 ++- src/bin/pg_dump/pg_dump.c | 38 +++++++++++++++-------- src/bin/scripts/createlang.sh | 12 ++++++-- src/test/regress/expected/privileges.out | 1 + src/test/regress/sql/privileges.sql | 1 + 8 files changed, 71 insertions(+), 36 deletions(-) diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index 5d5c294014..e64ec84bc2 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -1,5 +1,5 @@ @@ -62,15 +62,27 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } - Users other than the creator of an object do not have any access privileges - to the object unless the creator grants permissions. There is no need to grant privileges to the creator of an object, - as the creator automatically holds all privileges. + as the creator has all privileges by default. (The creator could, however, choose to revoke - some of his own privileges for safety. Note that the ability to + some of his own privileges for safety.) Note that the ability to grant and revoke privileges is inherent in the creator and cannot - be lost. The right to drop the object is likewise inherent in the - creator, and cannot be granted or revoked.) + be lost. The right to drop an object, or to alter it in any way + not described by a grantable right, is likewise inherent in the + creator, and cannot be granted or revoked. + + + + Depending on the type of object, the initial default privileges may + include granting some privileges to PUBLIC. + The default is no public access for tables and schemas; + TEMP table creation privilege for databases; + EXECUTE privilege for functions; and + USAGE privilege for languages. + The object creator may of course revoke these privileges. (For maximum + security, issue the REVOKE in the same transaction that + creates the object; then there is no window in which another user + may use the object.) @@ -137,9 +149,9 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } REFERENCES - To create a table with a foreign key constraint, it is - necessary to have this privilege on the table with the referenced - key. + To create a foreign key constraint, it is + necessary to have this privilege on both the referencing and + referenced tables. @@ -292,10 +304,9 @@ GRANT SELECT,UPDATE,INSERT ON mytable TO GROUP todos; If the Access privileges column is empty for a given object, it means the object has default privileges (that is, its privileges field -is NULL). Currently, default privileges are interpreted as all -privileges for the owner and no privileges for anyone else, except -for databases: the default privilege settings for a database allow anyone -to create temporary tables in it. The first GRANT or +is NULL). Default privileges always include all privileges for the owner, +and may include some privileges for PUBLIC depending on the +object type, as explained above. The first GRANT or REVOKE on an object will instantiate the default privileges (producing, for example, {=,miriam=arwdRxt}) and then modify them per the specified request. diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 56c9a4fe65..6741c5a5be 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.77 2002/09/04 20:31:13 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.78 2002/09/24 23:14:25 tgl Exp $ * * NOTES * See acl.h. @@ -481,7 +481,7 @@ ExecuteGrantStmt_Language(GrantStmt *stmt) elog(ERROR, "language \"%s\" not found", langname); pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple); - if (!pg_language_tuple->lanpltrusted) + if (!pg_language_tuple->lanpltrusted && stmt->is_grant) elog(ERROR, "language \"%s\" is not trusted", langname); /* diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 02d2e6746b..ffcb6ee891 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.79 2002/09/04 20:31:27 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.80 2002/09/24 23:14:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -417,11 +417,13 @@ acldefault(GrantObjectType objtype, AclId ownerid) owner_default = ACL_ALL_RIGHTS_DATABASE; break; case ACL_OBJECT_FUNCTION: - world_default = ACL_NO_RIGHTS; + /* Grant EXECUTE by default, for now */ + world_default = ACL_EXECUTE; owner_default = ACL_ALL_RIGHTS_FUNCTION; break; case ACL_OBJECT_LANGUAGE: - world_default = ACL_NO_RIGHTS; + /* Grant USAGE by default, for now */ + world_default = ACL_USAGE; owner_default = ACL_ALL_RIGHTS_LANGUAGE; break; case ACL_OBJECT_NAMESPACE: diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh index 830263bb03..60c4469add 100644 --- a/src/bin/initdb/initdb.sh +++ b/src/bin/initdb/initdb.sh @@ -27,7 +27,7 @@ # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # -# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.174 2002/09/18 21:35:23 tgl Exp $ +# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.175 2002/09/24 23:14:25 tgl Exp $ # #------------------------------------------------------------------------- @@ -1034,6 +1034,8 @@ $ECHO_N "setting privileges on built-in objects... "$ECHO_C WHERE proacl IS NULL; UPDATE pg_language SET lanacl = '{"=U"}' \ WHERE lanpltrusted; + UPDATE pg_language SET lanacl = '{"="}' \ + WHERE NOT lanpltrusted; EOF ) \ | "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 9dec0dcc21..e94d8c1103 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -22,7 +22,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.300 2002/09/22 20:57:20 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.301 2002/09/24 23:14:25 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -4839,16 +4839,18 @@ GetPrivileges(Archive *AH, const char *s, const char *type) } -/* +/*---------- * Write out grant/revoke information * - * 'type' must be TABLE, FUNCTION, LANGUAGE, or SCHEMA. 'name' is the - * formatted name of the object. Must be quoted etc. already. + * 'type' must be TABLE, FUNCTION, LANGUAGE, or SCHEMA. + * 'name' is the formatted name of the object. Must be quoted etc. already. + * 'tag' is the tag for the archive entry (typ. unquoted name of object). * 'nspname' is the namespace the object is in (NULL if none). * 'usename' is the owner, NULL if there is no owner (for languages). * 'acls' is the string read out of the fooacl system catalog field; * it will be parsed here. * 'objoid' is the OID of the object for purposes of ordering. + *---------- */ static void dumpACL(Archive *fout, const char *type, const char *name, @@ -4867,6 +4869,14 @@ dumpACL(Archive *fout, const char *type, const char *name, sql = createPQExpBuffer(); + /* + * Always start with REVOKE ALL FROM PUBLIC, so that we don't have to + * wire-in knowledge about the default public privileges for different + * kinds of objects. + */ + appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM PUBLIC;\n", + type, name); + /* Make a working copy of acls so we can use strtok */ aclbuf = strdup(acls); @@ -4938,18 +4948,21 @@ dumpACL(Archive *fout, const char *type, const char *name, else { /* No privileges. Issue explicit REVOKE for safety. */ - appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM ", - type, name); if (eqpos == tok) { - /* Empty left-hand side means "PUBLIC" */ - appendPQExpBuffer(sql, "PUBLIC;\n"); + /* Empty left-hand side means "PUBLIC"; already did it */ } else if (strncmp(tok, "group ", strlen("group ")) == 0) - appendPQExpBuffer(sql, "GROUP %s;\n", + { + appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM GROUP %s;\n", + type, name, fmtId(tok + strlen("group "))); + } else - appendPQExpBuffer(sql, "%s;\n", fmtId(tok)); + { + appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n", + type, name, fmtId(tok)); + } } free(priv); } @@ -4960,9 +4973,8 @@ dumpACL(Archive *fout, const char *type, const char *name, */ if (!found_owner_privs && usename) { - appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM ", - type, name); - appendPQExpBuffer(sql, "%s;\n", fmtId(usename)); + appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n", + type, name, fmtId(usename)); } ArchiveEntry(fout, objoid, tag, nspname, usename ? usename : "", diff --git a/src/bin/scripts/createlang.sh b/src/bin/scripts/createlang.sh index 3f0009224d..b84680aab7 100644 --- a/src/bin/scripts/createlang.sh +++ b/src/bin/scripts/createlang.sh @@ -7,7 +7,7 @@ # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # -# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.38 2002/08/22 00:01:47 tgl Exp $ +# $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.39 2002/09/24 23:14:25 tgl Exp $ # #------------------------------------------------------------------------- @@ -291,8 +291,13 @@ if [ "$?" -ne 0 ]; then exit 1 fi -if test -n "$trusted"; then - sqlcmd="GRANT USAGE ON LANGUAGE \"$langname\" TO PUBLIC;" +# ---------- +# Grant privileges. As of 7.3 the default privileges for a language include +# public USAGE, so we need not change them for a trusted language; but it +# seems best to disable public USAGE for an untrusted one. +# ---------- +if test -z "$trusted"; then + sqlcmd="REVOKE ALL ON LANGUAGE \"$langname\" FROM PUBLIC;" if [ "$showsql" = yes ]; then echo "$sqlcmd" fi @@ -302,4 +307,5 @@ if test -n "$trusted"; then exit 1 fi fi + exit 0 diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index 1050f71f6e..092b8e2e77 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -229,6 +229,7 @@ GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail ERROR: permission denied CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql; +REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC; GRANT EXECUTE ON FUNCTION testfunc1(int), testfunc2(int) TO regressuser2; GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error ERROR: invalid privilege type USAGE for function object diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index 26b1be671c..95e5c14f1a 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -156,6 +156,7 @@ GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql; +REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC; GRANT EXECUTE ON FUNCTION testfunc1(int), testfunc2(int) TO regressuser2; GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4;