Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to run pg_repack by non-superuser #431

Merged
merged 2 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions META.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "pg_repack",
"abstract": "PostgreSQL module for data reorganization",
"description": "Reorganize tables in PostgreSQL databases with minimal locks",
"version": "1.5.1",
"version": "1.5.2",
"maintainer": [
"Beena Emerson <[email protected]>",
"Josh Kupershmidt <[email protected]>",
Expand All @@ -17,7 +17,7 @@
"provides": {
"pg_repack": {
"file": "lib/pg_repack.sql",
"version": "1.5.1",
"version": "1.5.2",
"abstract": "Reorganize tables in PostgreSQL databases with minimal locks"
}
},
Expand Down
5 changes: 4 additions & 1 deletion bin/pgut/pgut.c
Original file line number Diff line number Diff line change
Expand Up @@ -1235,9 +1235,12 @@ call_atexit_callbacks(bool fatal)
{
pgut_atexit_item *item;

for (item = pgut_atexit_stack; item; item = item->next)
item = pgut_atexit_stack;
while (item != NULL)
{
pgut_atexit_stack = pgut_atexit_stack->next;
item->callback(fatal, item->userdata);
item = pgut_atexit_stack;
}
}

Expand Down
3 changes: 2 additions & 1 deletion doc/pg_repack.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ You can choose one of the following methods to reorganize:

NOTICE:

* Only superusers can use the utility.
* Only superusers or owners of tables and indexes can use the utility. To run
pg_repack as an owner you need to use the option `--no-superuser-check`.
* Target table must have a PRIMARY KEY, or at least a UNIQUE total index on a
NOT NULL column.

Expand Down
3 changes: 2 additions & 1 deletion doc/pg_repack_jp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ pg_repackでは再編成する方法として次のものが選択できます

.. NOTICE:

* Only superusers can use the utility.
* Only superusers or owners of tables and indexes can use the utility. To run
pg_repack as an owner you need to use the option `--no-superuser-check`.
* Target table must have a PRIMARY KEY, or at least a UNIQUE total index on a
NOT NULL column.

Expand Down
28 changes: 16 additions & 12 deletions lib/repack.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,20 @@ static void swap_heap_or_index_files(Oid r1, Oid r2);

/* check access authority */
static void
must_be_superuser(const char *func)
must_be_owner(Oid relId)
{
if (!superuser())
elog(ERROR, "must be superuser to use %s function", func);
#if PG_VERSION_NUM >= 160000
if (!object_ownercheck(RelationRelationId, relId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relId)),
get_rel_name(relId));
#elif PG_VERSION_NUM >= 110000
if (!pg_class_ownercheck(relId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relId)),
get_rel_name(relId));
#else
if (!pg_class_ownercheck(relId, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, get_rel_name(relId));
#endif
}


Expand Down Expand Up @@ -163,9 +173,6 @@ repack_trigger(PG_FUNCTION_ARGS)
Oid relid;
StringInfo sql;

/* authority check */
must_be_superuser("repack_trigger");

/* make sure it's called as a trigger at all */
if (!CALLED_AS_TRIGGER(fcinfo) ||
!TRIGGER_FIRED_AFTER(trigdata->tg_event) ||
Expand Down Expand Up @@ -259,9 +266,6 @@ repack_apply(PG_FUNCTION_ARGS)

initStringInfo(&sql_pop);

/* authority check */
must_be_superuser("repack_apply");

/* connect to SPI manager */
repack_init();

Expand Down Expand Up @@ -859,7 +863,7 @@ repack_swap(PG_FUNCTION_ARGS)
Oid owner2;

/* authority check */
must_be_superuser("repack_swap");
must_be_owner(oid);

/* connect to SPI manager */
repack_init();
Expand Down Expand Up @@ -1060,7 +1064,7 @@ repack_drop(PG_FUNCTION_ARGS)
}

/* authority check */
must_be_superuser("repack_drop");
must_be_owner(oid);

/* connect to SPI manager */
repack_init();
Expand Down Expand Up @@ -1413,7 +1417,7 @@ repack_index_swap(PG_FUNCTION_ARGS)
HeapTuple tuple;

/* authority check */
must_be_superuser("repack_index_swap");
must_be_owner(orig_idx_oid);

/* connect to SPI manager */
repack_init();
Expand Down
13 changes: 13 additions & 0 deletions regress/expected/nosuper.out
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,17 @@ ERROR: pg_repack failed with error: You must be a superuser to use pg_repack
ERROR: pg_repack failed with error: ERROR: permission denied for schema repack
LINE 1: select repack.version(), repack.version_sql()
^
GRANT ALL ON ALL TABLES IN SCHEMA repack TO nosuper;
GRANT USAGE ON SCHEMA repack TO nosuper;
-- => ERROR
\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check
INFO: repacking table "public.tbl_cluster"
ERROR: query failed: ERROR: current transaction is aborted, commands ignored until end of transaction block
DETAIL: query was: RESET lock_timeout
ERROR: query failed: ERROR: current transaction is aborted, commands ignored until end of transaction block
DETAIL: query was: RESET lock_timeout
ERROR: permission denied for table tbl_cluster
ERROR: permission denied for table tbl_cluster
REVOKE ALL ON ALL TABLES IN SCHEMA repack FROM nosuper;
REVOKE USAGE ON SCHEMA repack FROM nosuper;
DROP ROLE IF EXISTS nosuper;
15 changes: 15 additions & 0 deletions regress/expected/nosuper_1.out
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,19 @@ ERROR: pg_repack failed with error: You must be a superuser to use pg_repack
-- => ERROR
\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check
ERROR: pg_repack failed with error: ERROR: permission denied for schema repack
LINE 1: select repack.version(), repack.version_sql()
^
GRANT ALL ON ALL TABLES IN SCHEMA repack TO nosuper;
GRANT USAGE ON SCHEMA repack TO nosuper;
-- => ERROR
\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check
INFO: repacking table "public.tbl_cluster"
ERROR: query failed: ERROR: current transaction is aborted, commands ignored until end of transaction block
DETAIL: query was: RESET lock_timeout
ERROR: query failed: ERROR: current transaction is aborted, commands ignored until end of transaction block
DETAIL: query was: RESET lock_timeout
ERROR: permission denied for relation tbl_cluster
ERROR: permission denied for relation tbl_cluster
REVOKE ALL ON ALL TABLES IN SCHEMA repack FROM nosuper;
REVOKE USAGE ON SCHEMA repack FROM nosuper;
DROP ROLE IF EXISTS nosuper;
9 changes: 9 additions & 0 deletions regress/sql/nosuper.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,13 @@ CREATE ROLE nosuper WITH LOGIN;
\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper
-- => ERROR
\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check

GRANT ALL ON ALL TABLES IN SCHEMA repack TO nosuper;
GRANT USAGE ON SCHEMA repack TO nosuper;

-- => ERROR
\! pg_repack --dbname=contrib_regression --table=tbl_cluster --username=nosuper --no-superuser-check

REVOKE ALL ON ALL TABLES IN SCHEMA repack FROM nosuper;
REVOKE USAGE ON SCHEMA repack FROM nosuper;
DROP ROLE IF EXISTS nosuper;
Loading