Simplify creation of built-in functions with non-default ACLs.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 5 Mar 2026 22:43:09 +0000 (17:43 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 5 Mar 2026 22:43:09 +0000 (17:43 -0500)
Up to now, to create such a function, one had to make a pg_proc.dat
entry and then modify it with GRANT/REVOKE commands, which we put in
system_functions.sql.  That seems a little ugly though, because it
violates the idea of having a single source of truth about the initial
contents of pg_proc, and it results in leaving dead rows in the
initial contents of pg_proc.

This patch improves matters by allowing aclitemin to work during early
bootstrap, before pg_authid has been loaded.  On the same principle
that we use for early access to pg_type details, put a table of known
built-in role names into bootstrap.c, and use that in bootstrap mode.

To create a built-in function with a non-default ACL, one should write
the desired ACL list in its pg_proc.dat entry, using a simplified
version of aclitemout's notation: omit the grantor (if it is the
bootstrap superuser, which it pretty much always should be) and spell
the bootstrap superuser's name as POSTGRES, similarly to the notation
used elsewhere in src/include/catalog.  This results in entries like

  proacl => '{POSTGRES=X,pg_monitor=X}'

which shows that we've revoked public execute permissions and instead
granted that to pg_monitor.

In addition to fixing up pg_proc.dat entries, I got rid of some
role grants that had been stuck into system_functions.sql,
and instead put them into a new file pg_auth_members.dat;
that seems like a far less random place to put the information.

