Restrict pgstattuple functions to superusers. (This might be too strict,

but no permissions check at all is certainly no good.)  Clean up usage
of some deprecated APIs.
REL8_3_STABLE
Tom Lane 19 years ago
parent 0effa088f5
commit 38c75ecf83
  1. 46
      contrib/pgstattuple/pgstatindex.c
  2. 20
      contrib/pgstattuple/pgstattuple.c
  3. 66
      contrib/pgstattuple/pgstattuple.sql.in
  4. 6
      contrib/pgstattuple/uninstall_pgstattuple.sql

@ -24,27 +24,21 @@
#include "postgres.h"
#include "fmgr.h"
#include "funcapi.h"
#include "access/heapam.h"
#include "access/itup.h"
#include "access/nbtree.h"
#include "access/transam.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/inval.h"
PG_FUNCTION_INFO_V1(pgstatindex);
PG_FUNCTION_INFO_V1(pg_relpages);
extern Datum pgstatindex(PG_FUNCTION_ARGS);
extern Datum pg_relpages(PG_FUNCTION_ARGS);
#define PGSTATINDEX_TYPE "public.pgstatindex_type"
#define PGSTATINDEX_NCOLUMNS 10
PG_FUNCTION_INFO_V1(pgstatindex);
PG_FUNCTION_INFO_V1(pg_relpages);
#define IS_INDEX(r) ((r)->rd_rel->relkind == 'i')
#define IS_INDEX(r) ((r)->rd_rel->relkind == RELKIND_INDEX)
#define IS_BTREE(r) ((r)->rd_rel->relam == BTREE_AM_OID)
#define CHECK_PAGE_OFFSET_RANGE(pg, offnum) { \
@ -97,15 +91,20 @@ pgstatindex(PG_FUNCTION_ARGS)
uint32 blkno;
BTIndexStat indexStat;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use pgstattuple functions"))));
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
if (!IS_INDEX(rel) || !IS_BTREE(rel))
elog(ERROR, "pgstatindex() can only be used on b-tree index");
elog(ERROR, "relation \"%s\" is not a btree index",
RelationGetRelationName(rel));
/*-------------------
* Read a metapage
*-------------------
/*
* Read metapage
*/
{
Buffer buffer = ReadBuffer(rel, 0);
@ -194,11 +193,12 @@ pgstatindex(PG_FUNCTION_ARGS)
{
TupleDesc tupleDesc;
int j;
char *values[PGSTATINDEX_NCOLUMNS];
char *values[10];
HeapTuple tuple;
tupleDesc = RelationNameGetTupleDesc(PGSTATINDEX_TYPE);
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
j = 0;
values[j] = palloc(32);
@ -229,7 +229,7 @@ pgstatindex(PG_FUNCTION_ARGS)
tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc),
values);
result = TupleGetDatum(TupleDescGetSlot(tupleDesc), tuple);
result = HeapTupleGetDatum(tuple);
}
PG_RETURN_DATUM(result);
@ -238,7 +238,7 @@ pgstatindex(PG_FUNCTION_ARGS)
/* --------------------------------------------------------
* pg_relpages()
*
* Get a number of pages of the table/index.
* Get the number of pages of the table/index.
*
* Usage: SELECT pg_relpages('t1');
* SELECT pg_relpages('t1_pkey');
@ -248,11 +248,15 @@ Datum
pg_relpages(PG_FUNCTION_ARGS)
{
text *relname = PG_GETARG_TEXT_P(0);
Relation rel;
RangeVar *relrv;
int4 relpages;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use pgstattuple functions"))));
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);

@ -1,5 +1,5 @@
/*
* $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.27 2007/05/03 16:45:58 tgl Exp $
* $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.28 2007/08/26 23:59:50 tgl Exp $
*
* Copyright (c) 2001,2002 Tatsuo Ishii
*
@ -24,14 +24,13 @@
#include "postgres.h"
#include "fmgr.h"
#include "funcapi.h"
#include "access/gist_private.h"
#include "access/hash.h"
#include "access/heapam.h"
#include "access/nbtree.h"
#include "access/transam.h"
#include "catalog/namespace.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "utils/builtins.h"
@ -99,9 +98,6 @@ build_pgstattuple_type(pgstattuple_type * stat, FunctionCallInfo fcinfo)
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
/* make sure we have a persistent copy of the tupdesc */
tupdesc = CreateTupleDescCopy(tupdesc);
/*
* Generate attribute metadata needed later to produce tuples from raw C
* strings
@ -163,6 +159,11 @@ pgstattuple(PG_FUNCTION_ARGS)
RangeVar *relrv;
Relation rel;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use pgstattuple functions"))));
/* open relation */
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_openrv(relrv, AccessShareLock);
@ -176,6 +177,11 @@ pgstattuplebyid(PG_FUNCTION_ARGS)
Oid relid = PG_GETARG_OID(0);
Relation rel;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use pgstattuple functions"))));
/* open relation */
rel = relation_open(relid, AccessShareLock);

