aboutsummaryrefslogtreecommitdiff
path: root/src/backend/libpq/be-fsstubs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/libpq/be-fsstubs.c')
-rw-r--r--src/backend/libpq/be-fsstubs.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index 24605b5490d..0b816b6ff02 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/libpq/be-fsstubs.c,v 1.91 2009/06/11 14:48:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/libpq/be-fsstubs.c,v 1.92 2009/12/11 03:34:55 itagaki Exp $
*
* NOTES
* This should be moved to a more appropriate place. It is here
@@ -42,14 +42,20 @@
#include <sys/stat.h>
#include <unistd.h>
+#include "catalog/pg_largeobject_metadata.h"
#include "libpq/be-fsstubs.h"
#include "libpq/libpq-fs.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "storage/large_object.h"
+#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
+/*
+ * compatibility flag for permission checks
+ */
+bool lo_compat_privileges;
/*#define FSDB 1*/
#define BUFSIZE 8192
@@ -156,6 +162,17 @@ lo_read(int fd, char *buf, int len)
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("invalid large-object descriptor: %d", fd)));
+ /* Permission checks */
+ if (!lo_compat_privileges &&
+ pg_largeobject_aclcheck_snapshot(cookies[fd]->id,
+ GetUserId(),
+ ACL_SELECT,
+ cookies[fd]->snapshot) != ACLCHECK_OK)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("permission denied for large object %u",
+ cookies[fd]->id)));
+
status = inv_read(cookies[fd], buf, len);
return status;
@@ -177,6 +194,17 @@ lo_write(int fd, const char *buf, int len)
errmsg("large object descriptor %d was not opened for writing",
fd)));
+ /* Permission checks */
+ if (!lo_compat_privileges &&
+ pg_largeobject_aclcheck_snapshot(cookies[fd]->id,
+ GetUserId(),
+ ACL_UPDATE,
+ cookies[fd]->snapshot) != ACLCHECK_OK)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("permission denied for large object %u",
+ cookies[fd]->id)));
+
status = inv_write(cookies[fd], buf, len);
return status;
@@ -251,6 +279,13 @@ lo_unlink(PG_FUNCTION_ARGS)
{
Oid lobjId = PG_GETARG_OID(0);
+ /* Must be owner of the largeobject */
+ if (!lo_compat_privileges &&
+ !pg_largeobject_ownercheck(lobjId, GetUserId()))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be owner of large object %u", lobjId)));
+
/*
* If there are any open LO FDs referencing that ID, close 'em.
*/
@@ -482,6 +517,17 @@ lo_truncate(PG_FUNCTION_ARGS)
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("invalid large-object descriptor: %d", fd)));
+ /* Permission checks */
+ if (!lo_compat_privileges &&
+ pg_largeobject_aclcheck_snapshot(cookies[fd]->id,
+ GetUserId(),
+ ACL_UPDATE,
+ cookies[fd]->snapshot) != ACLCHECK_OK)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("permission denied for large object %u",
+ cookies[fd]->id)));
+
inv_truncate(cookies[fd], len);
PG_RETURN_INT32(0);