The correctness of the data changes can be verified by comparing the
initial contents of pg_proc and pg_auth_members before and after.
pg_proc should match exactly, but the OID column of pg_auth_members
will probably be different because those OIDs now get assigned a
little earlier in bootstrap.  (I forced a catversion bump out of
caution, but it wasn't really necessary.)

Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://postgr.es/m/183292bb-4891-4c96-a3ca-e78b5e0e1358@dunslane.net

12 files changed:
src/backend/bootstrap/bootstrap.c
src/backend/catalog/system_functions.sql
src/backend/catalog/system_views.sql
src/backend/utils/adt/acl.c
src/include/bootstrap/bootstrap.h
src/include/catalog/Makefile
src/include/catalog/catversion.h
src/include/catalog/meson.build
src/include/catalog/pg_auth_members.dat [new file with mode: 0644]
src/include/catalog/pg_auth_members.h
src/include/catalog/pg_authid.dat
src/include/catalog/pg_proc.dat

index e7699be55aaa39095d710554efb6d98af2612388..17118f2fe760e7b8f54672bdc9d4409cee4f412d 100644 (file)
@@ -25,6 +25,7 @@
 #include "access/xact.h"
 #include "bootstrap/bootstrap.h"
 #include "catalog/index.h"
+#include "catalog/pg_authid.h"
 #include "catalog/pg_collation.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
@@ -115,6 +116,8 @@ static const struct typinfo TypInfo[] = {
    F_JSONB_IN, F_JSONB_OUT},
    {"oid", OIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
    F_OIDIN, F_OIDOUT},
+   {"aclitem", ACLITEMOID, 0, 16, false, TYPALIGN_DOUBLE, TYPSTORAGE_PLAIN, InvalidOid,
+   F_ACLITEMIN, F_ACLITEMOUT},
    {"pg_node_tree", PG_NODE_TREEOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID,
    F_PG_NODE_TREE_IN, F_PG_NODE_TREE_OUT},
    {"int2vector", INT2VECTOROID, INT2OID, -1, false, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
@@ -144,6 +147,43 @@ struct typmap
 static List *Typ = NIL;            /* List of struct typmap* */
 static struct typmap *Ap = NULL;
 
+/*
+ * Basic information about built-in roles.
+ *
+ * Presently, this need only list roles that are mentioned in aclitem arrays
+ * in the catalog .dat files.  We might as well list everything that is in
+ * pg_authid.dat, since there aren't that many.  Like pg_authid.dat, we
+ * represent the bootstrap superuser's name as "POSTGRES", even though it
+ * (probably) won't be that in the finished installation; this means aclitem
+ * entries in .dat files must spell it like that.
+ */
+struct rolinfo
+{
+   const char *rolname;
+   Oid         oid;
+};
+
+static const struct rolinfo RolInfo[] = {
+   {"POSTGRES", BOOTSTRAP_SUPERUSERID},
+   {"pg_database_owner", ROLE_PG_DATABASE_OWNER},
+   {"pg_read_all_data", ROLE_PG_READ_ALL_DATA},
+   {"pg_write_all_data", ROLE_PG_WRITE_ALL_DATA},
+   {"pg_monitor", ROLE_PG_MONITOR},
+   {"pg_read_all_settings", ROLE_PG_READ_ALL_SETTINGS},
+   {"pg_read_all_stats", ROLE_PG_READ_ALL_STATS},
+   {"pg_stat_scan_tables", ROLE_PG_STAT_SCAN_TABLES},
+   {"pg_read_server_files", ROLE_PG_READ_SERVER_FILES},
+   {"pg_write_server_files", ROLE_PG_WRITE_SERVER_FILES},
+   {"pg_execute_server_program", ROLE_PG_EXECUTE_SERVER_PROGRAM},
+   {"pg_signal_backend", ROLE_PG_SIGNAL_BACKEND},
+   {"pg_checkpoint", ROLE_PG_CHECKPOINT},
+   {"pg_maintain", ROLE_PG_MAINTAIN},
+   {"pg_use_reserved_connections", ROLE_PG_USE_RESERVED_CONNECTIONS},
+   {"pg_create_subscription", ROLE_PG_CREATE_SUBSCRIPTION},
+   {"pg_signal_autovacuum_worker", ROLE_PG_SIGNAL_AUTOVACUUM_WORKER}
+};
+
+
 static Datum values[MAXATTR];  /* current row's attribute values */
 static bool Nulls[MAXATTR];
 
@@ -1034,6 +1074,25 @@ boot_get_type_io_data(Oid typid,
    }
 }
 
+/* ----------------
+ *     boot_get_role_oid
+ *
+ * Look up a role name at bootstrap time.  This is equivalent to
+ * get_role_oid(rolname, true): return the role OID or InvalidOid if
+ * not found.  We only need to cope with built-in role names.
+ * ----------------
+ */
+Oid
+boot_get_role_oid(const char *rolname)
+{
+   for (int i = 0; i < lengthof(RolInfo); i++)
+   {
+       if (strcmp(RolInfo[i].rolname, rolname) == 0)
+           return RolInfo[i].oid;
+   }
+   return InvalidOid;
+}
+
 /* ----------------
  *     AllocateAttribute
  *
index 69699f8830a6c3820facd41a2599e1a034a094e9..1c5b6d6df05dff4406450777a74d84938567ba43 100644 (file)
  * definitions of such functions into pg_proc.dat and then replace them
  * here.  The stub definitions would be unnecessary were it not that we'd
  * like these functions to have stable OIDs, the same as other built-in
- * functions.
- *
- * This file also takes care of adjusting privileges for those functions
- * that should not have the default public-EXECUTE privileges.  (However,
- * a small number of functions that exist mainly to underlie system views
- * are dealt with in system_views.sql, instead.)
+ * functions.  (That's important, for example, to their treatment by
+ * postgres_fdw.)
  *
  * Note: this file is read in single-user -j mode, which means that the
  * command terminator is semicolon-newline-newline; whenever the backend
@@ -376,161 +372,3 @@ CREATE OR REPLACE FUNCTION ts_debug(document text,
 BEGIN ATOMIC
     SELECT * FROM ts_debug(get_current_ts_config(), $1);
 END;
-
-
---
--- The default permissions for functions mean that anyone can execute them.
--- A number of functions shouldn't be executable by just anyone, but rather
--- than use explicit 'superuser()' checks in those functions, we use the GRANT
--- system to REVOKE access to those functions at initdb time.  Administrators
--- can later change who can access these functions, or leave them as only
--- available to superuser / cluster owner, if they choose.
---
-
-REVOKE EXECUTE ON FUNCTION pg_backup_start(text, boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_backup_stop(boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_create_restore_point(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_switch_wal() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_log_standby_snapshot() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_wal_replay_pause() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_wal_replay_resume() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_rotate_logfile() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_reload_conf() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_current_logfile() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_current_logfile(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_promote(boolean, integer) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_reset() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_reset_shared(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_reset_slru(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_table_counters(oid) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_function_counters(oid) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_reset_backend_stats(integer) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_reset_replication_slot(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_have_stats(text, oid, int8) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_reset_subscription_stats(oid) FROM public;
-
-REVOKE EXECUTE ON FUNCTION lo_import(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION lo_import(text, oid) FROM public;
-
-REVOKE EXECUTE ON FUNCTION lo_export(oid, text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_logdir() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_waldir() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_archive_statusdir() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_summariesdir() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir(oid) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_read_file(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_read_file(text,boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint,boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint,boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_advance(text, pg_lsn) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_create(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_drop(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_oid(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_progress(text, boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_is_setup() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_progress(boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_reset() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_setup(text, integer) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_reset() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_setup(pg_lsn, timestamp with time zone) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_show_replication_origin_status() FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_file(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_stat_file(text,boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_dir(text) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_dir(text,boolean,boolean) FROM public;
-
-REVOKE EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer) FROM PUBLIC;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_logicalsnapdir() FROM PUBLIC;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_logicalmapdir() FROM PUBLIC;
-
-REVOKE EXECUTE ON FUNCTION pg_ls_replslotdir(text) FROM PUBLIC;
-
---
--- We also set up some things as accessible to standard roles.
---
-
-GRANT EXECUTE ON FUNCTION pg_ls_logdir() TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_ls_waldir() TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_ls_archive_statusdir() TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_ls_summariesdir() TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_ls_tmpdir() TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_ls_tmpdir(oid) TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_ls_logicalsnapdir() TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_ls_logicalmapdir() TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_ls_replslotdir(text) TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_current_logfile() TO pg_monitor;
-
-GRANT EXECUTE ON FUNCTION pg_current_logfile(text) TO pg_monitor;
-
-GRANT pg_read_all_settings TO pg_monitor;
-
-GRANT pg_read_all_stats TO pg_monitor;
-
-GRANT pg_stat_scan_tables TO pg_monitor;
index 1ea8f1faa9e6cc6a64f8adf17969c0779e891135..e5c3e1855c1554bd8878629d084395ebc174d104 100644 (file)
@@ -5,6 +5,11 @@
  *
  * src/backend/catalog/system_views.sql
  *
+ * Some of these views are not meant to be publicly readable.  The
+ * underlying function(s) for such a view should not be publicly
+ * executable either --- but by default they will be.  So don't forget to
+ * adjust function permissions (in pg_proc.dat) when adding a new view.
+ *
  * Note: this file is read in single-user -j mode, which means that the
  * command terminator is semicolon-newline-newline; whenever the backend
  * sees that, it stops and executes what it's got.  If you write a lot of
@@ -650,19 +655,16 @@ CREATE VIEW pg_file_settings AS
    SELECT * FROM pg_show_all_file_settings() AS A;
 
 REVOKE ALL ON pg_file_settings FROM PUBLIC;
-REVOKE EXECUTE ON FUNCTION pg_show_all_file_settings() FROM PUBLIC;
 
 CREATE VIEW pg_hba_file_rules AS
    SELECT * FROM pg_hba_file_rules() AS A;
 
 REVOKE ALL ON pg_hba_file_rules FROM PUBLIC;
-REVOKE EXECUTE ON FUNCTION pg_hba_file_rules() FROM PUBLIC;
 
 CREATE VIEW pg_ident_file_mappings AS
    SELECT * FROM pg_ident_file_mappings() AS A;
 
 REVOKE ALL ON pg_ident_file_mappings FROM PUBLIC;
-REVOKE EXECUTE ON FUNCTION pg_ident_file_mappings() FROM PUBLIC;
 
 CREATE VIEW pg_timezone_abbrevs AS
     SELECT * FROM pg_timezone_abbrevs_zone() z
@@ -679,39 +681,30 @@ CREATE VIEW pg_config AS
     SELECT * FROM pg_config();
 
 REVOKE ALL ON pg_config FROM PUBLIC;
-REVOKE EXECUTE ON FUNCTION pg_config() FROM PUBLIC;
 
 CREATE VIEW pg_shmem_allocations AS
     SELECT * FROM pg_get_shmem_allocations();
 
 REVOKE ALL ON pg_shmem_allocations FROM PUBLIC;
 GRANT SELECT ON pg_shmem_allocations TO pg_read_all_stats;
-REVOKE EXECUTE ON FUNCTION pg_get_shmem_allocations() FROM PUBLIC;
-GRANT EXECUTE ON FUNCTION pg_get_shmem_allocations() TO pg_read_all_stats;
 
 CREATE VIEW pg_shmem_allocations_numa AS
     SELECT * FROM pg_get_shmem_allocations_numa();
 
 REVOKE ALL ON pg_shmem_allocations_numa FROM PUBLIC;
 GRANT SELECT ON pg_shmem_allocations_numa TO pg_read_all_stats;
-REVOKE EXECUTE ON FUNCTION pg_get_shmem_allocations_numa() FROM PUBLIC;
-GRANT EXECUTE ON FUNCTION pg_get_shmem_allocations_numa() TO pg_read_all_stats;
 
 CREATE VIEW pg_dsm_registry_allocations AS
     SELECT * FROM pg_get_dsm_registry_allocations();
 
 REVOKE ALL ON pg_dsm_registry_allocations FROM PUBLIC;
 GRANT SELECT ON pg_dsm_registry_allocations TO pg_read_all_stats;
-REVOKE EXECUTE ON FUNCTION pg_get_dsm_registry_allocations() FROM PUBLIC;
-GRANT EXECUTE ON FUNCTION pg_get_dsm_registry_allocations() TO pg_read_all_stats;
 
 CREATE VIEW pg_backend_memory_contexts AS
     SELECT * FROM pg_get_backend_memory_contexts();
 
 REVOKE ALL ON pg_backend_memory_contexts FROM PUBLIC;
 GRANT SELECT ON pg_backend_memory_contexts TO pg_read_all_stats;
-REVOKE EXECUTE ON FUNCTION pg_get_backend_memory_contexts() FROM PUBLIC;
-GRANT EXECUTE ON FUNCTION pg_get_backend_memory_contexts() TO pg_read_all_stats;
 
 -- Statistics views
 
@@ -1471,5 +1464,3 @@ CREATE VIEW pg_aios AS
     SELECT * FROM pg_get_aios();
 REVOKE ALL ON pg_aios FROM PUBLIC;
 GRANT SELECT ON pg_aios TO pg_read_all_stats;
-REVOKE EXECUTE ON FUNCTION pg_get_aios() FROM PUBLIC;
-GRANT EXECUTE ON FUNCTION pg_get_aios() TO pg_read_all_stats;
index 641673f0b0e0d362c04b9175f5fc644b16a1fdf1..071e3f2c49e8b4f769466eb7f9701a3c00c8c4a9 100644 (file)
@@ -17,6 +17,7 @@
 #include <ctype.h>
 
 #include "access/htup_details.h"
+#include "bootstrap/bootstrap.h"
 #include "catalog/catalog.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_auth_members.h"
@@ -261,6 +262,9 @@ putid(char *p, const char *s)
  *     This routine is called by the parser as well as aclitemin(), hence
  *     the added generality.
  *
+ *     In bootstrap mode, we consult a hard-wired list of role names
+ *     (see bootstrap.c) rather than trying to access the catalogs.
+ *
  * RETURNS:
  *     the string position in 's' immediately following the ACL
  *     specification.  Also:
@@ -376,7 +380,10 @@ aclparse(const char *s, AclItem *aip, Node *escontext)
        aip->ai_grantee = ACL_ID_PUBLIC;
    else
    {
-       aip->ai_grantee = get_role_oid(name, true);
+       if (IsBootstrapProcessingMode())
+           aip->ai_grantee = boot_get_role_oid(name);
+       else
+           aip->ai_grantee = get_role_oid(name, true);
        if (!OidIsValid(aip->ai_grantee))
            ereturn(escontext, NULL,
                    (errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -385,7 +392,8 @@ aclparse(const char *s, AclItem *aip, Node *escontext)
 
    /*
     * XXX Allow a degree of backward compatibility by defaulting the grantor
-    * to the superuser.
+    * to the superuser.  We condone that practice in the catalog .dat files
+    * (i.e., in bootstrap mode) for brevity; otherwise, issue a warning.
     */
    if (*s == '/')
    {
@@ -396,7 +404,10 @@ aclparse(const char *s, AclItem *aip, Node *escontext)
            ereturn(escontext, NULL,
                    (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                     errmsg("a name must follow the \"/\" sign")));
-       aip->ai_grantor = get_role_oid(name2, true);
+       if (IsBootstrapProcessingMode())
+           aip->ai_grantor = boot_get_role_oid(name2);
+       else
+           aip->ai_grantor = get_role_oid(name2, true);
        if (!OidIsValid(aip->ai_grantor))
            ereturn(escontext, NULL,
                    (errcode(ERRCODE_UNDEFINED_OBJECT),
@@ -405,10 +416,11 @@ aclparse(const char *s, AclItem *aip, Node *escontext)
    else
    {
        aip->ai_grantor = BOOTSTRAP_SUPERUSERID;
-       ereport(WARNING,
-               (errcode(ERRCODE_INVALID_GRANTOR),
-                errmsg("defaulting grantor to user ID %u",
-                       BOOTSTRAP_SUPERUSERID)));
+       if (!IsBootstrapProcessingMode())
+           ereport(WARNING,
+                   (errcode(ERRCODE_INVALID_GRANTOR),
+                    errmsg("defaulting grantor to user ID %u",
+                           BOOTSTRAP_SUPERUSERID)));
    }
 
    ACLITEM_SET_PRIVS_GOPTIONS(*aip, privs, goption);
index 21447a3d661a0debd50232602d36f952d8e2252e..e967b2b18857140a8529054dc327e12dca9dd801 100644 (file)
@@ -56,6 +56,8 @@ extern void boot_get_type_io_data(Oid typid,
                                  Oid *typoutput,
                                  Oid *typcollation);
 
+extern Oid boot_get_role_oid(const char *rolname);
+
 union YYSTYPE;
 typedef void *yyscan_t;
 
index 24b527230d47640964432655ac3255fe0a9111b7..444fc76eed6950fbfd4849940aff30cb40878bf9 100644 (file)
@@ -94,6 +94,7 @@ POSTGRES_BKI_DATA = \
    pg_amop.dat \
    pg_amproc.dat \
    pg_authid.dat \
+   pg_auth_members.dat \
    pg_cast.dat \
    pg_class.dat \
    pg_collation.dat \
index f164bf8767f6d83af2b2c3eb7d9a2b783543aa7f..123e7c4261b8cfea73266b032c1cc9cd8fda589a 100644 (file)
@@ -57,6 +57,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 202603041
+#define CATALOG_VERSION_NO 202603051
 
 #endif
index 433bcc908ad1c6dc0437963666f73756e98da7fa..bcc01c87c2e1cba627dd586685efaba2bf5c1d76 100644 (file)
@@ -78,6 +78,7 @@ bki_data = [
   'pg_amop.dat',
   'pg_amproc.dat',
   'pg_authid.dat',
+  'pg_auth_members.dat',
   'pg_cast.dat',
   'pg_class.dat',
   'pg_collation.dat',
diff --git a/src/include/catalog/pg_auth_members.dat b/src/include/catalog/pg_auth_members.dat
new file mode 100644 (file)
index 0000000..2463732
--- /dev/null
@@ -0,0 +1,20 @@
+#----------------------------------------------------------------------
+#
+# pg_auth_members.dat
+#    Initial contents of the pg_auth_members system catalog.
+#
+# Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/include/catalog/pg_auth_members.dat
+#
+#----------------------------------------------------------------------
+
+[
+
+# We grant these roles to pg_monitor.
+{ roleid => 'pg_read_all_settings', member => 'pg_monitor' },
+{ roleid => 'pg_read_all_stats', member => 'pg_monitor' },
+{ roleid => 'pg_stat_scan_tables', member => 'pg_monitor' },
+
+]
index b1902321a8fbfcd654e99e0746c700bc1e618d9a..b029cc575a5cc043383a79e5ba953621f4697371 100644 (file)
@@ -31,13 +31,26 @@ BEGIN_CATALOG_STRUCT
 
 CATALOG(pg_auth_members,1261,AuthMemRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2843,AuthMemRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
-   Oid         oid;            /* oid */
-   Oid         roleid BKI_LOOKUP(pg_authid);   /* ID of a role */
-   Oid         member BKI_LOOKUP(pg_authid);   /* ID of a member of that role */
-   Oid         grantor BKI_LOOKUP(pg_authid);  /* who granted the membership */
-   bool        admin_option;   /* granted with admin option? */
-   bool        inherit_option; /* exercise privileges without SET ROLE? */
-   bool        set_option;     /* use SET ROLE to the target role? */
+   /* OID for this record (needed for dependencies) */
+   Oid         oid;
+
+   /* ID of a role */
+   Oid         roleid BKI_LOOKUP(pg_authid);
+
+   /* ID of a member of that role */
+   Oid         member BKI_LOOKUP(pg_authid);
+
+   /* who granted the membership */
+   Oid         grantor BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid);
+
+   /* granted with admin option? */
+   bool        admin_option BKI_DEFAULT(f);
+
+   /* exercise privileges without SET ROLE? */
+   bool        inherit_option BKI_DEFAULT(t);
+
+   /* use SET ROLE to the target role? */
+   bool        set_option BKI_DEFAULT(t);
 } FormData_pg_auth_members;
 
 END_CATALOG_STRUCT
index 26b5c9971a4e66838ca2ee67052087e657e2a578..2960707c7293ae3af337c10ff0a4b5aa85c24cb0 100644 (file)
 # so make sure every entry has an oid_symbol value.
 
 # The bootstrap superuser is named POSTGRES according to this data and
-# according to BKI_DEFAULT entries in other catalogs.  However, initdb
-# will replace that at database initialization time.
+# according to BKI_DEFAULT entries and ACL entries in other catalogs.
+# initdb will replace that at database initialization time for standalone
+# references (the rolname below and various owner-OID columns), while
+# boot_get_role_oid() deals with it for ACL entries.
 
 { oid => '10', oid_symbol => 'BOOTSTRAP_SUPERUSERID',
   rolname => 'POSTGRES', rolsuper => 't', rolinherit => 't',
index dac40992cbc7fbbcc1c7472248ce37eca66f7866..4950bff280453289a3569e7e028b1d3409396602 100644 (file)
 
 { oid => '764', descr => 'large object import',
   proname => 'lo_import', provolatile => 'v', proparallel => 'u',
-  prorettype => 'oid', proargtypes => 'text', prosrc => 'be_lo_import' },
+  prorettype => 'oid', proargtypes => 'text', prosrc => 'be_lo_import',
+  proacl => '{POSTGRES=X}' },
 { oid => '767', descr => 'large object import',
   proname => 'lo_import', provolatile => 'v', proparallel => 'u',
   prorettype => 'oid', proargtypes => 'text oid',
-  prosrc => 'be_lo_import_with_oid' },
+  prosrc => 'be_lo_import_with_oid',
+  proacl => '{POSTGRES=X}' },
 { oid => '765', descr => 'large object export',
   proname => 'lo_export', provolatile => 'v', proparallel => 'u',
-  prorettype => 'int4', proargtypes => 'oid text', prosrc => 'be_lo_export' },
+  prorettype => 'int4', proargtypes => 'oid text', prosrc => 'be_lo_export',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '766', descr => 'increment',
   proname => 'int4inc', prorettype => 'int4', proargtypes => 'int4',
 { oid => '6230', descr => 'statistics: check if a stats object exists',
   proname => 'pg_stat_have_stats', provolatile => 'v', proparallel => 'r',
   prorettype => 'bool', proargtypes => 'text oid int8',
-  prosrc => 'pg_stat_have_stats' },
+  prosrc => 'pg_stat_have_stats',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6231', descr => 'statistics: information about subscription stats',
   proname => 'pg_stat_get_subscription_stats', provolatile => 's',
 { oid => '2274',
   descr => 'statistics: reset collected statistics for current database',
   proname => 'pg_stat_reset', proisstrict => 'f', provolatile => 'v',
-  prorettype => 'void', proargtypes => '', prosrc => 'pg_stat_reset' },
+  prorettype => 'void', proargtypes => '', prosrc => 'pg_stat_reset',
+  proacl => '{POSTGRES=X}' },
 { oid => '3775',
   descr => 'statistics: reset collected statistics shared across the cluster',
   proname => 'pg_stat_reset_shared', proisstrict => 'f', provolatile => 'v',
   prorettype => 'void', proargtypes => 'text',
   proargnames => '{target}', proargdefaults => '{NULL}',
-  prosrc => 'pg_stat_reset_shared' },
+  prosrc => 'pg_stat_reset_shared',
+  proacl => '{POSTGRES=X}' },
 { oid => '3776',
   descr => 'statistics: reset collected statistics for a single table or index in the current database or shared across all databases in the cluster',
   proname => 'pg_stat_reset_single_table_counters', provolatile => 'v',
   prorettype => 'void', proargtypes => 'oid',
-  prosrc => 'pg_stat_reset_single_table_counters' },
+  prosrc => 'pg_stat_reset_single_table_counters',
+  proacl => '{POSTGRES=X}' },
 { oid => '3777',
   descr => 'statistics: reset collected statistics for a single function in the current database',
   proname => 'pg_stat_reset_single_function_counters', provolatile => 'v',
   prorettype => 'void', proargtypes => 'oid',
-  prosrc => 'pg_stat_reset_single_function_counters' },
+  prosrc => 'pg_stat_reset_single_function_counters',
+  proacl => '{POSTGRES=X}' },
 { oid => '6387', descr => 'statistics: reset statistics for a single backend',
   proname => 'pg_stat_reset_backend_stats', provolatile => 'v',
   prorettype => 'void', proargtypes => 'int4',
-  prosrc => 'pg_stat_reset_backend_stats' },
+  prosrc => 'pg_stat_reset_backend_stats',
+  proacl => '{POSTGRES=X}' },
 { oid => '2307',
   descr => 'statistics: reset collected statistics for a single SLRU',
   proname => 'pg_stat_reset_slru', proisstrict => 'f', provolatile => 'v',
   prorettype => 'void', proargtypes => 'text', proargnames => '{target}',
   proargdefaults => '{NULL}',
-  prosrc => 'pg_stat_reset_slru' },
+  prosrc => 'pg_stat_reset_slru',
+  proacl => '{POSTGRES=X}' },
 { oid => '6170',
   descr => 'statistics: reset collected statistics for a single replication slot',
   proname => 'pg_stat_reset_replication_slot', proisstrict => 'f',
   provolatile => 'v', prorettype => 'void', proargtypes => 'text',
-  prosrc => 'pg_stat_reset_replication_slot' },
+  prosrc => 'pg_stat_reset_replication_slot',
+  proacl => '{POSTGRES=X}' },
 { oid => '6232',
   descr => 'statistics: reset collected statistics for a single subscription',
   proname => 'pg_stat_reset_subscription_stats', proisstrict => 'f',
   provolatile => 'v', prorettype => 'void', proargtypes => 'oid',
-  prosrc => 'pg_stat_reset_subscription_stats' },
+  prosrc => 'pg_stat_reset_subscription_stats',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '3163', descr => 'current trigger depth',
   proname => 'pg_trigger_depth', provolatile => 's', proparallel => 'r',
   proallargtypes => '{text,int4,int4,text,text,bool,text}',
   proargmodes => '{o,o,o,o,o,o,o}',
   proargnames => '{sourcefile,sourceline,seqno,name,setting,applied,error}',
