mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-22 22:56:29 +00:00
"node check": check role membership when trying to read pg_settings
From PostgreSQL 10, a member of the default roles "pg_monitor" and/or "pg_read_all_settings" can read pg_settings without requiring superuser privileges. Previously, a hint was being emitted about making the repmgr user a member of one of those groups, but no check for membership was being made, meaning the check could only be run by a superuser.
This commit is contained in:
3
HISTORY
3
HISTORY
@@ -1,3 +1,6 @@
|
||||
4.4.1 2019-??-??
|
||||
repmgr: improve data directory check (Ian)
|
||||
|
||||
4.4 2019-06-27
|
||||
repmgr: improve "daemon status" output (Ian)
|
||||
repmgr: add "--siblings-follow" option to "standby promote" (Ian)
|
||||
|
||||
51
dbutils.c
51
dbutils.c
@@ -336,12 +336,10 @@ establish_db_connection_by_params(t_conninfo_param_list *param_list,
|
||||
bool
|
||||
is_superuser_connection(PGconn *conn, t_connection_user *userinfo)
|
||||
{
|
||||
char *current_user = NULL;
|
||||
const char *superuser_status = NULL;
|
||||
bool is_superuser = false;
|
||||
const char *current_user = PQuser(conn);
|
||||
const char *superuser_status = PQparameterStatus(conn, "is_superuser");
|
||||
|
||||
current_user = PQuser(conn);
|
||||
superuser_status = PQparameterStatus(conn, "is_superuser");
|
||||
is_superuser = (strcmp(superuser_status, "on") == 0) ? true : false;
|
||||
|
||||
if (userinfo != NULL)
|
||||
@@ -356,6 +354,51 @@ is_superuser_connection(PGconn *conn, t_connection_user *userinfo)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
connection_has_pg_settings(PGconn *conn)
|
||||
{
|
||||
bool has_pg_settings = false;
|
||||
|
||||
/* superusers can always read pg_settings */
|
||||
if (is_superuser_connection(conn, NULL) == true)
|
||||
{
|
||||
has_pg_settings = true;
|
||||
}
|
||||
/* from PostgreSQL 10, a non-superuser may have been granted access */
|
||||
else if(PQserverVersion(conn) >= 100000)
|
||||
{
|
||||
PQExpBufferData query;
|
||||
PGresult *res;
|
||||
|
||||
initPQExpBuffer(&query);
|
||||
appendPQExpBufferStr(&query,
|
||||
" SELECT CASE "
|
||||
" WHEN pg_catalog.pg_has_role(CURRENT_USER, 'pg_monitor','MEMBER') "
|
||||
" THEN TRUE "
|
||||
" WHEN pg_catalog.pg_has_role(CURRENT_USER, 'pg_read_all_settings','MEMBER') "
|
||||
" THEN TRUE "
|
||||
" ELSE FALSE "
|
||||
" END AS has_pg_settings");
|
||||
|
||||
res = PQexec(conn, query.data);
|
||||
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||
{
|
||||
log_db_error(conn, query.data,
|
||||
_("connection_has_pg_settings(): unable to query user roles"));
|
||||
}
|
||||
else
|
||||
{
|
||||
has_pg_settings = atobool(PQgetvalue(res, 0, 0));
|
||||
}
|
||||
termPQExpBuffer(&query);
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
return has_pg_settings;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
close_connection(PGconn **conn)
|
||||
{
|
||||
|
||||
@@ -438,6 +438,7 @@ PGconn *get_primary_connection(PGconn *standby_conn, int *primary_id, char *p
|
||||
PGconn *get_primary_connection_quiet(PGconn *standby_conn, int *primary_id, char *primary_conninfo_out);
|
||||
|
||||
bool is_superuser_connection(PGconn *conn, t_connection_user *userinfo);
|
||||
bool connection_has_pg_settings(PGconn *conn);
|
||||
void close_connection(PGconn **conn);
|
||||
|
||||
/* conninfo manipulation functions */
|
||||
|
||||
@@ -1833,7 +1833,7 @@ do_node_check_data_directory(PGconn *conn, OutputMode mode, t_node_info *node_in
|
||||
* a superuser connection
|
||||
*/
|
||||
|
||||
if (is_superuser_connection(conn, NULL) == true)
|
||||
if (connection_has_pg_settings(conn) == true)
|
||||
{
|
||||
/* we expect to have a database connection */
|
||||
if (get_pg_setting(conn, "data_directory", actual_data_directory) == false)
|
||||
@@ -1878,7 +1878,7 @@ do_node_check_data_directory(PGconn *conn, OutputMode mode, t_node_info *node_in
|
||||
/* XXX add -S/--superuser option */
|
||||
if (PQserverVersion(conn) >= 100000)
|
||||
{
|
||||
log_hint(_("add the \"%s\" user to group \"pg_read_all_settings\""),
|
||||
log_hint(_("add the \"%s\" user to group \"pg_read_all_settings\" or \"pg_monitor\""),
|
||||
PQuser(conn));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user