hi.
just came to my mind.
If you're the table owner, you should be allowed to use get_raw_page (and other
pageinspect module functions)?
We can use RangeVarGetRelidExtended with
RangeVarCallbackOwnsRelation to perform the ownership check.
Attached is a draft POC.
Am I missing anything obvious?
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index aef442b5db3..144e33c8f26 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -19,6 +19,7 @@
#include "access/relation.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
+#include "commands/tablecmds.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "pageinspect.h"
@@ -145,18 +146,21 @@ static bytea *
get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
{
bytea *raw_page;
+ Oid relid;
RangeVar *relrv;
Relation rel;
char *raw_page_data;
Buffer buf;
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to use raw page functions")));
-
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
- rel = relation_openrv(relrv, AccessShareLock);
+
+ /* Open and lock sequence, and check for ownership along the way. */
+ relid = RangeVarGetRelidExtended(relrv,
+ AccessShareLock,
+ 0,
+ RangeVarCallbackOwnsRelation,
+ NULL);
+ rel = relation_open(relid, NoLock);
if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
ereport(ERROR,
@@ -196,7 +200,7 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
ReleaseBuffer(buf);
- relation_close(rel, AccessShareLock);
+ relation_close(rel, NoLock);
return raw_page;
}