-  prosrc => 'show_all_file_settings' },
+  prosrc => 'show_all_file_settings',
+  proacl => '{POSTGRES=X}' },
 { oid => '3401', descr => 'show pg_hba.conf rules',
   proname => 'pg_hba_file_rules', prorows => '1000', proretset => 't',
   provolatile => 'v', prorettype => 'record', proargtypes => '',
   proallargtypes => '{int4,text,int4,text,_text,_text,text,text,text,_text,text}',
   proargmodes => '{o,o,o,o,o,o,o,o,o,o,o}',
   proargnames => '{rule_number,file_name,line_number,type,database,user_name,address,netmask,auth_method,options,error}',
-  prosrc => 'pg_hba_file_rules' },
+  prosrc => 'pg_hba_file_rules',
+  proacl => '{POSTGRES=X}' },
 { oid => '6250', descr => 'show pg_ident.conf mappings',
   proname => 'pg_ident_file_mappings', prorows => '1000', proretset => 't',
   provolatile => 'v', prorettype => 'record', proargtypes => '',
   proallargtypes => '{int4,text,int4,text,text,text,text}',
   proargmodes => '{o,o,o,o,o,o,o}',
   proargnames => '{map_number,file_name,line_number,map_name,sys_name,pg_username,error}',
-  prosrc => 'pg_ident_file_mappings' },
+  prosrc => 'pg_ident_file_mappings',
+  proacl => '{POSTGRES=X}' },
 { oid => '1371', descr => 'view system lock information',
   proname => 'pg_lock_status', prorows => '1000', proretset => 't',
   provolatile => 'v', prorettype => 'record', proargtypes => '',
   proname => 'pg_backup_start', provolatile => 'v', proparallel => 'r',
   prorettype => 'pg_lsn', proargtypes => 'text bool',
   proargnames => '{label,fast}', proargdefaults => '{false}',
-  prosrc => 'pg_backup_start' },
+  prosrc => 'pg_backup_start',
+  proacl => '{POSTGRES=X}' },
 { oid => '2739', descr => 'finish taking an online backup',
   proname => 'pg_backup_stop', provolatile => 'v', proparallel => 'r',
   prorettype => 'record', proargtypes => 'bool',
   proallargtypes => '{bool,pg_lsn,text,text}', proargmodes => '{i,o,o,o}',
   proargnames => '{wait_for_archive,lsn,labelfile,spcmapfile}',
   proargdefaults => '{true}',
-  prosrc => 'pg_backup_stop' },
+  prosrc => 'pg_backup_stop',
+  proacl => '{POSTGRES=X}' },
 { oid => '3436', descr => 'promote standby server',
   proname => 'pg_promote', provolatile => 'v', prorettype => 'bool',
   proargtypes => 'bool int4', proargnames => '{wait,wait_seconds}',
   proargdefaults => '{true,60}',
-  prosrc => 'pg_promote' },
+  prosrc => 'pg_promote',
+  proacl => '{POSTGRES=X}' },
 { oid => '2848', descr => 'switch to new wal file',
   proname => 'pg_switch_wal', provolatile => 'v', prorettype => 'pg_lsn',
-  proargtypes => '', prosrc => 'pg_switch_wal' },
+  proargtypes => '', prosrc => 'pg_switch_wal',
+  proacl => '{POSTGRES=X}' },
 { oid => '6305', descr => 'log details of the current snapshot to WAL',
   proname => 'pg_log_standby_snapshot', provolatile => 'v',
   prorettype => 'pg_lsn', proargtypes => '',
-  prosrc => 'pg_log_standby_snapshot' },
+  prosrc => 'pg_log_standby_snapshot',
+  proacl => '{POSTGRES=X}' },
 { oid => '3098', descr => 'create a named restore point',
   proname => 'pg_create_restore_point', provolatile => 'v',
   prorettype => 'pg_lsn', proargtypes => 'text',
-  prosrc => 'pg_create_restore_point' },
+  prosrc => 'pg_create_restore_point',
+  proacl => '{POSTGRES=X}' },
 { oid => '2849', descr => 'current wal write location',
   proname => 'pg_current_wal_lsn', provolatile => 'v', prorettype => 'pg_lsn',
   proargtypes => '', prosrc => 'pg_current_wal_lsn' },
 
 { oid => '3071', descr => 'pause wal replay',
   proname => 'pg_wal_replay_pause', provolatile => 'v', prorettype => 'void',
-  proargtypes => '', prosrc => 'pg_wal_replay_pause' },
+  proargtypes => '', prosrc => 'pg_wal_replay_pause',
+  proacl => '{POSTGRES=X}' },
 { oid => '3072', descr => 'resume wal replay, if it was paused',
   proname => 'pg_wal_replay_resume', provolatile => 'v', prorettype => 'void',
-  proargtypes => '', prosrc => 'pg_wal_replay_resume' },
+  proargtypes => '', prosrc => 'pg_wal_replay_resume',
+  proacl => '{POSTGRES=X}' },
 { oid => '3073', descr => 'true if wal replay is paused',
   proname => 'pg_is_wal_replay_paused', provolatile => 'v',
   prorettype => 'bool', proargtypes => '',
 
 { oid => '2621', descr => 'reload configuration files',
   proname => 'pg_reload_conf', provolatile => 'v', prorettype => 'bool',
-  proargtypes => '', prosrc => 'pg_reload_conf' },
+  proargtypes => '', prosrc => 'pg_reload_conf',
+  proacl => '{POSTGRES=X}' },
 { oid => '2622', descr => 'rotate log file',
   proname => 'pg_rotate_logfile', provolatile => 'v', prorettype => 'bool',
-  proargtypes => '', prosrc => 'pg_rotate_logfile' },
+  proargtypes => '', prosrc => 'pg_rotate_logfile',
+  proacl => '{POSTGRES=X}' },
 { oid => '3800', descr => 'current logging collector file location',
   proname => 'pg_current_logfile', proisstrict => 'f', provolatile => 'v',
-  prorettype => 'text', proargtypes => '', prosrc => 'pg_current_logfile' },
+  prorettype => 'text', proargtypes => '', prosrc => 'pg_current_logfile',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 { oid => '3801', descr => 'current logging collector file location',
   proname => 'pg_current_logfile', proisstrict => 'f', provolatile => 'v',
   prorettype => 'text', proargtypes => 'text',
-  prosrc => 'pg_current_logfile_1arg' },
+  prosrc => 'pg_current_logfile_1arg',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 
 { oid => '2623', descr => 'get information about file',
   proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record',
   proallargtypes => '{text,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool}',
   proargmodes => '{i,o,o,o,o,o,o}',
   proargnames => '{filename,size,access,modification,change,creation,isdir}',
-  prosrc => 'pg_stat_file_1arg' },
+  prosrc => 'pg_stat_file_1arg',
+  proacl => '{POSTGRES=X}' },
 { oid => '3307', descr => 'get information about file',
   proname => 'pg_stat_file', provolatile => 'v', prorettype => 'record',
   proargtypes => 'text bool',
   proallargtypes => '{text,bool,int8,timestamptz,timestamptz,timestamptz,timestamptz,bool}',
   proargmodes => '{i,i,o,o,o,o,o,o}',
   proargnames => '{filename,missing_ok,size,access,modification,change,creation,isdir}',
-  prosrc => 'pg_stat_file' },
+  prosrc => 'pg_stat_file',
+  proacl => '{POSTGRES=X}' },
 { oid => '2624', descr => 'read text from a file',
   proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
-  proargtypes => 'text int8 int8', prosrc => 'pg_read_file_off_len' },
+  proargtypes => 'text int8 int8', prosrc => 'pg_read_file_off_len',
+  proacl => '{POSTGRES=X}' },
 { oid => '3293', descr => 'read text from a file',
   proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
   proargtypes => 'text int8 int8 bool',
-  prosrc => 'pg_read_file_off_len_missing' },
+  prosrc => 'pg_read_file_off_len_missing',
+  proacl => '{POSTGRES=X}' },
 { oid => '3826', descr => 'read text from a file',
   proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
-  proargtypes => 'text', prosrc => 'pg_read_file_all' },
+  proargtypes => 'text', prosrc => 'pg_read_file_all',
+  proacl => '{POSTGRES=X}' },
 { oid => '6208', descr => 'read text from a file',
   proname => 'pg_read_file', provolatile => 'v', prorettype => 'text',
-  proargtypes => 'text bool', prosrc => 'pg_read_file_all_missing' },
+  proargtypes => 'text bool', prosrc => 'pg_read_file_all_missing',
+  proacl => '{POSTGRES=X}' },
 { oid => '3827', descr => 'read bytea from a file',
   proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
-  proargtypes => 'text int8 int8', prosrc => 'pg_read_binary_file_off_len' },
+  proargtypes => 'text int8 int8', prosrc => 'pg_read_binary_file_off_len',
+  proacl => '{POSTGRES=X}' },
 { oid => '3295', descr => 'read bytea from a file',
   proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
   proargtypes => 'text int8 int8 bool',
-  prosrc => 'pg_read_binary_file_off_len_missing' },
+  prosrc => 'pg_read_binary_file_off_len_missing',
+  proacl => '{POSTGRES=X}' },
 { oid => '3828', descr => 'read bytea from a file',
   proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
-  proargtypes => 'text', prosrc => 'pg_read_binary_file_all' },
+  proargtypes => 'text', prosrc => 'pg_read_binary_file_all',
+  proacl => '{POSTGRES=X}' },
 { oid => '6209', descr => 'read bytea from a file',
   proname => 'pg_read_binary_file', provolatile => 'v', prorettype => 'bytea',
-  proargtypes => 'text bool', prosrc => 'pg_read_binary_file_all_missing' },
+  proargtypes => 'text bool', prosrc => 'pg_read_binary_file_all_missing',
+  proacl => '{POSTGRES=X}' },
 { oid => '2625', descr => 'list all files in a directory',
   proname => 'pg_ls_dir', prorows => '1000', proretset => 't',
   provolatile => 'v', prorettype => 'text', proargtypes => 'text',
-  prosrc => 'pg_ls_dir_1arg' },
+  prosrc => 'pg_ls_dir_1arg',
+  proacl => '{POSTGRES=X}' },
 { oid => '3297', descr => 'list all files in a directory',
   proname => 'pg_ls_dir', prorows => '1000', proretset => 't',
   provolatile => 'v', prorettype => 'text', proargtypes => 'text bool bool',
-  prosrc => 'pg_ls_dir' },
+  prosrc => 'pg_ls_dir',
+  proacl => '{POSTGRES=X}' },
 { oid => '2626', descr => 'sleep for the specified time in seconds',
   proname => 'pg_sleep', provolatile => 'v', prorettype => 'void',
   proargtypes => 'float8', prosrc => 'pg_sleep' },
   provolatile => 'v', prorettype => 'record', proargtypes => '',
   proallargtypes => '{text,int8,int8,int8}', proargmodes => '{o,o,o,o}',
   proargnames => '{name,off,size,allocated_size}',
