diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index 5d5c2940142db6f66873b10c631d173990245903..e64ec84bc261348e7851e5ed23ae59e4d5c04b47 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.29 2002/09/03 22:17:34 tgl Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v 1.30 2002/09/24 23:14:25 tgl Exp $ PostgreSQL documentation --> @@ -62,15 +62,27 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } </para> <para> - 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. + </para> + + <para> + Depending on the type of object, the initial default privileges may + include granting some privileges to <literal>PUBLIC</literal>. + The default is no public access for tables and schemas; + <literal>TEMP</> table creation privilege for databases; + <literal>EXECUTE</> privilege for functions; and + <literal>USAGE</> privilege for languages. + The object creator may of course revoke these privileges. (For maximum + security, issue the <command>REVOKE</> in the same transaction that + creates the object; then there is no window in which another user + may use the object.) </para> <para> @@ -137,9 +149,9 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] } <term>REFERENCES</term> <listitem> <para> - 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. </para> </listitem> </varlistentry> @@ -292,10 +304,9 @@ GRANT SELECT,UPDATE,INSERT ON mytable TO GROUP todos; <para> If the <quote>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 <quote>all -privileges for the owner and no privileges for anyone else</quote>, except -for databases: the default privilege settings for a database allow anyone -to create temporary tables in it. The first <command>GRANT</> or +is NULL). Default privileges always include all privileges for the owner, +and may include some privileges for <literal>PUBLIC</> depending on the +object type, as explained above. The first <command>GRANT</> or <command>REVOKE</> on an object will instantiate the default privileges (producing, for example, <literal>{=,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 56c9a4fe65cace27b9fe6038e8662ed84439eef6..6741c5a5be7824ef12d5256d5625ccf1bc49f51c 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 02d2e6746b565762d0bb7f4a31e871135f5e97f9..ffcb6ee891b15a94f34bc90056da75aa2c9bb560 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 830263bb03c1c18f31d76c3d860d29f1d9ce997a..60c4469adda76e1090f2156f591f881764f4717b 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 9dec0dcc212cdeb7d57fd8f90c13dc7374c21613..e94d8c1103eaaeec034e71dcaba31dfd271fc7f3 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 3f0009224d2b9596dc1f9ba9841d44bf132573d6..b84680aab792ebe383709372f801cafdc3a7a82f 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 1050f71f6e48e78ea689a99c91e66d3c06ad724d..092b8e2e77a74f2d4ca67d357368ce967a1aa295 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 26b1be671cee602ee470339c51163d2851fc95ba..95e5c14f1a9e8fe1834a707311072590749e74f2 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;