From 18860d4352c50fc6beb96757145456ceeab80c74 Mon Sep 17 00:00:00 2001 From: Hari Babu Date: Mon, 8 Jan 2018 14:20:50 +1100 Subject: [PATCH 2/2] Effective conninfo column addtion to pg_stat_wal_receiver This column provides the connection string that is currently effective in connecting to the server from the list of provided connection string details. --- doc/src/sgml/monitoring.sgml | 10 +++++++- src/backend/catalog/system_views.sql | 3 ++- .../libpqwalreceiver/libpqwalreceiver.c | 29 ++++++++++++++++++++-- src/backend/replication/walreceiver.c | 14 +++++++++++ src/include/catalog/pg_proc.h | 2 +- src/include/replication/walreceiver.h | 10 ++++++++ src/test/regress/expected/rules.out | 5 ++-- 7 files changed, 66 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 8a9793644f..a1c2d5b6d3 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -2026,7 +2026,15 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i conninfo text - Connection string used by this WAL receiver, + Initial connection string used by this WAL receiver, + with security-sensitive fields obfuscated. + + + + effective_conninfo + text + + Effective connection string used by this WAL receiver, with security-sensitive fields obfuscated. diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 5652e9ee6d..6644f6cc73 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -750,7 +750,8 @@ CREATE VIEW pg_stat_wal_receiver AS s.latest_end_lsn, s.latest_end_time, s.slot_name, - s.conninfo + s.conninfo, + s.effective_conninfo FROM pg_stat_get_wal_receiver() s WHERE s.pid IS NOT NULL; diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index f9aec0531a..31c5d77659 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -53,6 +53,7 @@ static WalReceiverConn *libpqrcv_connect(const char *conninfo, char **err); static void libpqrcv_check_conninfo(const char *conninfo); static char *libpqrcv_get_conninfo(WalReceiverConn *conn); +static char *libpqrcv_get_effective_conninfo(WalReceiverConn *conn); static char *libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli, int *server_version); @@ -82,6 +83,7 @@ static WalReceiverFunctionsType PQWalReceiverFunctions = { libpqrcv_connect, libpqrcv_check_conninfo, libpqrcv_get_conninfo, + libpqrcv_get_effective_conninfo, libpqrcv_identify_system, libpqrcv_readtimelinehistoryfile, libpqrcv_startstreaming, @@ -238,7 +240,7 @@ libpqrcv_check_conninfo(const char *conninfo) * are obfuscated. */ static char * -libpqrcv_get_conninfo(WalReceiverConn *conn) +libpqrcv_get_conninfo_internal(WalReceiverConn *conn, bool initial) { PQconninfoOption *conn_opts; PQconninfoOption *conn_opt; @@ -248,7 +250,10 @@ libpqrcv_get_conninfo(WalReceiverConn *conn) Assert(conn->streamConn != NULL); initPQExpBuffer(&buf); - conn_opts = PQconninfo(conn->streamConn); + if (initial) + conn_opts = PQconninfo(conn->streamConn); + else + conn_opts = PQeffectiveConninfo(conn->streamConn); if (conn_opts == NULL) ereport(ERROR, @@ -282,6 +287,26 @@ libpqrcv_get_conninfo(WalReceiverConn *conn) return retval; } +/* + * Return a user-displayable conninfo string. Any security-sensitive fields + * are obfuscated. + */ +static char * +libpqrcv_get_conninfo(WalReceiverConn *conn) +{ + return libpqrcv_get_conninfo_internal(conn, true); +} + +/* + * Return a user-displayable effective conninfo string. + * Any security-sensitive fields are obfuscated. + */ +static char * +libpqrcv_get_effective_conninfo(WalReceiverConn *conn) +{ + return libpqrcv_get_conninfo_internal(conn, false); +} + /* * Check that primary's system identifier matches ours, and fetch the current * timeline ID of the primary. diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index a39a98ff18..0f6d5ea3e0 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -189,6 +189,7 @@ WalReceiverMain(void) { char conninfo[MAXCONNINFO]; char *tmp_conninfo; + char *tmp_effective_conninfo; char slotname[NAMEDATALEN]; XLogRecPtr startpoint; TimeLineID startpointTLI; @@ -311,10 +312,17 @@ WalReceiverMain(void) * conninfo, for security. */ tmp_conninfo = walrcv_get_conninfo(wrconn); + tmp_effective_conninfo = walrcv_get_effective_conninfo(wrconn); + SpinLockAcquire(&walrcv->mutex); memset(walrcv->conninfo, 0, MAXCONNINFO); if (tmp_conninfo) strlcpy((char *) walrcv->conninfo, tmp_conninfo, MAXCONNINFO); + + memset(walrcv->effective_conninfo, 0, MAXCONNINFO); + if (tmp_effective_conninfo) + strlcpy((char *) walrcv->effective_conninfo, tmp_effective_conninfo, MAXCONNINFO); + walrcv->ready_to_display = true; SpinLockRelease(&walrcv->mutex); @@ -1404,6 +1412,7 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS) TimestampTz latest_end_time; char slotname[NAMEDATALEN]; char conninfo[MAXCONNINFO]; + char effective_conninfo[MAXCONNINFO]; /* Take a lock to ensure value consistency */ SpinLockAcquire(&WalRcv->mutex); @@ -1420,6 +1429,7 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS) latest_end_time = WalRcv->latestWalEndTime; strlcpy(slotname, (char *) WalRcv->slotname, sizeof(slotname)); strlcpy(conninfo, (char *) WalRcv->conninfo, sizeof(conninfo)); + strlcpy(effective_conninfo, (char *) WalRcv->effective_conninfo, sizeof(effective_conninfo)); SpinLockRelease(&WalRcv->mutex); /* @@ -1486,6 +1496,10 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS) nulls[11] = true; else values[11] = CStringGetTextDatum(conninfo); + if (*effective_conninfo == '\0') + nulls[12] = true; + else + values[12] = CStringGetTextDatum(effective_conninfo); } /* Returns the record as Datum */ diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 298e0ae2f0..c883bfda17 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -2883,7 +2883,7 @@ DATA(insert OID = 3318 ( pg_stat_get_progress_info PGNSP PGUID 12 1 100 0 0 DESCR("statistics: information about progress of backends running maintenance command"); DATA(insert OID = 3099 ( pg_stat_get_wal_senders PGNSP PGUID 12 1 10 0 0 f f f f f t s r 0 0 2249 "" "{23,25,3220,3220,3220,3220,1186,1186,1186,23,25}" "{o,o,o,o,o,o,o,o,o,o,o}" "{pid,state,sent_lsn,write_lsn,flush_lsn,replay_lsn,write_lag,flush_lag,replay_lag,sync_priority,sync_state}" _null_ _null_ pg_stat_get_wal_senders _null_ _null_ _null_ )); DESCR("statistics: information about currently active replication"); -DATA(insert OID = 3317 ( pg_stat_get_wal_receiver PGNSP PGUID 12 1 0 0 0 f f f f f f s r 0 0 2249 "" "{23,25,3220,23,3220,23,1184,1184,3220,1184,25,25}" "{o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,status,receive_start_lsn,receive_start_tli,received_lsn,received_tli,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time,slot_name,conninfo}" _null_ _null_ pg_stat_get_wal_receiver _null_ _null_ _null_ )); +DATA(insert OID = 3317 ( pg_stat_get_wal_receiver PGNSP PGUID 12 1 0 0 0 f f f f f f s r 0 0 2249 "" "{23,25,3220,23,3220,23,1184,1184,3220,1184,25,25,25}" "{o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,status,receive_start_lsn,receive_start_tli,received_lsn,received_tli,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time,slot_name,conninfo,effective_conninfo}" _null_ _null_ pg_stat_get_wal_receiver _null_ _null_ _null_ )); DESCR("statistics: information about WAL receiver"); DATA(insert OID = 6118 ( pg_stat_get_subscription PGNSP PGUID 12 1 0 0 0 f f f f f f s r 1 0 2249 "26" "{26,26,26,23,3220,1184,1184,3220,1184}" "{i,o,o,o,o,o,o,o,o}" "{subid,subid,relid,pid,received_lsn,last_msg_send_time,last_msg_receipt_time,latest_end_lsn,latest_end_time}" _null_ _null_ pg_stat_get_subscription _null_ _null_ _null_ )); DESCR("statistics: information about subscription"); diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h index ea7967f6fc..92f56b6834 100644 --- a/src/include/replication/walreceiver.h +++ b/src/include/replication/walreceiver.h @@ -108,6 +108,12 @@ typedef struct */ char conninfo[MAXCONNINFO]; + /* + * connection string; effectively used to connect to the primary, and later + * clobbered to hide security-sensitive fields. + */ + char effective_conninfo[MAXCONNINFO]; + /* * replication slot name; is also used for walreceiver to connect with the * primary @@ -197,6 +203,7 @@ typedef WalReceiverConn *(*walrcv_connect_fn) (const char *conninfo, bool logica char **err); typedef void (*walrcv_check_conninfo_fn) (const char *conninfo); typedef char *(*walrcv_get_conninfo_fn) (WalReceiverConn *conn); +typedef char *(*walrcv_get_effective_conninfo_fn) (WalReceiverConn *conn); typedef char *(*walrcv_identify_system_fn) (WalReceiverConn *conn, TimeLineID *primary_tli, int *server_version); @@ -227,6 +234,7 @@ typedef struct WalReceiverFunctionsType walrcv_connect_fn walrcv_connect; walrcv_check_conninfo_fn walrcv_check_conninfo; walrcv_get_conninfo_fn walrcv_get_conninfo; + walrcv_get_effective_conninfo_fn walrcv_get_effective_conninfo; walrcv_identify_system_fn walrcv_identify_system; walrcv_readtimelinehistoryfile_fn walrcv_readtimelinehistoryfile; walrcv_startstreaming_fn walrcv_startstreaming; @@ -246,6 +254,8 @@ extern PGDLLIMPORT WalReceiverFunctionsType *WalReceiverFunctions; WalReceiverFunctions->walrcv_check_conninfo(conninfo) #define walrcv_get_conninfo(conn) \ WalReceiverFunctions->walrcv_get_conninfo(conn) +#define walrcv_get_effective_conninfo(conn) \ + WalReceiverFunctions->walrcv_get_effective_conninfo(conn) #define walrcv_identify_system(conn, primary_tli, server_version) \ WalReceiverFunctions->walrcv_identify_system(conn, primary_tli, server_version) #define walrcv_readtimelinehistoryfile(conn, tli, filename, content, size) \ diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index f1c1b44d6f..3712a0d62f 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1970,8 +1970,9 @@ pg_stat_wal_receiver| SELECT s.pid, s.latest_end_lsn, s.latest_end_time, s.slot_name, - s.conninfo - FROM pg_stat_get_wal_receiver() s(pid, status, receive_start_lsn, receive_start_tli, received_lsn, received_tli, last_msg_send_time, last_msg_receipt_time, latest_end_lsn, latest_end_time, slot_name, conninfo) + s.conninfo, + s.effective_conninfo + FROM pg_stat_get_wal_receiver() s(pid, status, receive_start_lsn, receive_start_tli, received_lsn, received_tli, last_msg_send_time, last_msg_receipt_time, latest_end_lsn, latest_end_time, slot_name, conninfo, effective_conninfo) WHERE (s.pid IS NOT NULL); pg_stat_xact_all_tables| SELECT c.oid AS relid, n.nspname AS schemaname, -- 2.15.0.windows.1