-  prosrc => 'pg_get_shmem_allocations' },
+  prosrc => 'pg_get_shmem_allocations',
+  proacl => '{POSTGRES=X,pg_read_all_stats=X}' },
 
 { oid => '4099', descr => 'Is NUMA support available?',
   proname => 'pg_numa_available', provolatile => 's', prorettype => 'bool',
   provolatile => 'v', prorettype => 'record', proargtypes => '',
   proallargtypes => '{text,int4,int8}', proargmodes => '{o,o,o}',
   proargnames => '{name,numa_node,size}',
-  prosrc => 'pg_get_shmem_allocations_numa' },
+  prosrc => 'pg_get_shmem_allocations_numa',
+  proacl => '{POSTGRES=X,pg_read_all_stats=X}' },
 
 { oid => '9314',
   descr => 'shared memory allocations tracked in the DSM registry',
   proretset => 't', provolatile => 'v', prorettype => 'record',
   proargtypes => '', proallargtypes => '{text,text,int8}',
   proargmodes => '{o,o,o}', proargnames => '{name,type,size}',
-  prosrc => 'pg_get_dsm_registry_allocations' },
+  prosrc => 'pg_get_dsm_registry_allocations',
+  proacl => '{POSTGRES=X,pg_read_all_stats=X}' },
 
 # memory context of local backend
 { oid => '2282',
   proallargtypes => '{text,text,text,int4,_int4,int8,int8,int8,int8,int8}',
   proargmodes => '{o,o,o,o,o,o,o,o,o,o}',
   proargnames => '{name, ident, type, level, path, total_bytes, total_nblocks, free_bytes, free_chunks, used_bytes}',
-  prosrc => 'pg_get_backend_memory_contexts' },
+  prosrc => 'pg_get_backend_memory_contexts',
+  proacl => '{POSTGRES=X,pg_read_all_stats=X}' },
 
 # logging memory contexts of the specified backend
 { oid => '4543', descr => 'log memory contexts of the specified backend',
   proname => 'pg_log_backend_memory_contexts', provolatile => 'v',
   prorettype => 'bool', proargtypes => 'int4',
-  prosrc => 'pg_log_backend_memory_contexts' },
+  prosrc => 'pg_log_backend_memory_contexts',
+  proacl => '{POSTGRES=X}' },
 
 # non-persistent series generator
 { oid => '1066', descr => 'non-persistent series generator',
 { oid => '6003', descr => 'create a replication origin',
   proname => 'pg_replication_origin_create', provolatile => 'v',
   proparallel => 'u', prorettype => 'oid', proargtypes => 'text',
-  prosrc => 'pg_replication_origin_create' },
+  prosrc => 'pg_replication_origin_create',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6004', descr => 'drop replication origin identified by its name',
   proname => 'pg_replication_origin_drop', provolatile => 'v',
   proparallel => 'u', prorettype => 'void', proargtypes => 'text',
-  prosrc => 'pg_replication_origin_drop' },
+  prosrc => 'pg_replication_origin_drop',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6005',
   descr => 'translate the replication origin\'s name to its id',
   proname => 'pg_replication_origin_oid', provolatile => 's',
   prorettype => 'oid', proargtypes => 'text',
