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
-->
@ -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.

View File

@ -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);
/*

View File

@ -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:

View File

@ -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

View File

@ -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 : "",

View File

@ -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

View File

@ -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

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 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;