Change default privileges for languages and functions to be PUBLIC USAGE

and PUBLIC EXECUTE, respectively.  Per discussion about easing updates
from prior versions.
This commit is contained in:
Tom Lane 2002-09-24 23:14:25 +00:00
parent e92bec2844
commit c6367df506
8 changed files with 71 additions and 36 deletions

View File

@ -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 PostgreSQL documentation
--> -->
@ -62,15 +62,27 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
</para> </para>
<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, 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 (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 grant and revoke privileges is inherent in the creator and cannot
be lost. The right to drop the object is likewise inherent in the be lost. The right to drop an object, or to alter it in any way
creator, and cannot be granted or revoked.) 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>
<para> <para>
@ -137,9 +149,9 @@ GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
<term>REFERENCES</term> <term>REFERENCES</term>
<listitem> <listitem>
<para> <para>
To create a table with a foreign key constraint, it is To create a foreign key constraint, it is
necessary to have this privilege on the table with the referenced necessary to have this privilege on both the referencing and
key. referenced tables.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -292,10 +304,9 @@ GRANT SELECT,UPDATE,INSERT ON mytable TO GROUP todos;
<para> <para>
If the <quote>Access privileges</> column is empty for a given object, If the <quote>Access privileges</> column is empty for a given object,
it means the object has default privileges (that is, its privileges field it means the object has default privileges (that is, its privileges field
is NULL). Currently, default privileges are interpreted as <quote>all is NULL). Default privileges always include all privileges for the owner,
privileges for the owner and no privileges for anyone else</quote>, except and may include some privileges for <literal>PUBLIC</> depending on the
for databases: the default privilege settings for a database allow anyone object type, as explained above. The first <command>GRANT</> or
to create temporary tables in it. The first <command>GRANT</> or
<command>REVOKE</> on an object <command>REVOKE</> on an object
will instantiate the default privileges (producing, for example, will instantiate the default privileges (producing, for example,
<literal>{=,miriam=arwdRxt}</>) and then modify them per the specified request. <literal>{=,miriam=arwdRxt}</>) and then modify them per the specified request.

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* See acl.h. * See acl.h.
@ -481,7 +481,7 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
elog(ERROR, "language \"%s\" not found", langname); elog(ERROR, "language \"%s\" not found", langname);
pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple); 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); elog(ERROR, "language \"%s\" is not trusted", langname);
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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; owner_default = ACL_ALL_RIGHTS_DATABASE;
break; break;
case ACL_OBJECT_FUNCTION: 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; owner_default = ACL_ALL_RIGHTS_FUNCTION;
break; break;
case ACL_OBJECT_LANGUAGE: 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; owner_default = ACL_ALL_RIGHTS_LANGUAGE;
break; break;
case ACL_OBJECT_NAMESPACE: case ACL_OBJECT_NAMESPACE:

View File

@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # 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; WHERE proacl IS NULL;
UPDATE pg_language SET lanacl = '{"=U"}' \ UPDATE pg_language SET lanacl = '{"=U"}' \
WHERE lanpltrusted; WHERE lanpltrusted;
UPDATE pg_language SET lanacl = '{"="}' \
WHERE NOT lanpltrusted;
EOF EOF
) \ ) \
| "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely | "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely

View File

@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * 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 * Write out grant/revoke information
* *
* 'type' must be TABLE, FUNCTION, LANGUAGE, or SCHEMA. 'name' is the * 'type' must be TABLE, FUNCTION, LANGUAGE, or SCHEMA.
* formatted name of the object. Must be quoted etc. already. * '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). * 'nspname' is the namespace the object is in (NULL if none).
* 'usename' is the owner, NULL if there is no owner (for languages). * 'usename' is the owner, NULL if there is no owner (for languages).
* 'acls' is the string read out of the fooacl system catalog field; * 'acls' is the string read out of the fooacl system catalog field;
* it will be parsed here. * it will be parsed here.
* 'objoid' is the OID of the object for purposes of ordering. * 'objoid' is the OID of the object for purposes of ordering.
*----------
*/ */
static void static void
dumpACL(Archive *fout, const char *type, const char *name, dumpACL(Archive *fout, const char *type, const char *name,
@ -4867,6 +4869,14 @@ dumpACL(Archive *fout, const char *type, const char *name,
sql = createPQExpBuffer(); 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 */ /* Make a working copy of acls so we can use strtok */
aclbuf = strdup(acls); aclbuf = strdup(acls);
@ -4938,18 +4948,21 @@ dumpACL(Archive *fout, const char *type, const char *name,
else else
{ {
/* No privileges. Issue explicit REVOKE for safety. */ /* No privileges. Issue explicit REVOKE for safety. */
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM ",
type, name);
if (eqpos == tok) if (eqpos == tok)
{ {
/* Empty left-hand side means "PUBLIC" */ /* Empty left-hand side means "PUBLIC"; already did it */
appendPQExpBuffer(sql, "PUBLIC;\n");
} }
else if (strncmp(tok, "group ", strlen("group ")) == 0) 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 "))); fmtId(tok + strlen("group ")));
}
else else
appendPQExpBuffer(sql, "%s;\n", fmtId(tok)); {
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n",
type, name, fmtId(tok));
}
} }
free(priv); free(priv);
} }
@ -4960,9 +4973,8 @@ dumpACL(Archive *fout, const char *type, const char *name,
*/ */
if (!found_owner_privs && usename) if (!found_owner_privs && usename)
{ {
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM ", appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM %s;\n",
type, name); type, name, fmtId(usename));
appendPQExpBuffer(sql, "%s;\n", fmtId(usename));
} }
ArchiveEntry(fout, objoid, tag, nspname, usename ? usename : "", ArchiveEntry(fout, objoid, tag, nspname, usename ? usename : "",

View File

@ -7,7 +7,7 @@
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # 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 exit 1
fi 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 if [ "$showsql" = yes ]; then
echo "$sqlcmd" echo "$sqlcmd"
fi fi
@ -302,4 +307,5 @@ if test -n "$trusted"; then
exit 1 exit 1
fi fi
fi fi
exit 0 exit 0

View File

@ -229,6 +229,7 @@ GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
ERROR: permission denied ERROR: permission denied
CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $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 EXECUTE ON FUNCTION testfunc1(int), testfunc2(int) TO regressuser2;
GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error
ERROR: invalid privilege type USAGE for function object ERROR: invalid privilege type USAGE for function object

View File

@ -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 testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $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 EXECUTE ON FUNCTION testfunc1(int), testfunc2(int) TO regressuser2;
GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error GRANT USAGE ON FUNCTION testfunc1(int) TO regressuser3; -- semantic error
GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4; GRANT ALL PRIVILEGES ON FUNCTION testfunc1(int) TO regressuser4;