1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

Add large object access control.

A new system catalog pg_largeobject_metadata manages
ownership and access privileges of large objects.

KaiGai Kohei, reviewed by Jaime Casanova.
This commit is contained in:
Itagaki Takahiro
2009-12-11 03:34:57 +00:00
parent 64579962bb
commit f1325ce213
39 changed files with 1450 additions and 173 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.212 2009/12/07 05:22:21 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.213 2009/12/11 03:34:54 itagaki Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
@ -160,7 +160,12 @@
<row>
<entry><link linkend="catalog-pg-largeobject"><structname>pg_largeobject</structname></link></entry>
<entry>large objects</entry>
<entry>data pages for large objects</entry>
</row>
<row>
<entry><link linkend="catalog-pg-largeobject-metadata"><structname>pg_largeobject_metadata</structname></link></entry>
<entry>metadata for large objects</entry>
</row>
<row>
@ -3120,22 +3125,31 @@
<para>
The catalog <structname>pg_largeobject</structname> holds the data making up
<quote>large objects</quote>. A large object is identified by an
OID assigned when it is created. Each large object is broken into
<quote>large objects</quote>. A large object is identified by an OID of
<link linkend="catalog-pg-largeobject-metadata"><structname>pg_largeobject_metadata</></link>
catalog, assigned when it is created. Each large object is broken into
segments or <quote>pages</> small enough to be conveniently stored as rows
in <structname>pg_largeobject</structname>.
The amount of data per page is defined to be <symbol>LOBLKSIZE</> (which is currently
<literal>BLCKSZ/4</>, or typically 2 kB).
</para>
<para>
<structname>pg_largeobject</structname> should not be readable by the
public, since the catalog contains data in large objects of all users.
<structname>pg_largeobject_metadata</> is a publicly readable catalog
that only contains identifiers of large objects.
</para>
<table>
<title><structname>pg_largeobject</> Columns</title>
<tgroup cols="3">
<tgroup cols="4">
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>References</entry>
<entry>Description</entry>
</row>
</thead>
@ -3144,12 +3158,14 @@
<row>
<entry><structfield>loid</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-largeobject-metadata"><structname>pg_largeobject_metadata</structname></link>.oid</literal></entry>
<entry>Identifier of the large object that includes this page</entry>
</row>
<row>
<entry><structfield>pageno</structfield></entry>
<entry><type>int4</type></entry>
<entry></entry>
<entry>Page number of this page within its large object
(counting from zero)</entry>
</row>
@ -3157,6 +3173,7 @@
<row>
<entry><structfield>data</structfield></entry>
<entry><type>bytea</type></entry>
<entry></entry>
<entry>
Actual data stored in the large object.
This will never be more than <symbol>LOBLKSIZE</> bytes and might be less
@ -3177,6 +3194,55 @@
</sect1>
<sect1 id="catalog-pg-largeobject-metadata">
<title><structname>pg_largeobject_metadata</structname></title>
<indexterm zone="catalog-pg-largeobject-metadata">
<primary>pg_largeobject_metadata</primary>
</indexterm>
<para>
The purpose of <structname>pg_largeobject_metadata</structname> is to
hold metadata of <quote>large objects</quote>, such as OID of its owner,
access permissions and OID of the large object itself.
</para>
<table>
<title><structname>pg_largeobject_metadata</> Columns</title>
<tgroup cols="4">
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>References</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><structfield>lomowner</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the largeobejct</entry>
</row>
<row>
<entry><structfield>lomacl</structfield></entry>
<entry><type>aclitem[]</type></entry>
<entry>
Access privileges; see
<xref linkend="sql-grant" endterm="sql-grant-title"> and
<xref linkend="sql-revoke" endterm="sql-revoke-title">
for details
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="catalog-pg-listener">
<title><structname>pg_listener</structname></title>

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.236 2009/12/10 06:32:27 petere Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.237 2009/12/11 03:34:55 itagaki Exp $ -->
<chapter Id="runtime-config">
<title>Server Configuration</title>
@ -4816,6 +4816,35 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
</listitem>
</varlistentry>
<varlistentry id="guc-lo-compat-privileges" xreflabel="lo_compat_privileges">
<term><varname>lo_compat_privileges</varname> (<type>boolean</type>)</term>
<indexterm>
<primary>
<varname>lo_compat_privileges</varname> configuration parameter
</primary>
</indexterm>
<listitem>
<para>
This allows us to tuen on/off database privilege checks on large
objects. In the 8.4.x series and earlier release do not have
privilege checks on large object in most cases.
So, turning the <varname>lo_compat_privileges</varname> off means
the large object feature performs in compatible mode.
</para>
<para>
Please note that it is not equivalent to disable all the security
checks corresponding to large objects.
For example, the <literal>lo_import()</literal> and
<literal>lo_export()</literal> need superuser privileges independent
from this setting as prior versions were doing.
</para>
<para>
It is <literal>off</literal> by default.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-sql-inheritance" xreflabel="sql_inheritance">
<term><varname>sql_inheritance</varname> (<type>boolean</type>)</term>
<indexterm>

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.49 2008/12/07 23:46:39 alvherre Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/lobj.sgml,v 1.50 2009/12/11 03:34:55 itagaki Exp $ -->
<chapter id="largeObjects">
<title id="largeObjects-title">Large Objects</title>
@ -441,6 +441,57 @@ SELECT lo_export(image.raster, '/tmp/motd') FROM image
The client-side functions can be used by any
<productname>PostgreSQL</productname> user.
</para>
<sect2 id="lo-func-privilege">
<title>Large object and privileges</title>
<para>
Note that access control feature was not supported in the 8.4.x series
and earlier release.
Also see the <xref linkend="guc-lo-compat-privileges"> compatibility
option.
</para>
<para>
Now it supports access controls on large objects, and allows the owner
of large objects to set up access rights using
<xref linkend="sql-grant" endterm="sql-grant-title"> and
<xref linkend="sql-revoke" endterm="sql-revoke-title"> statement.
</para>
<para>
Two permissions are defined on the large object class.
These are checked only when <xref linkend="guc-lo-compat-privileges">
option is disabled.
</para>
<para>
The first is <literal>SELECT</literal>.
It is required on <function>loread()</function> function.
Note that when we open large object with read-only mode, we can see
a static image even if other concurrent transaction modified the
same large object.
This principle is also applied on the access rights of large objects.
Even if a transaction modified access rights and commit it, it is
not invisible from other transaction which already opened the large
object.
</para>
<para>
The second is <literal>UPDATE</literal>.
It is required on <function>lowrite()</function> function and
<function>lo_truncate()</function> function.
</para>
<para>
In addition, <function>lo_unlink()</function> function,
<command>COMMENT ON</command> and <command>ALTER LARGE OBJECT</command>
statements needs ownership of the large object to be accessed.
</para>
<para>
You may wonder why <literal>SELECT</literal> is not checked on the
<function>lo_export()</function> function or <literal>UPDATE</literal>
is not checked on the <function>lo_import</function> function.
These functions originally require database superuser privilege,
and it allows to bypass the default database privilege checks,
so we don't need to check an obvious test twice.
</para>
</sect2>
</sect1>
<sect1 id="lo-examplesect">

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.76 2009/10/05 19:24:33 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.77 2009/12/11 03:34:55 itagaki Exp $
PostgreSQL documentation
Complete list of usable sgml source files in this directory.
-->
@ -16,6 +16,7 @@ Complete list of usable sgml source files in this directory.
<!entity alterGroup system "alter_group.sgml">
<!entity alterIndex system "alter_index.sgml">
<!entity alterLanguage system "alter_language.sgml">
<!entity alterLargeObject system "alter_large_object.sgml">
<!entity alterOperator system "alter_operator.sgml">
<!entity alterOperatorClass system "alter_opclass.sgml">
<!entity alterOperatorFamily system "alter_opfamily.sgml">