@ -1,48 +1,48 @@
-- Adjust this setting to control where the objects get created.
SET search_path = public;
CREATE TYPE pgstattuple_type AS (
table_len BIGINT, -- physical table length in bytes
tuple_count BIGINT, -- number of live tuples
tuple_len BIGINT, -- total tuples length in bytes
tuple_percent FLOAT, -- live tuples in %
dead_tuple_count BIGINT, -- number of dead tuples
dead_tuple_len BIGINT, -- total dead tuples length in bytes
dead_tuple_percent FLOAT, -- dead tuples in %
free_space BIGINT, -- free space in bytes
free_percent FLOAT -- free space in %
);
CREATE OR REPLACE FUNCTION pgstattuple(text)
RETURNS pgstattuple_type
CREATE OR REPLACE FUNCTION pgstattuple(IN relname text,
OUT table_len BIGINT, -- physical table length in bytes
OUT tuple_count BIGINT, -- number of live tuples
OUT tuple_len BIGINT, -- total tuples length in bytes
OUT tuple_percent FLOAT, -- live tuples in %
OUT dead_tuple_count BIGINT, -- number of dead tuples
OUT dead_tuple_len BIGINT, -- total dead tuples length in bytes
OUT dead_tuple_percent FLOAT, -- dead tuples in %
OUT free_space BIGINT, -- free space in bytes
OUT free_percent FLOAT) -- free space in %
AS 'MODULE_PATHNAME', 'pgstattuple'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION pgstattuple(oid)
RETURNS pgstattuple_type
CREATE OR REPLACE FUNCTION pgstattuple(IN reloid oid,
OUT table_len BIGINT, -- physical table length in bytes
OUT tuple_count BIGINT, -- number of live tuples
OUT tuple_len BIGINT, -- total tuples length in bytes
OUT tuple_percent FLOAT, -- live tuples in %
OUT dead_tuple_count BIGINT, -- number of dead tuples
OUT dead_tuple_len BIGINT, -- total dead tuples length in bytes
OUT dead_tuple_percent FLOAT, -- dead tuples in %
OUT free_space BIGINT, -- free space in bytes
OUT free_percent FLOAT) -- free space in %
AS 'MODULE_PATHNAME', 'pgstattuplebyid'
LANGUAGE C STRICT;
--
-- pgstatindex
--
CREATE TYPE pgstatindex_type AS (
version int4,
tree_level int4,
index_size int4,
root_block_no int4,
internal_pages int4,
leaf_pages int4,
empty_pages int4,
deleted_pages int4,
avg_leaf_density float8,
leaf_fragmentation float8
);
CREATE OR REPLACE FUNCTION pgstatindex(text)
RETURNS pgstatindex_type
CREATE OR REPLACE FUNCTION pgstatindex(IN relname text,
OUT version int4,
OUT tree_level int4,
OUT index_size int4,
OUT root_block_no int4,
OUT internal_pages int4,
OUT leaf_pages int4,
OUT empty_pages int4,
OUT deleted_pages int4,
OUT avg_leaf_density float8,
OUT leaf_fragmentation float8)
AS 'MODULE_PATHNAME', 'pgstatindex'
LANGUAGE 'C' STRICT;
LANGUAGE C STRICT;
--
-- pg_relpages()
@ -50,4 +50,4 @@ LANGUAGE 'C' STRICT;
CREATE OR REPLACE FUNCTION pg_relpages(text)
RETURNS int
AS 'MODULE_PATHNAME', 'pg_relpages'
LANGUAGE 'C' STRICT;
LANGUAGE C STRICT;

@ -1,11 +1,7 @@
-- Adjust this setting to control where the objects get created.
SET search_path = public;
DROP FUNCTION pgstattuple(oid);
DROP FUNCTION pgstattuple(text);
DROP TYPE pgstattuple_type;
DROP FUNCTION pgstattuple(oid);
DROP FUNCTION pgstatindex(text);
DROP TYPE pgstatindex_type;
DROP FUNCTION pg_relpages(text);

Loading…
Cancel
Save