-  prosrc => 'pg_replication_origin_oid' },
+  prosrc => 'pg_replication_origin_oid',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6006',
   descr => 'configure session to maintain replication progress tracking for the passed in origin',
   proname => 'pg_replication_origin_session_setup', provolatile => 'v',
   proparallel => 'u', prorettype => 'void', proargtypes => 'text int4',
   proargnames => '{node_name,pid}', proargdefaults => '{0}',
-  prosrc => 'pg_replication_origin_session_setup' },
+  prosrc => 'pg_replication_origin_session_setup',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6007', descr => 'teardown configured replication progress tracking',
   proname => 'pg_replication_origin_session_reset', provolatile => 'v',
   proparallel => 'u', prorettype => 'void', proargtypes => '',
-  prosrc => 'pg_replication_origin_session_reset' },
+  prosrc => 'pg_replication_origin_session_reset',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6008',
   descr => 'is a replication origin configured in this session',
   proname => 'pg_replication_origin_session_is_setup', provolatile => 'v',
   proparallel => 'r', prorettype => 'bool', proargtypes => '',
-  prosrc => 'pg_replication_origin_session_is_setup' },
+  prosrc => 'pg_replication_origin_session_is_setup',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6009',
   descr => 'get the replication progress of the current session',
   proname => 'pg_replication_origin_session_progress', provolatile => 'v',
   proparallel => 'u', prorettype => 'pg_lsn', proargtypes => 'bool',