View File

@ -0,0 +1,75 @@
<refentry id="SQL-ALTERLARGEOBJECT">
<refmeta>
<refentrytitle id="SQL-ALTERLARGEOBJECT-title">ALTER LARGE OBJECT</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>ALTER LARGE OBJECT</refname>
<refpurpose>change the definition of a large object</refpurpose>
</refnamediv>
<indexterm zone="sql-alterlargeobject">
<primary>ALTER LARGE OBJECT</primary>
</indexterm>
<refsynopsisdiv>
<synopsis>
ALTER LARGE OBJECT <replaceable class="PARAMETER">large_object_oid</replaceable> OWNER TO <replaceable>new_owner</replaceable>
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>ALTER LARGE OBJECT</command> changes the definition of a
large object. The only functionality is to assign a new owner.
You must be superuser or owner of the large object to use
<command>ALTER LARGE OBJECT</command>.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><replaceable>large_object_oid</replaceable></term>
<listitem>
<para>
OID of the large object to be altered
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>new_owner</replaceable></term>
<listitem>
<para>
The new owner of the large object
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
There is no <command>ALTER LARGE OBJECT</command> statement in the SQL
standard.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="largeObjects" endterm="largeObjects-title"></member>
</simplelist>
</refsect1>
</refentry>

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.79 2009/10/12 20:39:39 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.80 2009/12/11 03:34:55 itagaki Exp $
PostgreSQL documentation
-->
@ -59,6 +59,10 @@ GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE <replaceable>lang_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { SELECT | UPDATE } [,...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT <replaceable class="PARAMETER">loid</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
ON SCHEMA <replaceable>schema_name</replaceable> [, ...]
TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
@ -170,6 +174,8 @@ GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replace
<xref linkend="sql-delete" endterm="sql-delete-title">.
For sequences, this privilege also allows the use of the
<function>currval</function> function.
For large objects, this privilege also allows to read from
the target large object.
</para>
</listitem>
</varlistentry>
@ -203,6 +209,8 @@ GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replace
<literal>SELECT</literal> privilege. For sequences, this
privilege allows the use of the <function>nextval</function> and
<function>setval</function> functions.
For large objects, this privilege also allows to write or truncate
on the target large object.
</para>
</listitem>
</varlistentry>

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.53 2009/10/12 20:39:39 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.54 2009/12/11 03:34:55 itagaki Exp $
PostgreSQL documentation
-->
@ -75,6 +75,12 @@ REVOKE [ GRANT OPTION FOR ]
FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ { SELECT | UPDATE } [,...] | ALL [ PRIVILEGES ] }
ON LARGE OBJECT <replaceable class="PARAMETER">loid</replaceable> [, ...]
FROM { [ GROUP ] <replaceable class="PARAMETER">rolename</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
REVOKE [ GRANT OPTION FOR ]
{ { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
ON SCHEMA <replaceable>schema_name</replaceable> [, ...]

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.69 2009/10/05 19:24:33 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.70 2009/12/11 03:34:55 itagaki Exp $ -->
<part id="reference">
<title>Reference</title>
@ -44,6 +44,7 @@
&alterGroup;
&alterIndex;
&alterLanguage;
&alterLargeObject;
&alterOperator;
&alterOperatorClass;
&alterOperatorFamily;