aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorItagaki Takahiro <itagaki.takahiro@gmail.com>2009-12-14 00:39:11 +0000
committerItagaki Takahiro <itagaki.takahiro@gmail.com>2009-12-14 00:39:11 +0000
commit84f910a7076e09e551bf69e0972473ec15d33c79 (patch)
tree7ce85524e7d24091581b2a0ce6309422d0330811 /src
parent0182d6f646997e486f56f847001ff74694bdd7da (diff)
downloadpostgresql-84f910a7076e09e551bf69e0972473ec15d33c79.tar.gz
postgresql-84f910a7076e09e551bf69e0972473ec15d33c79.zip
Additional fixes for large object access control.
Use pg_largeobject_metadata.oid instead of pg_largeobject.loid to enumerate existing large objects in pg_dump, pg_restore, and contrib modules.
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c5
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.h3
-rw-r--r--src/bin/pg_dump/pg_backup_db.c19
-rw-r--r--src/bin/pg_dump/pg_backup_null.c5
-rw-r--r--src/bin/pg_dump/pg_dump.c10
-rw-r--r--src/test/regress/expected/privileges.out10
-rw-r--r--src/test/regress/sql/privileges.sql7
7 files changed, 48 insertions, 11 deletions
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index e15e4dbdb9e..54f0bc4b6df 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.176 2009/10/05 19:24:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.177 2009/12/14 00:39:10 itagaki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -914,8 +914,7 @@ StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
ahlog(AH, 2, "restoring large object with OID %u\n", oid);
if (drop)
- ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u') THEN pg_catalog.lo_unlink('%u') END;\n",
- oid, oid);
+ DropBlobIfExists(AH, oid);
if (AH->connection)
{
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index fa6db407f2b..b3eb8b7b106 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -17,7 +17,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.82 2009/08/07 22:48:34 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.83 2009/12/14 00:39:11 itagaki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -371,6 +371,7 @@ extern void InitArchiveFmt_Tar(ArchiveHandle *AH);
extern bool isValidTarHeader(char *header);
extern int ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser);
+extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid);
int ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH);
int ahprintf(ArchiveHandle *AH, const char *fmt,...) __attribute__((format(printf, 2, 3)));
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index 836b02cb936..1d72d6dd7e2 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -5,7 +5,7 @@
* Implements the basic DB functions used by the archiver.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.84 2009/06/11 14:49:07 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.85 2009/12/14 00:39:11 itagaki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -652,6 +652,23 @@ CommitTransaction(ArchiveHandle *AH)
ExecuteSqlCommand(AH, "COMMIT", "could not commit database transaction");
}
+void
+DropBlobIfExists(ArchiveHandle *AH, Oid oid)
+{
+ /* Call lo_unlink only if exists to avoid not-found error. */
+ if (PQserverVersion(AH->connection) >= 80500)
+ {
+ ahprintf(AH, "SELECT pg_catalog.lo_unlink(oid) "
+ "FROM pg_catalog.pg_largeobject_metadata "
+ "WHERE oid = %u;\n", oid);
+ }
+ else
+ {
+ ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u') THEN pg_catalog.lo_unlink('%u') END;\n",
+ oid, oid);
+ }
+}
+
static bool
_isIdentChar(unsigned char c)
{
diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c
index d9cb02446b3..127ff572197 100644
--- a/src/bin/pg_dump/pg_backup_null.c
+++ b/src/bin/pg_dump/pg_backup_null.c
@@ -17,7 +17,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_null.c,v 1.22 2009/08/04 21:56:09 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_null.c,v 1.23 2009/12/14 00:39:11 itagaki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -151,8 +151,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
die_horribly(AH, NULL, "invalid OID for large object\n");
if (AH->ropt->dropSchema)
- ahprintf(AH, "SELECT CASE WHEN EXISTS(SELECT 1 FROM pg_catalog.pg_largeobject WHERE loid = '%u') THEN pg_catalog.lo_unlink('%u') END;\n",
- oid, oid);
+ DropBlobIfExists(AH, oid);
ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n",
oid, INV_WRITE);
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 7af461bd5a6..bb361b33669 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.555 2009/12/11 03:34:56 itagaki Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.556 2009/12/14 00:39:11 itagaki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1945,7 +1945,9 @@ hasBlobs(Archive *AH)
selectSourceSchema("pg_catalog");
/* Check for BLOB OIDs */
- if (AH->remoteVersion >= 70100)
+ if (AH->remoteVersion >= 80500)
+ blobQry = "SELECT oid FROM pg_largeobject_metadata LIMIT 1";
+ else if (AH->remoteVersion >= 70100)
blobQry = "SELECT loid FROM pg_largeobject LIMIT 1";
else
blobQry = "SELECT oid FROM pg_class WHERE relkind = 'l' LIMIT 1";
@@ -1981,7 +1983,9 @@ dumpBlobs(Archive *AH, void *arg)
selectSourceSchema("pg_catalog");
/* Cursor to get all BLOB OIDs */
- if (AH->remoteVersion >= 70100)
+ if (AH->remoteVersion >= 80500)
+ blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_largeobject_metadata";
+ else if (AH->remoteVersion >= 70100)
blobQry = "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject";
else
blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_class WHERE relkind = 'l'";
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 4160cba47da..5cda2302fcf 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -1041,6 +1041,16 @@ SELECT lo_unlink(1002);
SELECT lo_export(1001, '/dev/null'); -- to be denied
ERROR: must be superuser to use server-side lo_export()
HINT: Anyone can use the client-side lo_export() provided by libpq.
+-- don't allow unpriv users to access pg_largeobject contents
+\c -
+SELECT * FROM pg_largeobject LIMIT 0;
+ loid | pageno | data
+------+--------+------
+(0 rows)
+
+SET SESSION AUTHORIZATION regressuser1;
+SELECT * FROM pg_largeobject LIMIT 0; -- to be denied
+ERROR: permission denied for relation pg_largeobject
-- test default ACLs
\c -
CREATE SCHEMA testns;
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 8e8ff70608f..a87ce77aa6b 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -565,6 +565,13 @@ SELECT lo_truncate(lo_open(1002, x'20000'::int), 10);
SELECT lo_unlink(1002);
SELECT lo_export(1001, '/dev/null'); -- to be denied
+-- don't allow unpriv users to access pg_largeobject contents
+\c -
+SELECT * FROM pg_largeobject LIMIT 0;
+
+SET SESSION AUTHORIZATION regressuser1;
+SELECT * FROM pg_largeobject LIMIT 0; -- to be denied
+
-- test default ACLs
\c -