-  prosrc => 'pg_replication_origin_session_progress' },
+  prosrc => 'pg_replication_origin_session_progress',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6010', descr => 'setup the transaction\'s origin lsn and timestamp',
   proname => 'pg_replication_origin_xact_setup', provolatile => 'v',
   proparallel => 'r', prorettype => 'void', proargtypes => 'pg_lsn timestamptz',
-  prosrc => 'pg_replication_origin_xact_setup' },
+  prosrc => 'pg_replication_origin_xact_setup',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6011', descr => 'reset the transaction\'s origin lsn and timestamp',
   proname => 'pg_replication_origin_xact_reset', provolatile => 'v',
   proparallel => 'r', prorettype => 'void', proargtypes => '',
-  prosrc => 'pg_replication_origin_xact_reset' },
+  prosrc => 'pg_replication_origin_xact_reset',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6012', descr => 'advance replication origin to specific location',
   proname => 'pg_replication_origin_advance', provolatile => 'v',
   proparallel => 'u', prorettype => 'void', proargtypes => 'text pg_lsn',
-  prosrc => 'pg_replication_origin_advance' },
+  prosrc => 'pg_replication_origin_advance',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6013',
   descr => 'get an individual replication origin\'s replication progress',
   proname => 'pg_replication_origin_progress', provolatile => 'v',
   proparallel => 'u', prorettype => 'pg_lsn', proargtypes => 'text bool',
