diff options
Diffstat (limited to 'src/backend/libpq/be-fsstubs.c')
-rw-r--r-- | src/backend/libpq/be-fsstubs.c | 48 |
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); |