1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +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

@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.554 2009/12/07 05:22:22 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.555 2009/12/11 03:34:56 itagaki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2045,7 +2045,9 @@ dumpBlobs(Archive *AH, void *arg)
/*
* dumpBlobComments
* dump all blob comments
* dump all blob properties.
* It has "BLOB COMMENTS" tag due to the historical reason, but note
* that it is the routine to dump all the properties of blobs.
*
* Since we don't provide any way to be selective about dumping blobs,
* there's no need to be selective about their comments either. We put
@@ -2056,30 +2058,35 @@ dumpBlobComments(Archive *AH, void *arg)
{
const char *blobQry;
const char *blobFetchQry;
PQExpBuffer commentcmd = createPQExpBuffer();
PQExpBuffer cmdQry = createPQExpBuffer();
PGresult *res;
int i;
if (g_verbose)
write_msg(NULL, "saving large object comments\n");
write_msg(NULL, "saving large object properties\n");
/* Make sure we are in proper schema */
selectSourceSchema("pg_catalog");
/* Cursor to get all BLOB comments */
if (AH->remoteVersion >= 70300)
if (AH->remoteVersion >= 80500)
blobQry = "DECLARE blobcmt CURSOR FOR SELECT oid, "
"obj_description(oid, 'pg_largeobject'), "
"pg_get_userbyid(lomowner), lomacl "
"FROM pg_largeobject_metadata";
else if (AH->remoteVersion >= 70300)
blobQry = "DECLARE blobcmt CURSOR FOR SELECT loid, "
"obj_description(loid, 'pg_largeobject') "
"obj_description(loid, 'pg_largeobject'), NULL, NULL "
"FROM (SELECT DISTINCT loid FROM "
"pg_description d JOIN pg_largeobject l ON (objoid = loid) "
"WHERE classoid = 'pg_largeobject'::regclass) ss";
else if (AH->remoteVersion >= 70200)
blobQry = "DECLARE blobcmt CURSOR FOR SELECT loid, "
"obj_description(loid, 'pg_largeobject') "
"obj_description(loid, 'pg_largeobject'), NULL, NULL "
"FROM (SELECT DISTINCT loid FROM pg_largeobject) ss";
else if (AH->remoteVersion >= 70100)
blobQry = "DECLARE blobcmt CURSOR FOR SELECT loid, "
"obj_description(loid) "
"obj_description(loid), NULL, NULL "
"FROM (SELECT DISTINCT loid FROM pg_largeobject) ss";
else
blobQry = "DECLARE blobcmt CURSOR FOR SELECT oid, "
@@ -2087,7 +2094,7 @@ dumpBlobComments(Archive *AH, void *arg)
" SELECT description "
" FROM pg_description pd "
" WHERE pd.objoid=pc.oid "
" ) "
" ), NULL, NULL "
"FROM pg_class pc WHERE relkind = 'l'";
res = PQexec(g_conn, blobQry);
@@ -2107,22 +2114,51 @@ dumpBlobComments(Archive *AH, void *arg)
/* Process the tuples, if any */
for (i = 0; i < PQntuples(res); i++)
{
Oid blobOid;
char *comment;
Oid blobOid = atooid(PQgetvalue(res, i, 0));
char *lo_comment = PQgetvalue(res, i, 1);
char *lo_owner = PQgetvalue(res, i, 2);
char *lo_acl = PQgetvalue(res, i, 3);
char lo_name[32];
/* ignore blobs without comments */
if (PQgetisnull(res, i, 1))
continue;
resetPQExpBuffer(cmdQry);
blobOid = atooid(PQgetvalue(res, i, 0));
comment = PQgetvalue(res, i, 1);
/* comment on the blob */
if (!PQgetisnull(res, i, 1))
{
appendPQExpBuffer(cmdQry,
"COMMENT ON LARGE OBJECT %u IS ", blobOid);
appendStringLiteralAH(cmdQry, lo_comment, AH);
appendPQExpBuffer(cmdQry, ";\n");
}
printfPQExpBuffer(commentcmd, "COMMENT ON LARGE OBJECT %u IS ",
blobOid);
appendStringLiteralAH(commentcmd, comment, AH);
appendPQExpBuffer(commentcmd, ";\n");
/* dump blob ownership, if necessary */
if (!PQgetisnull(res, i, 2))
{
appendPQExpBuffer(cmdQry,
"ALTER LARGE OBJECT %u OWNER TO %s;\n",
blobOid, lo_owner);
}
archputs(commentcmd->data, AH);
/* dump blob privileges, if necessary */
if (!PQgetisnull(res, i, 3) &&
!dataOnly && !aclsSkip)
{
snprintf(lo_name, sizeof(lo_name), "%u", blobOid);
if (!buildACLCommands(lo_name, NULL, "LARGE OBJECT",
lo_acl, lo_owner, "",
AH->remoteVersion, cmdQry))
{
write_msg(NULL, "could not parse ACL (%s) for "
"large object %u", lo_acl, blobOid);
exit_nicely();
}
}
if (cmdQry->len > 0)
{
appendPQExpBuffer(cmdQry, "\n");
archputs(cmdQry->data, AH);
}
}
} while (PQntuples(res) > 0);
@@ -2130,7 +2166,7 @@ dumpBlobComments(Archive *AH, void *arg)
archputs("\n", AH);
destroyPQExpBuffer(commentcmd);
destroyPQExpBuffer(cmdQry);
return 1;
}