-  prosrc => 'pg_replication_origin_progress' },
+  prosrc => 'pg_replication_origin_progress',
+  proacl => '{POSTGRES=X}' },
 
 { oid => '6014', descr => 'get progress for all replication origins',
   proname => 'pg_show_replication_origin_status', prorows => '100',
   prorettype => 'record', proargtypes => '',
   proallargtypes => '{oid,text,pg_lsn,pg_lsn}', proargmodes => '{o,o,o,o}',
   proargnames => '{local_id, external_id, remote_lsn, local_lsn}',
-  prosrc => 'pg_show_replication_origin_status' },
+  prosrc => 'pg_show_replication_origin_status',
+  proacl => '{POSTGRES=X}' },
 
 # publications
 { oid => '6119',
   proname => 'pg_config', prorows => '23', proretset => 't', provolatile => 's',
   proparallel => 'r', prorettype => 'record', proargtypes => '',
   proallargtypes => '{text,text}', proargmodes => '{o,o}',
-  proargnames => '{name,setting}', prosrc => 'pg_config' },
+  proargnames => '{name,setting}', prosrc => 'pg_config',
+  proacl => '{POSTGRES=X}' },
 
 # pg_controldata related functions
 { oid => '3441',
   proname => 'pg_ls_logdir', procost => '10', prorows => '20', proretset => 't',
   provolatile => 'v', prorettype => 'record', proargtypes => '',
   proallargtypes => '{text,int8,timestamptz}', proargmodes => '{o,o,o}',
-  proargnames => '{name,size,modification}', prosrc => 'pg_ls_logdir' },
+  proargnames => '{name,size,modification}', prosrc => 'pg_ls_logdir',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 { oid => '3354', descr => 'list of files in the WAL directory',
   proname => 'pg_ls_waldir', procost => '10', prorows => '20', proretset => 't',
   provolatile => 'v', prorettype => 'record', proargtypes => '',
   proallargtypes => '{text,int8,timestamptz}', proargmodes => '{o,o,o}',
-  proargnames => '{name,size,modification}', prosrc => 'pg_ls_waldir' },
+  proargnames => '{name,size,modification}', prosrc => 'pg_ls_waldir',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 { oid => '6400', descr => 'list of files in the pg_wal/summaries directory',
   proname => 'pg_ls_summariesdir', procost => '10', prorows => '20',
   proretset => 't', provolatile => 'v', prorettype => 'record',
   proargtypes => '', proallargtypes => '{text,int8,timestamptz}',
   proargmodes => '{o,o,o}', proargnames => '{name,size,modification}',
-  prosrc => 'pg_ls_summariesdir' },
+  prosrc => 'pg_ls_summariesdir',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 { oid => '5031', descr => 'list of files in the archive_status directory',
   proname => 'pg_ls_archive_statusdir', procost => '10', prorows => '20',
   proretset => 't', provolatile => 'v', prorettype => 'record',
   proargtypes => '', proallargtypes => '{text,int8,timestamptz}',
   proargmodes => '{o,o,o}', proargnames => '{name,size,modification}',
-  prosrc => 'pg_ls_archive_statusdir' },
+  prosrc => 'pg_ls_archive_statusdir',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 { oid => '5029', descr => 'list files in the pgsql_tmp directory',
   proname => 'pg_ls_tmpdir', procost => '10', prorows => '20', proretset => 't',
   provolatile => 'v', prorettype => 'record', proargtypes => '',
   proallargtypes => '{text,int8,timestamptz}', proargmodes => '{o,o,o}',
-  proargnames => '{name,size,modification}', prosrc => 'pg_ls_tmpdir_noargs' },
+  proargnames => '{name,size,modification}', prosrc => 'pg_ls_tmpdir_noargs',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 { oid => '5030', descr => 'list files in the pgsql_tmp directory',
   proname => 'pg_ls_tmpdir', procost => '10', prorows => '20', proretset => 't',
   provolatile => 'v', prorettype => 'record', proargtypes => 'oid',
   proallargtypes => '{oid,text,int8,timestamptz}', proargmodes => '{i,o,o,o}',
   proargnames => '{tablespace,name,size,modification}',
-  prosrc => 'pg_ls_tmpdir_1arg' },
+  prosrc => 'pg_ls_tmpdir_1arg',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 { oid => '6270',
   descr => 'list of files in the pg_logical/snapshots directory',
   proname => 'pg_ls_logicalsnapdir', procost => '10', prorows => '20',
   proretset => 't', provolatile => 'v', prorettype => 'record',
   proargtypes => '', proallargtypes => '{text,int8,timestamptz}',
   proargmodes => '{o,o,o}', proargnames => '{name,size,modification}',
-  prosrc => 'pg_ls_logicalsnapdir' },
+  prosrc => 'pg_ls_logicalsnapdir',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 { oid => '6271',
   descr => 'list of files in the pg_logical/mappings directory',
   proname => 'pg_ls_logicalmapdir', procost => '10', prorows => '20',
   proretset => 't', provolatile => 'v', prorettype => 'record',
   proargtypes => '', proallargtypes => '{text,int8,timestamptz}',
   proargmodes => '{o,o,o}', proargnames => '{name,size,modification}',
-  prosrc => 'pg_ls_logicalmapdir' },
+  prosrc => 'pg_ls_logicalmapdir',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 { oid => '6272',
   descr => 'list of files in the pg_replslot/slot_name directory',
   proname => 'pg_ls_replslotdir', procost => '10', prorows => '20',
   proargtypes => 'text', proallargtypes => '{text,text,int8,timestamptz}',
   proargmodes => '{i,o,o,o}',
   proargnames => '{slot_name,name,size,modification}',
-  prosrc => 'pg_ls_replslotdir' },
+  prosrc => 'pg_ls_replslotdir',
+  proacl => '{POSTGRES=X,pg_monitor=X}' },
 
 # hash partitioning constraint function
 { oid => '5028', descr => 'hash partition CHECK constraint',
   proallargtypes => '{int4,int4,int8,text,text,int8,int8,text,int2,int4,text,text,bool,bool,bool}',
   proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
   proargnames => '{pid,io_id,io_generation,state,operation,off,length,target,handle_data_len,raw_result,result,target_desc,f_sync,f_localmem,f_buffered}',
-  prosrc => 'pg_get_aios' },
+  prosrc => 'pg_get_aios',
+  proacl => '{POSTGRES=X,pg_read_all_stats=X}' },
 
 # oid8 related functions
 { oid => '8255', descr => 'convert oid to oid8',